aboutsummaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2014-06-22 17:16:06 +0200
committerSebastian Dröge <sebastian@centricular.com>2014-06-22 17:16:06 +0200
commit5254e8378f4c28705a571d7bfbbad5fbd1adb3d3 (patch)
tree3f6cac985731dee5f68347ea99ad30ed19462168 /gst
parent1adbba7bfff7853fca8b02aec57dbe1850d4a55c (diff)
Imported Upstream version 1.3.3
Diffstat (limited to 'gst')
-rw-r--r--gst/Makefile.am11
-rw-r--r--gst/Makefile.in72
-rw-r--r--gst/gst.c57
-rw-r--r--gst/gst.h3
-rw-r--r--gst/gst_private.h29
-rw-r--r--gst/gstallocator.c14
-rw-r--r--gst/gstallocator.h12
-rw-r--r--gst/gstatomicqueue.c4
-rw-r--r--gst/gstatomicqueue.h2
-rw-r--r--gst/gstbin.c98
-rw-r--r--gst/gstbin.h4
-rw-r--r--gst/gstbuffer.c120
-rw-r--r--gst/gstbuffer.h22
-rw-r--r--gst/gstbufferlist.c15
-rw-r--r--gst/gstbufferlist.h4
-rw-r--r--gst/gstbufferpool.c316
-rw-r--r--gst/gstbufferpool.h24
-rw-r--r--gst/gstbus.c52
-rw-r--r--gst/gstbus.h2
-rw-r--r--gst/gstcaps.c102
-rw-r--r--gst/gstcaps.h6
-rw-r--r--gst/gstcapsfeatures.c12
-rw-r--r--gst/gstcapsfeatures.h4
-rw-r--r--gst/gstchildproxy.c14
-rw-r--r--gst/gstclock.c2
-rw-r--r--gst/gstconfig.h.in6
-rw-r--r--gst/gstcontext.c15
-rw-r--r--gst/gstcontext.h8
-rw-r--r--gst/gstcontrolbinding.c6
-rw-r--r--gst/gstcontrolbinding.h7
-rw-r--r--gst/gstcontrolsource.c8
-rw-r--r--gst/gstcontrolsource.h1
-rw-r--r--gst/gstdatetime.c53
-rw-r--r--gst/gstdatetime.h16
-rw-r--r--gst/gstdebugutils.c34
-rw-r--r--gst/gstdevice.c350
-rw-r--r--gst/gstdevice.h106
-rw-r--r--gst/gstdevicemonitor.c587
-rw-r--r--gst/gstdevicemonitor.h142
-rw-r--r--gst/gstdevicemonitorfactory.c594
-rw-r--r--gst/gstdevicemonitorfactory.h90
-rw-r--r--gst/gstelement.c28
-rw-r--r--gst/gstelement.h4
-rw-r--r--gst/gstelementfactory.c28
-rw-r--r--gst/gsterror.c8
-rw-r--r--gst/gstevent.c98
-rw-r--r--gst/gstevent.h14
-rw-r--r--gst/gstformat.c6
-rw-r--r--gst/gstghostpad.c44
-rw-r--r--gst/gstglobaldevicemonitor.c501
-rw-r--r--gst/gstglobaldevicemonitor.h105
-rw-r--r--gst/gstinfo.c124
-rw-r--r--gst/gstinfo.h14
-rw-r--r--gst/gstiterator.c78
-rw-r--r--gst/gstiterator.h2
-rw-r--r--gst/gstmemory.c23
-rw-r--r--gst/gstmemory.h3
-rw-r--r--gst/gstmessage.c186
-rw-r--r--gst/gstmessage.h48
-rw-r--r--gst/gstmeta.c4
-rw-r--r--gst/gstmeta.h7
-rw-r--r--gst/gstminiobject.c26
-rw-r--r--gst/gstminiobject.h4
-rw-r--r--gst/gstobject.c67
-rw-r--r--gst/gstobject.h4
-rw-r--r--gst/gstpad.c368
-rw-r--r--gst/gstpad.h424
-rw-r--r--gst/gstpadtemplate.c15
-rw-r--r--gst/gstpadtemplate.h2
-rw-r--r--gst/gstparamspecs.c2
-rw-r--r--gst/gstparse.c13
-rw-r--r--gst/gstparse.h4
-rw-r--r--gst/gstpipeline.c6
-rw-r--r--gst/gstplugin.c41
-rw-r--r--gst/gstplugin.h10
-rw-r--r--gst/gstpluginfeature.c8
-rw-r--r--gst/gstpluginfeature.h2
-rw-r--r--gst/gstpluginloader.c33
-rw-r--r--gst/gstpoll.c17
-rw-r--r--gst/gstpreset.c23
-rw-r--r--gst/gstquark.c4
-rw-r--r--gst/gstquark.h6
-rw-r--r--gst/gstquery.c193
-rw-r--r--gst/gstquery.h10
-rw-r--r--gst/gstregistry.c80
-rw-r--r--gst/gstregistrybinary.c2
-rw-r--r--gst/gstregistrychunks.c74
-rw-r--r--gst/gstregistrychunks.h13
-rw-r--r--gst/gstsample.c14
-rw-r--r--gst/gstsegment.c16
-rw-r--r--gst/gstsegment.h4
-rw-r--r--gst/gststructure.c251
-rw-r--r--gst/gststructure.h16
-rw-r--r--gst/gstsystemclock.c43
-rw-r--r--gst/gstsystemclock.h1
-rw-r--r--gst/gsttaglist.c113
-rw-r--r--gst/gsttaglist.h14
-rw-r--r--gst/gsttagsetter.c12
-rw-r--r--gst/gsttask.c7
-rw-r--r--gst/gsttaskpool.c6
-rw-r--r--gst/gsttoc.c86
-rw-r--r--gst/gsttoc.h39
-rw-r--r--gst/gsttocsetter.c6
-rw-r--r--gst/gsttypefind.c12
-rw-r--r--gst/gsttypefind.h2
-rw-r--r--gst/gsttypefindfactory.c22
-rw-r--r--gst/gsturi.c38
-rw-r--r--gst/gstutils.c209
-rw-r--r--gst/gstutils.h44
-rw-r--r--gst/gstvalue.c530
-rw-r--r--gst/gstvalue.h72
-rw-r--r--gst/parse/Makefile.am19
-rw-r--r--gst/parse/Makefile.in22
-rw-r--r--gst/parse/grammar.y854
-rw-r--r--gst/parse/parse.l34
-rw-r--r--gst/parse/types.h36
-rw-r--r--gst/printf/Makefile.in1
117 files changed, 6349 insertions, 1974 deletions
diff --git a/gst/Makefile.am b/gst/Makefile.am
index b6cf720..86d226e 100644
--- a/gst/Makefile.am
+++ b/gst/Makefile.am
@@ -71,12 +71,16 @@ libgstreamer_@GST_API_VERSION@_la_SOURCES = \
gstcontrolsource.c \
gstdatetime.c \
gstdebugutils.c \
+ gstdevice.c \
+ gstdevicemonitor.c \
+ gstdevicemonitorfactory.c \
gstelement.c \
gstelementfactory.c \
gsterror.c \
gstevent.c \
gstformat.c \
gstghostpad.c \
+ gstglobaldevicemonitor.c \
gstinfo.c \
gstiterator.c \
gstatomicqueue.c \
@@ -172,11 +176,15 @@ gst_headers = \
gstdebugutils.h \
gstelement.h \
gstelementmetadata.h \
+ gstdevice.h \
+ gstdevicemonitor.h \
+ gstdevicemonitorfactory.h \
gstelementfactory.h \
gsterror.h \
gstevent.h \
gstformat.h \
gstghostpad.h \
+ gstglobaldevicemonitor.h \
gstinfo.h \
gstiterator.h \
gstatomicqueue.h \
@@ -274,6 +282,7 @@ BUILT_GIRSOURCES = Gst-@GST_API_VERSION@.gir
gir_headers=$(patsubst %,$(srcdir)/%, $(libgstreamer_@GST_API_VERSION@include_HEADERS))
gir_headers+=$(patsubst %,$(builddir)/%, $(built_header_make))
+gir_headers+=$(patsubst %,$(builddir)/%, gstversion.h)
gir_sources=$(patsubst %,$(srcdir)/%, $(libgstreamer_@GST_API_VERSION@_la_SOURCES))
gir_sources+=$(patsubst %,$(builddir)/%, $(built_source_make))
@@ -290,7 +299,7 @@ Gst-@GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libgstreamer-@GST_API_VERSIO
--include=GLib-2.0 \
--include=GObject-2.0 \
--include=GModule-2.0 \
- --libtool="$(top_builddir)/libtool" \
+ --libtool="${LIBTOOL}" \
--pkg glib-2.0 \
--pkg gobject-2.0 \
--pkg gmodule-no-export-2.0 \
diff --git a/gst/Makefile.in b/gst/Makefile.in
index a074240..eb59429 100644
--- a/gst/Makefile.in
+++ b/gst/Makefile.in
@@ -94,7 +94,6 @@ am__aclocal_m4_deps = $(top_srcdir)/common/m4/as-ac-expand.m4 \
$(top_srcdir)/common/m4/as-compiler-flag.m4 \
$(top_srcdir)/common/m4/as-docbook.m4 \
$(top_srcdir)/common/m4/as-libtool.m4 \
- $(top_srcdir)/common/m4/as-scrub-include.m4 \
$(top_srcdir)/common/m4/as-version.m4 \
$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
$(top_srcdir)/common/m4/gst-arch.m4 \
@@ -175,17 +174,19 @@ am__libgstreamer_@GST_API_VERSION@_la_SOURCES_DIST = gst.c gstobject.c \
gstallocator.c gstbin.c gstbuffer.c gstbufferlist.c \
gstbufferpool.c gstbus.c gstcaps.c gstcapsfeatures.c \
gstchildproxy.c gstclock.c gstcontext.c gstcontrolbinding.c \
- gstcontrolsource.c gstdatetime.c gstdebugutils.c gstelement.c \
+ gstcontrolsource.c gstdatetime.c gstdebugutils.c gstdevice.c \
+ gstdevicemonitor.c gstdevicemonitorfactory.c gstelement.c \
gstelementfactory.c gsterror.c gstevent.c gstformat.c \
- gstghostpad.c gstinfo.c gstiterator.c gstatomicqueue.c \
- gstmessage.c gstmeta.c gstmemory.c gstminiobject.c gstpad.c \
- gstpadtemplate.c gstparamspecs.c gstpipeline.c gstplugin.c \
- gstpluginfeature.c gstpluginloader.c gstpoll.c gstpreset.c \
- gstquark.c gstquery.c gstregistry.c gstregistrychunks.c \
- gstsample.c gstsegment.c gststructure.c gstsystemclock.c \
- gsttaglist.c gsttagsetter.c gsttask.c gsttaskpool.c gsttoc.c \
- gsttocsetter.c gsttrace.c gsttypefind.c gsttypefindfactory.c \
- gsturi.c gstutils.c gstvalue.c gstparse.c gstregistrybinary.c
+ gstghostpad.c gstglobaldevicemonitor.c gstinfo.c gstiterator.c \
+ gstatomicqueue.c gstmessage.c gstmeta.c gstmemory.c \
+ gstminiobject.c gstpad.c gstpadtemplate.c gstparamspecs.c \
+ gstpipeline.c gstplugin.c gstpluginfeature.c gstpluginloader.c \
+ gstpoll.c gstpreset.c gstquark.c gstquery.c gstregistry.c \
+ gstregistrychunks.c gstsample.c gstsegment.c gststructure.c \
+ gstsystemclock.c gsttaglist.c gsttagsetter.c gsttask.c \
+ gsttaskpool.c gsttoc.c gsttocsetter.c gsttrace.c gsttypefind.c \
+ gsttypefindfactory.c gsturi.c gstutils.c gstvalue.c gstparse.c \
+ gstregistrybinary.c
@GST_DISABLE_TRACE_FALSE@am__objects_1 = libgstreamer_@GST_API_VERSION@_la-gsttrace.lo
@GST_DISABLE_REGISTRY_FALSE@am__objects_2 = libgstreamer_@GST_API_VERSION@_la-gstregistrybinary.lo
am_libgstreamer_@GST_API_VERSION@_la_OBJECTS = \
@@ -206,12 +207,16 @@ am_libgstreamer_@GST_API_VERSION@_la_OBJECTS = \
libgstreamer_@GST_API_VERSION@_la-gstcontrolsource.lo \
libgstreamer_@GST_API_VERSION@_la-gstdatetime.lo \
libgstreamer_@GST_API_VERSION@_la-gstdebugutils.lo \
+ libgstreamer_@GST_API_VERSION@_la-gstdevice.lo \
+ libgstreamer_@GST_API_VERSION@_la-gstdevicemonitor.lo \
+ libgstreamer_@GST_API_VERSION@_la-gstdevicemonitorfactory.lo \
libgstreamer_@GST_API_VERSION@_la-gstelement.lo \
libgstreamer_@GST_API_VERSION@_la-gstelementfactory.lo \
libgstreamer_@GST_API_VERSION@_la-gsterror.lo \
libgstreamer_@GST_API_VERSION@_la-gstevent.lo \
libgstreamer_@GST_API_VERSION@_la-gstformat.lo \
libgstreamer_@GST_API_VERSION@_la-gstghostpad.lo \
+ libgstreamer_@GST_API_VERSION@_la-gstglobaldevicemonitor.lo \
libgstreamer_@GST_API_VERSION@_la-gstinfo.lo \
libgstreamer_@GST_API_VERSION@_la-gstiterator.lo \
libgstreamer_@GST_API_VERSION@_la-gstatomicqueue.lo \
@@ -695,12 +700,16 @@ libgstreamer_@GST_API_VERSION@_la_SOURCES = \
gstcontrolsource.c \
gstdatetime.c \
gstdebugutils.c \
+ gstdevice.c \
+ gstdevicemonitor.c \
+ gstdevicemonitorfactory.c \
gstelement.c \
gstelementfactory.c \
gsterror.c \
gstevent.c \
gstformat.c \
gstghostpad.c \
+ gstglobaldevicemonitor.c \
gstinfo.c \
gstiterator.c \
gstatomicqueue.c \
@@ -798,11 +807,15 @@ gst_headers = \
gstdebugutils.h \
gstelement.h \
gstelementmetadata.h \
+ gstdevice.h \
+ gstdevicemonitor.h \
+ gstdevicemonitorfactory.h \
gstelementfactory.h \
gsterror.h \
gstevent.h \
gstformat.h \
gstghostpad.h \
+ gstglobaldevicemonitor.h \
gstinfo.h \
gstiterator.h \
gstatomicqueue.h \
@@ -859,7 +872,8 @@ noinst_HEADERS = \
@HAVE_INTROSPECTION_TRUE@gir_headers = $(patsubst %,$(srcdir)/%, \
@HAVE_INTROSPECTION_TRUE@ $(libgstreamer_@GST_API_VERSION@include_HEADERS)) \
@HAVE_INTROSPECTION_TRUE@ $(patsubst %,$(builddir)/%, \
-@HAVE_INTROSPECTION_TRUE@ $(built_header_make))
+@HAVE_INTROSPECTION_TRUE@ $(built_header_make)) $(patsubst \
+@HAVE_INTROSPECTION_TRUE@ %,$(builddir)/%, gstversion.h)
@HAVE_INTROSPECTION_TRUE@gir_sources = $(patsubst %,$(srcdir)/%, \
@HAVE_INTROSPECTION_TRUE@ $(libgstreamer_@GST_API_VERSION@_la_SOURCES)) \
@HAVE_INTROSPECTION_TRUE@ $(patsubst %,$(builddir)/%, \
@@ -972,6 +986,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstcontrolsource.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstdatetime.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstdebugutils.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstdevice.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstdevicemonitor.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstdevicemonitorfactory.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstelement.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstelementfactory.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstenumtypes.Plo@am__quote@
@@ -979,6 +996,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstevent.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstformat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstghostpad.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstglobaldevicemonitor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstinfo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstiterator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstmemory.Plo@am__quote@
@@ -1161,6 +1179,27 @@ libgstreamer_@GST_API_VERSION@_la-gstdebugutils.lo: gstdebugutils.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstreamer_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -c -o libgstreamer_@GST_API_VERSION@_la-gstdebugutils.lo `test -f 'gstdebugutils.c' || echo '$(srcdir)/'`gstdebugutils.c
+libgstreamer_@GST_API_VERSION@_la-gstdevice.lo: gstdevice.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstreamer_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -MT libgstreamer_@GST_API_VERSION@_la-gstdevice.lo -MD -MP -MF $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstdevice.Tpo -c -o libgstreamer_@GST_API_VERSION@_la-gstdevice.lo `test -f 'gstdevice.c' || echo '$(srcdir)/'`gstdevice.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstdevice.Tpo $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstdevice.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstdevice.c' object='libgstreamer_@GST_API_VERSION@_la-gstdevice.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstreamer_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -c -o libgstreamer_@GST_API_VERSION@_la-gstdevice.lo `test -f 'gstdevice.c' || echo '$(srcdir)/'`gstdevice.c
+
+libgstreamer_@GST_API_VERSION@_la-gstdevicemonitor.lo: gstdevicemonitor.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstreamer_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -MT libgstreamer_@GST_API_VERSION@_la-gstdevicemonitor.lo -MD -MP -MF $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstdevicemonitor.Tpo -c -o libgstreamer_@GST_API_VERSION@_la-gstdevicemonitor.lo `test -f 'gstdevicemonitor.c' || echo '$(srcdir)/'`gstdevicemonitor.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstdevicemonitor.Tpo $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstdevicemonitor.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstdevicemonitor.c' object='libgstreamer_@GST_API_VERSION@_la-gstdevicemonitor.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstreamer_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -c -o libgstreamer_@GST_API_VERSION@_la-gstdevicemonitor.lo `test -f 'gstdevicemonitor.c' || echo '$(srcdir)/'`gstdevicemonitor.c
+
+libgstreamer_@GST_API_VERSION@_la-gstdevicemonitorfactory.lo: gstdevicemonitorfactory.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstreamer_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -MT libgstreamer_@GST_API_VERSION@_la-gstdevicemonitorfactory.lo -MD -MP -MF $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstdevicemonitorfactory.Tpo -c -o libgstreamer_@GST_API_VERSION@_la-gstdevicemonitorfactory.lo `test -f 'gstdevicemonitorfactory.c' || echo '$(srcdir)/'`gstdevicemonitorfactory.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstdevicemonitorfactory.Tpo $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstdevicemonitorfactory.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstdevicemonitorfactory.c' object='libgstreamer_@GST_API_VERSION@_la-gstdevicemonitorfactory.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstreamer_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -c -o libgstreamer_@GST_API_VERSION@_la-gstdevicemonitorfactory.lo `test -f 'gstdevicemonitorfactory.c' || echo '$(srcdir)/'`gstdevicemonitorfactory.c
+
libgstreamer_@GST_API_VERSION@_la-gstelement.lo: gstelement.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstreamer_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -MT libgstreamer_@GST_API_VERSION@_la-gstelement.lo -MD -MP -MF $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstelement.Tpo -c -o libgstreamer_@GST_API_VERSION@_la-gstelement.lo `test -f 'gstelement.c' || echo '$(srcdir)/'`gstelement.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstelement.Tpo $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstelement.Plo
@@ -1203,6 +1242,13 @@ libgstreamer_@GST_API_VERSION@_la-gstghostpad.lo: gstghostpad.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstreamer_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -c -o libgstreamer_@GST_API_VERSION@_la-gstghostpad.lo `test -f 'gstghostpad.c' || echo '$(srcdir)/'`gstghostpad.c
+libgstreamer_@GST_API_VERSION@_la-gstglobaldevicemonitor.lo: gstglobaldevicemonitor.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstreamer_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -MT libgstreamer_@GST_API_VERSION@_la-gstglobaldevicemonitor.lo -MD -MP -MF $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstglobaldevicemonitor.Tpo -c -o libgstreamer_@GST_API_VERSION@_la-gstglobaldevicemonitor.lo `test -f 'gstglobaldevicemonitor.c' || echo '$(srcdir)/'`gstglobaldevicemonitor.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstglobaldevicemonitor.Tpo $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstglobaldevicemonitor.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gstglobaldevicemonitor.c' object='libgstreamer_@GST_API_VERSION@_la-gstglobaldevicemonitor.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstreamer_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -c -o libgstreamer_@GST_API_VERSION@_la-gstglobaldevicemonitor.lo `test -f 'gstglobaldevicemonitor.c' || echo '$(srcdir)/'`gstglobaldevicemonitor.c
+
libgstreamer_@GST_API_VERSION@_la-gstinfo.lo: gstinfo.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstreamer_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -MT libgstreamer_@GST_API_VERSION@_la-gstinfo.lo -MD -MP -MF $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstinfo.Tpo -c -o libgstreamer_@GST_API_VERSION@_la-gstinfo.lo `test -f 'gstinfo.c' || echo '$(srcdir)/'`gstinfo.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstinfo.Tpo $(DEPDIR)/libgstreamer_@GST_API_VERSION@_la-gstinfo.Plo
@@ -1919,7 +1965,7 @@ Android.mk: Makefile.am
@HAVE_INTROSPECTION_TRUE@ --include=GLib-2.0 \
@HAVE_INTROSPECTION_TRUE@ --include=GObject-2.0 \
@HAVE_INTROSPECTION_TRUE@ --include=GModule-2.0 \
-@HAVE_INTROSPECTION_TRUE@ --libtool="$(top_builddir)/libtool" \
+@HAVE_INTROSPECTION_TRUE@ --libtool="${LIBTOOL}" \
@HAVE_INTROSPECTION_TRUE@ --pkg glib-2.0 \
@HAVE_INTROSPECTION_TRUE@ --pkg gobject-2.0 \
@HAVE_INTROSPECTION_TRUE@ --pkg gmodule-no-export-2.0 \
diff --git a/gst/gst.c b/gst/gst.c
index 47f1f2a..f160772 100644
--- a/gst/gst.c
+++ b/gst/gst.c
@@ -53,7 +53,7 @@
* </programlisting>
* </example>
*
- * It's allowed to pass two NULL pointers to gst_init() in case you don't want
+ * It's allowed to pass two %NULL pointers to gst_init() in case you don't want
* to pass the command line args to GStreamer.
*
* You can also use GOption to initialize your own parameters as shown in
@@ -91,8 +91,6 @@
* The gst_deinit() call is used to clean up all internal resources used
* by <application>GStreamer</application>. It is mostly used in unit tests
* to check for leaks.
- *
- * Last reviewed on 2006-08-11 (0.10.10)
*/
#include "gst_private.h"
@@ -377,7 +375,7 @@ gst_init_check (int *argc, char **argv[], GError ** err)
* </para></note>
*
* WARNING: This function does not work in the same way as corresponding
- * functions in other glib-style libraries, such as gtk_init(). In
+ * functions in other glib-style libraries, such as gtk_init\(\). In
* particular, unknown command line options cause this function to
* abort program execution.
*/
@@ -402,7 +400,7 @@ gst_init (int *argc, char **argv[])
* Use this function to check if GStreamer has been initialized with gst_init()
* or gst_init_check().
*
- * Returns: TRUE if initialization has been done, FALSE otherwise.
+ * Returns: %TRUE if initialization has been done, %FALSE otherwise.
*/
gboolean
gst_is_initialized (void)
@@ -461,6 +459,7 @@ static gboolean
init_pre (GOptionContext * context, GOptionGroup * group, gpointer data,
GError ** error)
{
+ gchar *libdir;
if (gst_initialized) {
GST_DEBUG ("already initialized");
return TRUE;
@@ -471,6 +470,7 @@ init_pre (GOptionContext * context, GOptionGroup * group, gpointer data,
#ifndef GST_DISABLE_GST_DEBUG
_priv_gst_debug_init ();
+ priv_gst_dump_dot_dir = g_getenv ("GST_DEBUG_DUMP_DOT_DIR");
#endif
#ifdef ENABLE_NLS
@@ -478,29 +478,27 @@ init_pre (GOptionContext * context, GOptionGroup * group, gpointer data,
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif /* ENABLE_NLS */
-#ifndef GST_DISABLE_GST_DEBUG
+ /* This is the earliest we can make stuff show up in the logs.
+ * So give some useful info about GStreamer here */
+#ifdef G_OS_WIN32
{
- const gchar *debug_list;
- const gchar *color_mode;
-
- if (g_getenv ("GST_DEBUG_NO_COLOR") != NULL)
- gst_debug_set_color_mode (GST_DEBUG_COLOR_MODE_OFF);
- color_mode = g_getenv ("GST_DEBUG_COLOR_MODE");
- if (color_mode)
- gst_debug_set_color_mode_from_string (color_mode);
-
- debug_list = g_getenv ("GST_DEBUG");
- if (debug_list) {
- gst_debug_set_threshold_from_string (debug_list, FALSE);
- }
- }
+ gchar *basedir =
+ g_win32_get_package_installation_directory_of_module
+ (_priv_gst_dll_handle);
- priv_gst_dump_dot_dir = g_getenv ("GST_DEBUG_DUMP_DOT_DIR");
+ libdir = g_build_filename (basedir,
+#ifdef _DEBUG
+ "debug"
+#endif
+ "lib", NULL);
+ g_free (basedir);
+ }
+#else
+ libdir = g_strdup (LIBDIR);
#endif
- /* This is the earliest we can make stuff show up in the logs.
- * So give some useful info about GStreamer here */
GST_INFO ("Initializing GStreamer Core Library version %s", VERSION);
- GST_INFO ("Using library installed in %s", LIBDIR);
+ GST_INFO ("Using library installed in %s", libdir);
+ g_free (libdir);
/* Print some basic system details if possible (OS/architecture) */
#ifdef HAVE_SYS_UTSNAME_H
@@ -568,6 +566,7 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
_priv_gst_mini_object_initialize ();
_priv_gst_quarks_initialize ();
+ _priv_gst_allocator_initialize ();
_priv_gst_memory_initialize ();
_priv_gst_format_initialize ();
_priv_gst_query_initialize ();
@@ -575,6 +574,7 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
_priv_gst_caps_initialize ();
_priv_gst_caps_features_initialize ();
_priv_gst_meta_initialize ();
+ _priv_gst_message_initialize ();
g_type_class_ref (gst_object_get_type ());
g_type_class_ref (gst_pad_get_type ());
@@ -663,6 +663,7 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
g_type_class_ref (gst_meta_flags_get_type ());
g_type_class_ref (gst_toc_entry_type_get_type ());
g_type_class_ref (gst_toc_scope_get_type ());
+ g_type_class_ref (gst_toc_loop_type_get_type ());
g_type_class_ref (gst_control_binding_get_type ());
g_type_class_ref (gst_control_source_get_type ());
g_type_class_ref (gst_lock_flags_get_type ());
@@ -671,11 +672,12 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
_priv_gst_event_initialize ();
_priv_gst_buffer_initialize ();
- _priv_gst_message_initialize ();
_priv_gst_buffer_list_initialize ();
_priv_gst_sample_initialize ();
- _priv_gst_value_initialize ();
_priv_gst_context_initialize ();
+ _priv_gst_date_time_initialize ();
+ _priv_gst_toc_initialize ();
+ _priv_gst_value_initialize ();
g_type_class_ref (gst_param_spec_fraction_get_type ());
_priv_gst_tag_initialize ();
@@ -694,7 +696,7 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
* gstreamer as being initialized, since it is the case from a plugin point of
* view.
*
- * If anything fails, it will be put back to FALSE in gst_init_check().
+ * If anything fails, it will be put back to %FALSE in gst_init_check().
* This allows some special plugins that would call gst_init() to not cause a
* looping effect (i.e. initializing GStreamer twice).
*/
@@ -1059,6 +1061,7 @@ gst_deinit (void)
g_type_class_unref (g_type_class_peek (gst_control_binding_get_type ()));
g_type_class_unref (g_type_class_peek (gst_control_source_get_type ()));
g_type_class_unref (g_type_class_peek (gst_toc_entry_type_get_type ()));
+ g_type_class_unref (g_type_class_peek (gst_toc_loop_type_get_type ()));
g_type_class_unref (g_type_class_peek (gst_lock_flags_get_type ()));
g_type_class_unref (g_type_class_peek (gst_allocator_flags_get_type ()));
g_type_class_unref (g_type_class_peek (gst_stream_flags_get_type ()));
diff --git a/gst/gst.h b/gst/gst.h
index 82f6bf9..9b20ba1 100644
--- a/gst/gst.h
+++ b/gst/gst.h
@@ -42,11 +42,14 @@
#include <gst/gstcontrolsource.h>
#include <gst/gstdatetime.h>
#include <gst/gstdebugutils.h>
+#include <gst/gstdevice.h>
+#include <gst/gstdevicemonitor.h>
#include <gst/gstelement.h>
#include <gst/gstelementmetadata.h>
#include <gst/gsterror.h>
#include <gst/gstevent.h>
#include <gst/gstghostpad.h>
+#include <gst/gstglobaldevicemonitor.h>
#include <gst/gstinfo.h>
#include <gst/gstiterator.h>
#include <gst/gstmessage.h>
diff --git a/gst/gst_private.h b/gst/gst_private.h
index 61762b2..e85d5c5 100644
--- a/gst/gst_private.h
+++ b/gst/gst_private.h
@@ -54,6 +54,9 @@ extern const char g_log_domain_gstreamer[];
/* for GstElement */
#include "gstelement.h"
+/* for GstDeviceMonitor */
+#include "gstdevicemonitor.h"
+
/* for GstToc */
#include "gsttoc.h"
@@ -101,6 +104,8 @@ G_GNUC_INTERNAL gboolean _priv_gst_in_valgrind (void);
/* init functions called from gst_init(). */
G_GNUC_INTERNAL void _priv_gst_quarks_initialize (void);
G_GNUC_INTERNAL void _priv_gst_mini_object_initialize (void);
+G_GNUC_INTERNAL void _priv_gst_memory_initialize (void);
+G_GNUC_INTERNAL void _priv_gst_allocator_initialize (void);
G_GNUC_INTERNAL void _priv_gst_buffer_initialize (void);
G_GNUC_INTERNAL void _priv_gst_buffer_list_initialize (void);
G_GNUC_INTERNAL void _priv_gst_structure_initialize (void);
@@ -109,7 +114,6 @@ G_GNUC_INTERNAL void _priv_gst_caps_features_initialize (void);
G_GNUC_INTERNAL void _priv_gst_event_initialize (void);
G_GNUC_INTERNAL void _priv_gst_format_initialize (void);
G_GNUC_INTERNAL void _priv_gst_message_initialize (void);
-G_GNUC_INTERNAL void _priv_gst_memory_initialize (void);
G_GNUC_INTERNAL void _priv_gst_meta_initialize (void);
G_GNUC_INTERNAL void _priv_gst_plugin_initialize (void);
G_GNUC_INTERNAL void _priv_gst_query_initialize (void);
@@ -118,6 +122,8 @@ G_GNUC_INTERNAL void _priv_gst_tag_initialize (void);
G_GNUC_INTERNAL void _priv_gst_value_initialize (void);
G_GNUC_INTERNAL void _priv_gst_debug_init (void);
G_GNUC_INTERNAL void _priv_gst_context_initialize (void);
+G_GNUC_INTERNAL void _priv_gst_toc_initialize (void);
+G_GNUC_INTERNAL void _priv_gst_date_time_initialize (void);
/* Private registry functions */
G_GNUC_INTERNAL
@@ -352,7 +358,7 @@ struct _GstTypeFindFactory {
GstTypeFindFunction function;
gchar ** extensions;
- GstCaps * caps; /* FIXME: not yet saved in registry */
+ GstCaps * caps;
gpointer user_data;
GDestroyNotify user_data_notify;
@@ -393,5 +399,24 @@ struct _GstElementFactoryClass {
gpointer _gst_reserved[GST_PADDING];
};
+struct _GstDeviceMonitorFactory {
+ GstPluginFeature feature;
+ /* <private> */
+
+ GType type; /* unique GType the device factory or 0 if not loaded */
+
+ volatile GstDeviceMonitor *monitor;
+ gpointer metadata;
+
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+struct _GstDeviceMonitorFactoryClass {
+ GstPluginFeatureClass parent;
+ /* <private> */
+
+ gpointer _gst_reserved[GST_PADDING];
+};
+
G_END_DECLS
#endif /* __GST_PRIVATE_H__ */
diff --git a/gst/gstallocator.c b/gst/gstallocator.c
index f117d98..cbcb1e4 100644
--- a/gst/gstallocator.c
+++ b/gst/gstallocator.c
@@ -25,7 +25,7 @@
* @see_also: #GstMemory
*
* Memory is usually created by allocators with a gst_allocator_alloc()
- * method call. When NULL is used as the allocator, the default allocator will
+ * method call. When %NULL is used as the allocator, the default allocator will
* be used.
*
* New allocators can be registered with gst_allocator_register().
@@ -35,8 +35,6 @@
*
* New memory can be created with gst_memory_new_wrapped() that wraps the memory
* allocated elsewhere.
- *
- * Last reviewed on 2012-07-09 (0.11.3)
*/
#ifdef HAVE_CONFIG_H
@@ -220,10 +218,10 @@ gst_allocator_register (const gchar * name, GstAllocator * allocator)
* gst_allocator_find:
* @name: (allow-none): the name of the allocator
*
- * Find a previously registered allocator with @name. When @name is NULL, the
+ * Find a previously registered allocator with @name. When @name is %NULL, the
* default allocator will be returned.
*
- * Returns: (transfer full): a #GstAllocator or NULL when the allocator with @name was not
+ * Returns: (transfer full): a #GstAllocator or %NULL when the allocator with @name was not
* registered. Use gst_object_unref() to release the allocator after usage.
*/
GstAllocator *
@@ -276,13 +274,13 @@ gst_allocator_set_default (GstAllocator * allocator)
* @size big.
*
* The optional @params can specify the prefix and padding for the memory. If
- * NULL is passed, no flags, no extra prefix/padding and a default alignment is
+ * %NULL is passed, no flags, no extra prefix/padding and a default alignment is
* used.
*
* The prefix/padding will be filled with 0 if flags contains
* #GST_MEMORY_FLAG_ZERO_PREFIXED and #GST_MEMORY_FLAG_ZERO_PADDED respectively.
*
- * When @allocator is NULL, the default allocator will be used.
+ * When @allocator is %NULL, the default allocator will be used.
*
* The alignment in @params is given as a bitmask so that @align + 1 equals
* the amount of bytes to align to. For example, to align to 8 bytes,
@@ -571,7 +569,7 @@ gst_allocator_sysmem_init (GstAllocatorSysmem * allocator)
}
void
-_priv_gst_memory_initialize (void)
+_priv_gst_allocator_initialize (void)
{
g_rw_lock_init (&lock);
allocators = g_hash_table_new (g_str_hash, g_str_equal);
diff --git a/gst/gstallocator.h b/gst/gstallocator.h
index 2337855..99deee2 100644
--- a/gst/gstallocator.h
+++ b/gst/gstallocator.h
@@ -92,8 +92,6 @@ typedef enum {
/**
* GstAllocator:
- * @object: parent structure
- * @mem_type: the memory type this allocator provides
* @mem_map: the implementation of the GstMemoryMapFunction
* @mem_unmap: the implementation of the GstMemoryUnmapFunction
* @mem_copy: the implementation of the GstMemoryCopyFunction
@@ -108,6 +106,7 @@ struct _GstAllocator
const gchar *mem_type;
+ /*< public >*/
GstMemoryMapFunction mem_map;
GstMemoryUnmapFunction mem_unmap;
@@ -121,9 +120,18 @@ struct _GstAllocator
GstAllocatorPrivate *priv;
};
+/**
+ * GstAllocatorClass:
+ * @object_class: Object parent class
+ * @alloc: implementation that acquires memory
+ * @free: implementation that releases memory
+ *
+ * The #GstAllocator is used to create new memory.
+ */
struct _GstAllocatorClass {
GstObjectClass object_class;
+ /*< public >*/
GstMemory * (*alloc) (GstAllocator *allocator, gsize size,
GstAllocationParams *params);
void (*free) (GstAllocator *allocator, GstMemory *memory);
diff --git a/gst/gstatomicqueue.c b/gst/gstatomicqueue.c
index 89bbb33..72ad2e3 100644
--- a/gst/gstatomicqueue.c
+++ b/gst/gstatomicqueue.c
@@ -214,7 +214,7 @@ gst_atomic_queue_unref (GstAtomicQueue * queue)
*
* Peek the head element of the queue without removing it from the queue.
*
- * Returns: (transfer none): the head element of @queue or NULL when
+ * Returns: (transfer none): the head element of @queue or %NULL when
* the queue is empty.
*/
gpointer
@@ -264,7 +264,7 @@ gst_atomic_queue_peek (GstAtomicQueue * queue)
*
* Get the head element of the queue.
*
- * Returns: (transfer full): the head element of @queue or NULL when
+ * Returns: (transfer full): the head element of @queue or %NULL when
* the queue is empty.
*/
gpointer
diff --git a/gst/gstatomicqueue.h b/gst/gstatomicqueue.h
index 1b9c63a..a176c1b 100644
--- a/gst/gstatomicqueue.h
+++ b/gst/gstatomicqueue.h
@@ -34,7 +34,7 @@ G_BEGIN_DECLS
*
* Opaque atomic data queue.
*
- * Use the acessor functions to get the stored values.
+ * Use the accessor functions to get the stored values.
*/
typedef struct _GstAtomicQueue GstAtomicQueue;
diff --git a/gst/gstbin.c b/gst/gstbin.c
index 581b251..77bbc3e 100644
--- a/gst/gstbin.c
+++ b/gst/gstbin.c
@@ -148,13 +148,11 @@
* </variablelist>
*
* A #GstBin will by default forward any event sent to it to all sink elements.
- * If all the sinks return TRUE, the bin will also return TRUE, else FALSE is
- * returned. If no sinks are in the bin, the event handler will return TRUE.
+ * If all the sinks return %TRUE, the bin will also return %TRUE, else %FALSE is
+ * returned. If no sinks are in the bin, the event handler will return %TRUE.
*
* </para>
* </refsect2>
- *
- * Last reviewed on 2012-03-28 (0.11.3)
*/
#include "gst_private.h"
@@ -198,6 +196,7 @@ struct _GstBinPrivate
gboolean message_forward;
gboolean posted_eos;
+ gboolean posted_playing;
GList *contexts;
};
@@ -218,8 +217,7 @@ static void gst_bin_get_property (GObject * object, guint prop_id,
static GstStateChangeReturn gst_bin_change_state_func (GstElement * element,
GstStateChange transition);
-static void gst_bin_state_changed (GstElement * element, GstState oldstate,
- GstState newstate, GstState pending);
+static gboolean gst_bin_post_message (GstElement * element, GstMessage * msg);
static GstStateChangeReturn gst_bin_get_state_func (GstElement * element,
GstState * state, GstState * pending, GstClockTime timeout);
static void bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret,
@@ -372,7 +370,7 @@ gst_bin_class_init (GstBinClass * klass)
/**
* GstBin:async-handling:
*
- * If set to #TRUE, the bin will handle asynchronous state changes.
+ * If set to %TRUE, the bin will handle asynchronous state changes.
* This should be used only if the bin subclass is modifying the state
* of its children on its own.
*/
@@ -408,7 +406,7 @@ gst_bin_class_init (GstBinClass * klass)
* @bin: the #GstBin
*
* Will be emitted when the bin needs to perform latency calculations. This
- * signal is only emited for toplevel bins or when async-handling is
+ * signal is only emitted for toplevel bins or when async-handling is
* enabled.
*
* Only one signal handler is invoked. If no signals are connected, the
@@ -452,7 +450,7 @@ gst_bin_class_init (GstBinClass * klass)
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_bin_change_state_func);
- gstelement_class->state_changed = GST_DEBUG_FUNCPTR (gst_bin_state_changed);
+ gstelement_class->post_message = GST_DEBUG_FUNCPTR (gst_bin_post_message);
gstelement_class->get_state = GST_DEBUG_FUNCPTR (gst_bin_get_state_func);
#if 0
gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_bin_get_index_func);
@@ -888,8 +886,8 @@ find_message (GstBin * bin, GstObject * src, GstMessageType types)
guint i;
for (i = 0; i < 32; i++)
- if (types & (1 << i))
- GST_DEBUG_OBJECT (bin, " %s", gst_message_type_get_name (1 << i));
+ if (types & (1U << i))
+ GST_DEBUG_OBJECT (bin, " %s", gst_message_type_get_name (1U << i));
}
#endif
}
@@ -1281,7 +1279,7 @@ had_parent:
*
* MT safe.
*
- * Returns: TRUE if the element could be added, FALSE if
+ * Returns: %TRUE if the element could be added, %FALSE if
* the bin does not want to accept the element.
*/
gboolean
@@ -1594,7 +1592,7 @@ not_in_bin:
*
* MT safe.
*
- * Returns: TRUE if the element could be removed, FALSE if
+ * Returns: %TRUE if the element could be removed, %FALSE if
* the bin does not want to remove the element.
*/
gboolean
@@ -1635,7 +1633,7 @@ no_function:
*
* MT safe. Caller owns returned value.
*
- * Returns: (transfer full): a #GstIterator of #GstElement, or NULL
+ * Returns: (transfer full): a #GstIterator of #GstElement, or %NULL
*/
GstIterator *
gst_bin_iterate_elements (GstBin * bin)
@@ -1675,7 +1673,7 @@ iterate_child_recurse (GstIterator * it, const GValue * item)
*
* MT safe. Caller owns returned value.
*
- * Returns: (transfer full): a #GstIterator of #GstElement, or NULL
+ * Returns: (transfer full): a #GstIterator of #GstElement, or %NULL
*/
GstIterator *
gst_bin_iterate_recurse (GstBin * bin)
@@ -1732,7 +1730,7 @@ sink_iterator_filter (const GValue * vchild, GValue * vbin)
*
* MT safe. Caller owns returned value.
*
- * Returns: (transfer full): a #GstIterator of #GstElement, or NULL
+ * Returns: (transfer full): a #GstIterator of #GstElement, or %NULL
*/
GstIterator *
gst_bin_iterate_sinks (GstBin * bin)
@@ -1792,7 +1790,7 @@ src_iterator_filter (const GValue * vchild, GValue * vbin)
*
* MT safe. Caller owns returned value.
*
- * Returns: (transfer full): a #GstIterator of #GstElement, or NULL
+ * Returns: (transfer full): a #GstIterator of #GstElement, or %NULL
*/
GstIterator *
gst_bin_iterate_sources (GstBin * bin)
@@ -2168,7 +2166,7 @@ gst_bin_sort_iterator_new (GstBin * bin)
*
* MT safe. Caller owns returned value.
*
- * Returns: (transfer full): a #GstIterator of #GstElement, or NULL
+ * Returns: (transfer full): a #GstIterator of #GstElement, or %NULL
*/
GstIterator *
gst_bin_iterate_sorted (GstBin * bin)
@@ -2511,17 +2509,30 @@ gst_bin_do_latency_func (GstBin * bin)
return res;
}
-static void
-gst_bin_state_changed (GstElement * element, GstState oldstate,
- GstState newstate, GstState pending)
+static gboolean
+gst_bin_post_message (GstElement * element, GstMessage * msg)
{
GstElementClass *pklass = (GstElementClass *) parent_class;
+ gboolean ret;
+
+ ret = pklass->post_message (element, gst_message_ref (msg));
+
+ if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_STATE_CHANGED &&
+ GST_MESSAGE_SRC (msg) == GST_OBJECT_CAST (element)) {
+ GstState newstate, pending;
+
+ gst_message_parse_state_changed (msg, NULL, &newstate, &pending);
+ if (newstate == GST_STATE_PLAYING && pending == GST_STATE_VOID_PENDING) {
+ GST_BIN_CAST (element)->priv->posted_playing = TRUE;
+ bin_do_eos (GST_BIN_CAST (element));
+ } else {
+ GST_BIN_CAST (element)->priv->posted_playing = FALSE;
+ }
+ }
- if (newstate == GST_STATE_PLAYING && pending == GST_STATE_VOID_PENDING)
- bin_do_eos (GST_BIN_CAST (element));
+ gst_message_unref (msg);
- if (pklass->state_changed)
- pklass->state_changed (element, oldstate, newstate, pending);
+ return ret;
}
static GstStateChangeReturn
@@ -2579,9 +2590,10 @@ gst_bin_change_state_func (GstElement * element, GstStateChange transition)
GST_DEBUG_OBJECT (element, "clearing all cached messages");
bin_remove_messages (bin, NULL, GST_MESSAGE_ANY);
GST_OBJECT_UNLOCK (bin);
- if (current == GST_STATE_PAUSED)
- if (!(gst_bin_src_pads_activate (bin, FALSE)))
- goto activate_failure;
+ /* We might not have reached PAUSED yet due to async errors,
+ * make sure to always deactivate the pads nonetheless */
+ if (!(gst_bin_src_pads_activate (bin, FALSE)))
+ goto activate_failure;
break;
case GST_STATE_NULL:
if (current == GST_STATE_READY) {
@@ -3214,7 +3226,7 @@ bin_do_eos (GstBin * bin)
*/
eos = GST_STATE (bin) == GST_STATE_PLAYING
&& GST_STATE_PENDING (bin) == GST_STATE_VOID_PENDING
- && is_eos (bin, &seqnum);
+ && bin->priv->posted_playing && is_eos (bin, &seqnum);
GST_OBJECT_UNLOCK (bin);
if (eos
@@ -3273,8 +3285,7 @@ bin_do_stream_start (GstBin * bin)
}
}
-/* must be called with the object lock. This function releases the lock to post
- * the message. */
+/* must be called without the object lock as it posts messages */
static void
bin_do_message_forward (GstBin * bin, GstMessage * message)
{
@@ -3283,7 +3294,6 @@ bin_do_message_forward (GstBin * bin, GstMessage * message)
GST_DEBUG_OBJECT (bin, "pass %s message upward",
GST_MESSAGE_TYPE_NAME (message));
- GST_OBJECT_UNLOCK (bin);
/* we need to convert these messages to element messages so that our parent
* bin can easily ignore them and so that the application can easily
@@ -3293,8 +3303,6 @@ bin_do_message_forward (GstBin * bin, GstMessage * message)
"message", GST_TYPE_MESSAGE, message, NULL));
gst_element_post_message (GST_ELEMENT_CAST (bin), forwarded);
-
- GST_OBJECT_LOCK (bin);
}
}
@@ -3411,8 +3419,8 @@ gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
{
/* collect all eos messages from the children */
- GST_OBJECT_LOCK (bin);
bin_do_message_forward (bin, message);
+ GST_OBJECT_LOCK (bin);
/* ref message for future use */
bin_replace_message (bin, message, GST_MESSAGE_EOS);
GST_OBJECT_UNLOCK (bin);
@@ -3448,8 +3456,9 @@ gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
gst_message_parse_segment_start (message, &format, &position);
seqnum = gst_message_get_seqnum (message);
- GST_OBJECT_LOCK (bin);
bin_do_message_forward (bin, message);
+
+ GST_OBJECT_LOCK (bin);
/* if this is the first segment-start, post to parent but not to the
* application */
if (!find_message (bin, NULL, GST_MESSAGE_SEGMENT_START) &&
@@ -3481,8 +3490,9 @@ gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
gst_message_parse_segment_done (message, &format, &position);
seqnum = gst_message_get_seqnum (message);
- GST_OBJECT_LOCK (bin);
bin_do_message_forward (bin, message);
+
+ GST_OBJECT_LOCK (bin);
bin_replace_message (bin, message, GST_MESSAGE_SEGMENT_START);
/* if there are no more segment_start messages, everybody posted
* a segment_done and we can post one on the bus. */
@@ -3583,9 +3593,9 @@ gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
GST_DEBUG_OBJECT (bin, "ASYNC_START message %p, %s", message,
src ? GST_OBJECT_NAME (src) : "(NULL)");
- GST_OBJECT_LOCK (bin);
bin_do_message_forward (bin, message);
+ GST_OBJECT_LOCK (bin);
/* we ignore the message if we are going to <= READY */
if ((target = GST_STATE_TARGET (bin)) <= GST_STATE_READY)
goto ignore_start_message;
@@ -3616,9 +3626,9 @@ gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
gst_message_parse_async_done (message, &running_time);
- GST_OBJECT_LOCK (bin);
bin_do_message_forward (bin, message);
+ GST_OBJECT_LOCK (bin);
/* ignore messages if we are shutting down */
if ((target = GST_STATE_TARGET (bin)) <= GST_STATE_READY)
goto ignore_done_message;
@@ -4112,11 +4122,11 @@ compare_name (const GValue * velement, const gchar * name)
* Gets the element with the given name from a bin. This
* function recurses into child bins.
*
- * Returns NULL if no element with the given name is found in the bin.
+ * Returns %NULL if no element with the given name is found in the bin.
*
* MT safe. Caller owns returned reference.
*
- * Returns: (transfer full): the #GstElement with the given name, or NULL
+ * Returns: (transfer full): the #GstElement with the given name, or %NULL
*/
GstElement *
gst_bin_get_by_name (GstBin * bin, const gchar * name)
@@ -4154,12 +4164,12 @@ gst_bin_get_by_name (GstBin * bin, const gchar * name)
* Gets the element with the given name from this bin. If the
* element is not found, a recursion is performed on the parent bin.
*
- * Returns NULL if:
+ * Returns %NULL if:
* - no element with the given name is found in the bin
*
* MT safe. Caller owns returned reference.
*
- * Returns: (transfer full): the #GstElement with the given name, or NULL
+ * Returns: (transfer full): the #GstElement with the given name, or %NULL
*/
GstElement *
gst_bin_get_by_name_recurse_up (GstBin * bin, const gchar * name)
@@ -4260,7 +4270,7 @@ gst_bin_get_by_interface (GstBin * bin, GType iface)
* MT safe. Caller owns returned value.
*
* Returns: (transfer full): a #GstIterator of #GstElement for all elements
- * in the bin implementing the given interface, or NULL
+ * in the bin implementing the given interface, or %NULL
*/
GstIterator *
gst_bin_iterate_all_by_interface (GstBin * bin, GType iface)
diff --git a/gst/gstbin.h b/gst/gstbin.h
index 17d1441..33c8d98 100644
--- a/gst/gstbin.h
+++ b/gst/gstbin.h
@@ -41,7 +41,7 @@ G_BEGIN_DECLS
/**
* GstBinFlags:
* @GST_BIN_FLAG_NO_RESYNC: don't resync a state change when elements are
- * added or linked in the bin.
+ * added or linked in the bin (Since 1.0.5)
* @GST_BIN_FLAG_LAST: the last enum in the series of flags for bins.
* Derived classes can use this as first value in a list of flags.
*
@@ -62,7 +62,7 @@ typedef enum {
* Check if @bin will resync its state change when elements are added and
* removed.
*
- * Since: 1.1.1
+ * Since: 1.0.5
*/
#define GST_BIN_IS_NO_RESYNC(bin) (GST_OBJECT_FLAG_IS_SET(bin,GST_BIN_FLAG_NO_RESYNC))
diff --git a/gst/gstbuffer.c b/gst/gstbuffer.c
index 5c1d8f8..8aef1c2 100644
--- a/gst/gstbuffer.c
+++ b/gst/gstbuffer.c
@@ -33,9 +33,7 @@
* created one will typically allocate memory for it and add it to the buffer.
* The following example creates a buffer that can hold a given video frame
* with a given width, height and bits per plane.
- * <example>
- * <title>Creating a buffer for a video frame</title>
- * <programlisting>
+ * |[
* GstBuffer *buffer;
* GstMemory *memory;
* gint size, width, height, bpp;
@@ -45,11 +43,10 @@
* memory = gst_allocator_alloc (NULL, size, NULL);
* gst_buffer_insert_memory (buffer, -1, memory);
* ...
- * </programlisting>
- * </example>
+ * ]|
*
- * Alternatively, use gst_buffer_new_allocate()
- * to create a buffer with preallocated data of a given size.
+ * Alternatively, use gst_buffer_new_allocate() to create a buffer with
+ * preallocated data of a given size.
*
* Buffers can contain a list of #GstMemory objects. You can retrieve how many
* memory objects with gst_buffer_n_memory() and you can get a pointer
@@ -71,7 +68,7 @@
* produced so far. For compressed data, it could be the byte offset in a
* source or destination file. Likewise, the end offset will be the offset of
* the end of the buffer. These can only be meaningfully interpreted if you
- * know the media type of the buffer (the preceeding CAPS event). Either or both
+ * know the media type of the buffer (the preceding CAPS event). Either or both
* can be set to #GST_BUFFER_OFFSET_NONE.
*
* gst_buffer_ref() is used to increase the refcount of a buffer. This must be
@@ -91,7 +88,7 @@
*
* Several flags of the buffer can be set and unset with the
* GST_BUFFER_FLAG_SET() and GST_BUFFER_FLAG_UNSET() macros. Use
- * GST_BUFFER_FLAG_IS_SET() to test if a certain #GstBufferFlag is set.
+ * GST_BUFFER_FLAG_IS_SET() to test if a certain #GstBufferFlags flag is set.
*
* Buffers can be efficiently merged into a larger buffer with
* gst_buffer_append(). Copying of memory will only be done when absolutely
@@ -107,8 +104,6 @@
* the refcount drops to 0, any memory and metadata pointed to by the buffer is
* unreffed as well. Buffers allocated from a #GstBufferPool will be returned to
* the pool when the refcount drops to 0.
- *
- * Last reviewed on 2012-03-28 (0.11.3)
*/
#include "gst_private.h"
@@ -282,10 +277,11 @@ _replace_memory (GstBuffer * buffer, guint len, guint idx, guint length,
}
if (end < len) {
- g_memmove (&GST_BUFFER_MEM_PTR (buffer, idx),
+ memmove (&GST_BUFFER_MEM_PTR (buffer, idx),
&GST_BUFFER_MEM_PTR (buffer, end), (len - end) * sizeof (gpointer));
}
GST_BUFFER_MEM_LEN (buffer) = len - length;
+ GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
}
static inline void
@@ -320,6 +316,8 @@ _memory_add (GstBuffer * buffer, gint idx, GstMemory * mem, gboolean lock)
gst_memory_lock (mem, GST_LOCK_FLAG_EXCLUSIVE);
GST_BUFFER_MEM_PTR (buffer, idx) = mem;
GST_BUFFER_MEM_LEN (buffer) = len + 1;
+
+ GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
}
GST_DEFINE_MINI_OBJECT_TYPE (GstBuffer, gst_buffer);
@@ -341,7 +339,7 @@ _priv_gst_buffer_initialize (void)
*
* Returns: the maximum amount of memory blocks that a buffer can hold.
*
- * Since: 1.2.0
+ * Since: 1.2
*/
guint
gst_buffer_get_max_memory (void)
@@ -519,6 +517,9 @@ _gst_buffer_copy (GstBuffer * buffer)
if (!gst_buffer_copy_into (copy, buffer, GST_BUFFER_COPY_ALL, 0, -1))
gst_buffer_replace (&copy, NULL);
+ if (copy)
+ GST_BUFFER_FLAG_UNSET (copy, GST_BUFFER_FLAG_TAG_MEMORY);
+
return copy;
}
@@ -634,22 +635,22 @@ gst_buffer_new (void)
/**
* gst_buffer_new_allocate:
- * @allocator: (transfer none) (allow-none): the #GstAllocator to use, or NULL to use the
+ * @allocator: (transfer none) (allow-none): the #GstAllocator to use, or %NULL to use the
* default allocator
* @size: the size in bytes of the new buffer's data.
* @params: (transfer none) (allow-none): optional parameters
*
* Tries to create a newly allocated buffer with data of the given size and
* extra parameters from @allocator. If the requested amount of memory can't be
- * allocated, NULL will be returned. The allocated buffer memory is not cleared.
+ * allocated, %NULL will be returned. The allocated buffer memory is not cleared.
*
- * When @allocator is NULL, the default memory allocator will be used.
+ * When @allocator is %NULL, the default memory allocator will be used.
*
* Note that when @size == 0, the buffer will not have memory associated with it.
*
* MT safe.
*
- * Returns: (transfer full): a new #GstBuffer, or NULL if the memory couldn't
+ * Returns: (transfer full): a new #GstBuffer, or %NULL if the memory couldn't
* be allocated.
*/
GstBuffer *
@@ -723,6 +724,7 @@ gst_buffer_new_allocate (GstAllocator * allocator, gsize size,
if (size > 0)
_memory_add (newbuf, -1, gst_memory_ref (mem), TRUE);
#endif
+ GST_BUFFER_FLAG_UNSET (newbuf, GST_BUFFER_FLAG_TAG_MEMORY);
return newbuf;
@@ -769,6 +771,7 @@ gst_buffer_new_wrapped_full (GstMemoryFlags flags, gpointer data,
gst_memory_new_wrapped (flags, data, maxsize, offset, size, user_data,
notify);
_memory_add (newbuf, -1, mem, TRUE);
+ GST_BUFFER_FLAG_UNSET (newbuf, GST_BUFFER_FLAG_TAG_MEMORY);
return newbuf;
}
@@ -883,6 +886,7 @@ _get_mapped (GstBuffer * buffer, guint idx, GstMapInfo * info,
GST_BUFFER_MEM_PTR (buffer, idx) = mapped;
/* unlock old memory */
gst_memory_unlock (mem, GST_LOCK_FLAG_EXCLUSIVE);
+ GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
}
gst_memory_unref (mem);
@@ -1167,6 +1171,68 @@ gst_buffer_find_memory (GstBuffer * buffer, gsize offset, gsize size,
}
/**
+ * gst_buffer_is_memory_range_writable:
+ * @buffer: a #GstBuffer.
+ * @idx: an index
+ * @length: a length should not be 0
+ *
+ * Check if @length memory blocks in @buffer starting from @idx are writable.
+ *
+ * @length can be -1 to check all the memory blocks after @idx.
+ *
+ * Note that this function does not check if @buffer is writable, use
+ * gst_buffer_is_writable() to check that if needed.
+ *
+ * Returns: %TRUE if the memory range is writable
+ *
+ * Since: 1.4
+ */
+gboolean
+gst_buffer_is_memory_range_writable (GstBuffer * buffer, guint idx, gint length)
+{
+ guint i, len;
+
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
+
+ GST_CAT_DEBUG (GST_CAT_BUFFER, "idx %u, length %d", idx, length);
+
+ len = GST_BUFFER_MEM_LEN (buffer);
+ g_return_val_if_fail ((len == 0 && idx == 0 && length == -1) ||
+ (length == -1 && idx < len) || (length > 0 && length + idx <= len),
+ FALSE);
+
+ if (length == -1)
+ len -= idx;
+ else
+ len = length;
+
+ for (i = 0; i < len; i++) {
+ if (!gst_memory_is_writable (GST_BUFFER_MEM_PTR (buffer, i + idx)))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * gst_buffer_is_all_memory_writable:
+ * @buffer: a #GstBuffer.
+ *
+ * Check if all memory blocks in @buffer are writable.
+ *
+ * Note that this function does not check if @buffer is writable, use
+ * gst_buffer_is_writable() to check that if needed.
+ *
+ * Returns: %TRUE if all memory blocks in @buffer are writable
+ *
+ * Since: 1.4
+ */
+gboolean
+gst_buffer_is_all_memory_writable (GstBuffer * buffer)
+{
+ return gst_buffer_is_memory_range_writable (buffer, 0, -1);
+}
+
+/**
* gst_buffer_get_sizes:
* @buffer: a #GstBuffer.
* @offset: (out): a pointer to the offset
@@ -1277,7 +1343,7 @@ gst_buffer_get_sizes_range (GstBuffer * buffer, guint idx, gint length,
/**
* gst_buffer_resize:
* @buffer: a #GstBuffer.
- * @offset: the offset adjustement
+ * @offset: the offset adjustment
* @size: the new size or -1 to just adjust the offset
*
* Set the offset and total size of the memory blocks in @buffer.
@@ -1306,7 +1372,7 @@ gst_buffer_set_size (GstBuffer * buffer, gssize size)
* @buffer: a #GstBuffer.
* @idx: an index
* @length: a length
- * @offset: the offset adjustement
+ * @offset: the offset adjustment
* @size: the new size or -1 to just adjust the offset
*
* Set the total size of the @length memory blocks starting at @idx in
@@ -1393,6 +1459,8 @@ gst_buffer_resize_range (GstBuffer * buffer, guint idx, gint length,
GST_BUFFER_MEM_PTR (buffer, i) = newmem;
gst_memory_unlock (mem, GST_LOCK_FLAG_EXCLUSIVE);
gst_memory_unref (mem);
+
+ GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
}
}
@@ -1513,21 +1581,20 @@ not_writable:
{
GST_WARNING_OBJECT (buffer, "write map requested on non-writable buffer");
g_critical ("write map requested on non-writable buffer");
+ memset (info, 0, sizeof (GstMapInfo));
return FALSE;
}
no_memory:
{
/* empty buffer, we need to return NULL */
GST_DEBUG_OBJECT (buffer, "can't get buffer memory");
- info->memory = NULL;
- info->data = NULL;
- info->size = 0;
- info->maxsize = 0;
+ memset (info, 0, sizeof (GstMapInfo));
return TRUE;
}
cannot_map:
{
GST_DEBUG_OBJECT (buffer, "cannot map memory");
+ memset (info, 0, sizeof (GstMapInfo));
return FALSE;
}
}
@@ -1775,7 +1842,7 @@ gst_buffer_memset (GstBuffer * buffer, gsize offset, guint8 val, gsize size)
*
* MT safe.
*
- * Returns: (transfer full): the new #GstBuffer or NULL if the arguments were
+ * Returns: (transfer full): the new #GstBuffer or %NULL if the arguments were
* invalid.
*/
GstBuffer *
@@ -1853,6 +1920,7 @@ gst_buffer_append_region (GstBuffer * buf1, GstBuffer * buf2, gssize offset,
}
GST_BUFFER_MEM_LEN (buf2) = 0;
+ GST_BUFFER_FLAG_SET (buf2, GST_BUFFER_FLAG_TAG_MEMORY);
gst_buffer_unref (buf2);
return buf1;
@@ -1864,7 +1932,7 @@ gst_buffer_append_region (GstBuffer * buf1, GstBuffer * buf2, gssize offset,
* @api: the #GType of an API
*
* Get the metadata for @api on buffer. When there is no such
- * metadata, NULL is returned.
+ * metadata, %NULL is returned.
*
* Returns: (transfer none): the metadata for @api on @buffer.
*/
@@ -1993,7 +2061,7 @@ gst_buffer_remove_meta (GstBuffer * buffer, GstMeta * meta)
* Retrieve the next #GstMeta after @current. If @state points
* to %NULL, the first metadata is returned.
*
- * @state will be updated with an opage state pointer
+ * @state will be updated with an opaque state pointer
*
* Returns: (transfer none): The next #GstMeta or %NULL when there are
* no more items.
diff --git a/gst/gstbuffer.h b/gst/gstbuffer.h
index c241792..0ebf142 100644
--- a/gst/gstbuffer.h
+++ b/gst/gstbuffer.h
@@ -44,13 +44,13 @@ typedef struct _GstBufferPool GstBufferPool;
* GST_BUFFER_FLAGS:
* @buf: a #GstBuffer.
*
- * A flags word containing #GstBufferFlag flags set on this buffer.
+ * A flags word containing #GstBufferFlags flags set on this buffer.
*/
#define GST_BUFFER_FLAGS(buf) GST_MINI_OBJECT_FLAGS(buf)
/**
* GST_BUFFER_FLAG_IS_SET:
* @buf: a #GstBuffer.
- * @flag: the #GstBufferFlag to check.
+ * @flag: the #GstBufferFlags flag to check.
*
* Gives the status of a specific flag on a buffer.
*/
@@ -58,7 +58,7 @@ typedef struct _GstBufferPool GstBufferPool;
/**
* GST_BUFFER_FLAG_SET:
* @buf: a #GstBuffer.
- * @flag: the #GstBufferFlag to set.
+ * @flag: the #GstBufferFlags flag to set.
*
* Sets a buffer flag on a buffer.
*/
@@ -66,7 +66,7 @@ typedef struct _GstBufferPool GstBufferPool;
/**
* GST_BUFFER_FLAG_UNSET:
* @buf: a #GstBuffer.
- * @flag: the #GstBufferFlag to clear.
+ * @flag: the #GstBufferFlags flag to clear.
*
* Clears a buffer flag.
*/
@@ -192,6 +192,8 @@ typedef struct _GstBufferPool GstBufferPool;
* @GST_BUFFER_FLAG_DROPPABLE: the buffer can be dropped without breaking the
* stream, for example to reduce bandwidth.
* @GST_BUFFER_FLAG_DELTA_UNIT: this unit cannot be decoded independently.
+ * @GST_BUFFER_FLAG_TAG_MEMORY: this flag is set when memory of the buffer
+ * is added/removed
* @GST_BUFFER_FLAG_LAST: additional media specific flags can be added starting from
* this flag.
*
@@ -208,6 +210,7 @@ typedef enum {
GST_BUFFER_FLAG_GAP = (GST_MINI_OBJECT_FLAG_LAST << 7),
GST_BUFFER_FLAG_DROPPABLE = (GST_MINI_OBJECT_FLAG_LAST << 8),
GST_BUFFER_FLAG_DELTA_UNIT = (GST_MINI_OBJECT_FLAG_LAST << 9),
+ GST_BUFFER_FLAG_TAG_MEMORY = (GST_MINI_OBJECT_FLAG_LAST << 10),
GST_BUFFER_FLAG_LAST = (GST_MINI_OBJECT_FLAG_LAST << 16)
} GstBufferFlags;
@@ -284,6 +287,9 @@ void gst_buffer_remove_all_memory (GstBuffer *buffer);
gboolean gst_buffer_find_memory (GstBuffer *buffer, gsize offset, gsize size,
guint *idx, guint *length, gsize *skip);
+gboolean gst_buffer_is_memory_range_writable (GstBuffer *buffer, guint idx, gint length);
+gboolean gst_buffer_is_all_memory_writable (GstBuffer *buffer);
+
gsize gst_buffer_fill (GstBuffer *buffer, gsize offset,
gconstpointer src, gsize size);
gsize gst_buffer_extract (GstBuffer *buffer, gsize offset,
@@ -319,7 +325,7 @@ void gst_buffer_extract_dup (GstBuffer *buffer, gsize offset,
*
* Increases the refcount of the given buffer by one.
*
- * Note that the refcount affects the writeability
+ * Note that the refcount affects the writability
* of @buf and its metadata, see gst_buffer_is_writable().
* It is important to note that keeping additional references to
* GstBuffer instances can potentially increase the number
@@ -461,9 +467,9 @@ gboolean gst_buffer_copy_into (GstBuffer *dest, GstBuffer *src
* in some cases), and the reference counts are updated appropriately (the old
* buffer is unreffed, the new is reffed).
*
- * Either @nbuf or the #GstBuffer pointed to by @obuf may be NULL.
+ * Either @nbuf or the #GstBuffer pointed to by @obuf may be %NULL.
*
- * Returns: TRUE when @obuf was different from @nbuf.
+ * Returns: %TRUE when @obuf was different from @nbuf.
*/
#ifdef _FOOL_GTK_DOC_
G_INLINE_FUNC gboolean gst_buffer_replace (GstBuffer **obuf, GstBuffer *nbuf);
@@ -501,7 +507,7 @@ GstBuffer* gst_buffer_append (GstBuffer *buf1, GstBuffer *buf
* When this function returns %TRUE, the next meta will be
* returned. When %FALSE is returned, gst_buffer_foreach_meta() will return.
*
- * When @meta is set to NULL, the item will be removed from the buffer.
+ * When @meta is set to %NULL, the item will be removed from the buffer.
*
* Returns: %FALSE when gst_buffer_foreach_meta() should stop
*/
diff --git a/gst/gstbufferlist.c b/gst/gstbufferlist.c
index 565ed5b..dca866c 100644
--- a/gst/gstbufferlist.c
+++ b/gst/gstbufferlist.c
@@ -33,8 +33,6 @@
* Buffer lists can be pushed on a srcpad with gst_pad_push_list(). This is
* interesting when multiple buffers need to be pushed in one go because it
* can reduce the amount of overhead for pushing each buffer individually.
- *
- * Last reviewed on 2012-03-28 (0.11.3)
*/
#include "gst_private.h"
@@ -229,7 +227,7 @@ gst_buffer_list_foreach (GstBufferList * list, GstBufferListFunc func,
*
* Get the buffer at @idx.
*
- * Returns: (transfer none): the buffer at @idx in @group or NULL when there
+ * Returns: (transfer none): the buffer at @idx in @group or %NULL when there
* is no buffer. The buffer remains valid as long as @list is valid.
*/
GstBuffer *
@@ -283,14 +281,21 @@ gst_buffer_list_insert (GstBufferList * list, gint idx, GstBuffer * buffer)
* @idx: the index
* @length: the amount to remove
*
- * Remove @length buffers starting from @idx in @list. The following buffers are
- * moved to close the gap.
+ * Remove @length buffers starting from @idx in @list. The following buffers
+ * are moved to close the gap.
*/
void
gst_buffer_list_remove (GstBufferList * list, guint idx, guint length)
{
+ GstBuffer *buf;
+ gint i;
+
g_return_if_fail (GST_IS_BUFFER_LIST (list));
g_return_if_fail (idx < list->array->len);
+ for (i = idx; i < idx + length; ++i) {
+ buf = g_array_index (list->array, GstBuffer *, i);
+ gst_buffer_unref (buf);
+ }
g_array_remove_range (list->array, idx, length);
}
diff --git a/gst/gstbufferlist.h b/gst/gstbufferlist.h
index 4a6a99f..df8c455 100644
--- a/gst/gstbufferlist.h
+++ b/gst/gstbufferlist.h
@@ -48,7 +48,7 @@ typedef struct _GstBufferList GstBufferList;
* When this function returns %TRUE, the next buffer will be
* returned. When %FALSE is returned, gst_buffer_list_foreach() will return.
*
- * When @buffer is set to NULL, the item will be removed from the bufferlist.
+ * When @buffer is set to %NULL, the item will be removed from the bufferlist.
* When @buffer has been made writable, the new buffer reference can be assigned
* to @buffer. This function is responsible for unreffing the old buffer when
* removing or modifying.
@@ -66,7 +66,7 @@ typedef gboolean (*GstBufferListFunc) (GstBuffer **buffer, guint idx,
*
* Increases the refcount of the given buffer list by one.
*
- * Note that the refcount affects the writeability of @list and its data, see
+ * Note that the refcount affects the writability of @list and its data, see
* gst_buffer_list_make_writable(). It is important to note that keeping
* additional references to GstBufferList instances can potentially increase
* the number of memcpy operations in a pipeline.
diff --git a/gst/gstbufferpool.c b/gst/gstbufferpool.c
index cdd3b2b..6c14ce4 100644
--- a/gst/gstbufferpool.c
+++ b/gst/gstbufferpool.c
@@ -24,17 +24,17 @@
* @short_description: Pool for buffers
* @see_also: #GstBuffer
*
- * a #GstBufferPool is an object that can be used to pre-allocate and recycle
+ * A #GstBufferPool is an object that can be used to pre-allocate and recycle
* buffers of the same size and with the same properties.
*
* A #GstBufferPool is created with gst_buffer_pool_new().
*
- * After the buffer is created, it needs to be configured.
- * gst_buffer_pool_get_config() get the current configuration structure from the
- * pool. With gst_buffer_pool_config_set_params() and
- * gst_buffer_pool_config_set_allocator() the bufferpool parameters and allocator
- * can be configured. Other properties can be configured in the pool depending
- * on the pool implementation.
+ * Once a pool is created, it needs to be configured. A call to
+ * gst_buffer_pool_get_config() returns the current configuration structure from
+ * the pool. With gst_buffer_pool_config_set_params() and
+ * gst_buffer_pool_config_set_allocator() the bufferpool parameters and
+ * allocator can be configured. Other properties can be configured in the pool
+ * depending on the pool implementation.
*
* A bufferpool can have extra options that can be enabled with
* gst_buffer_pool_config_add_option(). The available options can be retrieved
@@ -52,8 +52,8 @@
* When the pool is active, gst_buffer_pool_acquire_buffer() can be used to
* retrieve a buffer from the pool.
*
- * Buffer allocated from a bufferpool will automatically be returned to the pool
- * with gst_buffer_pool_release_buffer() when their refcount drops to 0.
+ * Buffers allocated from a bufferpool will automatically be returned to the
+ * pool with gst_buffer_pool_release_buffer() when their refcount drops to 0.
*
* The bufferpool can be deactivated again with gst_buffer_pool_set_active().
* All further gst_buffer_pool_acquire_buffer() calls will return an error. When
@@ -61,8 +61,6 @@
*
* Use gst_object_unref() to release the reference to a bufferpool. If the
* refcount of the pool reaches 0, the pool will be freed.
- *
- * Last reviewed on 2012-03-28 (0.11.3)
*/
#include "gst_private.h"
@@ -100,7 +98,7 @@ struct _GstBufferPoolPrivate
gboolean started;
gboolean active;
- gint outstanding;
+ gint outstanding; /* number of buffers that are in use */
gboolean configured;
GstStructure *config;
@@ -113,12 +111,6 @@ struct _GstBufferPoolPrivate
GstAllocationParams params;
};
-enum
-{
- /* add more above */
- LAST_SIGNAL
-};
-
static void gst_buffer_pool_finalize (GObject * object);
G_DEFINE_TYPE (GstBufferPool, gst_buffer_pool, GST_TYPE_OBJECT);
@@ -167,7 +159,7 @@ gst_buffer_pool_init (GstBufferPool * pool)
g_rec_mutex_init (&priv->rec_lock);
priv->poll = gst_poll_new_timer ();
- priv->queue = gst_atomic_queue_new (10);
+ priv->queue = gst_atomic_queue_new (16);
pool->flushing = 1;
priv->active = FALSE;
priv->configured = FALSE;
@@ -178,6 +170,9 @@ gst_buffer_pool_init (GstBufferPool * pool)
gst_allocation_params_init (&priv->params);
gst_buffer_pool_config_set_allocator (priv->config, priv->allocator,
&priv->params);
+ /* 1 control write for flushing */
+ gst_poll_write_control (priv->poll);
+ /* 1 control write for marking that we are not waiting for poll */
gst_poll_write_control (priv->poll);
GST_DEBUG_OBJECT (pool, "created");
@@ -210,7 +205,7 @@ gst_buffer_pool_finalize (GObject * object)
*
* Creates a new #GstBufferPool instance.
*
- * Returns: (transfer full): a new #GstBufferPool instance
+ * Returns: (transfer floating): a new #GstBufferPool instance
*/
GstBufferPool *
gst_buffer_pool_new (void)
@@ -273,10 +268,17 @@ do_alloc_buffer (GstBufferPool * pool, GstBuffer ** buffer,
if (G_UNLIKELY (result != GST_FLOW_OK))
goto alloc_failed;
+ /* lock all metadata and mark as pooled, we want this to remain on
+ * the buffer and we want to remove any other metadata that gets added
+ * later */
gst_buffer_foreach_meta (*buffer, mark_meta_pooled, pool);
+ /* un-tag memory, this is how we expect the buffer when it is
+ * released again */
+ GST_BUFFER_FLAG_UNSET (*buffer, GST_BUFFER_FLAG_TAG_MEMORY);
+
GST_LOG_OBJECT (pool, "allocated buffer %d/%d, %p", cur_buffers,
- max_buffers, buffer);
+ max_buffers, *buffer);
return result;
@@ -300,8 +302,7 @@ alloc_failed:
}
}
-/* the default implementation for preallocating the buffers
- * in the pool */
+/* the default implementation for preallocating the buffers in the pool */
static gboolean
default_start (GstBufferPool * pool)
{
@@ -356,34 +357,42 @@ do_start (GstBufferPool * pool)
return TRUE;
}
-
static void
default_free_buffer (GstBufferPool * pool, GstBuffer * buffer)
{
gst_buffer_unref (buffer);
}
+static void
+do_free_buffer (GstBufferPool * pool, GstBuffer * buffer)
+{
+ GstBufferPoolPrivate *priv;
+ GstBufferPoolClass *pclass;
+
+ priv = pool->priv;
+ pclass = GST_BUFFER_POOL_GET_CLASS (pool);
+
+ g_atomic_int_add (&priv->cur_buffers, -1);
+ GST_LOG_OBJECT (pool, "freeing buffer %p (%u left)", buffer,
+ priv->cur_buffers);
+
+ if (G_LIKELY (pclass->free_buffer))
+ pclass->free_buffer (pool, buffer);
+}
+
/* must be called with the lock */
static gboolean
default_stop (GstBufferPool * pool)
{
GstBufferPoolPrivate *priv = pool->priv;
GstBuffer *buffer;
- GstBufferPoolClass *pclass;
-
- pclass = GST_BUFFER_POOL_GET_CLASS (pool);
/* clear the pool */
while ((buffer = gst_atomic_queue_pop (priv->queue))) {
- GST_LOG_OBJECT (pool, "freeing %p", buffer);
gst_poll_read_control (priv->poll);
-
- if (G_LIKELY (pclass->free_buffer))
- pclass->free_buffer (pool, buffer);
+ do_free_buffer (pool, buffer);
}
- priv->cur_buffers = 0;
-
- return TRUE;
+ return priv->cur_buffers == 0;
}
/* must be called with the lock */
@@ -407,13 +416,40 @@ do_stop (GstBufferPool * pool)
return TRUE;
}
+/* must be called with the lock */
+static void
+do_set_flushing (GstBufferPool * pool, gboolean flushing)
+{
+ GstBufferPoolPrivate *priv = pool->priv;
+ GstBufferPoolClass *pclass;
+
+ pclass = GST_BUFFER_POOL_GET_CLASS (pool);
+
+ if (GST_BUFFER_POOL_IS_FLUSHING (pool) == flushing)
+ return;
+
+ if (flushing) {
+ g_atomic_int_set (&pool->flushing, 1);
+ gst_poll_write_control (priv->poll);
+
+ if (pclass->flush_start)
+ pclass->flush_start (pool);
+ } else {
+ if (pclass->flush_stop)
+ pclass->flush_stop (pool);
+
+ gst_poll_read_control (priv->poll);
+ g_atomic_int_set (&pool->flushing, 0);
+ }
+}
+
/**
* gst_buffer_pool_set_active:
* @pool: a #GstBufferPool
* @active: the new active state
*
* Control the active state of @pool. When the pool is inactive, new calls to
- * gst_buffer_pool_acquire_buffer() will return with #GST_FLOW_FLUSHING.
+ * gst_buffer_pool_acquire_buffer() will return with %GST_FLOW_FLUSHING.
*
* Activating the bufferpool will preallocate all resources in the pool based on
* the configuration of the pool.
@@ -450,15 +486,17 @@ gst_buffer_pool_set_active (GstBufferPool * pool, gboolean active)
if (!do_start (pool))
goto start_failed;
+ /* flush_stop my release buffers, setting to active to avoid running
+ * do_stop while activating the pool */
+ priv->active = TRUE;
+
/* unset the flushing state now */
- gst_poll_read_control (priv->poll);
- g_atomic_int_set (&pool->flushing, 0);
+ do_set_flushing (pool, FALSE);
} else {
gint outstanding;
/* set to flushing first */
- g_atomic_int_set (&pool->flushing, 1);
- gst_poll_write_control (priv->poll);
+ do_set_flushing (pool, TRUE);
/* when all buffers are in the pool, free them. Else they will be
* freed when they are released */
@@ -468,8 +506,9 @@ gst_buffer_pool_set_active (GstBufferPool * pool, gboolean active)
if (!do_stop (pool))
goto stop_failed;
}
+
+ priv->active = FALSE;
}
- priv->active = active;
GST_BUFFER_POOL_UNLOCK (pool);
return res;
@@ -565,9 +604,11 @@ wrong_config:
* @pool: a #GstBufferPool
* @config: (transfer full): a #GstStructure
*
- * Set the configuration of the pool. The pool must be inactive and all buffers
- * allocated form this pool must be returned or else this function will do
- * nothing and return FALSE.
+ * Set the configuration of the pool. If the pool is already configured, and
+ * the configuration haven't change, this function will return %TRUE. If the
+ * pool is active, this function will try deactivating it. Buffers allocated
+ * form this pool must be returned or else this function will do nothing and
+ * return %FALSE.
*
* @config is a #GstStructure that contains the configuration parameters for
* the pool. A default and mandatory set of parameters can be configured with
@@ -575,12 +616,12 @@ wrong_config:
* and gst_buffer_pool_config_add_option().
*
* If the parameters in @config can not be set exactly, this function returns
- * FALSE and will try to update as much state as possible. The new state can
+ * %FALSE and will try to update as much state as possible. The new state can
* then be retrieved and refined with gst_buffer_pool_get_config().
*
* This function takes ownership of @config.
*
- * Returns: TRUE when the configuration could be set.
+ * Returns: %TRUE when the configuration could be set.
*/
gboolean
gst_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
@@ -595,9 +636,24 @@ gst_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
priv = pool->priv;
GST_BUFFER_POOL_LOCK (pool);
+
+ /* nothing to do if config is unchanged */
+ if (priv->configured && gst_structure_is_equal (config, priv->config))
+ goto config_unchanged;
+
/* can't change the settings when active */
- if (priv->active)
- goto was_active;
+ if (priv->active) {
+ GST_BUFFER_POOL_UNLOCK (pool);
+ if (!gst_buffer_pool_set_active (pool, FALSE)) {
+ GST_BUFFER_POOL_LOCK (pool);
+ goto was_active;
+ }
+ GST_BUFFER_POOL_LOCK (pool);
+
+ /* not likely but as we released the lock */
+ if (priv->active)
+ goto was_active;
+ }
/* we can't change when outstanding buffers */
if (g_atomic_int_get (&priv->outstanding) != 0)
@@ -611,20 +667,26 @@ gst_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
else
result = FALSE;
- if (result) {
- if (priv->config)
- gst_structure_free (priv->config);
- priv->config = config;
+ /* save the config regardless of the result so user can read back the
+ * modified config and evaluate if the changes are acceptable */
+ if (priv->config)
+ gst_structure_free (priv->config);
+ priv->config = config;
+ if (result) {
/* now we are configured */
priv->configured = TRUE;
- } else {
- gst_structure_free (config);
}
GST_BUFFER_POOL_UNLOCK (pool);
return result;
+config_unchanged:
+ {
+ gst_structure_free (config);
+ GST_BUFFER_POOL_UNLOCK (pool);
+ return TRUE;
+ }
/* ERRORS */
was_active:
{
@@ -673,11 +735,12 @@ static const gchar *empty_option[] = { NULL };
* gst_buffer_pool_get_options:
* @pool: a #GstBufferPool
*
- * Get a NULL terminated array of string with supported bufferpool options for
+ * Get a %NULL terminated array of string with supported bufferpool options for
* @pool. An option would typically be enabled with
* gst_buffer_pool_config_add_option().
*
- * Returns: (array zero-terminated=1) (transfer none): a NULL terminated array of strings.
+ * Returns: (array zero-terminated=1) (transfer none): a %NULL terminated array
+ * of strings.
*/
const gchar **
gst_buffer_pool_get_options (GstBufferPool * pool)
@@ -712,7 +775,7 @@ invalid_result:
*
* Check if the bufferpool supports @option.
*
- * Returns: a NULL terminated array of strings.
+ * Returns: %TRUE if the buffer pool contains @option.
*/
gboolean
gst_buffer_pool_has_option (GstBufferPool * pool, const gchar * option)
@@ -765,10 +828,10 @@ gst_buffer_pool_config_set_params (GstStructure * config, GstCaps * caps,
*
* Set the @allocator and @params on @config.
*
- * One of @allocator and @params can be NULL, but not both. When @allocator
- * is NULL, the default allocator of the pool will use the values in @param
- * to perform its allocation. When @param is NULL, the pool will use the
- * provided allocator with its default #GstAllocationParams.
+ * One of @allocator and @params can be %NULL, but not both. When @allocator
+ * is %NULL, the default allocator of the pool will use the values in @param
+ * to perform its allocation. When @param is %NULL, the pool will use the
+ * provided @allocator with its default #GstAllocationParams.
*
* A call to gst_buffer_pool_set_config() can update the allocator and params
* with the values that it is able to do. Some pools are, for example, not able
@@ -832,8 +895,8 @@ gst_buffer_pool_config_add_option (GstStructure * config, const gchar * option)
* gst_buffer_pool_config_n_options:
* @config: a #GstBufferPool configuration
*
- * Retrieve the number of values currently stored in the
- * options array of the @config structure.
+ * Retrieve the number of values currently stored in the options array of the
+ * @config structure.
*
* Returns: the options array size as a #guint.
*/
@@ -857,8 +920,8 @@ gst_buffer_pool_config_n_options (GstStructure * config)
* @config: a #GstBufferPool configuration
* @index: position in the option array to read
*
- * Parse an available @config and get the option
- * at @index of the options API array.
+ * Parse an available @config and get the option at @index of the options API
+ * array.
*
* Returns: a #gchar of the option at @index.
*/
@@ -886,9 +949,9 @@ gst_buffer_pool_config_get_option (GstStructure * config, guint index)
* @config: a #GstBufferPool configuration
* @option: an option
*
- * Check if @config contains @option
+ * Check if @config contains @option.
*
- * Returns: TRUE if the options array contains @option.
+ * Returns: %TRUE if the options array contains @option.
*/
gboolean
gst_buffer_pool_config_has_option (GstStructure * config, const gchar * option)
@@ -945,7 +1008,9 @@ gst_buffer_pool_config_get_params (GstStructure * config, GstCaps ** caps,
* @allocator: (transfer none): a #GstAllocator
* @params: #GstAllocationParams
*
- * Get the allocator and params from @config.
+ * Get the @allocator and @params from @config.
+ *
+ * Returns: %TRUE, if the values are set.
*/
gboolean
gst_buffer_pool_config_get_allocator (GstStructure * config,
@@ -970,6 +1035,44 @@ gst_buffer_pool_config_get_allocator (GstStructure * config,
return TRUE;
}
+/**
+ * gst_buffer_pool_config_validate_params:
+ * @config: (transfer none): a #GstBufferPool configuration
+ * @caps: (transfer none): the excepted caps of buffers
+ * @size: the expected size of each buffer, not including prefix and padding
+ * @min_buffers: the expected minimum amount of buffers to allocate.
+ * @max_buffers: the expect maximum amount of buffers to allocate or 0 for unlimited.
+ *
+ * Validate that changes made to @config are still valid in the context of the
+ * expected parameters. This function is a helper that can be used to validate
+ * changes made by a pool to a config when gst_buffer_pool_set_config()
+ * returns %FALSE. This expects that @caps and @size haven't changed, and that
+ * @min_buffers aren't lower then what we initially expected. This does not check
+ * if options or allocator parameters.
+ *
+ * Since: 1.4
+ *
+ * Returns: %TRUE, if the parameters are valid in this context.
+ */
+gboolean
+gst_buffer_pool_config_validate_params (GstStructure * config, GstCaps * caps,
+ guint size, guint min_buffers, G_GNUC_UNUSED guint max_buffers)
+{
+ GstCaps *newcaps;
+ guint newsize, newmin;
+ gboolean ret = FALSE;
+
+ g_return_val_if_fail (config != NULL, FALSE);
+
+ gst_buffer_pool_config_get_params (config, &newcaps, &newsize, &newmin, NULL);
+
+ if (gst_caps_is_equal (caps, newcaps) && (size == newsize)
+ && (newmin >= min_buffers))
+ ret = TRUE;
+
+ return ret;
+}
+
static GstFlowReturn
default_acquire_buffer (GstBufferPool * pool, GstBuffer ** buffer,
GstBufferPoolAcquireParams * params)
@@ -1007,9 +1110,12 @@ default_acquire_buffer (GstBufferPool * pool, GstBuffer ** buffer,
break;
}
- /* now wait */
- GST_LOG_OBJECT (pool, "waiting for free buffers");
+ /* now we release the control socket, we wait for a buffer release or
+ * flushing */
+ gst_poll_read_control (pool->priv->poll);
+ GST_LOG_OBJECT (pool, "waiting for free buffers or flushing");
gst_poll_wait (priv->poll, GST_CLOCK_TIME_NONE);
+ gst_poll_write_control (pool->priv->poll);
}
return result;
@@ -1030,9 +1136,9 @@ dec_outstanding (GstBufferPool * pool)
if (GST_BUFFER_POOL_IS_FLUSHING (pool)) {
/* take the lock so that set_active is not run concurrently */
GST_BUFFER_POOL_LOCK (pool);
- /* recheck the flushing state in the lock, the pool could have been
- * set to active again */
- if (GST_BUFFER_POOL_IS_FLUSHING (pool))
+ /* now that we have the lock, check if we have been de-activated with
+ * outstanding buffers */
+ if (!pool->priv->active)
do_stop (pool);
GST_BUFFER_POOL_UNLOCK (pool);
@@ -1053,7 +1159,7 @@ remove_meta_unpooled (GstBuffer * buffer, GstMeta ** meta, gpointer user_data)
static void
default_reset_buffer (GstBufferPool * pool, GstBuffer * buffer)
{
- GST_BUFFER_FLAGS (buffer) = 0;
+ GST_BUFFER_FLAGS (buffer) &= GST_BUFFER_FLAG_TAG_MEMORY;
GST_BUFFER_PTS (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DTS (buffer) = GST_CLOCK_TIME_NONE;
@@ -1074,9 +1180,10 @@ default_reset_buffer (GstBufferPool * pool, GstBuffer * buffer)
* Acquire a buffer from @pool. @buffer should point to a memory location that
* can hold a pointer to the new buffer.
*
- * @params can be NULL or contain optional parameters to influence the allocation.
+ * @params can be %NULL or contain optional parameters to influence the
+ * allocation.
*
- * Returns: a #GstFlowReturn such as GST_FLOW_FLUSHING when the pool is
+ * Returns: a #GstFlowReturn such as %GST_FLOW_FLUSHING when the pool is
* inactive.
*/
GstFlowReturn
@@ -1114,10 +1221,33 @@ gst_buffer_pool_acquire_buffer (GstBufferPool * pool, GstBuffer ** buffer,
static void
default_release_buffer (GstBufferPool * pool, GstBuffer * buffer)
{
+ GST_LOG_OBJECT (pool, "released buffer %p %d", buffer,
+ GST_MINI_OBJECT_FLAGS (buffer));
+
+ /* memory should be untouched */
+ if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY))
+ goto discard;
+
+ /* size should have been reset. This is not a catch all, pool with
+ * size requirement per memory should do their own check. */
+ if (gst_buffer_get_size (buffer) != pool->priv->size)
+ goto discard;
+
+ /* all memory should be exclusive to this buffer (and thus be writable) */
+ if (!gst_buffer_is_all_memory_writable (buffer))
+ goto discard;
+
/* keep it around in our queue */
- GST_LOG_OBJECT (pool, "released buffer %p", buffer);
gst_atomic_queue_push (pool->priv->queue, buffer);
gst_poll_write_control (pool->priv->poll);
+
+ return;
+
+discard:
+ {
+ do_free_buffer (pool, buffer);
+ return;
+ }
}
/**
@@ -1158,3 +1288,37 @@ gst_buffer_pool_release_buffer (GstBufferPool * pool, GstBuffer * buffer)
/* decrease the refcount that the buffer had to us */
gst_object_unref (pool);
}
+
+/**
+ * gst_buffer_pool_set_flushing:
+ * @pool: a #GstBufferPool
+ * @flushing: whether to start or stop flushing
+ *
+ * Enabled or disable the flushing state of a @pool without freeing or
+ * allocating buffers.
+ *
+ * Since: 1.4
+ */
+void
+gst_buffer_pool_set_flushing (GstBufferPool * pool, gboolean flushing)
+{
+ GstBufferPoolPrivate *priv;
+
+ g_return_if_fail (GST_IS_BUFFER_POOL (pool));
+
+ GST_LOG_OBJECT (pool, "flushing %d", flushing);
+
+ priv = pool->priv;
+
+ GST_BUFFER_POOL_LOCK (pool);
+
+ if (!priv->active) {
+ GST_WARNING_OBJECT (pool, "can't change flushing state of inactive pool");
+ goto done;
+ }
+
+ do_set_flushing (pool, flushing);
+
+done:
+ GST_BUFFER_POOL_UNLOCK (pool);
+}
diff --git a/gst/gstbufferpool.h b/gst/gstbufferpool.h
index 9806a6d..5427cb1 100644
--- a/gst/gstbufferpool.h
+++ b/gst/gstbufferpool.h
@@ -98,7 +98,6 @@ struct _GstBufferPoolAcquireParams {
/**
* GstBufferPool:
- * @object: the parent structure
*
* The structure of a #GstBufferPool. Use the associated macros to access the public
* variables.
@@ -133,22 +132,29 @@ struct _GstBufferPool {
* buffers from the configured memory allocator and with the configured
* parameters. All metadata that is present on the allocated buffer will
* be marked as #GST_META_FLAG_POOLED and #GST_META_FLAG_LOCKED and will
- * not be removed from the buffer in @reset_buffer.
+ * not be removed from the buffer in @reset_buffer. The buffer should
+ * have the GST_BUFFER_FLAG_TAG_MEMORY cleared.
* @reset_buffer: reset the buffer to its state when it was freshly allocated.
* The default implementation will clear the flags, timestamps and
* will remove the metadata without the #GST_META_FLAG_POOLED flag (even
- * the metadata with #GST_META_FLAG_LOCKED).
+ * the metadata with #GST_META_FLAG_LOCKED). If the
+ * #GST_BUFFER_FLAG_TAG_MEMORY was set, this function can also try to
+ * restore the memory and clear the #GST_BUFFER_FLAG_TAG_MEMORY again.
* @release_buffer: release a buffer back in the pool. The default
* implementation will put the buffer back in the queue and notify any
- * blocking acquire_buffer calls.
+ * blocking acquire_buffer calls when the #GST_BUFFER_FLAG_TAG_MEMORY
+ * is not set on the buffer. If #GST_BUFFER_FLAG_TAG_MEMORY is set, the
+ * buffer will be freed with @free_buffer.
* @free_buffer: free a buffer. The default implementation unrefs the buffer.
+ * @flush_start: enter the flushing state. Since: 1.4
+ * @flush_stop: leave the flushign state. Since: 1.4
*
* The GstBufferPool class.
*/
struct _GstBufferPoolClass {
GstObjectClass object_class;
- /* vmethods */
+ /*< public >*/
const gchar ** (*get_options) (GstBufferPool *pool);
gboolean (*set_config) (GstBufferPool *pool, GstStructure *config);
@@ -162,9 +168,11 @@ struct _GstBufferPoolClass {
void (*reset_buffer) (GstBufferPool *pool, GstBuffer *buffer);
void (*release_buffer) (GstBufferPool *pool, GstBuffer *buffer);
void (*free_buffer) (GstBufferPool *pool, GstBuffer *buffer);
+ void (*flush_start) (GstBufferPool *pool);
+ void (*flush_stop) (GstBufferPool *pool);
/*< private >*/
- gpointer _gst_reserved[GST_PADDING];
+ gpointer _gst_reserved[GST_PADDING - 2];
};
GType gst_buffer_pool_get_type (void);
@@ -182,6 +190,8 @@ GstStructure * gst_buffer_pool_get_config (GstBufferPool *pool);
const gchar ** gst_buffer_pool_get_options (GstBufferPool *pool);
gboolean gst_buffer_pool_has_option (GstBufferPool *pool, const gchar *option);
+void gst_buffer_pool_set_flushing (GstBufferPool *pool, gboolean flushing);
+
/* helpers for configuring the config structure */
void gst_buffer_pool_config_set_params (GstStructure *config, GstCaps *caps,
guint size, guint min_buffers, guint max_buffers);
@@ -197,6 +207,8 @@ guint gst_buffer_pool_config_n_options (GstStructure *config);
void gst_buffer_pool_config_add_option (GstStructure *config, const gchar *option);
const gchar * gst_buffer_pool_config_get_option (GstStructure *config, guint index);
gboolean gst_buffer_pool_config_has_option (GstStructure *config, const gchar *option);
+gboolean gst_buffer_pool_config_validate_params (GstStructure *config, GstCaps *caps,
+ guint size, guint min_buffers, guint max_buffers);
/* buffer management */
GstFlowReturn gst_buffer_pool_acquire_buffer (GstBufferPool *pool, GstBuffer **buffer,
diff --git a/gst/gstbus.c b/gst/gstbus.c
index b5343ab..69cf6b9 100644
--- a/gst/gstbus.c
+++ b/gst/gstbus.c
@@ -63,8 +63,6 @@
*
* Note that a #GstPipeline will set its bus into flushing state when changing
* from READY to NULL state.
- *
- * Last reviewed on 2012-03-28 (0.11.3)
*/
#include "gst_private.h"
@@ -293,7 +291,7 @@ gst_bus_new (void)
* Post a message on the given bus. Ownership of the message
* is taken by the bus.
*
- * Returns: TRUE if the message could be posted, FALSE if the bus is flushing.
+ * Returns: %TRUE if the message could be posted, %FALSE if the bus is flushing.
*
* MT safe.
*/
@@ -404,7 +402,7 @@ is_flushing:
* Check if there are pending messages on the bus that
* should be handled.
*
- * Returns: TRUE if there are messages on the bus to be handled, FALSE
+ * Returns: %TRUE if there are messages on the bus to be handled, %FALSE
* otherwise.
*
* MT safe.
@@ -429,7 +427,7 @@ gst_bus_have_pending (GstBus * bus)
*
* If @flushing, flush out and unref any messages queued in the bus. Releases
* references to the message origin objects. Will flush future messages until
- * gst_bus_set_flushing() sets @flushing to #FALSE.
+ * gst_bus_set_flushing() sets @flushing to %FALSE.
*
* MT safe.
*/
@@ -470,7 +468,7 @@ gst_bus_set_flushing (GstBus * bus, gboolean flushing)
* matching message was posted on the bus.
*
* Returns: (transfer full): a #GstMessage matching the filter in @types,
- * or NULL if no matching message was found on the bus until the timeout
+ * or %NULL if no matching message was found on the bus until the timeout
* expired. The message is taken from the bus and needs to be unreffed
* with gst_message_unref() after usage.
*
@@ -505,13 +503,18 @@ gst_bus_timed_pop_filtered (GstBus * bus, GstClockTime timeout,
message, GST_MESSAGE_TYPE_NAME (message),
GST_MESSAGE_SRC_NAME (message), (guint) types);
if ((GST_MESSAGE_TYPE (message) & types) != 0) {
- /* exit the loop, we have a message */
- goto beach;
- } else {
- GST_DEBUG_OBJECT (bus, "discarding message, does not match mask");
- gst_message_unref (message);
- message = NULL;
+ /* Extra check to ensure extended types don't get matched unless
+ * asked for */
+ if ((GST_MESSAGE_TYPE_IS_EXTENDED (message) == FALSE)
+ || (types & GST_MESSAGE_EXTENDED)) {
+ /* exit the loop, we have a message */
+ goto beach;
+ }
}
+
+ GST_DEBUG_OBJECT (bus, "discarding message, does not match mask");
+ gst_message_unref (message);
+ message = NULL;
}
/* no need to wait, exit loop */
@@ -566,7 +569,7 @@ beach:
* posted on the bus.
*
* Returns: (transfer full): the #GstMessage that is on the bus after the
- * specified timeout or NULL if the bus is empty after the timeout expired.
+ * specified timeout or %NULL if the bus is empty after the timeout expired.
* The message is taken from the bus and needs to be unreffed with
* gst_message_unref() after usage.
*
@@ -588,10 +591,11 @@ gst_bus_timed_pop (GstBus * bus, GstClockTime timeout)
* Get a message matching @type from the bus. Will discard all messages on
* the bus that do not match @type and that have been posted before the first
* message that does match @type. If there is no message matching @type on
- * the bus, all messages will be discarded.
+ * the bus, all messages will be discarded. It is not possible to use message
+ * enums beyond #GST_MESSAGE_EXTENDED in the @events mask.
*
* Returns: (transfer full): the next #GstMessage matching @type that is on
- * the bus, or NULL if the bus is empty or there is no message matching
+ * the bus, or %NULL if the bus is empty or there is no message matching
* @type. The message is taken from the bus and needs to be unreffed with
* gst_message_unref() after usage.
*
@@ -612,7 +616,7 @@ gst_bus_pop_filtered (GstBus * bus, GstMessageType types)
*
* Get a message from the bus.
*
- * Returns: (transfer full): the #GstMessage that is on the bus, or NULL if the
+ * Returns: (transfer full): the #GstMessage that is on the bus, or %NULL if the
* bus is empty. The message is taken from the bus and needs to be unreffed
* with gst_message_unref() after usage.
*
@@ -634,7 +638,7 @@ gst_bus_pop (GstBus * bus)
* on the bus' message queue. A reference is returned, and needs to be unreffed
* by the caller.
*
- * Returns: (transfer full): the #GstMessage that is on the bus, or NULL if the
+ * Returns: (transfer full): the #GstMessage that is on the bus, or %NULL if the
* bus is empty.
*
* MT safe.
@@ -671,7 +675,7 @@ gst_bus_peek (GstBus * bus)
* should handle messages asynchronously using the gst_bus watch and poll
* functions.
*
- * You cannot replace an existing sync_handler. You can pass NULL to this
+ * You cannot replace an existing sync_handler. You can pass %NULL to this
* function, which will clear the existing handler.
*/
void
@@ -892,7 +896,7 @@ gst_bus_add_watch_full_unlocked (GstBus * bus, gint priority,
* When @func is called, the message belongs to the caller; if you want to
* keep a copy of it, call gst_message_ref() before leaving @func.
*
- * The watch can be removed using g_source_remove() or by returning FALSE
+ * The watch can be removed using g_source_remove() or by returning %FALSE
* from @func.
*
* MT safe.
@@ -931,7 +935,7 @@ gst_bus_add_watch_full (GstBus * bus, gint priority,
* There can only be a single bus watch per bus, you must remove it before you
* can set a new one.
*
- * The watch can be removed using g_source_remove() or by returning FALSE
+ * The watch can be removed using g_source_remove() or by returning %FALSE
* from @func.
*
* Returns: The event source id.
@@ -1012,7 +1016,7 @@ poll_destroy_timeout (GstBusPollData * poll_data)
* gst_bus_poll:
* @bus: a #GstBus
* @events: a mask of #GstMessageType, representing the set of message types to
- * poll for.
+ * poll for (note special handling of extended message types below)
* @timeout: the poll timeout, as a #GstClockTime, or #GST_CLOCK_TIME_NONE to poll
* indefinitely.
*
@@ -1021,6 +1025,8 @@ poll_destroy_timeout (GstBusPollData * poll_data)
* @timeout is negative, this function will block indefinitely.
*
* All messages not in @events will be popped off the bus and will be ignored.
+ * It is not possible to use message enums beyond #GST_MESSAGE_EXTENDED in the
+ * @events mask
*
* Because poll is implemented using the "message" signal enabled by
* gst_bus_add_signal_watch(), calling gst_bus_poll() will cause the "message"
@@ -1048,7 +1054,7 @@ poll_destroy_timeout (GstBusPollData * poll_data)
* better handled by setting up an asynchronous bus watch and doing things
* from there.
*
- * Returns: (transfer full): the message that was received, or NULL if the
+ * Returns: (transfer full): the message that was received, or %NULL if the
* poll timed out. The message is taken from the bus and needs to be
* unreffed with gst_message_unref() after usage.
*/
@@ -1107,7 +1113,7 @@ gst_bus_poll (GstBus * bus, GstMessageType events, GstClockTime timeout)
* A helper #GstBusFunc that can be used to convert all asynchronous messages
* into signals.
*
- * Returns: TRUE
+ * Returns: %TRUE
*/
gboolean
gst_bus_async_signal_func (GstBus * bus, GstMessage * message, gpointer data)
diff --git a/gst/gstbus.h b/gst/gstbus.h
index 5821770..92d2160 100644
--- a/gst/gstbus.h
+++ b/gst/gstbus.h
@@ -99,7 +99,7 @@ typedef GstBusSyncReply (*GstBusSyncHandler) (GstBus * bus, GstMessage * mess
* function so it should not be freed in the function.
*
* Note that this function is used as a GSourceFunc which means that returning
- * FALSE will remove the GSource from the mainloop.
+ * %FALSE will remove the GSource from the mainloop.
*
* Returns: %FALSE if the event source should be removed.
*/
diff --git a/gst/gstcaps.c b/gst/gstcaps.c
index 7e10a2a..4525ead 100644
--- a/gst/gstcaps.c
+++ b/gst/gstcaps.c
@@ -34,20 +34,15 @@
* handle or produce at runtime.
*
* A #GstCaps can be constructed with the following code fragment:
- *
- * <example>
- * <title>Creating caps</title>
- * <programlisting>
- * GstCaps *caps;
- * caps = gst_caps_new_simple ("video/x-raw",
- * "format", G_TYPE_STRING, "I420",
- * "framerate", GST_TYPE_FRACTION, 25, 1,
- * "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
- * "width", G_TYPE_INT, 320,
- * "height", G_TYPE_INT, 240,
- * NULL);
- * </programlisting>
- * </example>
+ * |[
+ * GstCaps *caps = gst_caps_new_simple ("video/x-raw",
+ * "format", G_TYPE_STRING, "I420",
+ * "framerate", GST_TYPE_FRACTION, 25, 1,
+ * "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
+ * "width", G_TYPE_INT, 320,
+ * "height", G_TYPE_INT, 240,
+ * NULL);
+ * ]|
*
* A #GstCaps is fixed when it has no properties with ranges or lists. Use
* gst_caps_is_fixed() to test for fixed caps. Fixed caps can be used in a
@@ -56,7 +51,11 @@
* Various methods exist to work with the media types such as subtracting
* or intersecting.
*
- * Last reviewed on 2011-03-28 (0.11.3)
+ * Be aware that the current #GstCaps / #GstStructure serialization into string
+ * has limited support for nested #GstCaps / #GstStructure fields. It can only
+ * support one level of nesting. Using more levels will lead to unexpected
+ * behavior when using serialization features, such as gst_caps_to_string() or
+ * gst_value_serialize() and their counterparts.
*/
#ifdef HAVE_CONFIG_H
@@ -93,7 +92,7 @@ typedef struct _GstCapsImpl
/* same as gst_caps_is_any () */
#define CAPS_IS_ANY(caps) \
- (GST_CAPS_FLAGS(caps) & GST_CAPS_FLAG_ANY)
+ (!!(GST_CAPS_FLAGS(caps) & GST_CAPS_FLAG_ANY))
/* same as gst_caps_is_empty () */
#define CAPS_IS_EMPTY(caps) \
@@ -108,8 +107,10 @@ typedef struct _GstCapsImpl
* length check */
#define gst_caps_get_structure_unchecked(caps, index) \
(g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, (index)).structure)
+#define gst_caps_get_features_storage_unchecked(caps, index) \
+ (&g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, (index)).features)
#define gst_caps_get_features_unchecked(caps, index) \
- (g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, (index)).features)
+ (g_atomic_pointer_get (gst_caps_get_features_storage_unchecked (caps, index)))
/* quick way to append a structure without checking the args */
#define gst_caps_append_structure_unchecked(caps, s, f) G_STMT_START{\
GstCapsArrayElement __e={s, f}; \
@@ -326,7 +327,7 @@ gst_caps_new_simple (const char *media_type, const char *fieldname, ...)
* @...: additional structures to add
*
* Creates a new #GstCaps and adds all the structures listed as
- * arguments. The list must be NULL-terminated. The structures
+ * arguments. The list must be %NULL-terminated. The structures
* are not copied; the returned #GstCaps owns the structures.
*
* Returns: (transfer full): the new #GstCaps
@@ -350,7 +351,7 @@ gst_caps_new_full (GstStructure * struct1, ...)
* @var_args: additional structures to add
*
* Creates a new #GstCaps and adds all the structures listed as
- * arguments. The list must be NULL-terminated. The structures
+ * arguments. The list must be %NULL-terminated. The structures
* are not copied; the returned #GstCaps owns the structures.
*
* Returns: (transfer full): the new #GstCaps
@@ -644,7 +645,7 @@ gst_caps_append_structure_full (GstCaps * caps, GstStructure * structure,
* @caps: the #GstCaps to remove from
* @idx: Index of the structure to remove
*
- * removes the stucture with the given index from the list of structures
+ * removes the structure with the given index from the list of structures
* contained in @caps.
*/
void
@@ -850,8 +851,25 @@ gst_caps_get_features (const GstCaps * caps, guint index)
g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
features = gst_caps_get_features_unchecked (caps, index);
- if (!features)
- features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
+ if (!features) {
+ GstCapsFeatures **storage;
+
+ /* We have to do some atomic pointer magic here as the caps
+ * might not be writable and someone else calls this function
+ * at the very same time */
+ features = gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
+ gst_caps_features_set_parent_refcount (features, &GST_CAPS_REFCOUNT (caps));
+
+ storage = gst_caps_get_features_storage_unchecked (caps, index);
+ if (!g_atomic_pointer_compare_and_exchange (storage, NULL, features)) {
+ /* Someone did the same we just tried in the meantime */
+ gst_caps_features_set_parent_refcount (features, NULL);
+ gst_caps_features_free (features);
+
+ features = gst_caps_get_features_unchecked (caps, index);
+ g_assert (features != NULL);
+ }
+ }
return features;
}
@@ -860,7 +878,7 @@ gst_caps_get_features (const GstCaps * caps, guint index)
* gst_caps_set_features:
* @caps: a #GstCaps
* @index: the index of the structure
- * @features: (allow-none) (transfer full): the #GstFeatures to set
+ * @features: (allow-none) (transfer full): the #GstCapsFeatures to set
*
* Sets the #GstCapsFeatures @features for the structure at @index.
*
@@ -875,9 +893,10 @@ gst_caps_set_features (GstCaps * caps, guint index, GstCapsFeatures * features)
g_return_if_fail (index <= gst_caps_get_size (caps));
g_return_if_fail (IS_WRITABLE (caps));
- storage = &gst_caps_get_features_unchecked (caps, index);
- old = *storage;
- *storage = features;
+ storage = gst_caps_get_features_storage_unchecked (caps, index);
+ /* Not much problem here as caps are writable */
+ old = g_atomic_pointer_get (storage);
+ g_atomic_pointer_set (storage, features);
if (features)
gst_caps_features_set_parent_refcount (features, &GST_CAPS_REFCOUNT (caps));
@@ -980,7 +999,7 @@ gst_caps_set_value (GstCaps * caps, const char *field, const GValue * value)
* @varargs: additional parameters
*
* Sets fields in a #GstCaps. The arguments must be passed in the same
- * manner as gst_structure_set(), and be NULL-terminated.
+ * manner as gst_structure_set(), and be %NULL-terminated.
*/
void
gst_caps_set_simple_valist (GstCaps * caps, const char *field, va_list varargs)
@@ -1017,7 +1036,7 @@ gst_caps_set_simple_valist (GstCaps * caps, const char *field, va_list varargs)
* @...: additional parameters
*
* Sets fields in a #GstCaps. The arguments must be passed in the same
- * manner as gst_structure_set(), and be NULL-terminated.
+ * manner as gst_structure_set(), and be %NULL-terminated.
*/
void
gst_caps_set_simple (GstCaps * caps, const char *field, ...)
@@ -1040,7 +1059,7 @@ gst_caps_set_simple (GstCaps * caps, const char *field, ...)
*
* Determines if @caps represents any media format.
*
- * Returns: TRUE if @caps represents any format.
+ * Returns: %TRUE if @caps represents any format.
*/
gboolean
gst_caps_is_any (const GstCaps * caps)
@@ -1056,7 +1075,7 @@ gst_caps_is_any (const GstCaps * caps)
*
* Determines if @caps represents no media formats.
*
- * Returns: TRUE if @caps represents no formats.
+ * Returns: %TRUE if @caps represents no formats.
*/
gboolean
gst_caps_is_empty (const GstCaps * caps)
@@ -1084,7 +1103,7 @@ gst_caps_is_fixed_foreach (GQuark field_id, const GValue * value,
* one structure, and each field in the structure describes a fixed type.
* Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
*
- * Returns: TRUE if @caps is fixed
+ * Returns: %TRUE if @caps is fixed
*/
gboolean
gst_caps_is_fixed (const GstCaps * caps)
@@ -1097,7 +1116,7 @@ gst_caps_is_fixed (const GstCaps * caps)
if (GST_CAPS_LEN (caps) != 1)
return FALSE;
- features = gst_caps_get_features (caps, 0);
+ features = gst_caps_get_features_unchecked (caps, 0);
if (features && gst_caps_features_is_any (features))
return FALSE;
@@ -1114,7 +1133,7 @@ gst_caps_is_fixed (const GstCaps * caps)
* Tests if two #GstCaps are equal. This function only works on fixed
* #GstCaps.
*
- * Returns: TRUE if the arguments represent the same format
+ * Returns: %TRUE if the arguments represent the same format
*/
gboolean
gst_caps_is_equal_fixed (const GstCaps * caps1, const GstCaps * caps2)
@@ -1147,7 +1166,7 @@ gst_caps_is_equal_fixed (const GstCaps * caps1, const GstCaps * caps2)
* every media format that is in the first is also contained in the
* second. That is, @caps1 is a subset of @caps2.
*
- * Returns: TRUE if @caps1 is a subset of @caps2.
+ * Returns: %TRUE if @caps1 is a subset of @caps2.
*/
gboolean
gst_caps_is_always_compatible (const GstCaps * caps1, const GstCaps * caps2)
@@ -1303,7 +1322,7 @@ gst_caps_is_subset_structure_full (const GstCaps * caps,
*
* Checks if the given caps represent the same set of caps.
*
- * Returns: TRUE if both caps are equal.
+ * Returns: %TRUE if both caps are equal.
*/
gboolean
gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
@@ -1327,7 +1346,7 @@ gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
*
* Checks if the given caps are exactly the same set of caps.
*
- * Returns: TRUE if both caps are strictly equal.
+ * Returns: %TRUE if both caps are strictly equal.
*/
gboolean
gst_caps_is_strictly_equal (const GstCaps * caps1, const GstCaps * caps2)
@@ -2105,7 +2124,7 @@ gst_caps_fixate (GstCaps * caps)
gst_structure_fixate (s);
/* Set features to sysmem if they're still ANY */
- f = gst_caps_get_features (caps, 0);
+ f = gst_caps_get_features_unchecked (caps, 0);
if (f && gst_caps_features_is_any (f)) {
f = gst_caps_features_new_empty ();
gst_caps_set_features (caps, 0, f);
@@ -2129,6 +2148,9 @@ gst_caps_fixate (GstCaps * caps)
* ]|
* This prints the caps in human readable form.
*
+ * The current implementation of serialization will lead to unexpected results
+ * when there are nested #GstCaps / #GstStructure deeper than one level.
+ *
* Returns: (transfer full): a newly allocated string representing @caps.
*/
gchar *
@@ -2277,12 +2299,15 @@ gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
if (!priv_gst_structure_parse_fields (s, &s, structure)) {
gst_structure_free (structure);
+ if (features)
+ gst_caps_features_free (features);
g_free (copy);
return FALSE;
}
append:
gst_caps_append_structure_unchecked (caps, structure, features);
+ features = NULL;
if (*s == '\0')
break;
} while (TRUE);
@@ -2298,6 +2323,9 @@ gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
*
* Converts @caps from a string representation.
*
+ * The current implementation of serialization will lead to unexpected results
+ * when there are nested #GstCaps / #GstStructure deeper than one level.
+ *
* Returns: (transfer full): a newly allocated #GstCaps
*/
GstCaps *
diff --git a/gst/gstcaps.h b/gst/gstcaps.h
index 8df2499..e29da34 100644
--- a/gst/gstcaps.h
+++ b/gst/gstcaps.h
@@ -298,9 +298,9 @@ gst_caps_copy (const GstCaps * caps)
* in some cases), and the reference counts are updated appropriately (the old
* caps is unreffed, the new is reffed).
*
- * Either @ncaps or the #GstCaps pointed to by @ocaps may be NULL.
+ * Either @ncaps or the #GstCaps pointed to by @ocaps may be %NULL.
*
- * Returns: TRUE if @new_caps was different from @old_caps
+ * Returns: %TRUE if @new_caps was different from @old_caps
*/
#ifdef _FOOL_GTK_DOC_
G_INLINE_FUNC gboolean gst_caps_replace (GstCaps **old_caps, GstCaps *new_caps);
@@ -323,7 +323,7 @@ gst_caps_replace (GstCaps **old_caps, GstCaps *new_caps)
* function is similar to gst_caps_replace() except that it takes ownership
* of @new_caps.
*
- * Returns: TRUE if @new_caps was different from @old_caps
+ * Returns: %TRUE if @new_caps was different from @old_caps
*/
#ifdef _FOOL_GTK_DOC_
G_INLINE_FUNC gboolean gst_caps_take (GstCaps **old_caps, GstCaps *new_caps);
diff --git a/gst/gstcapsfeatures.c b/gst/gstcapsfeatures.c
index b64240e..e1e8f90 100644
--- a/gst/gstcapsfeatures.c
+++ b/gst/gstcapsfeatures.c
@@ -66,6 +66,7 @@ struct _GstCapsFeatures
};
GType _gst_caps_features_type = 0;
+static gint static_caps_features_parent_refcount = G_MAXINT;
GstCapsFeatures *_gst_caps_features_any = NULL;
GstCapsFeatures *_gst_caps_features_memory_system_memory = NULL;
static GQuark _gst_caps_feature_memory_system_memory = 0;
@@ -95,8 +96,13 @@ _priv_gst_caps_features_initialize (void)
gst_caps_features_transform_to_string);
_gst_caps_features_any = gst_caps_features_new_any ();
+ gst_caps_features_set_parent_refcount (_gst_caps_features_any,
+ &static_caps_features_parent_refcount);
_gst_caps_features_memory_system_memory =
gst_caps_features_new_id (_gst_caps_feature_memory_system_memory, 0);
+ gst_caps_features_set_parent_refcount
+ (_gst_caps_features_memory_system_memory,
+ &static_caps_features_parent_refcount);
}
gboolean
@@ -197,7 +203,7 @@ gst_caps_features_new_any (void)
* @...: additional features
*
* Creates a new #GstCapsFeatures with the given features.
- * The last argument must be NULL.
+ * The last argument must be %NULL.
*
* Free-function: gst_caps_features_free
*
@@ -411,7 +417,7 @@ gst_caps_features_free (GstCapsFeatures * features)
* |[
* GST_LOG ("features is %" GST_PTR_FORMAT, features);
* ]|
- * This prints the features in human readble form.
+ * This prints the features in human readable form.
*
* Free-function: g_free
*
@@ -465,7 +471,7 @@ priv_gst_caps_features_append_to_gstring (const GstCapsFeatures * features,
*
* Free-function: gst_caps_features_free
*
- * Returns: (transfer full): a new #GstCapsFeatures or NULL when the string could
+ * Returns: (transfer full): a new #GstCapsFeatures or %NULL when the string could
* not be parsed. Free with gst_caps_features_free() after use.
*
* Since: 1.2
diff --git a/gst/gstcapsfeatures.h b/gst/gstcapsfeatures.h
index 62d9e3c..441e1a1 100644
--- a/gst/gstcapsfeatures.h
+++ b/gst/gstcapsfeatures.h
@@ -28,7 +28,9 @@ G_BEGIN_DECLS
typedef struct _GstCapsFeatures GstCapsFeatures;
-#define GST_TYPE_CAPS_FEATURES (gst_caps_features_get_type ())
+GST_EXPORT GType _gst_caps_features_type;
+
+#define GST_TYPE_CAPS_FEATURES (_gst_caps_features_type)
#define GST_IS_CAPS_FEATURES(object) (gst_is_caps_features(object))
#define GST_CAPS_FEATURES_CAST(object) ((GstCapsFeatures *)(object))
#define GST_CAPS_FEATURES(object) (GST_CAPS_FEATURES_CAST(object))
diff --git a/gst/gstchildproxy.c b/gst/gstchildproxy.c
index 8ce03c9..a83356a 100644
--- a/gst/gstchildproxy.c
+++ b/gst/gstchildproxy.c
@@ -100,7 +100,7 @@ gst_child_proxy_default_get_child_by_name (GstChildProxy * parent,
/**
* gst_child_proxy_get_child_by_name:
* @parent: the parent object to get the child from
- * @name: the childs name
+ * @name: the child's name
*
* Looks up a child element by the given name.
*
@@ -125,7 +125,7 @@ gst_child_proxy_get_child_by_name (GstChildProxy * parent, const gchar * name)
/**
* gst_child_proxy_get_child_by_index:
* @parent: the parent object to get the child from
- * @index: the childs position in the child list
+ * @index: the child's position in the child list
*
* Fetches a child by its number.
*
@@ -174,7 +174,7 @@ gst_child_proxy_get_children_count (GstChildProxy * parent)
*
* MT safe.
*
- * Returns: TRUE if @target and @pspec could be found. FALSE otherwise. In that
+ * Returns: %TRUE if @target and @pspec could be found. %FALSE otherwise. In that
* case the values for @pspec and @target are not modified. Unref @target after
* usage. For plain GObjects @target is the same as @object.
*/
@@ -274,7 +274,7 @@ not_found:
* gst_child_proxy_get_valist:
* @object: the object to query
* @first_property_name: name of the first property to get
- * @var_args: return location for the first property, followed optionally by more name/return location pairs, followed by NULL
+ * @var_args: return location for the first property, followed optionally by more name/return location pairs, followed by %NULL
*
* Gets properties of the parent object and its children.
*/
@@ -328,7 +328,7 @@ cant_copy:
* gst_child_proxy_get:
* @object: the parent object
* @first_property_name: name of the first property to get
- * @...: return location for the first property, followed optionally by more name/return location pairs, followed by NULL
+ * @...: return location for the first property, followed optionally by more name/return location pairs, followed by %NULL
*
* Gets properties of the parent object and its children.
*/
@@ -383,7 +383,7 @@ not_found:
* gst_child_proxy_set_valist:
* @object: the parent object
* @first_property_name: name of the first property to set
- * @var_args: value for the first property, followed optionally by more name/value pairs, followed by NULL
+ * @var_args: value for the first property, followed optionally by more name/value pairs, followed by %NULL
*
* Sets properties of the parent object and its children.
*/
@@ -440,7 +440,7 @@ cant_copy:
* gst_child_proxy_set:
* @object: the parent object
* @first_property_name: name of the first property to set
- * @...: value for the first property, followed optionally by more name/value pairs, followed by NULL
+ * @...: value for the first property, followed optionally by more name/value pairs, followed by %NULL
*
* Sets properties of the parent object and its children.
*/
diff --git a/gst/gstclock.c b/gst/gstclock.c
index 4666b84..9f5b6fd 100644
--- a/gst/gstclock.c
+++ b/gst/gstclock.c
@@ -98,8 +98,6 @@
* clock and run the calibration functions. #GstClock:window-size defines the
* number of samples to use when calibrating and #GstClock:window-threshold
* defines the minimum number of samples before the calibration is performed.
- *
- * Last reviewed on 2012-03-28 (0.11.3)
*/
diff --git a/gst/gstconfig.h.in b/gst/gstconfig.h.in
index e6ea08d..8460281 100644
--- a/gst/gstconfig.h.in
+++ b/gst/gstconfig.h.in
@@ -33,7 +33,7 @@
* If a subsystem is disabled, most of this changes are done in an API
* compatible way, so you don't need to adapt your code in most cases. It is
* never done in an ABI compatible way though. So if you want to disable a
- * suybsystem, you have to rebuild all programs depending on GStreamer, too.
+ * subsystem, you have to rebuild all programs depending on GStreamer, too.
*
* If a subsystem is disabled in GStreamer, a value is defined in
* &lt;gst/gst.h&gt;. You can check this if you do subsystem-specific stuff.
@@ -81,14 +81,14 @@
/**
* GST_DISABLE_PARSE:
*
- * Configures the inclusion of the gst-lauch parser
+ * Configures the inclusion of the gst-launch parser
*/
@GST_DISABLE_PARSE_DEFINE@
/**
* GST_DISABLE_TRACE:
*
- * Configures the inclusion of a resource tracing facillity
+ * Configures the inclusion of a resource tracing facility
* (seems to be unused)
*/
@GST_DISABLE_TRACE_DEFINE@
diff --git a/gst/gstcontext.c b/gst/gstcontext.c
index 75a1c3f..b535574 100644
--- a/gst/gstcontext.c
+++ b/gst/gstcontext.c
@@ -32,17 +32,17 @@
*
* Applications can set a context on a complete pipeline by using
* gst_element_set_context(), which will then be propagated to all
- * child elements. Elements can handle these in GstElement::set_context()
+ * child elements. Elements can handle these in #GstElementClass.set_context()
* and merge them with the context information they already have.
*
* When an element needs a context it will do the following actions in this
* order until one step succeeds:
- * 1) Check if the element already has a context
- * 2) Query downstream with GST_QUERY_CONTEXT for the context
- * 2) Query upstream with GST_QUERY_CONTEXT for the context
- * 3) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with the required
+ * 1. Check if the element already has a context
+ * 2. Query downstream with GST_QUERY_CONTEXT for the context
+ * 3. Query upstream with GST_QUERY_CONTEXT for the context
+ * 4. Post a GST_MESSAGE_NEED_CONTEXT message on the bus with the required
* context types and afterwards check if a usable context was set now
- * 4) Create a context by itself and post a GST_MESSAGE_HAVE_CONTEXT message
+ * 5. Create a context by itself and post a GST_MESSAGE_HAVE_CONTEXT message
* on the bus.
*
* Bins will catch GST_MESSAGE_NEED_CONTEXT messages and will set any previously
@@ -68,7 +68,7 @@ struct _GstContext
#define GST_CONTEXT_STRUCTURE(c) (((GstContext *)(c))->structure)
-static GType _gst_context_type = 0;
+GType _gst_context_type = 0;
GST_DEFINE_MINI_OBJECT_TYPE (GstContext, gst_context);
void
@@ -141,6 +141,7 @@ gst_context_init (GstContext * context)
/**
* gst_context_new:
+ * @context_type: Context type
* @persistent: Persistent context
*
* Create a new context.
diff --git a/gst/gstcontext.h b/gst/gstcontext.h
index 9dd0914..0883f0d 100644
--- a/gst/gstcontext.h
+++ b/gst/gstcontext.h
@@ -31,7 +31,9 @@ typedef struct _GstContext GstContext;
#include <gst/gstminiobject.h>
#include <gst/gststructure.h>
-#define GST_TYPE_CONTEXT (gst_context_get_type())
+GST_EXPORT GType _gst_context_type;
+
+#define GST_TYPE_CONTEXT (_gst_context_type)
#define GST_IS_CONTEXT(obj) (GST_IS_MINI_OBJECT_TYPE (obj, GST_TYPE_CONTEXT))
#define GST_CONTEXT_CAST(obj) ((GstContext*)(obj))
#define GST_CONTEXT(obj) (GST_CONTEXT_CAST(obj))
@@ -130,9 +132,9 @@ gst_context_copy (const GstContext * context)
* in some cases), and the reference counts are updated appropriately (the old
* context is unreffed, the new one is reffed).
*
- * Either @new_context or the #GstContext pointed to by @old_context may be NULL.
+ * Either @new_context or the #GstContext pointed to by @old_context may be %NULL.
*
- * Returns: TRUE if @new_context was different from @old_context
+ * Returns: %TRUE if @new_context was different from @old_context
*/
#ifdef _FOOL_GTK_DOC_
G_INLINE_FUNC gboolean gst_context_replace (GstContext **old_context, GstContext *new_context);
diff --git a/gst/gstcontrolbinding.c b/gst/gstcontrolbinding.c
index 458151a..4981c89 100644
--- a/gst/gstcontrolbinding.c
+++ b/gst/gstcontrolbinding.c
@@ -283,12 +283,12 @@ gst_control_binding_get_value (GstControlBinding * binding,
}
/**
- * gst_control_binding_get_value_array:
+ * gst_control_binding_get_value_array: (skip)
* @binding: the control binding
* @timestamp: the time that should be processed
* @interval: the time spacing between subsequent values
* @n_values: the number of values
- * @values: array to put control-values in
+ * @values: (array length=n_values): array to put control-values in
*
* Gets a number of values for the given controlled property starting at the
* requested time. The array @values need to hold enough space for @n_values of
@@ -347,7 +347,7 @@ gst_control_binding_get_value_array (GstControlBinding * binding,
* @timestamp: the time that should be processed
* @interval: the time spacing between subsequent values
* @n_values: the number of values
- * @values: array to put control-values in
+ * @values: (array length=n_values): array to put control-values in
*
* Gets a number of #GValues for the given controlled property starting at the
* requested time. The array @values need to hold enough space for @n_values of
diff --git a/gst/gstcontrolbinding.h b/gst/gstcontrolbinding.h
index 170fce3..f870d34 100644
--- a/gst/gstcontrolbinding.h
+++ b/gst/gstcontrolbinding.h
@@ -75,6 +75,11 @@ struct _GstControlBinding {
/**
* GstControlBindingClass:
* @parent_class: Parent class
+ * @sync_values: implementation for updating the target values
+ * @get_value: implementation to fetch a single control-value
+ * @get_value_array: implementation to fetch a series of control-values
+ * @get_g_value_array: implementation to fetch a series of control-values
+ * as g_values
*
* The class structure of #GstControlBinding.
*/
@@ -83,7 +88,7 @@ struct _GstControlBindingClass
{
GstObjectClass parent_class;
- /* virtual methods */
+ /*< public >*/
gboolean (* sync_values) (GstControlBinding *binding, GstObject *object, GstClockTime timestamp, GstClockTime last_sync);
GValue * (* get_value) (GstControlBinding *binding, GstClockTime timestamp);
gboolean (* get_value_array) (GstControlBinding *binding, GstClockTime timestamp,GstClockTime interval, guint n_values, gpointer values);
diff --git a/gst/gstcontrolsource.c b/gst/gstcontrolsource.c
index c7b134d..be4816d 100644
--- a/gst/gstcontrolsource.c
+++ b/gst/gstcontrolsource.c
@@ -25,8 +25,8 @@
* @short_description: base class for control source sources
*
* The #GstControlSource is a base class for control value sources that could
- * be used by #GstController to get timestamp-value pairs. A control source
- * essentially is a function over time, returning gloat values between 0.0 and 1.0.
+ * be used to get timestamp-value pairs. A control source essentially is a
+ * function over time, returning float values between 0.0 and 1.0.
*
* A #GstControlSource is used by first getting an instance of a specific
* control-source, creating a binding for the control-source to the target property
@@ -96,7 +96,7 @@ gst_control_source_constructor (GType type, guint n_construct_params,
*
* Gets the value for this #GstControlSource at a given timestamp.
*
- * Returns: FALSE if the value couldn't be returned, TRUE otherwise.
+ * Returns: %FALSE if the value couldn't be returned, %TRUE otherwise.
*/
gboolean
gst_control_source_get_value (GstControlSource * self, GstClockTime timestamp,
@@ -118,7 +118,7 @@ gst_control_source_get_value (GstControlSource * self, GstClockTime timestamp,
* @timestamp: the first timestamp
* @interval: the time steps
* @n_values: the number of values to fetch
- * @values: array to put control-values in
+ * @values: (array length=n_values): array to put control-values in
*
* Gets an array of values for for this #GstControlSource. Values that are
* undefined contain NANs.
diff --git a/gst/gstcontrolsource.h b/gst/gstcontrolsource.h
index b0cd92a..655205b 100644
--- a/gst/gstcontrolsource.h
+++ b/gst/gstcontrolsource.h
@@ -113,7 +113,6 @@ struct _GstControlSource {
/**
* GstControlSourceClass:
* @parent_class: Parent class
- * @bind: Class method for binding the #GstControlSource to a specific GParamSpec
*
* The class structure of #GstControlSource.
*/
diff --git a/gst/gstdatetime.c b/gst/gstdatetime.c
index 003b0e6..d21cca4 100644
--- a/gst/gstdatetime.c
+++ b/gst/gstdatetime.c
@@ -56,12 +56,18 @@ typedef enum
struct _GstDateTime
{
+ GstMiniObject mini_object;
+
GDateTime *datetime;
GstDateTimeFields fields;
- volatile gint ref_count;
};
+GType _gst_date_time_type = 0;
+GST_DEFINE_MINI_OBJECT_TYPE (GstDateTime, gst_date_time);
+
+static void gst_date_time_free (GstDateTime * datetime);
+
/**
* gst_date_time_new_from_g_date_time:
* @dt: (transfer full): the #GDateTime. The new #GstDateTime takes ownership.
@@ -70,7 +76,7 @@ struct _GstDateTime
*
* Free-function: gst_date_time_unref
*
- * Returns: (transfer full): a newly created #GstDateTime, or NULL on error
+ * Returns: (transfer full): a newly created #GstDateTime, or %NULL on error
*/
GstDateTime *
gst_date_time_new_from_g_date_time (GDateTime * dt)
@@ -81,9 +87,12 @@ gst_date_time_new_from_g_date_time (GDateTime * dt)
return NULL;
gst_dt = g_slice_new (GstDateTime);
+
+ gst_mini_object_init (GST_MINI_OBJECT_CAST (gst_dt), 0, GST_TYPE_DATE_TIME,
+ NULL, NULL, (GstMiniObjectFreeFunction) gst_date_time_free);
+
gst_dt->datetime = dt;
gst_dt->fields = GST_DATE_TIME_FIELDS_YMD_HMS;
- gst_dt->ref_count = 1;
return gst_dt;
}
@@ -95,7 +104,7 @@ gst_date_time_new_from_g_date_time (GDateTime * dt)
*
* Free-function: g_date_time_unref
*
- * Returns: (transfer full): a newly created #GDateTime, or NULL on error
+ * Returns: (transfer full): a newly created #GDateTime, or %NULL on error
*/
GDateTime *
gst_date_time_to_g_date_time (GstDateTime * datetime)
@@ -112,8 +121,8 @@ gst_date_time_to_g_date_time (GstDateTime * datetime)
* gst_date_time_has_year:
* @datetime: a #GstDateTime
*
- * Returns: TRUE if @datetime<!-- -->'s year field is set (which should always
- * be the case), otherwise FALSE
+ * Returns: %TRUE if @datetime<!-- -->'s year field is set (which should always
+ * be the case), otherwise %FALSE
*/
gboolean
gst_date_time_has_year (const GstDateTime * datetime)
@@ -127,7 +136,7 @@ gst_date_time_has_year (const GstDateTime * datetime)
* gst_date_time_has_month:
* @datetime: a #GstDateTime
*
- * Returns: TRUE if @datetime<!-- -->'s month field is set, otherwise FALSE
+ * Returns: %TRUE if @datetime<!-- -->'s month field is set, otherwise %FALSE
*/
gboolean
gst_date_time_has_month (const GstDateTime * datetime)
@@ -141,7 +150,7 @@ gst_date_time_has_month (const GstDateTime * datetime)
* gst_date_time_has_day:
* @datetime: a #GstDateTime
*
- * Returns: TRUE if @datetime<!-- -->'s day field is set, otherwise FALSE
+ * Returns: %TRUE if @datetime<!-- -->'s day field is set, otherwise %FALSE
*/
gboolean
gst_date_time_has_day (const GstDateTime * datetime)
@@ -155,8 +164,8 @@ gst_date_time_has_day (const GstDateTime * datetime)
* gst_date_time_has_time:
* @datetime: a #GstDateTime
*
- * Returns: TRUE if @datetime<!-- -->'s hour and minute fields are set,
- * otherwise FALSE
+ * Returns: %TRUE if @datetime<!-- -->'s hour and minute fields are set,
+ * otherwise %FALSE
*/
gboolean
gst_date_time_has_time (const GstDateTime * datetime)
@@ -170,7 +179,7 @@ gst_date_time_has_time (const GstDateTime * datetime)
* gst_date_time_has_second:
* @datetime: a #GstDateTime
*
- * Returns: TRUE if @datetime<!-- -->'s second field is set, otherwise FALSE
+ * Returns: %TRUE if @datetime<!-- -->'s second field is set, otherwise %FALSE
*/
gboolean
gst_date_time_has_second (const GstDateTime * datetime)
@@ -587,7 +596,7 @@ __gst_date_time_compare (const GstDateTime * dt1, const GstDateTime * dt2)
*
* Note that @tzoffset is a float and was chosen so for being able to handle
* some fractional timezones, while it still keeps the readability of
- * represeting it in hours for most timezones.
+ * representing it in hours for most timezones.
*
* If value is -1 then all over value will be ignored. For example
* if @month == -1, then #GstDateTime will created only for @year. If
@@ -717,7 +726,7 @@ done:
* 2012-06-23T23:30+0100, 2012-06-23T23:30:59Z, 2012-06-23T23:30:59+0100
*
* Returns: a newly allocated string formatted according to ISO 8601 and
- * only including the datetime fields that are valid, or NULL in case
+ * only including the datetime fields that are valid, or %NULL in case
* there was an error. The string should be freed with g_free().
*/
gchar *
@@ -740,7 +749,7 @@ gst_date_time_to_iso8601_string (GstDateTime * datetime)
*
* Free-function: gst_date_time_unref
*
- * Returns: (transfer full): a newly created #GstDateTime, or NULL on error
+ * Returns: (transfer full): a newly created #GstDateTime, or %NULL on error
*/
GstDateTime *
gst_date_time_new_from_iso8601_string (const gchar * string)
@@ -868,7 +877,6 @@ ymd:
return gst_date_time_new_ymd (year, month, day);
}
-
static void
gst_date_time_free (GstDateTime * datetime)
{
@@ -887,10 +895,7 @@ gst_date_time_free (GstDateTime * datetime)
GstDateTime *
gst_date_time_ref (GstDateTime * datetime)
{
- g_return_val_if_fail (datetime != NULL, NULL);
- g_return_val_if_fail (datetime->ref_count > 0, NULL);
- g_atomic_int_inc (&datetime->ref_count);
- return datetime;
+ return (GstDateTime *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (datetime));
}
/**
@@ -903,9 +908,11 @@ gst_date_time_ref (GstDateTime * datetime)
void
gst_date_time_unref (GstDateTime * datetime)
{
- g_return_if_fail (datetime != NULL);
- g_return_if_fail (datetime->ref_count > 0);
+ gst_mini_object_unref (GST_MINI_OBJECT_CAST (datetime));
+}
- if (g_atomic_int_dec_and_test (&datetime->ref_count))
- gst_date_time_free (datetime);
+void
+_priv_gst_date_time_initialize (void)
+{
+ _gst_date_time_type = gst_date_time_get_type ();
}
diff --git a/gst/gstdatetime.h b/gst/gstdatetime.h
index 08139d7..251dce1 100644
--- a/gst/gstdatetime.h
+++ b/gst/gstdatetime.h
@@ -32,10 +32,24 @@ G_BEGIN_DECLS
* information. It currently supports ranges from 0001-01-01 to
* 9999-12-31 in the Gregorian proleptic calendar.
*
- * Use the acessor functions to get the stored values.
+ * Use the accessor functions to get the stored values.
*/
typedef struct _GstDateTime GstDateTime;
+GST_EXPORT GType _gst_date_time_type;
+
+/**
+ * GST_TYPE_DATE_TIME:
+ *
+ * a boxed #GValue type for #GstDateTime that represents a date and time.
+ *
+ * Returns: the #GType of GstDateTime
+ */
+
+#define GST_TYPE_DATE_TIME (_gst_date_time_type)
+
+GType gst_date_time_get_type (void);
+
/* query which fields are set */
gboolean gst_date_time_has_year (const GstDateTime * datetime);
diff --git a/gst/gstdebugutils.c b/gst/gstdebugutils.c
index 23c8f9b..7b3ebf9 100644
--- a/gst/gstdebugutils.c
+++ b/gst/gstdebugutils.c
@@ -163,6 +163,25 @@ debug_dump_pad (GstPad * pad, const gchar * color_name,
if (details & GST_DEBUG_GRAPH_SHOW_STATES) {
gchar pad_flags[4];
const gchar *activation_mode = "-><";
+ const gchar *task_mode = "";
+ GstTask *task;
+
+ GST_OBJECT_LOCK (pad);
+ task = GST_PAD_TASK (pad);
+ if (task) {
+ switch (gst_task_get_state (task)) {
+ case GST_TASK_STARTED:
+ task_mode = "[T]";
+ break;
+ case GST_TASK_PAUSED:
+ task_mode = "[t]";
+ break;
+ default:
+ /* Invalid task state, ignoring */
+ break;
+ }
+ }
+ GST_OBJECT_UNLOCK (pad);
/* check if pad flags */
pad_flags[0] =
@@ -174,9 +193,9 @@ debug_dump_pad (GstPad * pad, const gchar * color_name,
pad_flags[3] = '\0';
fprintf (out,
- "%s %s_%s [color=black, fillcolor=\"%s\", label=\"%s\\n[%c][%s]\", height=\"0.2\", style=\"%s\"];\n",
+ "%s %s_%s [color=black, fillcolor=\"%s\", label=\"%s\\n[%c][%s]%s\", height=\"0.2\", style=\"%s\"];\n",
spc, element_name, pad_name, color_name, GST_OBJECT_NAME (pad),
- activation_mode[pad->mode], pad_flags, style_name);
+ activation_mode[pad->mode], pad_flags, task_mode, style_name);
} else {
fprintf (out,
"%s %s_%s [color=black, fillcolor=\"%s\", label=\"%s\", height=\"0.2\", style=\"%s\"];\n",
@@ -254,6 +273,11 @@ string_append_field (GQuark field, const GValue * value, gpointer ptr)
gchar *value_str = gst_value_serialize (value);
gchar *esc_value_str;
+ if (value_str == NULL) {
+ g_string_append_printf (str, " %18s: NULL\\l", g_quark_to_string (field));
+ return TRUE;
+ }
+
/* some enums can become really long */
if (strlen (value_str) > 25) {
gint pos = 24;
@@ -645,6 +669,12 @@ gst_debug_bin_to_dot_file (GstBin * bin, GstDebugGraphDetails details,
" label=\"<%s>\\n%s%s%s\";\n"
" node [style=filled, shape=box, fontsize=\"9\", fontname=\"sans\", margin=\"0.0,0.0\"];\n"
" edge [labelfontsize=\"6\", fontsize=\"9\", fontname=\"monospace\"];\n"
+ " \n"
+ " legend [\n"
+ " pos=\"0,0!\",\n"
+ " margin=\"0.05,0.05\",\n"
+ " label=\"Legend\\lElement-States: [~] void-pending, [0] null, [-] ready, [=] paused, [>] playing\\lPad-Activation: [-] none, [>] push, [<] pull\\lPad-Flags: [b]locked, [f]lushing, [b]locking; upper-case is set\\lPad-Task: [T] has started task, [t] has paused task\\l\"\n,"
+ " ];"
"\n", G_OBJECT_TYPE_NAME (bin), GST_OBJECT_NAME (bin),
(state_name ? state_name : ""), (param_name ? param_name : "")
);
diff --git a/gst/gstdevice.c b/gst/gstdevice.c
new file mode 100644
index 0000000..9119ba9
--- /dev/null
+++ b/gst/gstdevice.c
@@ -0,0 +1,350 @@
+/* GStreamer
+ * Copyright (C) 2012 Olivier Crete <olivier.crete@collabora.com>
+ *
+ * gstdevice.c: Device discovery
+ *
+ * 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.
+ */
+
+/**
+ * SECTION:gstdevice
+ * @short_description: Object representing a device
+ * @see_also: #GstDeviceMonitor
+ *
+ * #GstDevice are objects representing a device, they contain
+ * relevant metadata about the device, such as its class and the #GstCaps
+ * representing the media types it can produce or handle.
+ *
+ * #GstDevice are created by #GstDeviceMonitor objects which can be
+ * aggregated by #GstGlobalDeviceMonitor objects.
+ *
+ * Since: 1.4
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gst_private.h"
+
+#include "gstdevice.h"
+
+enum
+{
+ PROP_DISPLAY_NAME = 1,
+ PROP_CAPS,
+ PROP_DEVICE_CLASS
+};
+
+enum
+{
+ REMOVED,
+ LAST_SIGNAL
+};
+
+struct _GstDevicePrivate
+{
+ GstCaps *caps;
+ gchar *device_class;
+ gchar *display_name;
+};
+
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_ABSTRACT_TYPE (GstDevice, gst_device, GST_TYPE_OBJECT);
+
+static void gst_device_get_property (GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec);
+static void gst_device_set_property (GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_device_finalize (GObject * object);
+
+
+static void
+gst_device_class_init (GstDeviceClass * klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GstDevicePrivate));
+
+ object_class->get_property = gst_device_get_property;
+ object_class->set_property = gst_device_set_property;
+ object_class->finalize = gst_device_finalize;
+
+ g_object_class_install_property (object_class, PROP_DISPLAY_NAME,
+ g_param_spec_string ("display-name", "Display Name",
+ "The user-friendly name of the device", "",
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (object_class, PROP_CAPS,
+ g_param_spec_boxed ("caps", "Device Caps",
+ "The possible caps of a device", GST_TYPE_CAPS,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (object_class, PROP_DEVICE_CLASS,
+ g_param_spec_string ("device-class", "Device Class",
+ "The Class of the device", "",
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ signals[REMOVED] = g_signal_new ("removed", G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
+}
+
+static void
+gst_device_init (GstDevice * device)
+{
+ device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device, GST_TYPE_DEVICE,
+ GstDevicePrivate);
+}
+
+static void
+gst_device_finalize (GObject * object)
+{
+ GstDevice *device = GST_DEVICE (object);
+
+ gst_caps_replace (&device->priv->caps, NULL);
+
+ g_free (device->priv->display_name);
+ g_free (device->priv->device_class);
+
+ G_OBJECT_CLASS (gst_device_parent_class)->finalize (object);
+}
+
+static void
+gst_device_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ GstDevice *gstdevice;
+
+ gstdevice = GST_DEVICE_CAST (object);
+
+ switch (prop_id) {
+ case PROP_DISPLAY_NAME:
+ g_value_take_string (value, gst_device_get_display_name (gstdevice));
+ break;
+ case PROP_CAPS:
+ if (gstdevice->priv->caps)
+ g_value_take_boxed (value, gst_device_get_caps (gstdevice));
+ break;
+ case PROP_DEVICE_CLASS:
+ g_value_take_string (value, gst_device_get_device_class (gstdevice));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+gst_device_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstDevice *gstdevice;
+
+ gstdevice = GST_DEVICE_CAST (object);
+
+ switch (prop_id) {
+ case PROP_DISPLAY_NAME:
+ gstdevice->priv->display_name = g_value_dup_string (value);
+ break;
+ case PROP_CAPS:
+ gst_caps_replace (&gstdevice->priv->caps, g_value_get_boxed (value));
+ break;
+ case PROP_DEVICE_CLASS:
+ gstdevice->priv->device_class = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * gst_device_create_element:
+ * @device: a #GstDevice
+ * @name: (allow-none): name of new element, or %NULL to automatically
+ * create a unique name.
+ *
+ * Creates the element with all of the required paramaters set to use
+ * this device.
+ *
+ * Returns: (transfer full): a new #GstElement configured to use this device
+ *
+ * Since: 1.4
+ */
+GstElement *
+gst_device_create_element (GstDevice * device, const gchar * name)
+{
+ GstDeviceClass *klass = GST_DEVICE_GET_CLASS (device);
+
+ if (klass->create_element)
+ return klass->create_element (device, name);
+ else
+ return NULL;
+}
+
+/**
+ * gst_device_get_caps:
+ * @device: a #GstDevice
+ *
+ * Getter for the #GstCaps that this device supports.
+ *
+ * Returns: The #GstCaps supported by this device. Unref with
+ * gst_caps_unref() when done.
+ *
+ * Since: 1.4
+ */
+GstCaps *
+gst_device_get_caps (GstDevice * device)
+{
+ if (device->priv->caps)
+ return gst_caps_ref (device->priv->caps);
+ else
+ return NULL;
+}
+
+/**
+ * gst_device_get_display_name:
+ * @device: a #GstDevice
+ *
+ * Gets the user-friendly name of the device.
+ *
+ * Returns: The device name. Free with g_free() after use.
+ *
+ * Since: 1.4
+ */
+gchar *
+gst_device_get_display_name (GstDevice * device)
+{
+ return
+ g_strdup (device->priv->display_name ? device->priv->display_name : "");
+}
+
+/**
+ * gst_device_get_device_class:
+ * @device: a #GstDevice
+ *
+ * Gets the "class" of a device. This is a "/" separated list of
+ * classes that represent this device. They are a subset of the
+ * classes of the #GstDeviceMonitor that produced this device.
+ *
+ * Returns: The device class. Free with g_free() after use.
+ *
+ * Since: 1.4
+ */
+gchar *
+gst_device_get_device_class (GstDevice * device)
+{
+ if (device->priv->device_class != NULL)
+ return g_strdup (device->priv->device_class);
+ else
+ return g_strdup ("");
+}
+
+/**
+ * gst_device_reconfigure_element:
+ * @device: a #GstDevice
+ * @element: a #GstElement
+ *
+ * Tries to reconfigure an existing element to use the device. If this
+ * function fails, then one must destroy the element and create a new one
+ * using gst_device_create_element().
+ *
+ * Note: This should only be implemented for elements can change their
+ * device in the PLAYING state.
+ *
+ * Returns: %TRUE if the element could be reconfigured to use this device,
+ * %FALSE otherwise.
+ *
+ * Since: 1.4
+ */
+gboolean
+gst_device_reconfigure_element (GstDevice * device, GstElement * element)
+{
+ GstDeviceClass *klass = GST_DEVICE_GET_CLASS (device);
+
+ if (klass->reconfigure_element)
+ return klass->reconfigure_element (device, element);
+ else
+ return FALSE;
+}
+
+/**
+ * gst_device_has_classesv:
+ * @device: a #GstDevice
+ * @classes: (array zero-terminated=1): a %NULL terminated array of klasses to match, only match if all
+ * classes are matched
+ *
+ * Check if @factory matches all of the given classes
+ *
+ * Returns: %TRUE if @device matches.
+ *
+ * Since: 1.4
+ */
+gboolean
+gst_device_has_classesv (GstDevice * device, gchar ** classes)
+{
+ g_return_val_if_fail (GST_IS_DEVICE (device), FALSE);
+
+
+ for (; classes[0]; classes++) {
+ const gchar *found;
+ guint len;
+
+ if (classes[0] == '\0')
+ continue;
+
+ found = strstr (device->priv->device_class, classes[0]);
+
+ if (!found)
+ return FALSE;
+ if (found != device->priv->device_class && *(found - 1) != '/')
+ return FALSE;
+
+ len = strlen (classes[0]);
+ if (found[len] != 0 && found[len] != '/')
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * gst_device_has_classes:
+ * @device: a #GstDevice
+ * @classes: a "/" separate list of device classes to match, only match if
+ * all classes are matched
+ *
+ * Check if @device matches all of the given classes
+ *
+ * Returns: %TRUE if @device matches.
+ *
+ * Since: 1.4
+ */
+gboolean
+gst_device_has_classes (GstDevice * device, const gchar * classes)
+{
+ gchar **classesv;
+ gboolean res;
+
+ classesv = g_strsplit (classes, "/", 0);
+
+ res = gst_device_has_classesv (device, classesv);
+
+ g_strfreev (classesv);
+
+ return res;
+}
diff --git a/gst/gstdevice.h b/gst/gstdevice.h
new file mode 100644
index 0000000..b055aa0
--- /dev/null
+++ b/gst/gstdevice.h
@@ -0,0 +1,106 @@
+/* GStreamer
+ * Copyright (C) 2012 Olivier Crete <olivier.crete@collabora.com>
+ *
+ * gstdevice.c: Device discovery
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GST_DEVICE_H__
+#define __GST_DEVICE_H__
+
+typedef struct _GstDevice GstDevice;
+typedef struct _GstDeviceClass GstDeviceClass;
+
+#include <gst/gstelement.h>
+#include <gst/gstcaps.h>
+
+
+G_BEGIN_DECLS
+
+typedef struct _GstDevicePrivate GstDevicePrivate;
+
+#define GST_TYPE_DEVICE (gst_device_get_type())
+#define GST_IS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEVICE))
+#define GST_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEVICE))
+#define GST_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEVICE, GstDeviceClass))
+#define GST_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEVICE, GstDevice))
+#define GST_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEVICE, GstDeviceClass))
+#define GST_DEVICE_CAST(obj) ((GstDevice *)(obj))
+
+/**
+ * GstDevice:
+ * @parent: The parent #GstObject strucuture.
+ *
+ * A device object.
+ *
+ * Since: 1.4
+ */
+
+struct _GstDevice {
+ GstObject parent;
+
+ /*< private >*/
+ GstDevicePrivate *priv;
+
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+/**
+ * GstDeviceClass:
+ * @parent_class: The parent #GstObjectClass strucuture.
+ * @create_element: Creates the fully configured element to access this device.
+ * Subclasses need to override this and return a new element.
+ * @reconfigure_element: This only needs to be implemented by subclasses if the
+ * element can be reconfigured to use a different device. See the documentation
+ * for gst_device_reconfigure_element().
+ *
+ * The class structure for a #GstDevice object.
+ *
+ * Since: 1.4
+ */
+
+struct _GstDeviceClass {
+ GstObjectClass parent_class;
+
+ GstElement * (*create_element) (GstDevice * device, const gchar * name);
+ gboolean (*reconfigure_element) (GstDevice * device, GstElement * element);
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+GType gst_device_get_type (void);
+
+GstElement * gst_device_create_element (GstDevice * device, const gchar * name);
+
+GstCaps * gst_device_get_caps (GstDevice * device);
+gchar * gst_device_get_display_name (GstDevice * device);
+gchar * gst_device_get_device_class (GstDevice * device);
+gboolean gst_device_reconfigure_element (GstDevice * device,
+ GstElement * element);
+
+gboolean gst_device_has_classesv (GstDevice * device,
+ gchar ** classes);
+
+gboolean gst_device_has_classes (GstDevice * device,
+ const gchar * classes);
+
+
+G_END_DECLS
+
+#endif /* __GST_DEVICE_H__ */
diff --git a/gst/gstdevicemonitor.c b/gst/gstdevicemonitor.c
new file mode 100644
index 0000000..6fabe11
--- /dev/null
+++ b/gst/gstdevicemonitor.c
@@ -0,0 +1,587 @@
+/* GStreamer
+ * Copyright (C) 2012 Olivier Crete <olivier.crete@collabora.com>
+ *
+ * gstdevicemonitor.c: Device probing and monitoring
+ *
+ * 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.
+ */
+
+/**
+ * SECTION:gstdevicemonitor
+ * @short_description: A device monitor and prober
+ * @see_also: #GstDevice, #GstGlobalDeviceMonitor
+ *
+ * A #GstDeviceMonitor subclass is provided by a plugin that handles devices
+ * if there is a way to programatically list connected devices. It can also
+ * optionally provide updates to the list of connected devices.
+ *
+ * Each #GstDeviceMonitor subclass is a singleton, a plugin should
+ * normally provide a single subclass for all devices.
+ *
+ * Applications would normally use a #GstGlobalDeviceMonitor to monitor devices
+ * from all revelant monitors.
+ *
+ * Since: 1.4
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gst_private.h"
+
+#include "gstdevicemonitor.h"
+
+#include "gstelementmetadata.h"
+#include "gstquark.h"
+
+struct _GstDeviceMonitorPrivate
+{
+ GstBus *bus;
+
+ GMutex start_lock;
+
+ gboolean started_count;
+};
+
+/* this is used in gstelementfactory.c:gst_element_register() */
+GQuark __gst_devicemonitorclass_factory = 0;
+
+static void gst_device_monitor_class_init (GstDeviceMonitorClass * klass);
+static void gst_device_monitor_init (GstDeviceMonitor * element);
+static void gst_device_monitor_base_class_init (gpointer g_class);
+static void gst_device_monitor_base_class_finalize (gpointer g_class);
+static void gst_device_monitor_dispose (GObject * object);
+static void gst_device_monitor_finalize (GObject * object);
+
+static gpointer gst_device_monitor_parent_class = NULL;
+
+GType
+gst_device_monitor_get_type (void)
+{
+ static volatile gsize gst_device_monitor_type = 0;
+
+ if (g_once_init_enter (&gst_device_monitor_type)) {
+ GType _type;
+ static const GTypeInfo element_info = {
+ sizeof (GstDeviceMonitorClass),
+ gst_device_monitor_base_class_init,
+ gst_device_monitor_base_class_finalize,
+ (GClassInitFunc) gst_device_monitor_class_init,
+ NULL,
+ NULL,
+ sizeof (GstDeviceMonitor),
+ 0,
+ (GInstanceInitFunc) gst_device_monitor_init,
+ NULL
+ };
+
+ _type = g_type_register_static (GST_TYPE_OBJECT, "GstDeviceMonitor",
+ &element_info, G_TYPE_FLAG_ABSTRACT);
+
+ __gst_devicemonitorclass_factory =
+ g_quark_from_static_string ("GST_DEVICEMONITORCLASS_FACTORY");
+ g_once_init_leave (&gst_device_monitor_type, _type);
+ }
+ return gst_device_monitor_type;
+}
+
+static void
+gst_device_monitor_base_class_init (gpointer g_class)
+{
+ GstDeviceMonitorClass *klass = GST_DEVICE_MONITOR_CLASS (g_class);
+
+ /* Copy the element details here so elements can inherit the
+ * details from their base class and classes only need to set
+ * the details in class_init instead of base_init */
+ klass->metadata =
+ klass->metadata ? gst_structure_copy (klass->metadata) :
+ gst_structure_new_empty ("metadata");
+
+ klass->factory = g_type_get_qdata (G_TYPE_FROM_CLASS (klass),
+ __gst_devicemonitorclass_factory);
+}
+
+static void
+gst_device_monitor_base_class_finalize (gpointer g_class)
+{
+ GstDeviceMonitorClass *klass = GST_DEVICE_MONITOR_CLASS (g_class);
+
+ gst_structure_free (klass->metadata);
+}
+
+static void
+gst_device_monitor_class_init (GstDeviceMonitorClass * klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+
+ gst_device_monitor_parent_class = g_type_class_peek_parent (klass);
+
+ g_type_class_add_private (klass, sizeof (GstDeviceMonitorPrivate));
+
+ gobject_class->dispose = gst_device_monitor_dispose;
+ gobject_class->finalize = gst_device_monitor_finalize;
+}
+
+static void
+gst_device_monitor_init (GstDeviceMonitor * monitor)
+{
+ monitor->priv = G_TYPE_INSTANCE_GET_PRIVATE (monitor,
+ GST_TYPE_DEVICE_MONITOR, GstDeviceMonitorPrivate);
+
+ g_mutex_init (&monitor->priv->start_lock);
+
+ monitor->priv->bus = gst_bus_new ();
+ gst_bus_set_flushing (monitor->priv->bus, TRUE);
+}
+
+
+static void
+gst_device_monitor_dispose (GObject * object)
+{
+ GstDeviceMonitor *monitor = GST_DEVICE_MONITOR (object);
+
+ gst_object_replace ((GstObject **) & monitor->priv->bus, NULL);
+
+ GST_OBJECT_LOCK (monitor);
+ g_list_free_full (monitor->devices, (GDestroyNotify) gst_object_unparent);
+ monitor->devices = NULL;
+ GST_OBJECT_UNLOCK (monitor);
+
+ G_OBJECT_CLASS (gst_device_monitor_parent_class)->dispose (object);
+}
+
+static void
+gst_device_monitor_finalize (GObject * object)
+{
+ GstDeviceMonitor *monitor = GST_DEVICE_MONITOR (object);
+
+ g_mutex_clear (&monitor->priv->start_lock);
+
+ G_OBJECT_CLASS (gst_device_monitor_parent_class)->finalize (object);
+}
+
+/**
+ * gst_device_monitor_class_add_metadata:
+ * @klass: class to set metadata for
+ * @key: the key to set
+ * @value: the value to set
+ *
+ * Set @key with @value as metadata in @klass.
+ */
+void
+gst_device_monitor_class_add_metadata (GstDeviceMonitorClass * klass,
+ const gchar * key, const gchar * value)
+{
+ g_return_if_fail (GST_IS_DEVICE_MONITOR_CLASS (klass));
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (value != NULL);
+
+ gst_structure_set ((GstStructure *) klass->metadata,
+ key, G_TYPE_STRING, value, NULL);
+}
+
+/**
+ * gst_device_monitor_class_add_static_metadata:
+ * @klass: class to set metadata for
+ * @key: the key to set
+ * @value: the value to set
+ *
+ * Set @key with @value as metadata in @klass.
+ *
+ * Same as gst_device_monitor_class_add_metadata(), but @value must be a static string
+ * or an inlined string, as it will not be copied. (GStreamer plugins will
+ * be made resident once loaded, so this function can be used even from
+ * dynamically loaded plugins.)
+ *
+ * Since: 1.4
+ */
+void
+gst_device_monitor_class_add_static_metadata (GstDeviceMonitorClass * klass,
+ const gchar * key, const gchar * value)
+{
+ GValue val = G_VALUE_INIT;
+
+ g_return_if_fail (GST_IS_DEVICE_MONITOR_CLASS (klass));
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (value != NULL);
+
+ g_value_init (&val, G_TYPE_STRING);
+ g_value_set_static_string (&val, value);
+ gst_structure_take_value ((GstStructure *) klass->metadata, key, &val);
+}
+
+/**
+ * gst_device_monitor_class_set_metadata:
+ * @klass: class to set metadata for
+ * @longname: The long English name of the device monitor. E.g. "File Sink"
+ * @classification: String describing the type of device monitor, as an unordered list
+ * separated with slashes ('/'). See draft-klass.txt of the design docs
+ * for more details and common types. E.g: "Sink/File"
+ * @description: Sentence describing the purpose of the device monitor.
+ * E.g: "Write stream to a file"
+ * @author: Name and contact details of the author(s). Use \n to separate
+ * multiple author metadata. E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
+ *
+ * Sets the detailed information for a #GstDeviceMonitorClass.
+ * <note>This function is for use in _class_init functions only.</note>
+ *
+ * Since: 1.4
+ */
+void
+gst_device_monitor_class_set_metadata (GstDeviceMonitorClass * klass,
+ const gchar * longname, const gchar * classification,
+ const gchar * description, const gchar * author)
+{
+ g_return_if_fail (GST_IS_DEVICE_MONITOR_CLASS (klass));
+ g_return_if_fail (longname != NULL && *longname != '\0');
+ g_return_if_fail (classification != NULL && *classification != '\0');
+ g_return_if_fail (description != NULL && *description != '\0');
+ g_return_if_fail (author != NULL && *author != '\0');
+
+ gst_structure_id_set ((GstStructure *) klass->metadata,
+ GST_QUARK (ELEMENT_METADATA_LONGNAME), G_TYPE_STRING, longname,
+ GST_QUARK (ELEMENT_METADATA_KLASS), G_TYPE_STRING, classification,
+ GST_QUARK (ELEMENT_METADATA_DESCRIPTION), G_TYPE_STRING, description,
+ GST_QUARK (ELEMENT_METADATA_AUTHOR), G_TYPE_STRING, author, NULL);
+}
+
+/**
+ * gst_device_monitor_class_set_static_metadata:
+ * @klass: class to set metadata for
+ * @longname: The long English name of the element. E.g. "File Sink"
+ * @classification: String describing the type of element, as an unordered list
+ * separated with slashes ('/'). See draft-klass.txt of the design docs
+ * for more details and common types. E.g: "Sink/File"
+ * @description: Sentence describing the purpose of the element.
+ * E.g: "Write stream to a file"
+ * @author: Name and contact details of the author(s). Use \n to separate
+ * multiple author metadata. E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
+ *
+ * Sets the detailed information for a #GstDeviceMonitorClass.
+ * <note>This function is for use in _class_init functions only.</note>
+ *
+ * Same as gst_device_monitor_class_set_metadata(), but @longname, @classification,
+ * @description, and @author must be static strings or inlined strings, as
+ * they will not be copied. (GStreamer plugins will be made resident once
+ * loaded, so this function can be used even from dynamically loaded plugins.)
+ *
+ * Since: 1.4
+ */
+void
+gst_device_monitor_class_set_static_metadata (GstDeviceMonitorClass * klass,
+ const gchar * longname, const gchar * classification,
+ const gchar * description, const gchar * author)
+{
+ GstStructure *s = (GstStructure *) klass->metadata;
+ GValue val = G_VALUE_INIT;
+
+ g_return_if_fail (GST_IS_DEVICE_MONITOR_CLASS (klass));
+ g_return_if_fail (longname != NULL && *longname != '\0');
+ g_return_if_fail (classification != NULL && *classification != '\0');
+ g_return_if_fail (description != NULL && *description != '\0');
+ g_return_if_fail (author != NULL && *author != '\0');
+
+ g_value_init (&val, G_TYPE_STRING);
+
+ g_value_set_static_string (&val, longname);
+ gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_LONGNAME), &val);
+
+ g_value_set_static_string (&val, classification);
+ gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_KLASS), &val);
+
+ g_value_set_static_string (&val, description);
+ gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_DESCRIPTION),
+ &val);
+
+ g_value_set_static_string (&val, author);
+ gst_structure_id_take_value (s, GST_QUARK (ELEMENT_METADATA_AUTHOR), &val);
+}
+
+/**
+ * gst_device_monitor_class_get_metadata:
+ * @klass: class to get metadata for
+ * @key: the key to get
+ *
+ * Get metadata with @key in @klass.
+ *
+ * Returns: the metadata for @key.
+ *
+ * Since: 1.4
+ */
+const gchar *
+gst_device_monitor_class_get_metadata (GstDeviceMonitorClass * klass,
+ const gchar * key)
+{
+ g_return_val_if_fail (GST_IS_DEVICE_MONITOR_CLASS (klass), NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ return gst_structure_get_string ((GstStructure *) klass->metadata, key);
+}
+
+/**
+ * gst_device_monitor_get_devices:
+ * @monitor: A #GstDeviceMonitor
+ *
+ * Gets a list of devices that this monitor understands. This may actually
+ * probe the hardware if the monitor is not currently started.
+ *
+ * Returns: (transfer full) (element-type GstDevice): a #GList of
+ * #GstDevice
+ *
+ * Since: 1.4
+ */
+
+GList *
+gst_device_monitor_get_devices (GstDeviceMonitor * monitor)
+{
+ GstDeviceMonitorClass *klass;
+ GList *devices = NULL;
+ gboolean started;
+ GList *item;
+
+ g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), NULL);
+ klass = GST_DEVICE_MONITOR_GET_CLASS (monitor);
+
+ g_mutex_lock (&monitor->priv->start_lock);
+ started = (monitor->priv->started_count > 0);
+
+ if (started) {
+ GST_OBJECT_LOCK (monitor);
+ for (item = monitor->devices; item; item = item->next)
+ devices = g_list_prepend (devices, gst_object_ref (item->data));
+ GST_OBJECT_UNLOCK (monitor);
+ } else if (klass->probe)
+ devices = klass->probe (monitor);
+
+ g_mutex_unlock (&monitor->priv->start_lock);
+
+ return devices;
+}
+
+/**
+ * gst_device_monitor_start:
+ * @monitor: A #GstDeviceMonitor
+ *
+ * Starts monitoring the devices. This will cause #GST_MESSAGE_DEVICE messages
+ * to be posted on the monitor's bus when devices are added or removed from
+ * the system.
+ *
+ * Since the #GstDeviceMonitor is a singleton,
+ * gst_device_monitor_start() may already have been called by another
+ * user of the object, gst_device_monitor_stop() needs to be called the same
+ * number of times.
+ *
+ * Returns: %TRUE if the device monitoring could be started
+ *
+ * Since: 1.4
+ */
+
+gboolean
+gst_device_monitor_start (GstDeviceMonitor * monitor)
+{
+ GstDeviceMonitorClass *klass;
+ gboolean ret = FALSE;
+
+ g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), FALSE);
+ klass = GST_DEVICE_MONITOR_GET_CLASS (monitor);
+
+ g_mutex_lock (&monitor->priv->start_lock);
+
+ if (monitor->priv->started_count > 0) {
+ ret = TRUE;
+ goto started;
+ }
+
+ if (klass->start)
+ ret = klass->start (monitor);
+
+ if (ret) {
+ monitor->priv->started_count++;
+ gst_bus_set_flushing (monitor->priv->bus, FALSE);
+ }
+
+started:
+
+ g_mutex_unlock (&monitor->priv->start_lock);
+
+ return ret;
+}
+
+/**
+ * gst_device_monitor_stop:
+ * @monitor: A #GstDeviceMonitor
+ *
+ * Decreases the use-count by one. If the use count reaches zero, this
+ * #GstDeviceMonitor will stop monitoring the devices. This needs to be
+ * called the same number of times that gst_device_monitor_start() was called.
+ *
+ * Since: 1.4
+ */
+
+void
+gst_device_monitor_stop (GstDeviceMonitor * monitor)
+{
+ GstDeviceMonitorClass *klass;
+
+ g_return_if_fail (GST_IS_DEVICE_MONITOR (monitor));
+ klass = GST_DEVICE_MONITOR_GET_CLASS (monitor);
+
+ g_mutex_lock (&monitor->priv->start_lock);
+
+ if (monitor->priv->started_count == 1) {
+ gst_bus_set_flushing (monitor->priv->bus, TRUE);
+ if (klass->stop)
+ klass->stop (monitor);
+ GST_OBJECT_LOCK (monitor);
+ g_list_free_full (monitor->devices, (GDestroyNotify) gst_object_unparent);
+ monitor->devices = NULL;
+ GST_OBJECT_UNLOCK (monitor);
+ } else if (monitor->priv->started_count < 1) {
+ g_critical ("Trying to stop a GstDeviceMonitor %s which is already stopped",
+ GST_OBJECT_NAME (monitor));
+ }
+
+ monitor->priv->started_count--;
+ g_mutex_unlock (&monitor->priv->start_lock);
+}
+
+
+/**
+ * gst_device_monitor_get_factory:
+ * @monitor: a #GstDeviceMonitor to request the device monitor factory of.
+ *
+ * Retrieves the factory that was used to create this device monitor.
+ *
+ * Returns: (transfer none): the #GstDeviceMonitorFactory used for creating this
+ * device monitor. no refcounting is needed.
+ *
+ * Since: 1.4
+ */
+GstDeviceMonitorFactory *
+gst_device_monitor_get_factory (GstDeviceMonitor * monitor)
+{
+ g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), NULL);
+
+ return GST_DEVICE_MONITOR_GET_CLASS (monitor)->factory;
+}
+
+/**
+ * gst_device_monitor_can_monitor:
+ * @monitor: a #GstDeviceMonitor
+ *
+ * If this function returns %TRUE, then the device monitor can monitor if
+ * devices are added or removed. Otherwise, it can only do static probing.
+ *
+ * Returns: %TRUE if the #GstDeviceMonitor support monitoring, %FALSE otherwise
+ */
+gboolean
+gst_device_monitor_can_monitor (GstDeviceMonitor * monitor)
+{
+ GstDeviceMonitorClass *klass;
+
+ g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), FALSE);
+ klass = GST_DEVICE_MONITOR_GET_CLASS (monitor);
+
+ if (klass->start)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/**
+ * gst_device_monitor_get_bus:
+ * @monitor: a #GstDeviceMonitor
+ *
+ * Gets the #GstBus of this #GstDeviceMonitor
+ *
+ * Returns: (transfer full): a #GstBus
+ *
+ * Since: 1.4
+ */
+GstBus *
+gst_device_monitor_get_bus (GstDeviceMonitor * monitor)
+{
+ g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), NULL);
+
+ return gst_object_ref (monitor->priv->bus);
+}
+
+/**
+ * gst_device_monitor_device_add:
+ * @monitor: a #GstDeviceMonitor
+ * @device: (transfer full): a #GstDevice that has been added
+ *
+ * Posts a message on the monitor's #GstBus to inform applications that
+ * a new device has been added.
+ *
+ * This is for use by subclasses.
+ *
+ * Since: 1.4
+ */
+void
+gst_device_monitor_device_add (GstDeviceMonitor * monitor, GstDevice * device)
+{
+ GstMessage *message;
+
+ if (!gst_object_set_parent (GST_OBJECT (device), GST_OBJECT (monitor))) {
+ GST_WARNING_OBJECT (monitor, "Could not parent device %p to monitor,"
+ " it already has a parent", device);
+ return;
+ }
+
+ GST_OBJECT_LOCK (monitor);
+ monitor->devices = g_list_prepend (monitor->devices, gst_object_ref (device));
+ GST_OBJECT_UNLOCK (monitor);
+
+ message = gst_message_new_device_added (GST_OBJECT (monitor), device);
+ gst_bus_post (monitor->priv->bus, message);
+ gst_object_unref (device);
+}
+
+
+/**
+ * gst_device_monitor_device_remove:
+ * @monitor: a #GstDeviceMonitor
+ * @device: a #GstDevice that has been removed
+ *
+ * Posts a message on the monitor's #GstBus to inform applications that
+ * a device has been removed.
+ *
+ * This is for use by subclasses.
+ *
+ * Since: 1.4
+ */
+void
+gst_device_monitor_device_remove (GstDeviceMonitor * monitor,
+ GstDevice * device)
+{
+ GstMessage *message;
+ GList *item;
+
+ GST_OBJECT_LOCK (monitor);
+ item = g_list_find (monitor->devices, device);
+ if (item) {
+ monitor->devices = g_list_delete_link (monitor->devices, item);
+ }
+ GST_OBJECT_UNLOCK (monitor);
+
+ message = gst_message_new_device_removed (GST_OBJECT (monitor), device);
+ g_signal_emit_by_name (device, "removed");
+ gst_bus_post (monitor->priv->bus, message);
+ if (item)
+ gst_object_unparent (GST_OBJECT (device));
+}
diff --git a/gst/gstdevicemonitor.h b/gst/gstdevicemonitor.h
new file mode 100644
index 0000000..f5c3307
--- /dev/null
+++ b/gst/gstdevicemonitor.h
@@ -0,0 +1,142 @@
+/* GStreamer
+ * Copyright (C) 2012 Olivier Crete <olivier.crete@collabora.com>
+ *
+ * gstdevicemonitor.h: Device probing and monitoring
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gst/gstdevicemonitorfactory.h>
+
+
+#ifndef __GST_DEVICE_MONITOR_H__
+#define __GST_DEVICE_MONITOR_H__
+
+#include <gst/gstelement.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GstDeviceMonitor GstDeviceMonitor;
+typedef struct _GstDeviceMonitorClass GstDeviceMonitorClass;
+typedef struct _GstDeviceMonitorPrivate GstDeviceMonitorPrivate;
+
+#define GST_TYPE_DEVICE_MONITOR (gst_device_monitor_get_type())
+#define GST_IS_DEVICE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEVICE_MONITOR))
+#define GST_IS_DEVICE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEVICE_MONITOR))
+#define GST_DEVICE_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEVICE_MONITOR, GstDeviceMonitorClass))
+#define GST_DEVICE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEVICE_MONITOR, GstDeviceMonitor))
+#define GST_DEVICE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEVICE_MONITOR, GstDeviceMonitorClass))
+#define GST_DEVICE_MONITOR_CAST(obj) ((GstDeviceMonitor *)(obj))
+
+
+/**
+ * GstDeviceMonitor:
+ * @parent: The parent #GstObject
+ * @devices: a #GList of the #GstDevice objects
+ *
+ * The structure of the base #GstDeviceMonitor
+ *
+ * Since: 1.4
+ */
+struct _GstDeviceMonitor {
+ GstObject parent;
+
+ /* Protected by the Object lock */
+ GList *devices;
+
+ /*< private >*/
+
+ GstDeviceMonitorPrivate *priv;
+
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+/**
+ * GstDeviceMonitorClass:
+ * @parent_class: the parent #GstObjectClass structure
+ * @factory: a pointer to the #GstDeviceMonitorFactory that creates this
+ * monitor
+ * @probe: Returns a list of devices that are currently available.
+ * This should never block.
+ * @start: Starts monitoring for new devices. Only subclasses that can know
+ * that devices have been added or remove need to implement this method.
+ * @stop: Stops monitoring for new devices. Only subclasses that implement
+ * the start() method need to implement this method.
+ *
+ * The structure of the base #GstDeviceMonitorClass
+ *
+ * Since: 1.4
+ */
+
+struct _GstDeviceMonitorClass {
+ GstObjectClass parent_class;
+
+ GstDeviceMonitorFactory *factory;
+
+ GList* (*probe) (GstDeviceMonitor * monitor);
+
+ gboolean (*start) (GstDeviceMonitor * monitor);
+ void (*stop) (GstDeviceMonitor * monitor);
+
+ /*< private >*/
+ gpointer metadata;
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+GType gst_device_monitor_get_type (void);
+
+
+GList * gst_device_monitor_get_devices (GstDeviceMonitor * monitor);
+
+gboolean gst_device_monitor_start (GstDeviceMonitor * monitor);
+void gst_device_monitor_stop (GstDeviceMonitor * monitor);
+
+gboolean gst_device_monitor_can_monitor (GstDeviceMonitor * monitor);
+
+GstBus * gst_device_monitor_get_bus (GstDeviceMonitor * monitor);
+
+void gst_device_monitor_device_add (GstDeviceMonitor * monitor,
+ GstDevice * device);
+void gst_device_monitor_device_remove (GstDeviceMonitor * monitor,
+ GstDevice * device);
+
+
+/* device monitor class meta data */
+void gst_device_monitor_class_set_metadata (GstDeviceMonitorClass *klass,
+ const gchar *longname,
+ const gchar *classification,
+ const gchar *description,
+ const gchar *author);
+void gst_device_monitor_class_set_static_metadata (GstDeviceMonitorClass *klass,
+ const gchar *longname,
+ const gchar *classification,
+ const gchar *description,
+ const gchar *author);
+void gst_device_monitor_class_add_metadata (GstDeviceMonitorClass * klass,
+ const gchar * key, const gchar * value);
+void gst_device_monitor_class_add_static_metadata (GstDeviceMonitorClass * klass,
+ const gchar * key, const gchar * value);
+const gchar * gst_device_monitor_class_get_metadata (GstDeviceMonitorClass * klass,
+ const gchar * key);
+
+/* factory management */
+GstDeviceMonitorFactory * gst_device_monitor_get_factory (GstDeviceMonitor * monitor);
+
+G_END_DECLS
+
+#endif /* __GST_DEVICE_MONITOR_H__ */
diff --git a/gst/gstdevicemonitorfactory.c b/gst/gstdevicemonitorfactory.c
new file mode 100644
index 0000000..f8c9826
--- /dev/null
+++ b/gst/gstdevicemonitorfactory.c
@@ -0,0 +1,594 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ * 2000 Wim Taymans <wtay@chello.be>
+ * 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
+ *
+ * gstdevicemonitorfactory.c: GstDeviceMonitorFactory object, support routines
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:gstdevicemonitorfactory
+ * @short_description: Create GstDeviceMonitors from a factory
+ * @see_also: #GstDeviceMonitor, #GstPlugin, #GstPluginFeature, #GstPadTemplate.
+ *
+ * #GstDeviceMonitorFactory is used to create instances of device monitors. A
+ * GstDeviceMonitorfactory can be added to a #GstPlugin as it is also a
+ * #GstPluginFeature.
+ *
+ * Use the gst_device_monitor_factory_find() and gst_device_monitor_factory_create()
+ * functions to create device monitor instances or use gst_device_monitor_factory_make() as a
+ * convenient shortcut.
+ *
+ * Since: 1.4
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gst_private.h"
+
+#include "gstdevicemonitorfactory.h"
+#include "gst.h"
+
+#include "glib-compat-private.h"
+
+GST_DEBUG_CATEGORY_STATIC (device_monitor_factory_debug);
+#define GST_CAT_DEFAULT device_monitor_factory_debug
+
+static void gst_device_monitor_factory_finalize (GObject * object);
+static void gst_device_monitor_factory_cleanup (GstDeviceMonitorFactory *
+ factory);
+
+/* static guint gst_device_monitor_factory_signals[LAST_SIGNAL] = { 0 }; */
+
+/* this is defined in gstelement.c */
+extern GQuark __gst_devicemonitorclass_factory;
+
+#define _do_init \
+{ \
+ GST_DEBUG_CATEGORY_INIT (device_monitor_factory_debug, "GST_DEVICE_MONITOR_FACTORY", \
+ GST_DEBUG_BOLD | GST_DEBUG_FG_WHITE | GST_DEBUG_BG_RED, \
+ "device monitor factories keep information about installed device monitors"); \
+}
+
+G_DEFINE_TYPE_WITH_CODE (GstDeviceMonitorFactory, gst_device_monitor_factory,
+ GST_TYPE_PLUGIN_FEATURE, _do_init);
+
+static void
+gst_device_monitor_factory_class_init (GstDeviceMonitorFactoryClass * klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+
+ gobject_class->finalize = gst_device_monitor_factory_finalize;
+}
+
+static void
+gst_device_monitor_factory_init (GstDeviceMonitorFactory * factory)
+{
+}
+
+static void
+gst_device_monitor_factory_finalize (GObject * object)
+{
+ GstDeviceMonitorFactory *factory = GST_DEVICE_MONITOR_FACTORY (object);
+ GstDeviceMonitor *monitor;
+
+ gst_device_monitor_factory_cleanup (factory);
+
+ monitor = g_atomic_pointer_get (&factory->monitor);
+ if (monitor)
+ gst_object_unref (monitor);
+
+ G_OBJECT_CLASS (gst_device_monitor_factory_parent_class)->finalize (object);
+}
+
+/**
+ * gst_device_monitor_factory_find:
+ * @name: name of factory to find
+ *
+ * Search for an device monitor factory of the given name. Refs the returned
+ * device monitor factory; caller is responsible for unreffing.
+ *
+ * Returns: (transfer full): #GstDeviceMonitorFactory if found, %NULL otherwise
+ *
+ * Since: 1.4
+ */
+GstDeviceMonitorFactory *
+gst_device_monitor_factory_find (const gchar * name)
+{
+ GstPluginFeature *feature;
+
+ g_return_val_if_fail (name != NULL, NULL);
+
+ feature = gst_registry_find_feature (gst_registry_get (), name,
+ GST_TYPE_DEVICE_MONITOR_FACTORY);
+ if (feature)
+ return GST_DEVICE_MONITOR_FACTORY (feature);
+
+ /* this isn't an error, for instance when you query if an device monitor factory is
+ * present */
+ GST_LOG ("no such device monitor factory \"%s\"", name);
+
+ return NULL;
+}
+
+static void
+gst_device_monitor_factory_cleanup (GstDeviceMonitorFactory * factory)
+{
+ if (factory->metadata) {
+ gst_structure_free ((GstStructure *) factory->metadata);
+ factory->metadata = NULL;
+ }
+ if (factory->type) {
+ factory->type = G_TYPE_INVALID;
+ }
+}
+
+#define CHECK_METADATA_FIELD(klass, name, key) \
+ G_STMT_START { \
+ const gchar *metafield = gst_device_monitor_class_get_metadata (klass, key); \
+ if (G_UNLIKELY (metafield == NULL || *metafield == '\0')) { \
+ g_warning ("Device monitor factory metadata for '%s' has no valid %s field", name, key); \
+ goto detailserror; \
+ } \
+ } G_STMT_END;
+
+/**
+ * gst_device_monitor_register:
+ * @plugin: (allow-none): #GstPlugin to register the device monitor with, or %NULL for
+ * a static device monitor.
+ * @name: name of device monitors of this type
+ * @rank: rank of device monitor (higher rank means more importance when autoplugging)
+ * @type: GType of device monitor to register
+ *
+ * Create a new device monitorfactory capable of instantiating objects of the
+ * @type and add the factory to @plugin.
+ *
+ * Returns: %TRUE, if the registering succeeded, %FALSE on error
+ *
+ * Since: 1.4
+ */
+gboolean
+gst_device_monitor_register (GstPlugin * plugin, const gchar * name, guint rank,
+ GType type)
+{
+ GstPluginFeature *existing_feature;
+ GstRegistry *registry;
+ GstDeviceMonitorFactory *factory;
+ GstDeviceMonitorClass *klass;
+
+ g_return_val_if_fail (name != NULL, FALSE);
+ g_return_val_if_fail (g_type_is_a (type, GST_TYPE_DEVICE_MONITOR), FALSE);
+
+ registry = gst_registry_get ();
+
+ /* check if feature already exists, if it exists there is no need to update it
+ * when the registry is getting updated, outdated plugins and all their
+ * features are removed and readded.
+ */
+ existing_feature = gst_registry_lookup_feature (registry, name);
+ if (existing_feature) {
+ GST_DEBUG_OBJECT (registry, "update existing feature %p (%s)",
+ existing_feature, name);
+ factory = GST_DEVICE_MONITOR_FACTORY_CAST (existing_feature);
+ factory->type = type;
+ existing_feature->loaded = TRUE;
+ g_type_set_qdata (type, __gst_devicemonitorclass_factory, factory);
+ gst_object_unref (existing_feature);
+ return TRUE;
+ }
+
+ factory =
+ GST_DEVICE_MONITOR_FACTORY_CAST (g_object_newv
+ (GST_TYPE_DEVICE_MONITOR_FACTORY, 0, NULL));
+ gst_plugin_feature_set_name (GST_PLUGIN_FEATURE_CAST (factory), name);
+ GST_LOG_OBJECT (factory, "Created new device monitorfactory for type %s",
+ g_type_name (type));
+
+ /* provide info needed during class structure setup */
+ g_type_set_qdata (type, __gst_devicemonitorclass_factory, factory);
+ klass = GST_DEVICE_MONITOR_CLASS (g_type_class_ref (type));
+
+ CHECK_METADATA_FIELD (klass, name, GST_ELEMENT_METADATA_LONGNAME);
+ CHECK_METADATA_FIELD (klass, name, GST_ELEMENT_METADATA_KLASS);
+ CHECK_METADATA_FIELD (klass, name, GST_ELEMENT_METADATA_DESCRIPTION);
+ CHECK_METADATA_FIELD (klass, name, GST_ELEMENT_METADATA_AUTHOR);
+
+ factory->type = type;
+ factory->metadata = gst_structure_copy ((GstStructure *) klass->metadata);
+
+ if (plugin && plugin->desc.name) {
+ GST_PLUGIN_FEATURE_CAST (factory)->plugin_name = plugin->desc.name;
+ GST_PLUGIN_FEATURE_CAST (factory)->plugin = plugin;
+ g_object_add_weak_pointer ((GObject *) plugin,
+ (gpointer *) & GST_PLUGIN_FEATURE_CAST (factory)->plugin);
+ } else {
+ GST_PLUGIN_FEATURE_CAST (factory)->plugin_name = "NULL";
+ GST_PLUGIN_FEATURE_CAST (factory)->plugin = NULL;
+ }
+ gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE_CAST (factory), rank);
+ GST_PLUGIN_FEATURE_CAST (factory)->loaded = TRUE;
+
+ gst_registry_add_feature (registry, GST_PLUGIN_FEATURE_CAST (factory));
+
+ return TRUE;
+
+ /* ERRORS */
+detailserror:
+ {
+ gst_device_monitor_factory_cleanup (factory);
+ return FALSE;
+ }
+}
+
+/**
+ * gst_device_monitor_factory_get:
+ * @factory: factory to instantiate
+ *
+ * Returns the device monitor of the type defined by the given device
+ * monitorfactory.
+ *
+ * Returns: (transfer full): the #GstDeviceMonitor or %NULL if the
+ * device monitor couldn't be created
+ *
+ * Since: 1.4
+ */
+GstDeviceMonitor *
+gst_device_monitor_factory_get (GstDeviceMonitorFactory * factory)
+{
+ GstDeviceMonitor *device_monitor;
+ GstDeviceMonitorClass *oclass;
+ GstDeviceMonitorFactory *newfactory;
+
+ g_return_val_if_fail (factory != NULL, NULL);
+
+ newfactory =
+ GST_DEVICE_MONITOR_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE
+ (factory)));
+
+ if (newfactory == NULL)
+ goto load_failed;
+
+ factory = newfactory;
+
+ GST_INFO ("getting device monitor \"%s\"", GST_OBJECT_NAME (factory));
+
+ if (factory->type == 0)
+ goto no_type;
+
+ device_monitor = g_atomic_pointer_get (&newfactory->monitor);
+ if (device_monitor)
+ return gst_object_ref (device_monitor);
+
+ /* create an instance of the device monitor, cast so we don't assert on NULL
+ * also set name as early as we can
+ */
+ device_monitor = GST_DEVICE_MONITOR_CAST (g_object_newv (factory->type, 0,
+ NULL));
+ if (G_UNLIKELY (device_monitor == NULL))
+ goto no_device_monitor;
+
+ /* fill in the pointer to the factory in the device monitor class. The
+ * class will not be unreffed currently.
+ * Be thread safe as there might be 2 threads creating the first instance of
+ * an device monitor at the same moment
+ */
+ oclass = GST_DEVICE_MONITOR_GET_CLASS (device_monitor);
+ if (!g_atomic_pointer_compare_and_exchange (&oclass->factory, NULL, factory))
+ gst_object_unref (factory);
+
+ gst_object_ref_sink (device_monitor);
+
+ /* We use an atomic to make sure we don't create two in parallel */
+ if (!g_atomic_pointer_compare_and_exchange (&newfactory->monitor, NULL,
+ device_monitor)) {
+ gst_object_unref (device_monitor);
+
+ device_monitor = g_atomic_pointer_get (&newfactory->monitor);
+ }
+
+ GST_DEBUG ("created device monitor \"%s\"", GST_OBJECT_NAME (factory));
+
+ return gst_object_ref (device_monitor);
+
+ /* ERRORS */
+load_failed:
+ {
+ GST_WARNING_OBJECT (factory,
+ "loading plugin containing feature %s returned NULL!",
+ GST_OBJECT_NAME (factory));
+ return NULL;
+ }
+no_type:
+ {
+ GST_WARNING_OBJECT (factory, "factory has no type");
+ gst_object_unref (factory);
+ return NULL;
+ }
+no_device_monitor:
+ {
+ GST_WARNING_OBJECT (factory, "could not create device monitor");
+ gst_object_unref (factory);
+ return NULL;
+ }
+}
+
+/**
+ * gst_device_monitor_factory_get_by_name:
+ * @factoryname: a named factory to instantiate
+ *
+ * Returns the device monitor of the type defined by the given device
+ * monitor factory.
+ *
+ * Returns: (transfer full): a #GstDeviceMonitor or %NULL if unable to
+ * create device monitor
+ *
+ * Since: 1.4
+ */
+GstDeviceMonitor *
+gst_device_monitor_factory_get_by_name (const gchar * factoryname)
+{
+ GstDeviceMonitorFactory *factory;
+ GstDeviceMonitor *device_monitor;
+
+ g_return_val_if_fail (factoryname != NULL, NULL);
+ g_return_val_if_fail (gst_is_initialized (), NULL);
+
+ GST_LOG ("gstdevicemonitorfactory: get_by_name \"%s\"", factoryname);
+
+ factory = gst_device_monitor_factory_find (factoryname);
+ if (factory == NULL)
+ goto no_factory;
+
+ GST_LOG_OBJECT (factory, "found factory %p", factory);
+ device_monitor = gst_device_monitor_factory_get (factory);
+ if (device_monitor == NULL)
+ goto create_failed;
+
+ gst_object_unref (factory);
+ return device_monitor;
+
+ /* ERRORS */
+no_factory:
+ {
+ GST_INFO ("no such device monitor factory \"%s\"!", factoryname);
+ return NULL;
+ }
+create_failed:
+ {
+ GST_INFO_OBJECT (factory, "couldn't create instance!");
+ gst_object_unref (factory);
+ return NULL;
+ }
+}
+
+/**
+ * gst_device_monitor_factory_get_device_monitor_type:
+ * @factory: factory to get managed #GType from
+ *
+ * Get the #GType for device monitors managed by this factory. The type can
+ * only be retrieved if the device monitor factory is loaded, which can be
+ * assured with gst_plugin_feature_load().
+ *
+ * Returns: the #GType for device monitors managed by this factory or 0 if
+ * the factory is not loaded.
+ *
+ * Since: 1.4
+ */
+GType
+gst_device_monitor_factory_get_device_monitor_type (GstDeviceMonitorFactory *
+ factory)
+{
+ g_return_val_if_fail (GST_IS_DEVICE_MONITOR_FACTORY (factory), 0);
+
+ return factory->type;
+}
+
+/**
+ * gst_device_monitor_factory_get_metadata:
+ * @factory: a #GstDeviceMonitorFactory
+ * @key: a key
+ *
+ * Get the metadata on @factory with @key.
+ *
+ * Returns: the metadata with @key on @factory or %NULL when there was no
+ * metadata with the given @key.
+ *
+ * Since: 1.4
+ */
+const gchar *
+gst_device_monitor_factory_get_metadata (GstDeviceMonitorFactory * factory,
+ const gchar * key)
+{
+ return gst_structure_get_string ((GstStructure *) factory->metadata, key);
+}
+
+/**
+ * gst_device_monitor_factory_get_metadata_keys:
+ * @factory: a #GstDeviceMonitorFactory
+ *
+ * Get the available keys for the metadata on @factory.
+ *
+ * Returns: (transfer full) (element-type utf8) (array zero-terminated=1):
+ * a %NULL-terminated array of key strings, or %NULL when there is no
+ * metadata. Free with g_strfreev() when no longer needed.
+ *
+ * Since: 1.4
+ */
+gchar **
+gst_device_monitor_factory_get_metadata_keys (GstDeviceMonitorFactory * factory)
+{
+ GstStructure *metadata;
+ gchar **arr;
+ gint i, num;
+
+ g_return_val_if_fail (GST_IS_DEVICE_MONITOR_FACTORY (factory), NULL);
+
+ metadata = (GstStructure *) factory->metadata;
+ if (metadata == NULL)
+ return NULL;
+
+ num = gst_structure_n_fields (metadata);
+ if (num == 0)
+ return NULL;
+
+ arr = g_new (gchar *, num + 1);
+ for (i = 0; i < num; ++i) {
+ arr[i] = g_strdup (gst_structure_nth_field_name (metadata, i));
+ }
+ arr[i] = NULL;
+ return arr;
+}
+
+/**
+ * gst_device_monitor_factory_has_classesv:
+ * @factory: a #GstDeviceMonitorFactory
+ * @classes: (array zero-terminated=1): a %NULL terminated array of
+ * klasses to match, only match if all classes are matched
+ *
+ * Check if @factory matches all of the given classes
+ *
+ * Returns: %TRUE if @factory matches.
+ *
+ * Since: 1.4
+ */
+gboolean
+gst_device_monitor_factory_has_classesv (GstDeviceMonitorFactory * factory,
+ gchar ** classes)
+{
+ const gchar *klass;
+
+ g_return_val_if_fail (GST_IS_DEVICE_MONITOR_FACTORY (factory), FALSE);
+
+ klass = gst_device_monitor_factory_get_metadata (factory,
+ GST_ELEMENT_METADATA_KLASS);
+
+ if (klass == NULL) {
+ GST_ERROR_OBJECT (factory,
+ "device monitor factory is missing klass identifiers");
+ return FALSE;
+ }
+
+ for (; classes[0]; classes++) {
+ const gchar *found;
+ guint len;
+
+ if (classes[0] == '\0')
+ continue;
+
+ found = strstr (klass, classes[0]);
+
+ if (!found)
+ return FALSE;
+ if (found != klass && *(found - 1) != '/')
+ return FALSE;
+
+ len = strlen (classes[0]);
+ if (found[len] != 0 && found[len] != '/')
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * gst_device_monitor_factory_has_classes:
+ * @factory: a #GstDeviceMonitorFactory
+ * @classes: a "/" separate list of klasses to match, only match if all classes
+ * are matched
+ *
+ * Check if @factory matches all of the given @classes
+ *
+ * Returns: %TRUE if @factory matches.
+ *
+ * Since: 1.4
+ */
+gboolean
+gst_device_monitor_factory_has_classes (GstDeviceMonitorFactory * factory,
+ const gchar * classes)
+{
+ gchar **classesv;
+ gboolean res;
+
+ classesv = g_strsplit (classes, "/", 0);
+
+ res = gst_device_monitor_factory_has_classesv (factory, classesv);
+
+ g_strfreev (classesv);
+
+ return res;
+}
+
+typedef struct
+{
+ const char *classes;
+ GstRank minrank;
+} FilterData;
+
+static gboolean
+device_monitor_filter (GstPluginFeature * feature, FilterData * data)
+{
+ gboolean res;
+
+ /* we only care about device monitor factories */
+ if (G_UNLIKELY (!GST_IS_DEVICE_MONITOR_FACTORY (feature)))
+ return FALSE;
+
+ res = (gst_plugin_feature_get_rank (feature) >= data->minrank) &&
+ gst_device_monitor_factory_has_classes (GST_DEVICE_MONITOR_FACTORY_CAST
+ (feature), data->classes);
+
+ return res;
+}
+
+/**
+ * gst_device_monitor_factory_list_get_device_monitors:
+ * @classes: a "/" separate list of klasses to match, only match if all classes
+ * are matched
+ * @minrank: Minimum rank
+ *
+ * Get a list of factories that match all of the given @classes. Only
+ * device monitors with a rank greater or equal to @minrank will be
+ * returned. The list of factories is returned by decreasing rank.
+ *
+ * Returns: (transfer full) (element-type Gst.DeviceMonitorFactory): a #GList of
+ * #GstDeviceMonitorFactory device monitors. Use gst_plugin_feature_list_free() after
+ * usage.
+ *
+ * Since: 1.4
+ */
+GList *gst_device_monitor_factory_list_get_device_monitors
+ (const gchar * classes, GstRank minrank)
+{
+ GList *result;
+ FilterData data;
+
+ /* prepare type */
+ data.classes = classes;
+ data.minrank = minrank;
+
+ /* get the feature list using the filter */
+ result = gst_registry_feature_filter (gst_registry_get (),
+ (GstPluginFeatureFilter) device_monitor_filter, FALSE, &data);
+
+ /* sort on rank and name */
+ result = g_list_sort (result, gst_plugin_feature_rank_compare_func);
+
+ return result;
+}
diff --git a/gst/gstdevicemonitorfactory.h b/gst/gstdevicemonitorfactory.h
new file mode 100644
index 0000000..02bf04a
--- /dev/null
+++ b/gst/gstdevicemonitorfactory.h
@@ -0,0 +1,90 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ * 2000,2004 Wim Taymans <wim@fluendo.com>
+ * 2012 Olivier Crete <olivier.crete@collabora.com>
+ *
+ * gstdevicemonitorfactory.h: Header for GstDeviceMonitorFactory
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+
+#ifndef __GST_DEVICE_MONITOR_FACTORY_H__
+#define __GST_DEVICE_MONITOR_FACTORY_H__
+
+/**
+ * GstDeviceMonitorFactory:
+ *
+ * The opaque #GstDeviceMonitorFactory data structure.
+ *
+ * Since: 1.4
+ */
+
+/**
+ * GstDeviceMonitorFactoryClass:
+ *
+ * The opaque #GstDeviceMonitorFactoryClass data structure.
+ *
+ * Since: 1.4
+ */
+typedef struct _GstDeviceMonitorFactory GstDeviceMonitorFactory;
+typedef struct _GstDeviceMonitorFactoryClass GstDeviceMonitorFactoryClass;
+
+#include <gst/gstconfig.h>
+#include <gst/gstplugin.h>
+#include <gst/gstpluginfeature.h>
+#include <gst/gstdevicemonitor.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_DEVICE_MONITOR_FACTORY (gst_device_monitor_factory_get_type())
+#define GST_DEVICE_MONITOR_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DEVICE_MONITOR_FACTORY,\
+ GstDeviceMonitorFactory))
+#define GST_DEVICE_MONITOR_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DEVICE_MONITOR_FACTORY,\
+ GstDeviceMonitorFactoryClass))
+#define GST_IS_DEVICE_MONITOR_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DEVICE_MONITOR_FACTORY))
+#define GST_IS_DEVICE_MONITOR_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DEVICE_MONITOR_FACTORY))
+#define GST_DEVICE_MONITOR_FACTORY_CAST(obj) ((GstDeviceMonitorFactory *)(obj))
+
+GType gst_device_monitor_factory_get_type (void);
+
+GstDeviceMonitorFactory * gst_device_monitor_factory_find (const gchar *name);
+
+GType gst_device_monitor_factory_get_device_monitor_type (GstDeviceMonitorFactory *factory);
+
+const gchar * gst_device_monitor_factory_get_metadata (GstDeviceMonitorFactory *factory, const gchar *key);
+gchar ** gst_device_monitor_factory_get_metadata_keys (GstDeviceMonitorFactory *factory);
+
+GstDeviceMonitor* gst_device_monitor_factory_get (GstDeviceMonitorFactory *factory) G_GNUC_MALLOC;
+GstDeviceMonitor* gst_device_monitor_factory_get_by_name (const gchar *factoryname) G_GNUC_MALLOC;
+
+gboolean gst_device_monitor_register (GstPlugin *plugin, const gchar *name,
+ guint rank,
+ GType type);
+
+gboolean gst_device_monitor_factory_has_classesv (GstDeviceMonitorFactory * factory,
+ gchar ** classes);
+
+gboolean gst_device_monitor_factory_has_classes (GstDeviceMonitorFactory *factory,
+ const gchar * classes);
+
+GList * gst_device_monitor_factory_list_get_device_monitors (const gchar *classes,
+ GstRank minrank) G_GNUC_MALLOC;
+
+G_END_DECLS
+
+#endif /* __GST_DEVICE_MONITOR_FACTORY_H__ */
diff --git a/gst/gstelement.c b/gst/gstelement.c
index 6af2ca1..25870f5 100644
--- a/gst/gstelement.c
+++ b/gst/gstelement.c
@@ -43,8 +43,7 @@
*
* An existing pad of an element can be retrieved by name with
* gst_element_get_static_pad(). A new dynamic pad can be created using
- * gst_element_request_pad() with a #GstPadTemplate or
- * gst_element_get_request_pad() with the template name such as "src_\%u".
+ * gst_element_request_pad() with a #GstPadTemplate.
* An iterator of all pads can be retrieved with gst_element_iterate_pads().
*
* Elements can be linked through their pads.
@@ -72,11 +71,9 @@
* #GST_ELEMENT_FLAG_REQUIRE_CLOCK() flag is set, a clock should be set on the
* element with gst_element_set_clock().
*
- * Note that clock slection and distribution is normally handled by the
+ * Note that clock selection and distribution is normally handled by the
* toplevel #GstPipeline so the clock functions are only to be used in very
* specific situations.
- *
- * Last reviewed on 2012-03-28 (0.11.3)
*/
#include "gst_private.h"
@@ -308,10 +305,10 @@ gst_element_init (GstElement * element)
* @pad: the #GstPad to release.
*
* Makes the element free the previously requested pad as obtained
- * with gst_element_get_request_pad().
+ * with gst_element_request_pad().
*
* This does not unref the pad. If the pad was created by using
- * gst_element_get_request_pad(), gst_element_release_request_pad() needs to be
+ * gst_element_request_pad(), gst_element_release_request_pad() needs to be
* followed by gst_object_unref() to free the @pad.
*
* MT safe.
@@ -735,7 +732,7 @@ no_direction:
*
* This function is used by plugin developers and should not be used
* by applications. Pads that were dynamically requested from elements
- * with gst_element_get_request_pad() should be released with the
+ * with gst_element_request_pad() should be released with the
* gst_element_release_request_pad() function instead.
*
* Pads are not automatically deactivated so elements should perform the needed
@@ -798,6 +795,7 @@ gst_element_remove_pad (GstElement * element, GstPad * pad)
break;
}
element->pads = g_list_remove (element->pads, pad);
+ GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_NEED_PARENT);
element->numpads--;
element->pads_cookie++;
GST_OBJECT_UNLOCK (element);
@@ -1535,7 +1533,7 @@ gst_element_default_send_event (GstElement * element, GstEvent * event)
* event handler, the event will be pushed on a random linked sink pad for
* upstream events or a random linked source pad for downstream events.
*
- * This function takes owership of the provided event so you should
+ * This function takes ownership of the provided event so you should
* gst_event_ref() it if you want to reuse the event after this call.
*
* MT safe.
@@ -1643,7 +1641,7 @@ gst_element_default_query (GstElement * element, GstQuery * query)
*
* Please note that some queries might need a running pipeline to work.
*
- * Returns: TRUE if the query could be performed.
+ * Returns: %TRUE if the query could be performed.
*
* MT safe.
*/
@@ -1875,7 +1873,7 @@ void gst_element_message_full
*
* MT safe.
*
- * Returns: TRUE, if the element's state is locked.
+ * Returns: %TRUE, if the element's state is locked.
*/
gboolean
gst_element_is_locked_state (GstElement * element)
@@ -1894,14 +1892,14 @@ gst_element_is_locked_state (GstElement * element)
/**
* gst_element_set_locked_state:
* @element: a #GstElement
- * @locked_state: TRUE to lock the element's state
+ * @locked_state: %TRUE to lock the element's state
*
* Locks the state of an element, so state changes of the parent don't affect
* this element anymore.
*
* MT safe.
*
- * Returns: TRUE if the state was changed, FALSE if bad parameters were given
+ * Returns: %TRUE if the state was changed, %FALSE if bad parameters were given
* or the elements state-locking needed no change.
*/
gboolean
@@ -1946,9 +1944,9 @@ was_ok:
* @element: a #GstElement.
*
* Tries to change the state of the element to the same as its parent.
- * If this function returns FALSE, the state of element is undefined.
+ * If this function returns %FALSE, the state of element is undefined.
*
- * Returns: TRUE, if the element's state could be synced to the parent's state.
+ * Returns: %TRUE, if the element's state could be synced to the parent's state.
*
* MT safe.
*/
diff --git a/gst/gstelement.h b/gst/gstelement.h
index 73ca545..408d10c 100644
--- a/gst/gstelement.h
+++ b/gst/gstelement.h
@@ -212,7 +212,7 @@ typedef enum {
* </para></listitem>
* <listitem><para>
* The pipeline selects a #GstClock and distributes this to all the children
- * before setting them to PLAYING. This means that it is only alowed to
+ * before setting them to PLAYING. This means that it is only allowed to
* synchronize on the #GstClock in the PLAYING state.
* </para></listitem>
* <listitem><para>
@@ -691,7 +691,7 @@ GType gst_element_get_type (void);
*
* Returns a copy of the name of @elem.
* Caller should g_free() the return value after usage.
- * For a nameless element, this returns NULL, which you can safely g_free()
+ * For a nameless element, this returns %NULL, which you can safely g_free()
* as well.
*
* Returns: (transfer full): the name of @elem. g_free() after usage. MT safe.
diff --git a/gst/gstelementfactory.c b/gst/gstelementfactory.c
index 49bfec1..aa0c5af 100644
--- a/gst/gstelementfactory.c
+++ b/gst/gstelementfactory.c
@@ -27,7 +27,7 @@
* @see_also: #GstElement, #GstPlugin, #GstPluginFeature, #GstPadTemplate.
*
* #GstElementFactory is used to create instances of elements. A
- * GstElementfactory can be added to a #GstPlugin as it is also a
+ * GstElementFactory can be added to a #GstPlugin as it is also a
* #GstPluginFeature.
*
* Use the gst_element_factory_find() and gst_element_factory_create()
@@ -53,8 +53,6 @@
* ...
* </programlisting>
* </example>
- *
- * Last reviewed on 2005-11-23 (0.9.5)
*/
#include "gst_private.h"
@@ -125,7 +123,7 @@ gst_element_factory_finalize (GObject * object)
* Search for an element factory of the given name. Refs the returned
* element factory; caller is responsible for unreffing.
*
- * Returns: (transfer full): #GstElementFactory if found, NULL otherwise
+ * Returns: (transfer full): #GstElementFactory if found, %NULL otherwise
*/
GstElementFactory *
gst_element_factory_find (const gchar * name)
@@ -188,7 +186,7 @@ gst_element_factory_cleanup (GstElementFactory * factory)
/**
* gst_element_register:
- * @plugin: (allow-none): #GstPlugin to register the element with, or NULL for
+ * @plugin: (allow-none): #GstPlugin to register the element with, or %NULL for
* a static element.
* @name: name of elements of this type
* @rank: rank of element (higher rank means more importance when autoplugging)
@@ -197,7 +195,7 @@ gst_element_factory_cleanup (GstElementFactory * factory)
* Create a new elementfactory capable of instantiating objects of the
* @type and add the factory to @plugin.
*
- * Returns: TRUE, if the registering succeeded, FALSE on error
+ * Returns: %TRUE, if the registering succeeded, %FALSE on error
*/
gboolean
gst_element_register (GstPlugin * plugin, const gchar * name, guint rank,
@@ -330,14 +328,14 @@ detailserror:
/**
* gst_element_factory_create:
* @factory: factory to instantiate
- * @name: (allow-none): name of new element, or NULL to automatically create
+ * @name: (allow-none): name of new element, or %NULL to automatically create
* a unique name
*
* Create a new element of the type defined by the given elementfactory.
* It will be given the name supplied, since all elements require a name as
* their first argument.
*
- * Returns: (transfer floating): new #GstElement or NULL if the element couldn't
+ * Returns: (transfer floating): new #GstElement or %NULL if the element couldn't
* be created
*/
GstElement *
@@ -416,15 +414,15 @@ no_element:
/**
* gst_element_factory_make:
* @factoryname: a named factory to instantiate
- * @name: (allow-none): name of new element, or NULL to automatically create
+ * @name: (allow-none): name of new element, or %NULL to automatically create
* a unique name
*
* Create a new element of the type defined by the given element factory.
- * If name is NULL, then the element will receive a guaranteed unique name,
+ * If name is %NULL, then the element will receive a guaranteed unique name,
* consisting of the element factory name and a number.
* If name is given, it will be given the name supplied.
*
- * Returns: (transfer floating): new #GstElement or NULL if unable to create element
+ * Returns: (transfer floating): new #GstElement or %NULL if unable to create element
*/
GstElement *
gst_element_factory_make (const gchar * factoryname, const gchar * name)
@@ -621,13 +619,13 @@ gst_element_factory_get_uri_type (GstElementFactory * factory)
* gst_element_factory_get_uri_protocols:
* @factory: a #GstElementFactory
*
- * Gets a NULL-terminated array of protocols this element supports or NULL if
+ * 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 owned by the element factory. Use g_strdupv() to
* make a copy of the protocol string array if you need to.
*
* Returns: (transfer none) (array zero-terminated=1): the supported protocols
- * or NULL
+ * or %NULL
*/
const gchar *const *
gst_element_factory_get_uri_protocols (GstElementFactory * factory)
@@ -644,7 +642,7 @@ gst_element_factory_get_uri_protocols (GstElementFactory * factory)
*
* Check if @factory implements the interface with name @interfacename.
*
- * Returns: #TRUE when @factory implement the interface.
+ * Returns: %TRUE when @factory implement the interface.
*/
gboolean
gst_element_factory_has_interface (GstElementFactory * factory,
@@ -818,7 +816,7 @@ gst_element_factory_list_get_elements (GstElementFactoryListType type,
* whose pad templates caps can intersect with @caps will be returned.
*
* Returns: (transfer full) (element-type Gst.ElementFactory): a #GList of
- * #GstElementFactory elements that match the given requisits.
+ * #GstElementFactory elements that match the given requisites.
* Use #gst_plugin_feature_list_free after usage.
*/
GList *
diff --git a/gst/gsterror.c b/gst/gsterror.c
index e925689..0cf5285 100644
--- a/gst/gsterror.c
+++ b/gst/gsterror.c
@@ -23,7 +23,7 @@
* @see_also: #GstMessage
*
* GStreamer elements can throw non-fatal warnings and fatal errors.
- * Higher-level elements and applications can programatically filter
+ * Higher-level elements and applications can programmatically filter
* the ones they are interested in or can recover from,
* and have a default handler handle the rest of them.
*
@@ -80,7 +80,7 @@
* currently provided should be enough. If you find your type of error
* does not fit the current codes, you should use FAILED.</para></listitem>
* <listitem><para>Don't provide a message if the default one suffices.
- * this keeps messages more uniform. Use (NULL) - not forgetting the
+ * this keeps messages more uniform. Use (%NULL) - not forgetting the
* parentheses.</para></listitem>
* <listitem><para>If you do supply a custom message, it should be
* marked for translation. The message should start with a capital
@@ -89,13 +89,11 @@
* A user interface will present this message as the first thing a user
* sees. Details, technical info, ... should go in the debug string.
* </para></listitem>
- * <listitem><para>The debug string can be as you like. Again, use (NULL)
+ * <listitem><para>The debug string can be as you like. Again, use (%NULL)
* if there's nothing to add - file and line number will still be
* passed. #GST_ERROR_SYSTEM can be used as a shortcut to give
* debug information on a system call error.</para></listitem>
* </itemizedlist>
- *
- * Last reviewed on 2006-09-15 (0.10.10)
*/
/* FIXME 0.11: the entire error system needs an overhaul - it's not very
diff --git a/gst/gstevent.c b/gst/gstevent.c
index a26cd9e..2217968 100644
--- a/gst/gstevent.c
+++ b/gst/gstevent.c
@@ -51,9 +51,7 @@
* construct and use seek events.
* To do that gst_event_new_seek() is used to create a seek event. It takes
* the needed parameters to specify seeking time and mode.
- * <example>
- * <title>performing a seek on a pipeline</title>
- * <programlisting>
+ * |[
* GstEvent *event;
* gboolean result;
* ...
@@ -69,10 +67,7 @@
* if (!result)
* g_warning ("seek failed");
* ...
- * </programlisting>
- * </example>
- *
- * Last reviewed on 2012-03-28 (0.11.3)
+ * ]|
*/
@@ -93,6 +88,7 @@ typedef struct
GstEvent event;
GstStructure *structure;
+ gint64 running_time_offset;
} GstEventImpl;
#define GST_EVENT_STRUCTURE(e) (((GstEventImpl *)(e))->structure)
@@ -254,6 +250,10 @@ _gst_event_copy (GstEvent * event)
} else {
GST_EVENT_STRUCTURE (copy) = NULL;
}
+
+ ((GstEventImpl *) copy)->running_time_offset =
+ ((GstEventImpl *) event)->running_time_offset;
+
return GST_EVENT_CAST (copy);
}
@@ -267,6 +267,7 @@ gst_event_init (GstEventImpl * event, GstEventType type)
GST_EVENT_TYPE (event) = type;
GST_EVENT_TIMESTAMP (event) = GST_CLOCK_TIME_NONE;
GST_EVENT_SEQNUM (event) = gst_util_seqnum_next ();
+ event->running_time_offset = 0;
}
@@ -347,10 +348,11 @@ gst_event_get_structure (GstEvent * event)
*
* Get a writable version of the structure.
*
- * Returns: The structure of the event. The structure is still
- * owned by the event, which means that you should not free it and
- * that the pointer becomes invalid when you free the event.
- * This function checks if @event is writable and will never return NULL.
+ * Returns: (transfer none): The structure of the event. The structure
+ * is still owned by the event, which means that you should not free
+ * it and that the pointer becomes invalid when you free the event.
+ * This function checks if @event is writable and will never return
+ * %NULL.
*
* MT safe.
*/
@@ -446,6 +448,54 @@ gst_event_set_seqnum (GstEvent * event, guint32 seqnum)
}
/**
+ * gst_event_get_running_time_offset:
+ * @event: A #GstEvent.
+ *
+ * Retrieve the accumulated running time offset of the event.
+ *
+ * Events passing through #GstPads that have a running time
+ * offset set via gst_pad_set_offset() will get their offset
+ * adjusted according to the pad's offset.
+ *
+ * If the event contains any information that related to the
+ * running time, this information will need to be updated
+ * before usage with this offset.
+ *
+ * Returns: The event's running time offset
+ *
+ * MT safe.
+ *
+ * Since: 1.4
+ */
+gint64
+gst_event_get_running_time_offset (GstEvent * event)
+{
+ g_return_val_if_fail (GST_IS_EVENT (event), 0);
+
+ return ((GstEventImpl *) event)->running_time_offset;
+}
+
+/**
+ * gst_event_set_running_time_offset:
+ * @event: A #GstEvent.
+ * @offset: A the new running time offset
+ *
+ * Set the running time offset of a event. See
+ * gst_event_get_running_time_offset() for more information.
+ *
+ * MT safe.
+ *
+ * Since: 1.4
+ */
+void
+gst_event_set_running_time_offset (GstEvent * event, gint64 offset)
+{
+ g_return_if_fail (GST_IS_EVENT (event));
+
+ ((GstEventImpl *) event)->running_time_offset = offset;
+}
+
+/**
* gst_event_new_flush_start:
*
* Allocate a new flush start event. The flush start event can be sent
@@ -481,7 +531,7 @@ gst_event_new_flush_start (void)
* pads accept data again.
*
* Elements can process this event synchronized with the dataflow since
- * the preceeding FLUSH_START event stopped the dataflow.
+ * the preceding FLUSH_START event stopped the dataflow.
*
* This event is typically generated to complete a seek and to resume
* dataflow.
@@ -934,7 +984,7 @@ gst_event_parse_buffer_size (GstEvent * event, GstFormat * format,
* increasing value.
*
* The upstream element can use the @diff and @timestamp values to decide
- * whether to process more buffers. For possitive @diff, all buffers with
+ * whether to process more buffers. For positive @diff, all buffers with
* timestamp <= @timestamp + @diff will certainly arrive late in the sink
* as well. A (negative) @diff value so that @timestamp + @diff would yield a
* result smaller than 0 is not allowed.
@@ -979,6 +1029,8 @@ gst_event_new_qos (GstQOSType type, gdouble proportion,
*
* Get the type, proportion, diff and timestamp in the qos event. See
* gst_event_new_qos() for more information about the different QoS values.
+ *
+ * @timestamp will be adjusted for any pad offsets of pads it was passing through.
*/
void
gst_event_parse_qos (GstEvent * event, GstQOSType * type,
@@ -1002,10 +1054,18 @@ gst_event_parse_qos (GstEvent * event, GstQOSType * type,
*diff =
g_value_get_int64 (gst_structure_id_get_value (structure,
GST_QUARK (DIFF)));
- if (timestamp)
+ if (timestamp) {
+ gint64 offset = gst_event_get_running_time_offset (event);
+
*timestamp =
g_value_get_uint64 (gst_structure_id_get_value (structure,
GST_QUARK (TIMESTAMP)));
+ /* Catch underflows */
+ if (*timestamp > -offset)
+ *timestamp += offset;
+ else
+ *timestamp = 0;
+ }
}
/**
@@ -1097,9 +1157,9 @@ gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags,
* @format: (out): result location for the stream format
* @flags: (out): result location for the #GstSeekFlags
* @start_type: (out): result location for the #GstSeekType of the start position
- * @start: (out): result location for the start postion expressed in @format
+ * @start: (out): result location for the start position expressed in @format
* @stop_type: (out): result location for the #GstSeekType of the stop position
- * @stop: (out): result location for the stop postion expressed in @format
+ * @stop: (out): result location for the stop position expressed in @format
*
* Parses a seek @event and stores the results in the given result locations.
*/
@@ -1298,7 +1358,7 @@ gst_event_parse_step (GstEvent * event, GstFormat * format, guint64 * amount,
/**
* gst_event_new_reconfigure:
- * Create a new reconfigure event. The purpose of the reconfingure event is
+ * Create a new reconfigure event. The purpose of the reconfigure event is
* to travel upstream and make elements renegotiate their caps or reconfigure
* their buffer pools. This is useful when changing properties on elements
* or changing the topology of the pipeline.
@@ -1660,8 +1720,8 @@ gst_event_new_segment_done (GstFormat format, gint64 position)
/**
* gst_event_parse_segment_done:
* @event: A valid #GstEvent of type GST_EVENT_SEGMENT_DONE.
- * @format: (out) (allow-none): Result location for the format, or NULL
- * @position: (out) (allow-none): Result location for the position, or NULL
+ * @format: (out) (allow-none): Result location for the format, or %NULL
+ * @position: (out) (allow-none): Result location for the position, or %NULL
*
* Extracts the position and format from the segment done message.
*
diff --git a/gst/gstevent.h b/gst/gstevent.h
index 0d1f58d..2ee38eb 100644
--- a/gst/gstevent.h
+++ b/gst/gstevent.h
@@ -285,9 +285,9 @@ GST_EXPORT GType _gst_event_type;
* in some cases), and the reference counts are updated appropriately (the old
* event is unreffed, the new one is reffed).
*
- * Either @new_event or the #GstEvent pointed to by @old_event may be NULL.
+ * Either @new_event or the #GstEvent pointed to by @old_event may be %NULL.
*
- * Returns: TRUE if @new_event was different from @old_event
+ * Returns: %TRUE if @new_event was different from @old_event
*/
#ifdef _FOOL_GTK_DOC_
G_INLINE_FUNC gboolean gst_event_replace (GstEvent **old_event, GstEvent *new_event);
@@ -304,7 +304,7 @@ gst_event_replace (GstEvent **old_event, GstEvent *new_event)
* @old_event: (inout) (transfer full): pointer to a pointer to a #GstEvent
* to be stolen.
*
- * Atomically replace the #GstEvent pointed to by @old_event with NULL and
+ * Atomically replace the #GstEvent pointed to by @old_event with %NULL and
* return the original event.
*
* Returns: the #GstEvent that was in @old_event
@@ -330,9 +330,9 @@ gst_event_steal (GstEvent **old_event)
* function is similar to gst_event_replace() except that it takes ownership of
* @new_event.
*
- * Either @new_event or the #GstEvent pointed to by @old_event may be NULL.
+ * Either @new_event or the #GstEvent pointed to by @old_event may be %NULL.
*
- * Returns: TRUE if @new_event was different from @old_event
+ * Returns: %TRUE if @new_event was different from @old_event
*/
#ifdef _FOOL_GTK_DOC_
G_INLINE_FUNC gboolean gst_event_take (GstEvent **old_event, GstEvent *new_event);
@@ -482,6 +482,10 @@ gboolean gst_event_has_name (GstEvent *event, const gchar *n
guint32 gst_event_get_seqnum (GstEvent *event);
void gst_event_set_seqnum (GstEvent *event, guint32 seqnum);
+/* accumulated pad offsets for the event */
+gint64 gst_event_get_running_time_offset (GstEvent *event);
+void gst_event_set_running_time_offset (GstEvent *event, gint64 offset);
+
/* Stream start event */
GstEvent * gst_event_new_stream_start (const gchar *stream_id) G_GNUC_MALLOC;
void gst_event_parse_stream_start (GstEvent *event, const gchar **stream_id);
diff --git a/gst/gstformat.c b/gst/gstformat.c
index 311b4bd..69600cd 100644
--- a/gst/gstformat.c
+++ b/gst/gstformat.c
@@ -85,7 +85,7 @@ _priv_gst_format_initialize (void)
*
* Get a printable name for the given format. Do not modify or free.
*
- * Returns: a reference to the static name of the format or NULL if
+ * Returns: a reference to the static name of the format or %NULL if
* the format is unknown.
*/
const gchar *
@@ -201,7 +201,7 @@ gst_format_get_by_nick (const gchar * nick)
*
* See if the given format is inside the format array.
*
- * Returns: TRUE if the format is found inside the array
+ * Returns: %TRUE if the format is found inside the array
*/
gboolean
gst_formats_contains (const GstFormat * formats, GstFormat format)
@@ -225,7 +225,7 @@ gst_formats_contains (const GstFormat * formats, GstFormat format)
*
* Get details about the given format.
*
- * Returns: The #GstFormatDefinition for @format or NULL on failure.
+ * Returns: The #GstFormatDefinition for @format or %NULL on failure.
*
* MT safe.
*/
diff --git a/gst/gstghostpad.c b/gst/gstghostpad.c
index f6952cb..cac0d51 100644
--- a/gst/gstghostpad.c
+++ b/gst/gstghostpad.c
@@ -40,8 +40,6 @@
* association later on.
*
* Note that GhostPads add overhead to the data processing of a pipeline.
- *
- * Last reviewed on 2005-11-18 (0.9.5)
*/
#include "gst_private.h"
@@ -77,11 +75,11 @@ static GstPad *gst_proxy_pad_get_target (GstPad * pad);
/**
* gst_proxy_pad_iterate_internal_links_default:
* @pad: the #GstPad to get the internal links of.
- * @parent: (allow-none): the parent of @pad or NULL
+ * @parent: (allow-none): the parent of @pad or %NULL
*
* Invoke the default iterate internal links function of the proxy pad.
*
- * Returns: a #GstIterator of #GstPad, or NULL if @pad has no parent. Unref each
+ * Returns: a #GstIterator of #GstPad, or %NULL if @pad has no parent. Unref each
* returned pad with gst_object_unref().
*/
GstIterator *
@@ -106,7 +104,7 @@ gst_proxy_pad_iterate_internal_links_default (GstPad * pad, GstObject * parent)
/**
* gst_proxy_pad_chain_default:
* @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
- * @parent: (allow-none): the parent of @pad or NULL
+ * @parent: (allow-none): the parent of @pad or %NULL
* @buffer: (transfer full): the #GstBuffer to send, return GST_FLOW_ERROR
* if not.
*
@@ -134,7 +132,7 @@ gst_proxy_pad_chain_default (GstPad * pad, GstObject * parent,
/**
* gst_proxy_pad_chain_list_default:
* @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
- * @parent: (allow-none): the parent of @pad or NULL
+ * @parent: (allow-none): the parent of @pad or %NULL
* @list: (transfer full): the #GstBufferList to send, return GST_FLOW_ERROR
* if not.
*
@@ -210,7 +208,7 @@ gst_proxy_pad_get_target (GstPad * pad)
* The internal pad of a #GstGhostPad is the internally used
* pad of opposite direction, which is used to link to the target.
*
- * Returns: (transfer full): the target #GstProxyPad, can be NULL.
+ * Returns: (transfer full): the target #GstProxyPad, can be %NULL.
* Unref target pad after usage.
*/
GstProxyPad *
@@ -332,7 +330,7 @@ gst_ghost_pad_internal_activate_pull_default (GstPad * pad, GstObject * parent,
/**
* gst_ghost_pad_internal_activate_mode_default:
* @pad: the #GstPad to activate or deactivate.
- * @parent: (allow-none): the parent of @pad or NULL
+ * @parent: (allow-none): the parent of @pad or %NULL
* @mode: the requested activation mode
* @active: whether the pad should be active or not.
*
@@ -420,7 +418,7 @@ gst_ghost_pad_activate_pull_default (GstPad * pad, GstObject * parent,
/**
* gst_ghost_pad_activate_mode_default:
* @pad: the #GstPad to activate or deactivate.
- * @parent: (allow-none): the parent of @pad or NULL
+ * @parent: (allow-none): the parent of @pad or %NULL
* @mode: the requested activation mode
* @active: whether the pad should be active or not.
*
@@ -646,7 +644,7 @@ construct_failed:
/**
* gst_ghost_pad_new_no_target:
- * @name: (allow-none): the name of the new pad, or NULL to assign a default name.
+ * @name: (allow-none): the name of the new pad, or %NULL to assign a default name.
* @dir: the direction of the ghostpad
*
* Create a new ghostpad without a target with the given direction.
@@ -655,7 +653,7 @@ construct_failed:
*
* The created ghostpad will not have a padtemplate.
*
- * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
+ * Returns: (transfer full): a new #GstPad, or %NULL in case of an error.
*/
GstPad *
gst_ghost_pad_new_no_target (const gchar * name, GstPadDirection dir)
@@ -673,7 +671,7 @@ gst_ghost_pad_new_no_target (const gchar * name, GstPadDirection dir)
/**
* gst_ghost_pad_new:
- * @name: (allow-none): the name of the new pad, or NULL to assign a default name
+ * @name: (allow-none): the name of the new pad, or %NULL to assign a default name
* @target: (transfer none): the pad to ghost.
*
* Create a new ghostpad with @target as the target. The direction will be taken
@@ -681,7 +679,7 @@ gst_ghost_pad_new_no_target (const gchar * name, GstPadDirection dir)
*
* Will ref the target.
*
- * Returns: (transfer floating): a new #GstPad, or NULL in case of an error.
+ * Returns: (transfer floating): a new #GstPad, or %NULL in case of an error.
*/
GstPad *
gst_ghost_pad_new (const gchar * name, GstPad * target)
@@ -712,7 +710,7 @@ set_target_failed:
/**
* gst_ghost_pad_new_from_template:
- * @name: (allow-none): the name of the new pad, or NULL to assign a default name.
+ * @name: (allow-none): the name of the new pad, or %NULL to assign a default name.
* @target: (transfer none): the pad to ghost.
* @templ: (transfer none): the #GstPadTemplate to use on the ghostpad.
*
@@ -721,7 +719,7 @@ set_target_failed:
*
* Will ref the target.
*
- * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
+ * Returns: (transfer full): a new #GstPad, or %NULL in case of an error.
*/
GstPad *
@@ -757,13 +755,13 @@ set_target_failed:
/**
* gst_ghost_pad_new_no_target_from_template:
- * @name: (allow-none): the name of the new pad, or NULL to assign a default name
+ * @name: (allow-none): the name of the new pad, or %NULL to assign a default name
* @templ: (transfer none): the #GstPadTemplate to create the ghostpad from.
*
* Create a new ghostpad based on @templ, without setting a target. The
* direction will be taken from the @templ.
*
- * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
+ * Returns: (transfer full): a new #GstPad, or %NULL in case of an error.
*/
GstPad *
gst_ghost_pad_new_no_target_from_template (const gchar * name,
@@ -785,7 +783,7 @@ gst_ghost_pad_new_no_target_from_template (const gchar * name,
*
* Get the target pad of @gpad. Unref target pad after usage.
*
- * Returns: (transfer full): the target #GstPad, can be NULL if the ghostpad
+ * Returns: (transfer full): the target #GstPad, can be %NULL if the ghostpad
* has no target set. Unref target pad after usage.
*/
GstPad *
@@ -809,10 +807,10 @@ gst_ghost_pad_get_target (GstGhostPad * gpad)
*
* Set the new target of the ghostpad @gpad. Any existing target
* is unlinked and links to the new target are established. if @newtarget is
- * NULL the target will be cleared.
+ * %NULL the target will be cleared.
*
- * Returns: (transfer full): TRUE if the new target could be set. This function
- * can return FALSE when the internal pads could not be linked.
+ * Returns: (transfer full): %TRUE if the new target could be set. This function
+ * can return %FALSE when the internal pads could not be linked.
*/
gboolean
gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
@@ -869,8 +867,8 @@ gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
/* ERRORS */
link_failed:
{
- GST_WARNING_OBJECT (gpad, "could not link internal and target, reason:%d",
- lret);
+ GST_WARNING_OBJECT (gpad, "could not link internal and target, reason:%s",
+ gst_pad_link_get_name (lret));
return FALSE;
}
}
diff --git a/gst/gstglobaldevicemonitor.c b/gst/gstglobaldevicemonitor.c
new file mode 100644
index 0000000..68900ef
--- /dev/null
+++ b/gst/gstglobaldevicemonitor.c
@@ -0,0 +1,501 @@
+/* GStreamer
+ * Copyright (C) 2013 Olivier Crete <olivier.crete@collabora.com>
+ *
+ * gstglobaldevicemonitor.c: Global device monitor
+ *
+ * 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.
+ */
+
+/**
+ * SECTION:gstglobaldevicemonitor
+ * @short_description: A global device monitor and prober
+ * @see_also: #GstDevice, #GstDeviceMonitor
+ *
+ * Applications should create a #GstGlobalDeviceMonitor when they want
+ * to probe, list and monitor devices of a specific type. The
+ * #GstGlobalDeviceMonitor will create the appropriate
+ * #GstDeviceMonitor objects and manage them. It will then post
+ * messages on its #GstBus for devices that have been added and
+ * removed.
+ *
+ * Since: 1.4
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gst_private.h"
+#include "gstglobaldevicemonitor.h"
+
+struct _GstGlobalDeviceMonitorPrivate
+{
+ gboolean started;
+
+ GstBus *bus;
+
+ GPtrArray *monitors;
+ guint cookie;
+
+ GstCaps *caps;
+ gchar *classes;
+};
+
+
+G_DEFINE_TYPE (GstGlobalDeviceMonitor, gst_global_device_monitor,
+ GST_TYPE_OBJECT);
+
+static void gst_global_device_monitor_dispose (GObject * object);
+
+static void
+gst_global_device_monitor_class_init (GstGlobalDeviceMonitorClass * klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GstGlobalDeviceMonitorPrivate));
+
+ object_class->dispose = gst_global_device_monitor_dispose;
+}
+
+static void
+bus_sync_message (GstBus * bus, GstMessage * message,
+ GstGlobalDeviceMonitor * monitor)
+{
+ GstMessageType type = GST_MESSAGE_TYPE (message);
+
+ if (type == GST_MESSAGE_DEVICE_ADDED || type == GST_MESSAGE_DEVICE_REMOVED) {
+ gboolean matches;
+ GstCaps *caps;
+ GstDevice *device;
+
+ if (type == GST_MESSAGE_DEVICE_ADDED)
+ gst_message_parse_device_added (message, &device);
+ else
+ gst_message_parse_device_removed (message, &device);
+
+ GST_OBJECT_LOCK (monitor);
+ caps = gst_device_get_caps (device);
+ matches = gst_caps_can_intersect (monitor->priv->caps, caps) &&
+ gst_device_has_classes (device, monitor->priv->classes);
+ gst_caps_unref (caps);
+ GST_OBJECT_UNLOCK (monitor);
+
+ if (matches)
+ gst_bus_post (monitor->priv->bus, gst_message_ref (message));
+ }
+}
+
+
+static void
+gst_global_device_monitor_init (GstGlobalDeviceMonitor * self)
+{
+ GList *factories;
+
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ GST_TYPE_GLOBAL_DEVICE_MONITOR, GstGlobalDeviceMonitorPrivate);
+
+ self->priv->bus = gst_bus_new ();
+ gst_bus_set_flushing (self->priv->bus, TRUE);
+
+ self->priv->monitors = g_ptr_array_new ();
+ self->priv->caps = gst_caps_new_any ();
+ self->priv->classes = g_strdup ("");
+
+ factories =
+ gst_device_monitor_factory_list_get_device_monitors (self->priv->classes,
+ 1);
+
+ while (factories) {
+ GstDeviceMonitorFactory *factory = factories->data;
+ GstDeviceMonitor *monitor;
+
+ factories = g_list_remove (factories, factory);
+
+ monitor = gst_device_monitor_factory_get (factory);
+ if (monitor) {
+ GstBus *bus = gst_device_monitor_get_bus (monitor);
+
+ gst_bus_enable_sync_message_emission (bus);
+ g_signal_connect (bus, "sync-message",
+ G_CALLBACK (bus_sync_message), self);
+ g_ptr_array_add (self->priv->monitors, monitor);
+ }
+
+ gst_object_unref (factory);
+ }
+}
+
+
+static void
+gst_global_device_monitor_remove (GstGlobalDeviceMonitor * self, guint i)
+{
+ GstDeviceMonitor *monitor = g_ptr_array_index (self->priv->monitors, i);
+ GstBus *bus;
+
+ g_ptr_array_remove_index_fast (self->priv->monitors, i);
+
+ bus = gst_device_monitor_get_bus (monitor);
+ g_signal_handlers_disconnect_by_func (bus, bus_sync_message, self);
+ gst_object_unref (bus);
+
+ gst_object_unref (monitor);
+}
+
+static void
+gst_global_device_monitor_dispose (GObject * object)
+{
+ GstGlobalDeviceMonitor *self = GST_GLOBAL_DEVICE_MONITOR (object);
+
+ g_return_if_fail (self->priv->started == FALSE);
+
+ if (self->priv->monitors) {
+ while (self->priv->monitors->len)
+ gst_global_device_monitor_remove (self, self->priv->monitors->len - 1);
+ g_ptr_array_unref (self->priv->monitors);
+ self->priv->monitors = NULL;
+ }
+
+ gst_caps_replace (&self->priv->caps, NULL);
+ g_free (self->priv->classes);
+ gst_object_replace ((GstObject **) & self->priv->bus, NULL);
+
+ G_OBJECT_CLASS (gst_global_device_monitor_parent_class)->dispose (object);
+}
+
+/**
+ * gst_global_device_monitor_get_devices:
+ * @monitor: A #GstDeviceMonitor
+ *
+ * Gets a list of devices from all of the relevant monitors. This may actually
+ * probe the hardware if the global monitor is not currently started.
+ *
+ * Returns: (transfer full) (element-type GstDevice): a #GList of
+ * #GstDevice
+ *
+ * Since: 1.4
+ */
+
+GList *
+gst_global_device_monitor_get_devices (GstGlobalDeviceMonitor * monitor)
+{
+ GList *devices = NULL;
+ guint i;
+ guint cookie;
+
+ g_return_val_if_fail (GST_IS_GLOBAL_DEVICE_MONITOR (monitor), NULL);
+
+ GST_OBJECT_LOCK (monitor);
+
+again:
+
+ g_list_free_full (devices, gst_object_unref);
+ devices = NULL;
+
+ cookie = monitor->priv->cookie;
+
+ for (i = 0; i < monitor->priv->monitors->len; i++) {
+ GList *tmpdev;
+ GstDeviceMonitor *device_monitor =
+ gst_object_ref (g_ptr_array_index (monitor->priv->monitors, i));
+ GList *item;
+
+ GST_OBJECT_UNLOCK (monitor);
+
+ tmpdev = gst_device_monitor_get_devices (device_monitor);
+
+ for (item = tmpdev; item; item = item->next) {
+ GstDevice *dev = GST_DEVICE (item->data);
+ GstCaps *caps = gst_device_get_caps (dev);
+
+ if (gst_caps_can_intersect (monitor->priv->caps, caps) &&
+ gst_device_has_classes (dev, monitor->priv->classes))
+ devices = g_list_prepend (devices, gst_object_ref (dev));
+ gst_caps_unref (caps);
+ }
+
+ g_list_free_full (tmpdev, gst_object_unref);
+ gst_object_unref (device_monitor);
+
+ GST_OBJECT_LOCK (monitor);
+
+ if (monitor->priv->cookie != cookie)
+ goto again;
+ }
+
+ GST_OBJECT_UNLOCK (monitor);
+
+ return devices;
+}
+
+/**
+ * gst_global_device_monitor_start:
+ * @monitor: A #GstGlobalDeviceMonitor
+ *
+ * Starts monitoring the devices, one this has succeeded, the
+ * %GST_MESSAGE_DEVICE_ADDED and %GST_MESSAGE_DEVICE_REMOVED messages
+ * will be emitted on the bus when the list of devices changes.
+ *
+ * Returns: %TRUE if the device monitoring could be started
+ *
+ * Since: 1.4
+ */
+
+gboolean
+gst_global_device_monitor_start (GstGlobalDeviceMonitor * monitor)
+{
+ guint i;
+
+ g_return_val_if_fail (GST_IS_GLOBAL_DEVICE_MONITOR (monitor), FALSE);
+
+ GST_OBJECT_LOCK (monitor);
+
+ if (monitor->priv->monitors->len == 0) {
+ GST_OBJECT_UNLOCK (monitor);
+ return FALSE;
+ }
+
+ gst_bus_set_flushing (monitor->priv->bus, FALSE);
+
+ for (i = 0; i < monitor->priv->monitors->len; i++) {
+ if (!gst_device_monitor_start (g_ptr_array_index (monitor->priv->monitors,
+ i))) {
+ gst_bus_set_flushing (monitor->priv->bus, TRUE);
+
+ for (; i != 0; i--)
+ gst_device_monitor_stop (g_ptr_array_index (monitor->priv->monitors,
+ i - 1));
+
+ GST_OBJECT_UNLOCK (monitor);
+ return FALSE;
+ }
+ }
+
+ monitor->priv->started = TRUE;
+ GST_OBJECT_UNLOCK (monitor);
+
+ return TRUE;
+}
+
+/**
+ * gst_global_device_monitor_stop:
+ * @monitor: A #GstDeviceMonitor
+ *
+ * Stops monitoring the devices.
+ *
+ * Since: 1.4
+ */
+void
+gst_global_device_monitor_stop (GstGlobalDeviceMonitor * monitor)
+{
+ guint i;
+
+ g_return_if_fail (GST_IS_GLOBAL_DEVICE_MONITOR (monitor));
+
+ gst_bus_set_flushing (monitor->priv->bus, TRUE);
+
+ GST_OBJECT_LOCK (monitor);
+ for (i = 0; i < monitor->priv->monitors->len; i++)
+ gst_device_monitor_stop (g_ptr_array_index (monitor->priv->monitors, i));
+ monitor->priv->started = FALSE;
+ GST_OBJECT_UNLOCK (monitor);
+
+}
+
+/**
+ * gst_global_device_monitor_set_classes_filter:
+ * @monitor: the global device monitor
+ * @classes: device classes to use as filter
+ *
+ * Filter devices monitored by device class, e.g. in case you are only
+ * interested in a certain type of device like audio devices or
+ * video sources.
+ *
+ * Since: 1.4
+ */
+void
+gst_global_device_monitor_set_classes_filter (GstGlobalDeviceMonitor * monitor,
+ const gchar * classes)
+{
+ GList *factories = NULL;
+ guint i;
+
+ g_return_if_fail (GST_IS_GLOBAL_DEVICE_MONITOR (monitor));
+ g_return_if_fail (!monitor->priv->started);
+
+ GST_OBJECT_LOCK (monitor);
+ if (!strcmp (monitor->priv->classes, classes)) {
+ GST_OBJECT_UNLOCK (monitor);
+ return;
+ }
+
+ g_free (monitor->priv->classes);
+ monitor->priv->classes = g_strdup (classes);
+
+ factories = gst_device_monitor_factory_list_get_device_monitors (classes, 1);
+
+ for (i = 0; i < monitor->priv->monitors->len; i++) {
+ GstDeviceMonitor *dev_monitor;
+ GstDeviceMonitorFactory *f;
+ GList *item;
+
+ dev_monitor = g_ptr_array_index (monitor->priv->monitors, i);
+ f = gst_device_monitor_get_factory (dev_monitor);
+
+ item = g_list_find (factories, f);
+
+ if (item) {
+ /* If the item is in our list, then remove it from the list of factories,
+ * we don't have it to re-create it later
+ */
+ factories = g_list_remove_link (factories, item);
+ gst_object_unref (f);
+ } else {
+ /* If it's not in our list, them remove it from the list of monitors.
+ */
+
+ monitor->priv->cookie++;
+ gst_global_device_monitor_remove (monitor, i);
+ i--;
+ }
+ }
+
+ while (factories) {
+ GstDeviceMonitorFactory *factory = factories->data;
+ GstDeviceMonitor *device_monitor;
+
+ factories = g_list_remove (factories, factory);
+
+ device_monitor = gst_device_monitor_factory_get (factory);
+ if (device_monitor) {
+ GstBus *bus = gst_device_monitor_get_bus (device_monitor);
+
+ gst_bus_enable_sync_message_emission (bus);
+ g_signal_connect (bus, "sync-message",
+ G_CALLBACK (bus_sync_message), monitor);
+ gst_object_unref (bus);
+ g_ptr_array_add (monitor->priv->monitors, device_monitor);
+ monitor->priv->cookie++;
+ }
+
+ gst_object_unref (factory);
+ }
+
+ GST_OBJECT_UNLOCK (monitor);
+}
+
+/**
+ * gst_global_device_monitor_get_classes_filter:
+ * @monitor: the global device monitor
+ *
+ * Return the type (device classes) filter active for device filtering.
+ *
+ * Returns: string of device classes that are being filtered.
+ *
+ * Since: 1.4
+ */
+gchar *
+gst_global_device_monitor_get_classes_filter (GstGlobalDeviceMonitor * monitor)
+{
+ gchar *res;
+
+ g_return_val_if_fail (GST_IS_GLOBAL_DEVICE_MONITOR (monitor), 0);
+
+ GST_OBJECT_LOCK (monitor);
+ res = g_strdup (monitor->priv->classes);
+ GST_OBJECT_UNLOCK (monitor);
+
+ return res;
+}
+
+/**
+ * gst_global_device_monitor_set_caps_filter:
+ * @monitor: the global device monitor
+ * @caps: caps to filter
+ *
+ * Set caps to use as filter for devices. By default ANY caps are used,
+ * meaning no caps filter is active.
+ *
+ * Since: 1.4
+ */
+void
+gst_global_device_monitor_set_caps_filter (GstGlobalDeviceMonitor * monitor,
+ GstCaps * caps)
+{
+ g_return_if_fail (GST_IS_GLOBAL_DEVICE_MONITOR (monitor));
+ g_return_if_fail (GST_IS_CAPS (caps));
+
+ GST_OBJECT_LOCK (monitor);
+ gst_caps_replace (&monitor->priv->caps, caps);
+ GST_OBJECT_UNLOCK (monitor);
+}
+
+/**
+ * gst_global_device_monitor_get_caps_filter:
+ * @monitor: a global device monitor
+ *
+ * Get the #GstCaps filter set by gst_global_device_monitor_set_caps_filter().
+ *
+ * Returns: (transfer full): the filter caps that are active (or ANY caps)
+ *
+ * Since: 1.4
+ */
+GstCaps *
+gst_global_device_monitor_get_caps_filter (GstGlobalDeviceMonitor * monitor)
+{
+ GstCaps *res;
+
+ g_return_val_if_fail (GST_IS_GLOBAL_DEVICE_MONITOR (monitor), NULL);
+
+ GST_OBJECT_LOCK (monitor);
+ res = gst_caps_ref (monitor->priv->caps);
+ GST_OBJECT_UNLOCK (monitor);
+
+ return res;
+}
+
+/**
+ * gst_global_device_monitor_new:
+ *
+ * Create a new #GstGlobalDeviceMonitor
+ *
+ * Returns: (transfer full): a new global device monitor.
+ *
+ * Since: 1.4
+ */
+GstGlobalDeviceMonitor *
+gst_global_device_monitor_new (void)
+{
+ return g_object_new (GST_TYPE_GLOBAL_DEVICE_MONITOR, NULL);
+}
+
+/**
+ * gst_global_device_monitor_get_bus:
+ * @monitor: a #GstDeviceMonitor
+ *
+ * Gets the #GstBus of this #GstGlobalDeviceMonitor
+ *
+ * Returns: (transfer full): a #GstBus
+ *
+ * Since: 1.4
+ */
+GstBus *
+gst_global_device_monitor_get_bus (GstGlobalDeviceMonitor * monitor)
+{
+ g_return_val_if_fail (GST_IS_GLOBAL_DEVICE_MONITOR (monitor), NULL);
+
+ return gst_object_ref (monitor->priv->bus);
+}
diff --git a/gst/gstglobaldevicemonitor.h b/gst/gstglobaldevicemonitor.h
new file mode 100644
index 0000000..b92fd40
--- /dev/null
+++ b/gst/gstglobaldevicemonitor.h
@@ -0,0 +1,105 @@
+/* GStreamer
+ * Copyright (C) 2013 Olivier Crete <olivier.crete@collabora.com>
+ *
+ * gstglobaldevicemonitor.c: Global device monitor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GST_GLOBAL_DEVICE_MONITOR_H__
+#define __GST_GLOBAL_DEVICE_MONITOR_H__
+
+#include <gst/gstobject.h>
+#include <gst/gstdevice.h>
+#include <gst/gstdevicemonitor.h>
+#include <gst/gstdevicemonitorfactory.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GstGlobalDeviceMonitor GstGlobalDeviceMonitor;
+typedef struct _GstGlobalDeviceMonitorPrivate GstGlobalDeviceMonitorPrivate;
+typedef struct _GstGlobalDeviceMonitorClass GstGlobalDeviceMonitorClass;
+
+#define GST_TYPE_GLOBAL_DEVICE_MONITOR (gst_global_device_monitor_get_type())
+#define GST_IS_GLOBAL_DEVICE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_GLOBAL_DEVICE_MONITOR))
+#define GST_IS_GLOBAL_DEVICE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_GLOBAL_DEVICE_MONITOR))
+#define GST_GLOBAL_DEVICE_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_GLOBAL_DEVICE_MONITOR, GstGlobalDeviceMonitorClass))
+#define GST_GLOBAL_DEVICE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_GLOBAL_DEVICE_MONITOR, GstGlobalDeviceMonitor))
+#define GST_GLOBAL_DEVICE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_GLOBAL_DEVICE_MONITOR, GstGlobalDeviceMonitorClass))
+#define GST_GLOBAL_DEVICE_MONITOR_CAST(obj) ((GstGlobalDeviceMonitor *)(obj))
+
+/**
+ * GstGlobalDeviceMonitor:
+ * @parent: the parent #GstObject structure
+ *
+ * Opaque global device monitor object structure.
+ *
+ * Since: 1.4
+ */
+struct _GstGlobalDeviceMonitor {
+ GstObject parent;
+
+ /*< private >*/
+
+ GstGlobalDeviceMonitorPrivate *priv;
+
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+/**
+ * GstGlobalDeviceMonitorClass:
+ * @parent_class: the parent #GstObjectClass structure
+ *
+ * Opaque global device monitor class structure.
+ *
+ * Since: 1.4
+ */
+struct _GstGlobalDeviceMonitorClass {
+ GstObjectClass parent_class;
+
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING];
+};
+
+GType gst_global_device_monitor_get_type (void);
+
+GstGlobalDeviceMonitor * gst_global_device_monitor_new (void);
+
+GstBus * gst_global_device_monitor_get_bus (GstGlobalDeviceMonitor * monitor);
+
+GList * gst_global_device_monitor_get_devices (GstGlobalDeviceMonitor * monitor);
+
+
+gboolean gst_global_device_monitor_start (GstGlobalDeviceMonitor * monitor);
+
+void gst_global_device_monitor_stop (GstGlobalDeviceMonitor * monitor);
+
+
+void gst_global_device_monitor_set_classes_filter (GstGlobalDeviceMonitor * monitor,
+ const gchar * classes);
+
+gchar * gst_global_device_monitor_get_classes_filter (GstGlobalDeviceMonitor * monitor);
+
+
+void gst_global_device_monitor_set_caps_filter (GstGlobalDeviceMonitor * monitor,
+ GstCaps * caps);
+
+GstCaps * gst_global_device_monitor_get_caps_filter (GstGlobalDeviceMonitor * monitor);
+
+G_END_DECLS
+
+#endif /* __GST_GLOBAL_DEVICE_MONITOR_H__ */
diff --git a/gst/gstinfo.c b/gst/gstinfo.c
index 5501217..3f56686 100644
--- a/gst/gstinfo.c
+++ b/gst/gstinfo.c
@@ -50,19 +50,15 @@
* categories. This is easily done with 3 lines. At the top of your code,
* declare
* the variables and set the default category.
- * <informalexample>
- * <programlisting>
- * GST_DEBUG_CATEGORY_STATIC (my_category); // define category (statically)
- * &hash;define GST_CAT_DEFAULT my_category // set as default
- * </programlisting>
- * </informalexample>
+ * |[
+ * GST_DEBUG_CATEGORY_STATIC (my_category); // define category (statically)
+ * #define GST_CAT_DEFAULT my_category // set as default
+ * ]|
* After that you only need to initialize the category.
- * <informalexample>
- * <programlisting>
- * GST_DEBUG_CATEGORY_INIT (my_category, "my category",
- * 0, "This is my very own");
- * </programlisting>
- * </informalexample>
+ * |[
+ * GST_DEBUG_CATEGORY_INIT (my_category, "my category",
+ * 0, "This is my very own");
+ * ]|
* Initialization must be done before the category is used first.
* Plugins do this
* in their plugin_init function, libraries and applications should do that
@@ -248,6 +244,9 @@ LevelNameEntry;
static GMutex __cat_mutex;
static GSList *__categories = NULL;
+static GstDebugCategory *_gst_debug_get_category_locked (const gchar * name);
+
+
/* all registered debug handlers */
typedef struct
{
@@ -406,6 +405,17 @@ _priv_gst_debug_init (void)
else if (strstr (env, "pretty_tags") || strstr (env, "pretty-tags"))
pretty_tags = TRUE;
}
+
+ if (g_getenv ("GST_DEBUG_NO_COLOR") != NULL)
+ gst_debug_set_color_mode (GST_DEBUG_COLOR_MODE_OFF);
+ env = g_getenv ("GST_DEBUG_COLOR_MODE");
+ if (env)
+ gst_debug_set_color_mode_from_string (env);
+
+ env = g_getenv ("GST_DEBUG");
+ if (env) {
+ gst_debug_set_threshold_from_string (env, FALSE);
+ }
}
/* we can't do this further above, because we initialize the GST_CAT_DEFAULT struct */
@@ -419,7 +429,7 @@ _priv_gst_debug_init (void)
* @function: the function that emitted the message
* @line: the line from that the message was emitted, usually __LINE__
* @object: (transfer none) (allow-none): the object this message relates to,
- * or NULL if none
+ * or %NULL if none
* @format: a printf style format string
* @...: optional arguments for the format
*
@@ -471,7 +481,7 @@ gst_path_basename (const gchar * file_name)
* @function: the function that emitted the message
* @line: the line from that the message was emitted, usually __LINE__
* @object: (transfer none) (allow-none): the object this message relates to,
- * or NULL if none
+ * or %NULL if none
* @format: a printf style format string
* @args: optional arguments for the format
*
@@ -562,7 +572,7 @@ prettify_structure_string (gchar * str)
if (count > MAX_BUFFER_DUMP_STRING_LEN) {
memcpy (pos + MAX_BUFFER_DUMP_STRING_LEN - 6, "..", 2);
memcpy (pos + MAX_BUFFER_DUMP_STRING_LEN - 4, pos + count - 4, 4);
- g_memmove (pos + MAX_BUFFER_DUMP_STRING_LEN, pos + count,
+ memmove (pos + MAX_BUFFER_DUMP_STRING_LEN, pos + count,
strlen (pos + count) + 1);
pos += MAX_BUFFER_DUMP_STRING_LEN;
}
@@ -661,16 +671,16 @@ gst_debug_print_object (gpointer ptr)
if (object == NULL) {
return g_strdup ("(NULL)");
}
- if (*(GType *) ptr == GST_TYPE_CAPS) {
+ if (GST_IS_CAPS (ptr)) {
return gst_caps_to_string ((const GstCaps *) ptr);
}
- if (*(GType *) ptr == GST_TYPE_STRUCTURE) {
+ if (GST_IS_STRUCTURE (ptr)) {
return gst_info_structure_to_string ((const GstStructure *) ptr);
}
if (*(GType *) ptr == GST_TYPE_CAPS_FEATURES) {
return gst_caps_features_to_string ((const GstCapsFeatures *) ptr);
}
- if (*(GType *) ptr == GST_TYPE_TAG_LIST) {
+ if (GST_IS_TAG_LIST (ptr)) {
gchar *str = gst_tag_list_to_string ((GstTagList *) ptr);
if (G_UNLIKELY (pretty_tags))
return prettify_structure_string (str);
@@ -688,15 +698,6 @@ gst_debug_print_object (gpointer ptr)
return g_strdup_printf ("<poisoned@%p>", ptr);
}
#endif
- if (GST_IS_PAD (object) && GST_OBJECT_NAME (object)) {
- return g_strdup_printf ("<%s:%s>", GST_DEBUG_PAD_NAME (object));
- }
- if (GST_IS_OBJECT (object) && GST_OBJECT_NAME (object)) {
- return g_strdup_printf ("<%s>", GST_OBJECT_NAME (object));
- }
- if (G_IS_OBJECT (object)) {
- return g_strdup_printf ("<%s@%p>", G_OBJECT_TYPE_NAME (object), object);
- }
if (GST_IS_MESSAGE (object)) {
return gst_info_describe_message (GST_MESSAGE_CAST (object));
}
@@ -721,6 +722,15 @@ gst_debug_print_object (gpointer ptr)
g_free (s);
return ret;
}
+ if (GST_IS_PAD (object) && GST_OBJECT_NAME (object)) {
+ return g_strdup_printf ("<%s:%s>", GST_DEBUG_PAD_NAME (object));
+ }
+ if (GST_IS_OBJECT (object) && GST_OBJECT_NAME (object)) {
+ return g_strdup_printf ("<%s>", GST_OBJECT_NAME (object));
+ }
+ if (G_IS_OBJECT (object)) {
+ return g_strdup_printf ("<%s@%p>", G_OBJECT_TYPE_NAME (object), object);
+ }
return g_strdup_printf ("%p", ptr);
}
@@ -741,10 +751,11 @@ gst_debug_print_segment (gpointer ptr)
}
case GST_FORMAT_TIME:{
return g_strdup_printf ("time segment start=%" GST_TIME_FORMAT
- ", stop=%" GST_TIME_FORMAT ", rate=%f, applied_rate=%f"
- ", flags=0x%02x, time=%" GST_TIME_FORMAT ", base=%" GST_TIME_FORMAT
- ", position %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
- GST_TIME_ARGS (segment->start), GST_TIME_ARGS (segment->stop),
+ ", offset=%" GST_TIME_FORMAT ", stop=%" GST_TIME_FORMAT
+ ", rate=%f, applied_rate=%f" ", flags=0x%02x, time=%" GST_TIME_FORMAT
+ ", base=%" GST_TIME_FORMAT ", position %" GST_TIME_FORMAT
+ ", duration %" GST_TIME_FORMAT, GST_TIME_ARGS (segment->start),
+ GST_TIME_ARGS (segment->offset), GST_TIME_ARGS (segment->stop),
segment->rate, segment->applied_rate, (guint) segment->flags,
GST_TIME_ARGS (segment->time), GST_TIME_ARGS (segment->base),
GST_TIME_ARGS (segment->position), GST_TIME_ARGS (segment->duration));
@@ -756,12 +767,13 @@ gst_debug_print_segment (gpointer ptr)
if (G_UNLIKELY (format_name == NULL))
format_name = "(UNKNOWN FORMAT)";
return g_strdup_printf ("%s segment start=%" G_GINT64_FORMAT
- ", stop=%" G_GINT64_FORMAT ", rate=%f, applied_rate=%f"
- ", flags=0x%02x, time=%" G_GINT64_FORMAT ", base=%" G_GINT64_FORMAT
- ", position %" G_GINT64_FORMAT ", duration %" G_GINT64_FORMAT,
- format_name, segment->start, segment->stop, segment->rate,
- segment->applied_rate, (guint) segment->flags,
- segment->time, segment->base, segment->position, segment->duration);
+ ", offset=%" G_GINT64_FORMAT ", stop=%" G_GINT64_FORMAT
+ ", rate=%f, applied_rate=%f" ", flags=0x%02x, time=%" G_GINT64_FORMAT
+ ", base=%" G_GINT64_FORMAT ", position %" G_GINT64_FORMAT
+ ", duration %" G_GINT64_FORMAT, format_name, segment->start,
+ segment->offset, segment->stop, segment->rate, segment->applied_rate,
+ (guint) segment->flags, segment->time, segment->base,
+ segment->position, segment->duration);
}
}
}
@@ -949,7 +961,7 @@ static const gchar *levelcolormap[GST_LEVEL_COUNT] = {
* @line: the line from that the message was emitted, usually __LINE__
* @message: the actual message
* @object: (transfer none) (allow-none): the object this message relates to,
- * or NULL if none
+ * or %NULL if none
* @unused: an unused variable, reserved for some user_data.
*
* The default logging handler used by GStreamer. Logging functions get called
@@ -1306,7 +1318,7 @@ gst_debug_set_color_mode_from_string (const gchar * mode)
*
* Checks if the debugging output should be colored.
*
- * Returns: TRUE, if the debug output should be colored.
+ * Returns: %TRUE, if the debug output should be colored.
*/
gboolean
gst_debug_is_colored (void)
@@ -1355,7 +1367,7 @@ gst_debug_set_active (gboolean active)
*
* Checks if debugging output is activated.
*
- * Returns: TRUE, if debugging is activated
+ * Returns: %TRUE, if debugging is activated
*/
gboolean
gst_debug_is_active (void)
@@ -1506,7 +1518,7 @@ GstDebugCategory *
_gst_debug_category_new (const gchar * name, guint color,
const gchar * description)
{
- GstDebugCategory *cat;
+ GstDebugCategory *cat, *catfound;
g_return_val_if_fail (name != NULL, NULL);
@@ -1523,7 +1535,15 @@ _gst_debug_category_new (const gchar * name, guint color,
/* add to category list */
g_mutex_lock (&__cat_mutex);
- __categories = g_slist_prepend (__categories, cat);
+ catfound = _gst_debug_get_category_locked (name);
+ if (catfound) {
+ g_free ((gpointer) cat->name);
+ g_free ((gpointer) cat->description);
+ g_slice_free (GstDebugCategory, cat);
+ cat = catfound;
+ } else {
+ __categories = g_slist_prepend (__categories, cat);
+ }
g_mutex_unlock (&__cat_mutex);
return cat;
@@ -1674,8 +1694,8 @@ gst_debug_get_all_categories (void)
return ret;
}
-GstDebugCategory *
-_gst_debug_get_category (const gchar * name)
+static GstDebugCategory *
+_gst_debug_get_category_locked (const gchar * name)
{
GstDebugCategory *ret = NULL;
GSList *node;
@@ -1689,6 +1709,18 @@ _gst_debug_get_category (const gchar * name)
return NULL;
}
+GstDebugCategory *
+_gst_debug_get_category (const gchar * name)
+{
+ GstDebugCategory *ret;
+
+ g_mutex_lock (&__cat_mutex);
+ ret = _gst_debug_get_category_locked (name);
+ g_mutex_unlock (&__cat_mutex);
+
+ return ret;
+}
+
static gboolean
parse_debug_category (gchar * str, const gchar ** category)
{
@@ -1759,7 +1791,7 @@ parse_debug_level (gchar * str, GstDebugLevel * level)
* the order matters when you use wild cards, e.g. "foosrc:6,*src:3,*:2" sets
* everything to log level 2.
*
- * Since: 1.2.0
+ * Since: 1.2
*/
void
gst_debug_set_threshold_from_string (const gchar * list, gboolean reset)
@@ -2153,7 +2185,7 @@ __gst_info_fallback_vasprintf (char **result, char const *format, va_list args)
continue;
}
len = strlen (c + 4);
- g_memmove (c + 2, c + 4, len + 1);
+ memmove (c + 2, c + 4, len + 1);
c += 2;
}
while ((c = strstr (clean_format, "%P"))) /* old GST_PTR_FORMAT */
diff --git a/gst/gstinfo.h b/gst/gstinfo.h
index 4f9baa6..319e841 100644
--- a/gst/gstinfo.h
+++ b/gst/gstinfo.h
@@ -34,10 +34,10 @@ G_BEGIN_DECLS
* GstDebugLevel:
* @GST_LEVEL_NONE: No debugging level specified or desired. Used to deactivate
* debugging output.
- * @GST_LEVEL_ERROR: Error messages are to be used only when an error occured
+ * @GST_LEVEL_ERROR: Error messages are to be used only when an error occurred
* that stops the application from keeping working correctly.
* An examples is gst_element_error, which outputs a message with this priority.
- * It does not mean that the application is terminating as with g_errror.
+ * It does not mean that the application is terminating as with g_error.
* @GST_LEVEL_WARNING: Warning messages are to inform about abnormal behaviour
* that could lead to problems or weird behaviour later on. An example of this
* would be clocking issues ("your computer is pretty slow") or broken input
@@ -199,9 +199,9 @@ struct _GstDebugCategory {
* GST_STR_NULL:
* @str: The string to check.
*
- * Macro to use when a string must not be NULL, but may be NULL. If the string
- * is NULL, "(NULL)" is printed instead.
- * In GStreamer printf string arguments may not be NULL, because on some
+ * Macro to use when a string must not be %NULL, but may be %NULL. If the string
+ * is %NULL, "(NULL)" is printed instead.
+ * In GStreamer printf string arguments may not be %NULL, because on some
* platforms (ie Solaris) the libc crashes in that case. This includes debugging
* strings.
*/
@@ -470,7 +470,7 @@ G_STMT_START{ \
*
* Looks up an existing #GstDebugCategory by its @name and sets @cat. If the
* category is not found, but GST_CAT_DEFAULT is defined, that is assigned to
- * @cat. Otherwise @cat will be NULL.
+ * @cat. Otherwise @cat will be %NULL.
*
* |[
* GST_DEBUG_CATEGORY_STATIC (gst_myplugin_debug);
@@ -511,7 +511,7 @@ GST_EXPORT GstDebugLevel _gst_debug_min;
* GST_CAT_LEVEL_LOG:
* @cat: category to use
* @level: the severity of the message
- * @object: (allow-none): the #GObject the message belongs to or NULL if none
+ * @object: (allow-none): the #GObject the message belongs to or %NULL if none
* @...: A printf-style message to output
*
* Outputs a debugging message. This is the most general macro for outputting
diff --git a/gst/gstiterator.c b/gst/gstiterator.c
index 0a63a90..4e5b1f5 100644
--- a/gst/gstiterator.c
+++ b/gst/gstiterator.c
@@ -34,40 +34,34 @@
*
* In general, whenever calling a GstIterator function results in your code
* receiving a refcounted object, the refcount for that object will have been
- * increased. Your code is responsible for unrefing that object after use.
+ * increased. Your code is responsible for unreffing that object after use.
*
* The basic use pattern of an iterator is as follows:
- *
- * <example>
- * <title>Using an iterator</title>
- * <programlisting>
- * it = _get_iterator(object);
- * done = FALSE;
- * while (!done) {
- * switch (gst_iterator_next (it, &amp;item)) {
- * case GST_ITERATOR_OK:
- * ... use/change item here...
- * g_value_reset (&amp;item);
- * break;
- * case GST_ITERATOR_RESYNC:
- * ...rollback changes to items...
- * gst_iterator_resync (it);
- * break;
- * case GST_ITERATOR_ERROR:
- * ...wrong parameters were given...
- * done = TRUE;
- * break;
- * case GST_ITERATOR_DONE:
- * done = TRUE;
- * break;
- * }
- * }
- * g_value_unset (&amp;item);
- * gst_iterator_free (it);
- * </programlisting>
- * </example>
- *
- * Last reviewed on 2009-06-16 (0.10.24)
+ * |[
+ * GstIterator *it = _get_iterator(object);
+ * done = FALSE;
+ * while (!done) {
+ * switch (gst_iterator_next (it, &amp;item)) {
+ * case GST_ITERATOR_OK:
+ * ... use/change item here...
+ * g_value_reset (&amp;item);
+ * break;
+ * case GST_ITERATOR_RESYNC:
+ * ...rollback changes to items...
+ * gst_iterator_resync (it);
+ * break;
+ * case GST_ITERATOR_ERROR:
+ * ...wrong parameters were given...
+ * done = TRUE;
+ * break;
+ * case GST_ITERATOR_DONE:
+ * done = TRUE;
+ * break;
+ * }
+ * }
+ * g_value_unset (&amp;item);
+ * gst_iterator_free (it);
+ * ]|
*/
#include "gst_private.h"
@@ -459,6 +453,7 @@ typedef struct _GstIteratorFilter
GstIterator iterator;
GstIterator *slave;
+ GMutex *master_lock;
GCompareFunc func;
GValue user_data;
gboolean have_user_data;
@@ -475,15 +470,15 @@ filter_next (GstIteratorFilter * it, GValue * elem)
result = gst_iterator_next (it->slave, &item);
switch (result) {
case GST_ITERATOR_OK:
- if (G_LIKELY (GST_ITERATOR (it)->lock))
- g_mutex_unlock (GST_ITERATOR (it)->lock);
+ if (G_LIKELY (it->master_lock))
+ g_mutex_unlock (it->master_lock);
if (it->func (&item, &it->user_data) == 0) {
g_value_copy (&item, elem);
done = TRUE;
}
g_value_reset (&item);
- if (G_LIKELY (GST_ITERATOR (it)->lock))
- g_mutex_lock (GST_ITERATOR (it)->lock);
+ if (G_LIKELY (it->master_lock))
+ g_mutex_lock (it->master_lock);
break;
case GST_ITERATOR_RESYNC:
case GST_ITERATOR_DONE:
@@ -502,6 +497,8 @@ static void
filter_copy (const GstIteratorFilter * it, GstIteratorFilter * copy)
{
copy->slave = gst_iterator_copy (it->slave);
+ copy->master_lock = copy->slave->lock ? copy->slave->lock : it->master_lock;
+ copy->slave->lock = NULL;
if (it->have_user_data) {
memset (&copy->user_data, 0, sizeof (copy->user_data));
@@ -559,6 +556,7 @@ gst_iterator_filter (GstIterator * it, GCompareFunc func,
(GstIteratorResyncFunction) filter_resync,
(GstIteratorFreeFunction) filter_free);
+ result->master_lock = it->lock;
it->lock = NULL;
result->func = func;
if (user_data) {
@@ -588,8 +586,8 @@ gst_iterator_filter (GstIterator * it, GCompareFunc func,
* This procedure can be used (and is used internally) to implement the
* gst_iterator_foreach() and gst_iterator_find_custom() operations.
*
- * The fold will proceed as long as @func returns TRUE. When the iterator has no
- * more arguments, %GST_ITERATOR_DONE will be returned. If @func returns FALSE,
+ * The fold will proceed as long as @func returns %TRUE. When the iterator has no
+ * more arguments, %GST_ITERATOR_DONE will be returned. If @func returns %FALSE,
* the fold will stop, and %GST_ITERATOR_OK will be returned. Errors or resyncs
* will cause fold to return %GST_ITERATOR_ERROR or %GST_ITERATOR_RESYNC as
* appropriate.
@@ -705,10 +703,10 @@ find_custom_fold_func (const GValue * item, GValue * ret,
*
* The iterator will not be freed.
*
- * This function will return FALSE if an error happened to the iterator
+ * This function will return %FALSE if an error happened to the iterator
* or if the element wasn't found.
*
- * Returns: Returns TRUE if the element was found, else FALSE.
+ * Returns: Returns %TRUE if the element was found, else %FALSE.
*
* MT safe.
*/
diff --git a/gst/gstiterator.h b/gst/gstiterator.h
index 7ad54ee..264f197 100644
--- a/gst/gstiterator.h
+++ b/gst/gstiterator.h
@@ -146,7 +146,7 @@ typedef void (*GstIteratorForeachFunction) (const GValue * item, gpo
*
* A function to be passed to gst_iterator_fold().
*
- * Returns: TRUE if the fold should continue, FALSE if it should stop.
+ * Returns: %TRUE if the fold should continue, %FALSE if it should stop.
*/
typedef gboolean (*GstIteratorFoldFunction) (const GValue * item, GValue * ret, gpointer user_data);
diff --git a/gst/gstmemory.c b/gst/gstmemory.c
index 1f44e7b..c29fccd 100644
--- a/gst/gstmemory.c
+++ b/gst/gstmemory.c
@@ -33,7 +33,7 @@
* in the allocated region.
*
* Memory is usually created by allocators with a gst_allocator_alloc()
- * method call. When NULL is used as the allocator, the default allocator will
+ * method call. When %NULL is used as the allocator, the default allocator will
* be used.
*
* New allocators can be registered with gst_allocator_register().
@@ -59,9 +59,7 @@
* memory with an existing memory block at a custom offset and with a custom
* size.
*
- * Memory can be efficiently merged when gst_memory_is_span() returns TRUE.
- *
- * Last reviewed on 2012-03-28 (0.11.3)
+ * Memory can be efficiently merged when gst_memory_is_span() returns %TRUE.
*/
#ifdef HAVE_CONFIG_H
@@ -71,6 +69,7 @@
#include "gst_private.h"
#include "gstmemory.h"
+GType _gst_memory_type = 0;
GST_DEFINE_MINI_OBJECT_TYPE (GstMemory, gst_memory);
static GstMemory *
@@ -226,7 +225,7 @@ gst_memory_resize (GstMemory * mem, gssize offset, gsize size)
* This function takes ownership of old @mem and returns a reference to a new
* #GstMemory.
*
- * Returns: (transfer full): a #GstMemory object mapped with @flags or NULL when
+ * Returns: (transfer full): a #GstMemory object mapped with @flags or %NULL when
* a mapping is not possible.
*/
GstMemory *
@@ -290,7 +289,7 @@ gst_memory_map (GstMemory * mem, GstMapInfo * info, GstMapFlags flags)
g_return_val_if_fail (mem != NULL, FALSE);
g_return_val_if_fail (info != NULL, FALSE);
- if (!gst_memory_lock (mem, flags))
+ if (!gst_memory_lock (mem, (GstLockFlags) flags))
goto lock_failed;
info->data = mem->allocator->mem_map (mem, mem->maxsize, flags);
@@ -310,13 +309,15 @@ gst_memory_map (GstMemory * mem, GstMapInfo * info, GstMapFlags flags)
lock_failed:
{
GST_CAT_DEBUG (GST_CAT_MEMORY, "mem %p: lock %d failed", mem, flags);
+ memset (info, 0, sizeof (GstMapInfo));
return FALSE;
}
error:
{
/* something went wrong, restore the orginal state again */
GST_CAT_ERROR (GST_CAT_MEMORY, "mem %p: subclass map failed", mem);
- gst_memory_unlock (mem, flags);
+ gst_memory_unlock (mem, (GstLockFlags) flags);
+ memset (info, 0, sizeof (GstMapInfo));
return FALSE;
}
}
@@ -336,7 +337,7 @@ gst_memory_unmap (GstMemory * mem, GstMapInfo * info)
g_return_if_fail (info->memory == mem);
mem->allocator->mem_unmap (mem);
- gst_memory_unlock (mem, info->flags);
+ gst_memory_unlock (mem, (GstLockFlags) info->flags);
}
/**
@@ -425,3 +426,9 @@ gst_memory_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
return TRUE;
}
+
+void
+_priv_gst_memory_initialize (void)
+{
+ _gst_memory_type = gst_memory_get_type ();
+}
diff --git a/gst/gstmemory.h b/gst/gstmemory.h
index b5180ca..4819e2a 100644
--- a/gst/gstmemory.h
+++ b/gst/gstmemory.h
@@ -29,7 +29,8 @@
G_BEGIN_DECLS
-#define GST_TYPE_MEMORY (gst_memory_get_type())
+GST_EXPORT GType _gst_memory_type;
+#define GST_TYPE_MEMORY (_gst_memory_type)
GType gst_memory_get_type(void);
typedef struct _GstMemory GstMemory;
diff --git a/gst/gstmessage.c b/gst/gstmessage.c
index 1e6deff..5014016 100644
--- a/gst/gstmessage.c
+++ b/gst/gstmessage.c
@@ -34,18 +34,12 @@
* application using the #GstBus.
*
* The basic use pattern of posting a message on a #GstBus is as follows:
- *
- * <example>
- * <title>Posting a #GstMessage</title>
- * <programlisting>
- * gst_bus_post (bus, gst_message_new_eos());
- * </programlisting>
- * </example>
+ * |[
+ * gst_bus_post (bus, gst_message_new_eos());
+ * ]|
*
* A #GstElement usually posts messages on the bus provided by the parent
* container using gst_element_post_message().
- *
- * Last reviewed on 2005-11-09 (0.9.4)
*/
@@ -109,10 +103,12 @@ static GstMessageQuarks message_quarks[] = {
{GST_MESSAGE_STREAM_START, "stream-start", 0},
{GST_MESSAGE_NEED_CONTEXT, "need-context", 0},
{GST_MESSAGE_HAVE_CONTEXT, "have-context", 0},
+ {GST_MESSAGE_DEVICE_ADDED, "device-added", 0},
+ {GST_MESSAGE_DEVICE_REMOVED, "device-removed", 0},
{0, NULL, 0}
};
-static GType _gst_message_type = 0;
+GType _gst_message_type = 0;
GST_DEFINE_MINI_OBJECT_TYPE (GstMessage, gst_message);
void
@@ -265,7 +261,7 @@ gst_message_init (GstMessageImpl * message, GstMessageType type,
*
* Create a new custom-typed message. This can be used for anything not
* handled by other message-specific functions to pass a message to the
- * app. The structure field can be NULL.
+ * app. The structure field can be %NULL.
*
* Returns: (transfer full): The new message.
*
@@ -384,7 +380,7 @@ gst_message_new_eos (GstObject * src)
*
* Create a new error message. The message will copy @error and
* @debug. This message is posted by element when a fatal event
- * occured. The pipeline will probably (partially) stop. The application
+ * occurred. The pipeline will probably (partially) stop. The application
* receiving this message should stop the pipeline.
*
* Returns: (transfer full): the new error message.
@@ -586,7 +582,7 @@ gst_message_new_state_dirty (GstObject * src)
* gst_message_new_clock_provide:
* @src: (transfer none): the object originating the message.
* @clock: (transfer none): the clock it provides
- * @ready: TRUE if the sender can provide a clock
+ * @ready: %TRUE if the sender can provide a clock
*
* Create a clock provide message. This message is posted whenever an
* element is ready to provide a clock or lost its ability to provide
@@ -649,7 +645,7 @@ gst_message_new_clock_lost (GstObject * src, GstClock * clock)
* @clock: (transfer none): the new selected clock
*
* Create a new clock message. This message is posted whenever the
- * pipeline selectes a new clock for the pipeline.
+ * pipeline selects a new clock for the pipeline.
*
* Returns: (transfer full): The new new clock message.
*
@@ -795,7 +791,7 @@ gst_message_new_application (GstObject * src, GstStructure * structure)
* Create a new element-specific message. This is meant as a generic way of
* allowing one-way communication from an element to an application, for example
* "the firewire cable was unplugged". The format of the message should be
- * documented in the element's documentation. The structure field can be NULL.
+ * documented in the element's documentation. The structure field can be %NULL.
*
* Returns: (transfer full): The new element message.
*
@@ -912,7 +908,7 @@ gst_message_new_latency (GstObject * src)
* changed. A typical use case would be an audio server that wants to pause the
* pipeline because a higher priority stream is being played.
*
- * Returns: (transfer full): the new requst state message.
+ * Returns: (transfer full): the new request state message.
*
* MT safe.
*/
@@ -1060,11 +1056,11 @@ gst_message_set_buffering_stats (GstMessage * message, GstBufferingMode mode,
/**
* gst_message_parse_buffering_stats:
* @message: A valid #GstMessage of type GST_MESSAGE_BUFFERING.
- * @mode: (out) (allow-none): a buffering mode, or NULL
- * @avg_in: (out) (allow-none): the average input rate, or NULL
- * @avg_out: (out) (allow-none): the average output rate, or NULL
+ * @mode: (out) (allow-none): a buffering mode, or %NULL
+ * @avg_in: (out) (allow-none): the average input rate, or %NULL
+ * @avg_out: (out) (allow-none): the average output rate, or %NULL
* @buffering_left: (out) (allow-none): amount of buffering time left in
- * milliseconds, or NULL
+ * milliseconds, or %NULL
*
* Extracts the buffering stats values from @message.
*/
@@ -1097,9 +1093,9 @@ gst_message_parse_buffering_stats (GstMessage * message,
/**
* gst_message_parse_state_changed:
* @message: a valid #GstMessage of type GST_MESSAGE_STATE_CHANGED
- * @oldstate: (out) (allow-none): the previous state, or NULL
- * @newstate: (out) (allow-none): the new (current) state, or NULL
- * @pending: (out) (allow-none): the pending (target) state, or NULL
+ * @oldstate: (out) (allow-none): the previous state, or %NULL
+ * @newstate: (out) (allow-none): the new (current) state, or %NULL
+ * @pending: (out) (allow-none): the pending (target) state, or %NULL
*
* Extracts the old and new states from the GstMessage.
*
@@ -1152,8 +1148,8 @@ gst_message_parse_state_changed (GstMessage * message,
* gst_message_parse_clock_provide:
* @message: A valid #GstMessage of type GST_MESSAGE_CLOCK_PROVIDE.
* @clock: (out) (allow-none) (transfer none): a pointer to hold a clock
- * object, or NULL
- * @ready: (out) (allow-none): a pointer to hold the ready flag, or NULL
+ * object, or %NULL
+ * @ready: (out) (allow-none): a pointer to hold the ready flag, or %NULL
*
* Extracts the clock and ready flag from the GstMessage.
* The clock object returned remains valid until the message is freed.
@@ -1285,7 +1281,7 @@ gst_message_parse_structure_change (GstMessage * message,
* @message: A valid #GstMessage of type GST_MESSAGE_ERROR.
* @gerror: (out) (allow-none) (transfer full): location for the GError
* @debug: (out) (allow-none) (transfer full): location for the debug message,
- * or NULL
+ * or %NULL
*
* Extracts the GError and debug string from the GstMessage. The values returned
* in the output arguments are copies; the caller must free them when done.
@@ -1329,7 +1325,7 @@ gst_message_parse_error (GstMessage * message, GError ** gerror, gchar ** debug)
* @message: A valid #GstMessage of type GST_MESSAGE_WARNING.
* @gerror: (out) (allow-none) (transfer full): location for the GError
* @debug: (out) (allow-none) (transfer full): location for the debug message,
- * or NULL
+ * or %NULL
*
* Extracts the GError and debug string from the GstMessage. The values returned
* in the output arguments are copies; the caller must free them when done.
@@ -1353,7 +1349,7 @@ gst_message_parse_warning (GstMessage * message, GError ** gerror,
* @message: A valid #GstMessage of type GST_MESSAGE_INFO.
* @gerror: (out) (allow-none) (transfer full): location for the GError
* @debug: (out) (allow-none) (transfer full): location for the debug message,
- * or NULL
+ * or %NULL
*
* Extracts the GError and debug string from the GstMessage. The values returned
* in the output arguments are copies; the caller must free them when done.
@@ -1374,8 +1370,8 @@ gst_message_parse_info (GstMessage * message, GError ** gerror, gchar ** debug)
/**
* gst_message_parse_segment_start:
* @message: A valid #GstMessage of type GST_MESSAGE_SEGMENT_START.
- * @format: (out) (allow-none): Result location for the format, or NULL
- * @position: (out) (allow-none): Result location for the position, or NULL
+ * @format: (out) (allow-none): Result location for the format, or %NULL
+ * @position: (out) (allow-none): Result location for the position, or %NULL
*
* Extracts the position and format from the segment start message.
*
@@ -1404,8 +1400,8 @@ gst_message_parse_segment_start (GstMessage * message, GstFormat * format,
/**
* gst_message_parse_segment_done:
* @message: A valid #GstMessage of type GST_MESSAGE_SEGMENT_DONE.
- * @format: (out) (allow-none): Result location for the format, or NULL
- * @position: (out) (allow-none): Result location for the position, or NULL
+ * @format: (out) (allow-none): Result location for the format, or %NULL
+ * @position: (out) (allow-none): Result location for the position, or %NULL
*
* Extracts the position and format from the segment done message.
*
@@ -1434,7 +1430,7 @@ gst_message_parse_segment_done (GstMessage * message, GstFormat * format,
/**
* gst_message_parse_async_done:
* @message: A valid #GstMessage of type GST_MESSAGE_ASYNC_DONE.
- * @running_time: (out) (allow-none): Result location for the running_time or NULL
+ * @running_time: (out) (allow-none): Result location for the running_time or %NULL
*
* Extract the running_time from the async_done message.
*
@@ -1458,7 +1454,7 @@ gst_message_parse_async_done (GstMessage * message, GstClockTime * running_time)
/**
* gst_message_parse_request_state:
* @message: A valid #GstMessage of type GST_MESSAGE_REQUEST_STATE.
- * @state: (out) (allow-none): Result location for the requested state or NULL
+ * @state: (out) (allow-none): Result location for the requested state or %NULL
*
* Extract the requested state from the request_state message.
*
@@ -1600,7 +1596,7 @@ gst_message_get_stream_status_object (GstMessage * message)
* @eos: the step caused EOS
*
* This message is posted by elements when they complete a part, when @intermediate set
- * to TRUE, or a complete step operation.
+ * to %TRUE, or a complete step operation.
*
* @duration will contain the amount of time (in GST_FORMAT_TIME) of the stepped
* @amount of media in format @format.
@@ -1679,12 +1675,12 @@ gst_message_parse_step_done (GstMessage * message, GstFormat * format,
* This message is posted by elements when they accept or activate a new step
* event for @amount in @format.
*
- * @active is set to FALSE when the element accepted the new step event and has
+ * @active is set to %FALSE when the element accepted the new step event and has
* queued it for execution in the streaming threads.
*
- * @active is set to TRUE when the element has activated the step operation and
+ * @active is set to %TRUE when the element has activated the step operation and
* is now ready to start executing the step in the streaming thread. After this
- * message is emited, the application can queue a new step operation in the
+ * message is emitted, the application can queue a new step operation in the
* element.
*
* Returns: (transfer full): The new step_start message.
@@ -2064,7 +2060,7 @@ gst_message_new_toc (GstObject * src, GstToc * toc, gboolean updated)
* @toc: (out) (transfer full): return location for the TOC.
* @updated: (out): return location for the updated flag.
*
- * Extract thef TOC from the #GstMessage. The TOC returned in the
+ * Extract the TOC from the #GstMessage. The TOC returned in the
* output argument is a copy; the caller must free it with
* gst_toc_unref() when done.
*
@@ -2111,7 +2107,7 @@ gst_message_new_reset_time (GstObject * src, GstClockTime running_time)
* gst_message_parse_reset_time:
* @message: A valid #GstMessage of type GST_MESSAGE_RESET_TIME.
* @running_time: (out) (allow-none): Result location for the running_time or
- * NULL
+ * %NULL
*
* Extract the running-time from the RESET_TIME message.
*
@@ -2192,7 +2188,7 @@ gst_message_set_group_id (GstMessage * message, guint group_id)
* gst_message_parse_group_id:
* @message: A valid #GstMessage of type GST_MESSAGE_STREAM_START.
* @group_id: (out) (allow-none): Result location for the group id or
- * NULL
+ * %NULL
*
* Extract the group from the STREAM_START message.
*
@@ -2256,7 +2252,7 @@ gst_message_new_need_context (GstObject * src, const gchar * context_type)
/**
* gst_message_parse_context_type:
* @message: a GST_MESSAGE_NEED_CONTEXT type message
- * @context_type: (out) (allow-none): the context type, or NULL
+ * @context_type: (out) (allow-none): the context type, or %NULL
*
* Parse a context type from an existing GST_MESSAGE_NEED_CONTEXT message.
*
@@ -2315,7 +2311,7 @@ gst_message_new_have_context (GstObject * src, GstContext * context)
* gst_message_parse_have_context:
* @message: A valid #GstMessage of type GST_MESSAGE_HAVE_CONTEXT.
* @context: (out) (transfer full) (allow-none): Result location for the
- * context or NULL
+ * context or %NULL
*
* Extract the context from the HAVE_CONTEXT message.
*
@@ -2333,3 +2329,107 @@ gst_message_parse_have_context (GstMessage * message, GstContext ** context)
gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
GST_QUARK (CONTEXT), GST_TYPE_CONTEXT, context, NULL);
}
+
+/**
+ * gst_message_new_device_added:
+ * @src: The #GstObject that created the message
+ * @device: (transfer none): The new #GstDevice
+ *
+ * Creates a new device-added message. The device-added message is produced by
+ * #GstDeviceMonitor or a #GstGlobalDeviceMonitor. They announce the appearance
+ * of monitored devices.
+ *
+ * Returns: a newly allocated #GstMessage
+ *
+ * Since: 1.4
+ */
+GstMessage *
+gst_message_new_device_added (GstObject * src, GstDevice * device)
+{
+ GstMessage *message;
+ GstStructure *structure;
+
+ g_return_val_if_fail (device != NULL, NULL);
+ g_return_val_if_fail (GST_IS_DEVICE (device), NULL);
+
+ structure = gst_structure_new_id (GST_QUARK (MESSAGE_DEVICE_ADDED),
+ GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
+ message = gst_message_new_custom (GST_MESSAGE_DEVICE_ADDED, src, structure);
+
+ return message;
+}
+
+/**
+ * gst_message_parse_device_added:
+ * @message: a #GstMessage of type %GST_MESSAGE_DEVICE_ADDED
+ * @device: (out) (allow-none) (transfer none): A location where to store a
+ * pointer to the new #GstDevice, or %NULL
+ *
+ * Parses a device-added message. The device-added message is produced by
+ * #GstDeviceMonitor or a #GstGlobalDeviceMonitor. It announces the appearance
+ * of monitored devices.
+ *
+ * Since: 1.4
+ */
+void
+gst_message_parse_device_added (GstMessage * message, GstDevice ** device)
+{
+ g_return_if_fail (GST_IS_MESSAGE (message));
+ g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DEVICE_ADDED);
+
+ if (device)
+ gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
+ GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
+}
+
+/**
+ * gst_message_new_device_removed:
+ * @src: The #GstObject that created the message
+ * @device: (transfer none): The removed #GstDevice
+ *
+ * Creates a new device-removed message. The device-removed message is produced
+ * by #GstDeviceMonitor or a #GstGlobalDeviceMonitor. They announce the
+ * disappearance of monitored devices.
+ *
+ * Returns: a newly allocated #GstMessage
+ *
+ * Since: 1.4
+ */
+GstMessage *
+gst_message_new_device_removed (GstObject * src, GstDevice * device)
+{
+ GstMessage *message;
+ GstStructure *structure;
+
+ g_return_val_if_fail (device != NULL, NULL);
+ g_return_val_if_fail (GST_IS_DEVICE (device), NULL);
+
+ structure = gst_structure_new_id (GST_QUARK (MESSAGE_DEVICE_REMOVED),
+ GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
+ message = gst_message_new_custom (GST_MESSAGE_DEVICE_REMOVED, src, structure);
+
+ return message;
+}
+
+/**
+ * gst_message_parse_device_removed:
+ * @message: a #GstMessage of type %GST_MESSAGE_DEVICE_REMOVED
+ * @device: (out) (allow-none) (transfer none): A location where to store a
+ * pointer to the removed #GstDevice, or %NULL
+ *
+ * Parses a device-removed message. The device-removed message is produced by
+ * #GstDeviceMonitor or a #GstGlobalDeviceMonitor. It announces the
+ * disappearance of monitored devices.
+ *
+ * Since: 1.4
+ */
+void
+gst_message_parse_device_removed (GstMessage * message, GstDevice ** device)
+{
+ g_return_if_fail (GST_IS_MESSAGE (message));
+ g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DEVICE_REMOVED);
+
+ if (device)
+ gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
+ GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
+}
diff --git a/gst/gstmessage.h b/gst/gstmessage.h
index 38e6d7e..7433edc 100644
--- a/gst/gstmessage.h
+++ b/gst/gstmessage.h
@@ -33,11 +33,11 @@ typedef struct _GstMessage GstMessage;
* only receive this message in the PLAYING state and every time it sets a
* pipeline to PLAYING that is in the EOS state. The application can perform a
* flushing seek in the pipeline, which will undo the EOS state again.
- * @GST_MESSAGE_ERROR: an error occured. When the application receives an error
+ * @GST_MESSAGE_ERROR: an error occurred. When the application receives an error
* message it should stop playback of the pipeline and not assume that more
* data will be played.
- * @GST_MESSAGE_WARNING: a warning occured.
- * @GST_MESSAGE_INFO: an info message occured
+ * @GST_MESSAGE_WARNING: a warning occurred.
+ * @GST_MESSAGE_INFO: an info message occurred
* @GST_MESSAGE_TAG: a tag was found.
* @GST_MESSAGE_BUFFERING: the pipeline is buffering. When the application
* receives a buffering message in the PLAYING state for a non-live pipeline it
@@ -99,6 +99,15 @@ typedef struct _GstMessage GstMessage;
* the URI for the next title has been set).
* @GST_MESSAGE_NEED_CONTEXT: Message indicating that an element wants a specific context (Since 1.2)
* @GST_MESSAGE_HAVE_CONTEXT: Message indicating that an element created a context (Since 1.2)
+ * @GST_MESSAGE_EXTENDED: Message is an extended message type (see below).
+ * These extended message IDs can't be used directly with mask-based API
+ * like gst_bus_poll() or gst_bus_timed_pop_filtered(), but you can still
+ * filter for GST_MESSAGE_EXTENDED and then check the result for the
+ * specific type. (Since 1.4)
+ * @GST_MESSAGE_DEVICE_ADDED: Message indicating a #GstDevice was added to
+ * a #GstDeviceMonitor (Since 1.4)
+ * @GST_MESSAGE_DEVICE_REMOVED: Message indicating a #GstDevice was removed
+ * from a #GstDeviceMonitor (Since 1.4)
* @GST_MESSAGE_ANY: mask for all of the above messages.
*
* The different message types that are available.
@@ -106,6 +115,7 @@ typedef struct _GstMessage GstMessage;
/* NOTE: keep in sync with quark registration in gstmessage.c
* NOTE: keep GST_MESSAGE_ANY a valid gint to avoid compiler warnings.
*/
+/* FIXME: 2.0: Make it NOT flags, just a regular 1,2,3,4.. enumeration */
typedef enum
{
GST_MESSAGE_UNKNOWN = 0,
@@ -140,6 +150,9 @@ typedef enum
GST_MESSAGE_STREAM_START = (1 << 28),
GST_MESSAGE_NEED_CONTEXT = (1 << 29),
GST_MESSAGE_HAVE_CONTEXT = (1 << 30),
+ GST_MESSAGE_EXTENDED = (1 << 31),
+ GST_MESSAGE_DEVICE_ADDED = GST_MESSAGE_EXTENDED + 1,
+ GST_MESSAGE_DEVICE_REMOVED = GST_MESSAGE_EXTENDED + 2,
GST_MESSAGE_ANY = ~0
} GstMessageType;
@@ -150,8 +163,11 @@ typedef enum
#include <gst/gststructure.h>
#include <gst/gstquery.h>
#include <gst/gsttoc.h>
+#include <gst/gstdevice.h>
-#define GST_TYPE_MESSAGE (gst_message_get_type())
+GST_EXPORT GType _gst_message_type;
+
+#define GST_TYPE_MESSAGE (_gst_message_type)
#define GST_IS_MESSAGE(obj) (GST_IS_MINI_OBJECT_TYPE (obj, GST_TYPE_MESSAGE))
#define GST_MESSAGE_CAST(obj) ((GstMessage*)(obj))
#define GST_MESSAGE(obj) (GST_MESSAGE_CAST(obj))
@@ -174,6 +190,15 @@ typedef enum
*/
#define GST_MESSAGE_TYPE(message) (GST_MESSAGE_CAST(message)->type)
/**
+ * GST_MESSAGE_TYPE_IS_EXTENDED:
+ * @message: a #GstMessage
+ *
+ * Check if the message is in the extended message group
+ * (Since 1.4)
+ */
+#define GST_MESSAGE_TYPE_IS_EXTENDED(message) (!!(GST_MESSAGE_CAST(message)->type & GST_MESSAGE_EXTENDED))
+
+/**
* GST_MESSAGE_TYPE_NAME:
* @message: a #GstMessage
*
@@ -260,7 +285,7 @@ typedef enum {
* posted on the bus.
*
* The type of a %GST_MESSAGE_PROGRESS. The progress messages inform the
- * application of the status of assynchronous tasks.
+ * application of the status of asynchronous tasks.
*/
typedef enum {
GST_PROGRESS_TYPE_START = 0,
@@ -389,9 +414,9 @@ gst_message_copy (const GstMessage * msg)
* in some cases), and the reference counts are updated appropriately (the old
* message is unreffed, the new one is reffed).
*
- * Either @new_message or the #GstMessage pointed to by @old_message may be NULL.
+ * Either @new_message or the #GstMessage pointed to by @old_message may be %NULL.
*
- * Returns: TRUE if @new_message was different from @old_message
+ * Returns: %TRUE if @new_message was different from @old_message
*/
#ifdef _FOOL_GTK_DOC_
G_INLINE_FUNC gboolean gst_message_replace (GstMessage **old_message, GstMessage *new_message);
@@ -572,6 +597,15 @@ gboolean gst_message_parse_context_type (GstMessage * message, const gch
GstMessage * gst_message_new_have_context (GstObject * src, GstContext *context) G_GNUC_MALLOC;
void gst_message_parse_have_context (GstMessage *message, GstContext **context);
+/* DEVICE_ADDED */
+GstMessage * gst_message_new_device_added (GstObject * src, GstDevice * device) G_GNUC_MALLOC;
+void gst_message_parse_device_added (GstMessage * message, GstDevice ** device);
+
+/* DEVICE_REMOVED */
+GstMessage * gst_message_new_device_removed (GstObject * src, GstDevice * device) G_GNUC_MALLOC;
+void gst_message_parse_device_removed (GstMessage * message, GstDevice ** device);
+
+
G_END_DECLS
#endif /* __GST_MESSAGE_H__ */
diff --git a/gst/gstmeta.c b/gst/gstmeta.c
index 31f3ff1..0e0aca1 100644
--- a/gst/gstmeta.c
+++ b/gst/gstmeta.c
@@ -42,8 +42,6 @@
*
* See #GstBuffer for how the metadata can be added, retrieved and removed from
* buffers.
- *
- * Last reviewed on 2012-03-28 (0.11.3)
*/
#include "gst_private.h"
@@ -207,7 +205,7 @@ gst_meta_register (GType api, const gchar * impl, gsize size,
* Lookup a previously registered meta info structure by its implementation name
* @impl.
*
- * Returns: (transfer none): a #GstMetaInfo with @impl, or #NULL when no such
+ * Returns: (transfer none): a #GstMetaInfo with @impl, or %NULL when no such
* metainfo exists.
*/
const GstMetaInfo *
diff --git a/gst/gstmeta.h b/gst/gstmeta.h
index d294126..4283f8e 100644
--- a/gst/gstmeta.h
+++ b/gst/gstmeta.h
@@ -83,6 +83,7 @@ typedef enum {
/**
* GST_META_TAG_MEMORY_STR:
+ *
* This metadata stays relevant as long as memory layout is unchanged.
*
* Since: 1.2
@@ -174,8 +175,8 @@ typedef gboolean (*GstMetaTransformFunction) (GstBuffer *transbuf,
/**
* GstMetaInfo:
- * @api: tag indentifying the metadata structure and api
- * @type: type indentifying the implementor of the api
+ * @api: tag identifying the metadata structure and api
+ * @type: type identifying the implementor of the api
* @size: size of the metadata
* @init_func: function for initializing the metadata
* @free_func: function for freeing the metadata
@@ -221,7 +222,9 @@ GST_EXPORT GQuark _gst_meta_tag_memory;
* Deprecated: The GQuarks are not exported by any public API, use
* GST_META_TAG_MEMORY_STR instead.
*/
+#ifndef GST_DISABLE_DEPRECATED
#define GST_META_TAG_MEMORY (_gst_meta_tag_memory)
+#endif
G_END_DECLS
diff --git a/gst/gstminiobject.c b/gst/gstminiobject.c
index 25efc08..bece06a 100644
--- a/gst/gstminiobject.c
+++ b/gst/gstminiobject.c
@@ -47,8 +47,6 @@
*
* A weak reference can be added and remove with gst_mini_object_weak_ref()
* and gst_mini_object_weak_unref() respectively.
- *
- * Last reviewed on 2012-06-15 (0.11.93)
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -106,9 +104,9 @@ _priv_gst_mini_object_initialize (void)
* @mini_object: a #GstMiniObject
* @flags: initial #GstMiniObjectFlags
* @type: the #GType of the mini-object to create
- * @copy_func: (allow-none): the copy function, or NULL
- * @dispose_func: (allow-none): the dispose function, or NULL
- * @free_func: (allow-none): the free function or NULL
+ * @copy_func: (allow-none): the copy function, or %NULL
+ * @dispose_func: (allow-none): the dispose function, or %NULL
+ * @free_func: (allow-none): the free function or %NULL
*
* Initializes a mini-object with the desired type and copy/dispose/free
* functions.
@@ -281,7 +279,7 @@ gst_mini_object_unlock (GstMiniObject * object, GstLockFlags flags)
* Modification of a mini-object should only be done after verifying that it
* is writable.
*
- * Returns: TRUE if the object is writable.
+ * Returns: %TRUE if the object is writable.
*/
gboolean
gst_mini_object_is_writable (const GstMiniObject * mini_object)
@@ -336,7 +334,7 @@ gst_mini_object_make_writable (GstMiniObject * mini_object)
*
* Increase the reference count of the mini-object.
*
- * Note that the refcount affects the writeability
+ * Note that the refcount affects the writability
* of @mini-object, see gst_mini_object_is_writable(). It is
* important to note that keeping additional references to
* GstMiniObject instances can potentially increase the number
@@ -479,9 +477,9 @@ gst_mini_object_unref (GstMiniObject * mini_object)
* The reference count of @olddata is decreased and the reference count of
* @newdata is increased.
*
- * Either @newdata and the value pointed to by @olddata may be NULL.
+ * Either @newdata and the value pointed to by @olddata may be %NULL.
*
- * Returns: TRUE if @newdata was different from @olddata
+ * Returns: %TRUE if @newdata was different from @olddata
*/
gboolean
gst_mini_object_replace (GstMiniObject ** olddata, GstMiniObject * newdata)
@@ -520,7 +518,7 @@ gst_mini_object_replace (GstMiniObject ** olddata, GstMiniObject * newdata)
* @olddata: (inout) (transfer full): pointer to a pointer to a mini-object to
* be stolen
*
- * Replace the current #GstMiniObject pointer to by @olddata with NULL and
+ * Replace the current #GstMiniObject pointer to by @olddata with %NULL and
* return the old value.
*
* Returns: the #GstMiniObject at @oldata
@@ -556,9 +554,9 @@ gst_mini_object_steal (GstMiniObject ** olddata)
* except that it does not increase the refcount of @newdata and thus
* takes ownership of @newdata.
*
- * Either @newdata and the value pointed to by @olddata may be NULL.
+ * Either @newdata and the value pointed to by @olddata may be %NULL.
*
- * Returns: TRUE if @newdata was different from @olddata
+ * Returns: %TRUE if @newdata was different from @olddata
*/
gboolean
gst_mini_object_take (GstMiniObject ** olddata, GstMiniObject * newdata)
@@ -645,12 +643,12 @@ gst_mini_object_weak_unref (GstMiniObject * object,
* needs to be freed
*
* This sets an opaque, named pointer on a miniobject.
- * The name is specified through a #GQuark (retrived e.g. via
+ * The name is specified through a #GQuark (retrieved e.g. via
* g_quark_from_static_string()), and the pointer
* can be gotten back from the @object with gst_mini_object_get_qdata()
* until the @object is disposed.
* Setting a previously set user data pointer, overrides (frees)
- * the old pointer set, using #NULL as pointer essentially
+ * the old pointer set, using %NULL as pointer essentially
* removes the data stored.
*
* @destroy may be specified which is called with @data as argument
diff --git a/gst/gstminiobject.h b/gst/gstminiobject.h
index 7ae012d..bd56553 100644
--- a/gst/gstminiobject.h
+++ b/gst/gstminiobject.h
@@ -62,7 +62,7 @@ typedef gboolean (*GstMiniObjectDisposeFunction) (GstMiniObject *obj);
* GstMiniObjectFreeFunction:
* @obj: MiniObject to free
*
- * Virtual function prototype for methods to free ressources used by
+ * Virtual function prototype for methods to free resources used by
* mini-objects.
*/
typedef void (*GstMiniObjectFreeFunction) (GstMiniObject *obj);
@@ -114,7 +114,7 @@ typedef void (*GstMiniObjectNotify) (gpointer user_data, GstMiniObject * obj);
* @obj: MiniObject to unset flag in.
* @flag: Flag to set, must be a single bit in guint32.
*
- * This macro usets the given bits.
+ * This macro unsets the given bits.
*/
#define GST_MINI_OBJECT_FLAG_UNSET(obj,flag) (GST_MINI_OBJECT_FLAGS (obj) &= ~(flag))
diff --git a/gst/gstobject.c b/gst/gstobject.c
index 3300464..b997db6 100644
--- a/gst/gstobject.c
+++ b/gst/gstobject.c
@@ -30,11 +30,11 @@
* #GInitiallyUnowned. It is an abstract class that is not very usable on its own.
*
* #GstObject gives us basic refcounting, parenting functionality and locking.
- * Most of the function are just extended for special GStreamer needs and can be
+ * Most of the functions are just extended for special GStreamer needs and can be
* found under the same name in the base class of #GstObject which is #GObject
* (e.g. g_object_ref() becomes gst_object_ref()).
*
- * Since #GstObject dereives from #GInitiallyUnowned, it also inherits the
+ * Since #GstObject derives from #GInitiallyUnowned, it also inherits the
* floating reference. Be aware that functions such as gst_bin_add() and
* gst_element_add_pad() take ownership of the floating reference.
*
@@ -45,10 +45,10 @@
* <refsect2>
* <title>controlled properties</title>
* <para>
- * Controlled properties offers a lightweight way to adjust gobject
- * properties over stream-time. It works by using time-stamped value pairs that
- * are queued for element-properties. At run-time the elements continuously pull
- * values changes for the current stream-time.
+ * Controlled properties offers a lightweight way to adjust gobject properties
+ * over stream-time. It works by using time-stamped value pairs that are queued
+ * for element-properties. At run-time the elements continuously pull value
+ * changes for the current stream-time.
*
* What needs to be changed in a #GstElement?
* Very little - it is just two steps to make a plugin controllable!
@@ -60,8 +60,8 @@
* <listitem><para>
* when processing data (get, chain, loop function) at the beginning call
* gst_object_sync_values(element,timestamp).
- * This will made the controller to update all gobject properties that are under
- * control with the current values based on timestamp.
+ * This will make the controller update all GObject properties that are
+ * under its control with the current values based on the timestamp.
* </para></listitem>
* </orderedlist>
*
@@ -88,8 +88,6 @@
* </orderedlist>
* </para>
* </refsect2>
- *
- * Last reviewed on 2012-03-29 (0.11.3)
*/
#include "gst_private.h"
@@ -172,6 +170,15 @@ gst_object_class_init (GstObjectClass * klass)
g_param_spec_string ("name", "Name", "The name of the object", NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+ /**
+ * GstObject:parent:
+ *
+ * The parent of the object. Please note, that when changing the 'parent'
+ * property, we don't emit #GObject::notify and #GstObject::deep-notify
+ * signals due to locking issues. In some cases one can use
+ * #GstBin::element-added or #GstBin::element-removed signals on the parent to
+ * achieve a similar effect.
+ */
properties[PROP_PARENT] =
g_param_spec_object ("parent", "Parent", "The parent of the object",
GST_TYPE_OBJECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
@@ -311,9 +318,9 @@ gst_object_ref_sink (gpointer object)
* The reference count of @oldobj is decreased and the reference count of
* @newobj is increased.
*
- * Either @newobj and the value pointed to by @oldobj may be NULL.
+ * Either @newobj and the value pointed to by @oldobj may be %NULL.
*
- * Returns: TRUE if @newobj was different from @oldobj
+ * Returns: %TRUE if @newobj was different from @oldobj
*/
gboolean
gst_object_replace (GstObject ** oldobj, GstObject * newobj)
@@ -474,7 +481,7 @@ gst_object_dispatch_properties_changed (GObject * object,
* @orig: a #GstObject that initiated the notify.
* @pspec: a #GParamSpec of the property.
* @excluded_props: (array zero-terminated=1) (element-type gchar*) (allow-none):
- * a set of user-specified properties to exclude or NULL to show
+ * a set of user-specified properties to exclude or %NULL to show
* all changes.
*
* A default deep_notify signal callback for an object. The user data
@@ -584,12 +591,12 @@ had_parent:
* @name: new name of object
*
* Sets the name of @object, or gives @object a guaranteed unique
- * name (if @name is NULL).
+ * name (if @name is %NULL).
* This function makes a copy of the provided name, so the caller
* retains ownership of the name it sent.
*
- * Returns: TRUE if the name could be set. Since Objects that have
- * a parent cannot be renamed, this function returns FALSE in those
+ * Returns: %TRUE if the name could be set. Since Objects that have
+ * a parent cannot be renamed, this function returns %FALSE in those
* cases.
*
* MT safe. This function grabs and releases @object's LOCK.
@@ -637,7 +644,7 @@ had_parent:
*
* Returns a copy of the name of @object.
* Caller should g_free() the return value after usage.
- * For a nameless object, this returns NULL, which you can safely g_free()
+ * For a nameless object, this returns %NULL, which you can safely g_free()
* as well.
*
* Free-function: g_free
@@ -668,7 +675,7 @@ gst_object_get_name (GstObject * object)
* Sets the parent of @object to @parent. The object's reference count will
* be incremented, and any floating reference will be removed (see gst_object_ref_sink()).
*
- * Returns: TRUE if @parent could be set or FALSE when @object
+ * Returns: %TRUE if @parent could be set or %FALSE when @object
* already had a parent or @object and @parent are the same.
*
* MT safe. Grabs and releases @object's LOCK.
@@ -691,9 +698,11 @@ gst_object_set_parent (GstObject * object, GstObject * parent)
gst_object_ref_sink (object);
GST_OBJECT_UNLOCK (object);
- /* FIXME, this does not work, the deep notify takes the lock from the parent
- * object and deadlocks when the parent holds its lock when calling this
- * function (like _element_add_pad()) */
+ /* FIXME-2.0: this does not work, the deep notify takes the lock from the
+ * parent object and deadlocks when the parent holds its lock when calling
+ * this function (like _element_add_pad()), we need to use a GRecMutex
+ * for locking the parent instead.
+ */
/* g_object_notify_by_pspec ((GObject *)object, properties[PROP_PARENT]); */
return TRUE;
@@ -715,7 +724,7 @@ had_parent:
* Returns the parent of @object. This function increases the refcount
* of the parent object so you should gst_object_unref() it after usage.
*
- * Returns: (transfer full): parent of @object, this can be NULL if @object
+ * Returns: (transfer full): parent of @object, this can be %NULL if @object
* has no parent. unref after usage.
*
* MT safe. Grabs and releases @object's LOCK.
@@ -776,7 +785,7 @@ gst_object_unparent (GstObject * object)
* Check if @object has an ancestor @ancestor somewhere up in
* the hierarchy. One can e.g. check if a #GstElement is inside a #GstPipeline.
*
- * Returns: TRUE if @ancestor is an ancestor of @object.
+ * Returns: %TRUE if @ancestor is an ancestor of @object.
*
* MT safe. Grabs and releases @object's locks.
*/
@@ -813,10 +822,10 @@ gst_object_has_ancestor (GstObject * object, GstObject * ancestor)
* does not do any locking of any kind. You might want to protect the
* provided list with the lock of the owner of the list. This function
* will lock each #GstObject in the list to compare the name, so be
- * carefull when passing a list with a locked object.
+ * careful when passing a list with a locked object.
*
- * Returns: TRUE if a #GstObject named @name does not appear in @list,
- * FALSE if it does.
+ * Returns: %TRUE if a #GstObject named @name does not appear in @list,
+ * %FALSE if it does.
*
* MT safe. Grabs and releases the LOCK of each object in the list.
*/
@@ -921,7 +930,7 @@ gst_object_get_path_string (GstObject * object)
path = g_strdup ("");
/* first walk the object hierarchy to build a list of the parents,
- * be carefull here with refcounting. */
+ * be careful here with refcounting. */
do {
if (GST_IS_OBJECT (object)) {
parent = gst_object_get_parent (object);
@@ -1136,8 +1145,8 @@ gst_object_set_control_bindings_disabled (GstObject * object, gboolean disabled)
* @disabled: boolean that specifies whether to disable the controller
* or not.
*
- * This function is used to disable the #GstController on a property for
- * some time, i.e. gst_controller_sync_values() will do nothing for the
+ * This function is used to disable the control bindings on a property for
+ * some time, i.e. gst_object_sync_values() will do nothing for the
* property.
*/
void
diff --git a/gst/gstobject.h b/gst/gstobject.h
index 209fe6c..86c5715 100644
--- a/gst/gstobject.h
+++ b/gst/gstobject.h
@@ -89,7 +89,7 @@ typedef enum
* @obj: a #GstObject.
*
* This macro will try to obtain a lock on the object, but will return with
- * FALSE if it can't get it immediately.
+ * %FALSE if it can't get it immediately.
*/
#define GST_OBJECT_TRYLOCK(obj) g_mutex_trylock(GST_OBJECT_GET_LOCK(obj))
/**
@@ -145,7 +145,7 @@ typedef enum
* @obj: a #GstObject
* @flag: Flag to set
*
- * This macro usets the given bits.
+ * This macro unsets the given bits.
*/
#define GST_OBJECT_FLAG_UNSET(obj,flag) (GST_OBJECT_FLAGS (obj) &= ~(flag))
diff --git a/gst/gstpad.c b/gst/gstpad.c
index 1261a47..09ce750 100644
--- a/gst/gstpad.c
+++ b/gst/gstpad.c
@@ -38,7 +38,7 @@
* application requests.
*
* Pads without pad templates can be created with gst_pad_new(),
- * which takes a direction and a name as an argument. If the name is NULL,
+ * which takes a direction and a name as an argument. If the name is %NULL,
* then a guaranteed unique name will be assigned to it.
*
* A #GstElement creating a pad will typically use the various
@@ -47,7 +47,7 @@
*
* gst_pad_get_parent() will retrieve the #GstElement that owns the pad.
*
- * After two pads are retrieved from an element with gst_element_get_pad(),
+ * After two pads are retrieved from an element by gst_element_get_static_pad(),
* the pads can be linked with gst_pad_link(). (For quick links,
* you can also use gst_element_link(), which will make the obvious
* link for you if it's straightforward.). Pads can be unlinked again with
@@ -84,8 +84,6 @@
* Convenience functions exist to start, pause and stop the task on a pad with
* gst_pad_start_task(), gst_pad_pause_task() and gst_pad_stop_task()
* respectively.
- *
- * Last reviewed on 2012-03-29 (0.11.3)
*/
#include "gst_private.h"
@@ -125,7 +123,7 @@ enum
/* we have a pending and an active event on the pad. On source pads only the
* active event is used. On sinkpads, events are copied to the pending entry and
- * moved to the active event when the eventfunc returned TRUE. */
+ * moved to the active event when the eventfunc returned %TRUE. */
typedef struct
{
gboolean received;
@@ -136,6 +134,7 @@ struct _GstPadPrivate
{
guint events_cookie;
GArray *events;
+ guint last_cookie;
gint using;
guint probe_list_cookie;
@@ -250,6 +249,38 @@ gst_flow_to_quark (GstFlowReturn ret)
return 0;
}
+/**
+ * gst_pad_link_get_name:
+ * @ret: a #GstPadLinkReturn to get the name of.
+ *
+ * Gets a string representing the given pad-link return.
+ *
+ * Returns: a static string with the name of the pad-link return.
+ *
+ * Since: 1.4
+ */
+const gchar *
+gst_pad_link_get_name (GstPadLinkReturn ret)
+{
+ switch (ret) {
+ case GST_PAD_LINK_OK:
+ return "ok";
+ case GST_PAD_LINK_WRONG_HIERARCHY:
+ return "wrong hierarchy";
+ case GST_PAD_LINK_WAS_LINKED:
+ return "was linked";
+ case GST_PAD_LINK_WRONG_DIRECTION:
+ return "wrong direction";
+ case GST_PAD_LINK_NOFORMAT:
+ return "no common format";
+ case GST_PAD_LINK_NOSCHED:
+ return "incompatible scheduling";
+ case GST_PAD_LINK_REFUSED:
+ return "refused";
+ }
+ g_return_val_if_reached ("unknown");
+}
+
#define _do_init \
{ \
gint i; \
@@ -356,6 +387,9 @@ gst_pad_init (GstPad * pad)
g_hook_list_init (&pad->probes, sizeof (GstProbe));
pad->priv->events = g_array_sized_new (FALSE, TRUE, sizeof (PadEvent), 16);
+ pad->priv->events_cookie = 0;
+ pad->priv->last_cookie = -1;
+ pad->ABI.abi.last_flowret = GST_FLOW_FLUSHING;
}
/* called when setting the pad inactive. It removes all sticky events from
@@ -470,7 +504,7 @@ remove_event_by_type (GstPad * pad, GstEventType type)
}
/* check all events on srcpad against those on sinkpad. All events that are not
- * on sinkpad are marked as received=FALSE and the PENDING_EVENTS is set on the
+ * on sinkpad are marked as received=%FALSE and the PENDING_EVENTS is set on the
* srcpad so that the events will be sent next time */
/* should be called with srcpad and sinkpad LOCKS */
static void
@@ -566,20 +600,35 @@ restart:
/* should be called with LOCK */
static GstEvent *
-apply_pad_offset (GstPad * pad, GstEvent * event)
+apply_pad_offset (GstPad * pad, GstEvent * event, gboolean upstream)
{
/* check if we need to adjust the segment */
if (pad->offset != 0) {
- GstSegment segment;
-
- /* copy segment values */
- gst_event_copy_segment (event, &segment);
- gst_event_unref (event);
+ gint64 offset;
GST_DEBUG_OBJECT (pad, "apply pad offset %" GST_TIME_FORMAT,
GST_TIME_ARGS (pad->offset));
- gst_segment_offset_running_time (&segment, segment.format, pad->offset);
- event = gst_event_new_segment (&segment);
+
+ if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
+ GstSegment segment;
+
+ g_assert (!upstream);
+
+ /* copy segment values */
+ gst_event_copy_segment (event, &segment);
+ gst_event_unref (event);
+
+ gst_segment_offset_running_time (&segment, segment.format, pad->offset);
+ event = gst_event_new_segment (&segment);
+ }
+
+ event = gst_event_make_writable (event);
+ offset = gst_event_get_running_time_offset (event);
+ if (upstream)
+ offset -= pad->offset;
+ else
+ offset += pad->offset;
+ gst_event_set_running_time_offset (event, offset);
}
return event;
}
@@ -721,11 +770,11 @@ gst_pad_get_property (GObject * object, guint prop_id,
* @direction: the #GstPadDirection of the pad.
*
* Creates a new pad with the given name in the given direction.
- * If name is NULL, a guaranteed unique name (across all pads)
+ * If name is %NULL, a guaranteed unique name (across all pads)
* will be assigned.
* This function makes a copy of the name so you can safely free the name.
*
- * Returns: (transfer floating): a new #GstPad, or NULL in case of an error.
+ * Returns: (transfer floating): a new #GstPad, or %NULL in case of an error.
*
* MT safe.
*/
@@ -742,11 +791,11 @@ gst_pad_new (const gchar * name, GstPadDirection direction)
* @name: the name of the element
*
* Creates a new pad with the given name from the given template.
- * If name is NULL, a guaranteed unique name (across all pads)
+ * If name is %NULL, a guaranteed unique name (across all pads)
* will be assigned.
* This function makes a copy of the name so you can safely free the name.
*
- * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
+ * Returns: (transfer floating): a new #GstPad, or %NULL in case of an error.
*/
GstPad *
gst_pad_new_from_template (GstPadTemplate * templ, const gchar * name)
@@ -763,11 +812,11 @@ gst_pad_new_from_template (GstPadTemplate * templ, const gchar * name)
* @name: the name of the element
*
* Creates a new pad with the given name from the given static template.
- * If name is NULL, a guaranteed unique name (across all pads)
+ * If name is %NULL, a guaranteed unique name (across all pads)
* will be assigned.
* This function makes a copy of the name so you can safely free the name.
*
- * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
+ * Returns: (transfer floating): a new #GstPad, or %NULL in case of an error.
*/
GstPad *
gst_pad_new_from_static_template (GstStaticPadTemplate * templ,
@@ -860,6 +909,7 @@ pre_activate (GstPad * pad, GstPadMode new_mode)
GST_OBJECT_LOCK (pad);
GST_DEBUG_OBJECT (pad, "setting PAD_MODE NONE, set flushing");
GST_PAD_SET_FLUSHING (pad);
+ pad->ABI.abi.last_flowret = GST_FLOW_FLUSHING;
GST_PAD_MODE (pad) = new_mode;
/* unlock blocked pads so element can resume and stop */
GST_PAD_BLOCK_BROADCAST (pad);
@@ -871,6 +921,7 @@ pre_activate (GstPad * pad, GstPadMode new_mode)
GST_DEBUG_OBJECT (pad, "setting pad into %s mode, unset flushing",
gst_pad_mode_get_name (new_mode));
GST_PAD_UNSET_FLUSHING (pad);
+ pad->ABI.abi.last_flowret = GST_FLOW_OK;
GST_PAD_MODE (pad) = new_mode;
if (GST_PAD_IS_SINK (pad)) {
GstPad *peer;
@@ -930,9 +981,9 @@ post_activate (GstPad * pad, GstPadMode new_mode)
* function to perform the actual activation.
*
* If not @active, calls gst_pad_activate_mode() with the pad's current mode
- * and a FALSE argument.
+ * and a %FALSE argument.
*
- * Returns: #TRUE if the operation was successful.
+ * Returns: %TRUE if the operation was successful.
*
* MT safe.
*/
@@ -954,6 +1005,8 @@ gst_pad_set_active (GstPad * pad, gboolean active)
if (old == GST_PAD_MODE_NONE) {
GST_DEBUG_OBJECT (pad, "activating pad from none");
ret = (GST_PAD_ACTIVATEFUNC (pad)) (pad, parent);
+ if (ret)
+ pad->ABI.abi.last_flowret = GST_FLOW_OK;
} else {
GST_DEBUG_OBJECT (pad, "pad was active in %s mode",
gst_pad_mode_get_name (old));
@@ -967,6 +1020,8 @@ gst_pad_set_active (GstPad * pad, gboolean active)
GST_DEBUG_OBJECT (pad, "deactivating pad from %s mode",
gst_pad_mode_get_name (old));
ret = gst_pad_activate_mode (pad, old, FALSE);
+ if (ret)
+ pad->ABI.abi.last_flowret = GST_FLOW_FLUSHING;
}
}
@@ -1009,7 +1064,7 @@ failed:
*
* If you don't know what this is, you probably don't want to call it.
*
- * Returns: TRUE if the operation was successful.
+ * Returns: %TRUE if the operation was successful.
*
* MT safe.
*/
@@ -1161,7 +1216,7 @@ failure:
*
* Query if a pad is active
*
- * Returns: TRUE if the pad is active.
+ * Returns: %TRUE if the pad is active.
*
* MT safe.
*/
@@ -1219,8 +1274,10 @@ cleanup_hook (GstPad * pad, GHook * hook)
* Be notified of different states of pads. The provided callback is called for
* every state that matches @mask.
*
- * Returns: an id or 0 on error. The id can be used to remove the probe with
- * gst_pad_remove_probe().
+ * Returns: an id or 0 if no probe is pending. The id can be used to remove the
+ * probe with gst_pad_remove_probe(). When using GST_PAD_PROBE_TYPE_IDLE it can
+ * happend that the probe can be run immediately and if the probe returns
+ * GST_PAD_PROBE_REMOVE this functions returns 0.
*
* MT safe.
*/
@@ -1379,7 +1436,7 @@ not_found:
* last requested state of the pad. It is not certain that the pad
* is actually blocking at this point (see gst_pad_is_blocking()).
*
- * Returns: TRUE if the pad is blocked.
+ * Returns: %TRUE if the pad is blocked.
*
* MT safe.
*/
@@ -1404,7 +1461,7 @@ gst_pad_is_blocked (GstPad * pad)
* Checks if the pad is blocking or not. This is a guaranteed state
* of whether the pad is actually blocking on a #GstBuffer or a #GstEvent.
*
- * Returns: TRUE if the pad is blocking.
+ * Returns: %TRUE if the pad is blocking.
*
* MT safe.
*/
@@ -1496,7 +1553,7 @@ gst_pad_mark_reconfigure (GstPad * pad)
* @p: a #GstPad.
* @f: the #GstPadActivateFunction to set.
*
- * Calls gst_pad_set_activate_function_full() with NULL for the user_data and
+ * Calls gst_pad_set_activate_function_full() with %NULL for the user_data and
* notify.
*/
/**
@@ -1533,7 +1590,7 @@ gst_pad_set_activate_function_full (GstPad * pad,
* @p: a #GstPad.
* @f: the #GstPadActivateModeFunction to set.
*
- * Calls gst_pad_set_activatemode_function_full() with NULL for the user_data and
+ * Calls gst_pad_set_activatemode_function_full() with %NULL for the user_data and
* notify.
*/
/**
@@ -1568,7 +1625,7 @@ gst_pad_set_activatemode_function_full (GstPad * pad,
* @p: a sink #GstPad.
* @f: the #GstPadChainFunction to set.
*
- * Calls gst_pad_set_chain_function_full() with NULL for the user_data and
+ * Calls gst_pad_set_chain_function_full() with %NULL for the user_data and
* notify.
*/
/**
@@ -1603,7 +1660,7 @@ gst_pad_set_chain_function_full (GstPad * pad, GstPadChainFunction chain,
* @p: a sink #GstPad.
* @f: the #GstPadChainListFunction to set.
*
- * Calls gst_pad_set_chain_list_function_full() with NULL for the user_data and
+ * Calls gst_pad_set_chain_list_function_full() with %NULL for the user_data and
* notify.
*/
/**
@@ -1640,7 +1697,7 @@ gst_pad_set_chain_list_function_full (GstPad * pad,
* @p: a source #GstPad.
* @f: the #GstPadGetRangeFunction to set.
*
- * Calls gst_pad_set_getrange_function_full() with NULL for the user_data and
+ * Calls gst_pad_set_getrange_function_full() with %NULL for the user_data and
* notify.
*/
/**
@@ -1676,7 +1733,7 @@ gst_pad_set_getrange_function_full (GstPad * pad, GstPadGetRangeFunction get,
* @p: a #GstPad of either direction.
* @f: the #GstPadEventFunction to set.
*
- * Calls gst_pad_set_event_function_full() with NULL for the user_data and
+ * Calls gst_pad_set_event_function_full() with %NULL for the user_data and
* notify.
*/
/**
@@ -1709,7 +1766,7 @@ gst_pad_set_event_function_full (GstPad * pad, GstPadEventFunction event,
* @p: a #GstPad of either direction.
* @f: the #GstPadQueryFunction to set.
*
- * Calls gst_pad_set_query_function_full() with NULL for the user_data and
+ * Calls gst_pad_set_query_function_full() with %NULL for the user_data and
* notify.
*/
/**
@@ -1742,7 +1799,7 @@ gst_pad_set_query_function_full (GstPad * pad, GstPadQueryFunction query,
* @p: a #GstPad of either direction.
* @f: the #GstPadIterIntLinkFunction to set.
*
- * Calls gst_pad_set_iterate_internal_links_function_full() with NULL
+ * Calls gst_pad_set_iterate_internal_links_function_full() with %NULL
* for the user_data and notify.
*/
/**
@@ -1776,7 +1833,7 @@ gst_pad_set_iterate_internal_links_function_full (GstPad * pad,
* @p: a #GstPad.
* @f: the #GstPadLinkFunction to set.
*
- * Calls gst_pad_set_link_function_full() with NULL
+ * Calls gst_pad_set_link_function_full() with %NULL
* for the user_data and notify.
*/
/**
@@ -1819,7 +1876,7 @@ gst_pad_set_link_function_full (GstPad * pad, GstPadLinkFunction link,
* @p: a #GstPad.
* @f: the #GstPadUnlinkFunction to set.
*
- * Calls gst_pad_set_unlink_function_full() with NULL
+ * Calls gst_pad_set_unlink_function_full() with %NULL
* for the user_data and notify.
*/
/**
@@ -1856,7 +1913,7 @@ gst_pad_set_unlink_function_full (GstPad * pad, GstPadUnlinkFunction unlink,
* Unlinks the source pad from the sink pad. Will emit the #GstPad::unlinked
* signal on both pads.
*
- * Returns: TRUE if the pads were unlinked. This function returns FALSE if
+ * Returns: %TRUE if the pads were unlinked. This function returns %FALSE if
* the pads were not linked together.
*
* MT safe.
@@ -1958,7 +2015,7 @@ not_linked_together:
*
* Checks if a @pad is linked to another pad or not.
*
- * Returns: TRUE if the pad is linked, FALSE otherwise.
+ * Returns: %TRUE if the pad is linked, %FALSE otherwise.
*
* MT safe.
*/
@@ -2022,7 +2079,7 @@ gst_pad_link_check_compatible_unlocked (GstPad * src, GstPad * sink,
sinkcaps);
/* if we have caps on both pads we can check the intersection. If one
- * of the caps is NULL, we return TRUE. */
+ * of the caps is %NULL, we return %TRUE. */
if (G_UNLIKELY (srccaps == NULL || sinkcaps == NULL)) {
if (srccaps)
gst_caps_unref (srccaps);
@@ -2037,7 +2094,7 @@ gst_pad_link_check_compatible_unlocked (GstPad * src, GstPad * sink,
done:
GST_CAT_DEBUG (GST_CAT_CAPS, "caps are %scompatible",
- (compatible ? "" : "not"));
+ (compatible ? "" : "not "));
return compatible;
}
@@ -2188,7 +2245,7 @@ no_format:
* Checks if the source pad and the sink pad are compatible so they can be
* linked.
*
- * Returns: TRUE if the pads can be linked.
+ * Returns: %TRUE if the pads can be linked.
*/
gboolean
gst_pad_can_link (GstPad * srcpad, GstPad * sinkpad)
@@ -2347,8 +2404,9 @@ concurrent_link:
}
link_failed:
{
- GST_CAT_INFO (GST_CAT_PADS, "link between %s:%s and %s:%s failed",
- GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
+ GST_CAT_INFO (GST_CAT_PADS, "link between %s:%s and %s:%s failed: %s",
+ GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad),
+ gst_pad_link_get_name (result));
GST_PAD_PEER (srcpad) = NULL;
GST_PAD_PEER (sinkpad) = NULL;
@@ -2422,7 +2480,7 @@ gst_pad_get_pad_template (GstPad * pad)
*
* Check if @pad has caps set on it with a #GST_EVENT_CAPS event.
*
- * Returns: TRUE when @pad has caps associated with it.
+ * Returns: %TRUE when @pad has caps associated with it.
*/
gboolean
gst_pad_has_current_caps (GstPad * pad)
@@ -2527,7 +2585,7 @@ gst_pad_get_peer (GstPad * pad)
* on the resulting caps.
*
* Returns: (transfer full): the allowed #GstCaps of the pad link. Unref the
- * caps when you no longer need it. This function returns NULL when @pad
+ * caps when you no longer need it. This function returns %NULL when @pad
* has no peer.
*
* MT safe.
@@ -2574,7 +2632,7 @@ no_peer:
/**
* gst_pad_iterate_internal_links_default:
* @pad: the #GstPad to get the internal links of.
- * @parent: (allow-none): the parent of @pad or NULL
+ * @parent: (allow-none): the parent of @pad or %NULL
*
* Iterate the list of pads to which the given pad is linked to inside of
* the parent element.
@@ -2583,7 +2641,7 @@ no_peer:
*
* The caller must free this iterator after use with gst_iterator_free().
*
- * Returns: a #GstIterator of #GstPad, or NULL if @pad has no parent. Unref each
+ * Returns: a #GstIterator of #GstPad, or %NULL if @pad has no parent. Unref each
* returned pad with gst_object_unref().
*/
GstIterator *
@@ -2691,9 +2749,9 @@ no_parent:
* dynamically changing internal pads and will make sure that the @forward
* function is only called once for each pad.
*
- * When @forward returns TRUE, no further pads will be processed.
+ * When @forward returns %TRUE, no further pads will be processed.
*
- * Returns: TRUE if one of the dispatcher functions returned TRUE.
+ * Returns: %TRUE if one of the dispatcher functions returned %TRUE.
*/
gboolean
gst_pad_forward (GstPad * pad, GstPadForwardFunction forward,
@@ -2783,7 +2841,7 @@ event_forward_func (GstPad * pad, EventData * data)
/**
* gst_pad_event_default:
* @pad: a #GstPad to call the default event handler on.
- * @parent: (allow-none): the parent of @pad or NULL
+ * @parent: (allow-none): the parent of @pad or %NULL
* @event: (transfer full): the #GstEvent to handle.
*
* Invokes the default event handler for the given pad.
@@ -2794,7 +2852,7 @@ event_forward_func (GstPad * pad, EventData * data)
* The the event is sent to all pads internally linked to @pad. This function
* takes ownership of @event.
*
- * Returns: TRUE if the event was sent successfully.
+ * Returns: %TRUE if the event was sent successfully.
*/
gboolean
gst_pad_event_default (GstPad * pad, GstObject * parent, GstEvent * event)
@@ -2864,8 +2922,16 @@ gst_pad_query_accept_caps_default (GstPad * pad, GstQuery * query)
allowed = gst_pad_query_caps (pad, caps);
if (allowed) {
- GST_DEBUG_OBJECT (pad, "allowed caps %" GST_PTR_FORMAT, allowed);
- result = gst_caps_is_subset (caps, allowed);
+ if (GST_PAD_IS_ACCEPT_INTERSECT (pad)) {
+ GST_DEBUG_OBJECT (pad,
+ "allowed caps intersect %" GST_PTR_FORMAT ", caps %" GST_PTR_FORMAT,
+ allowed, caps);
+ result = gst_caps_can_intersect (caps, allowed);
+ } else {
+ GST_DEBUG_OBJECT (pad, "allowed caps subset %" GST_PTR_FORMAT ", caps %"
+ GST_PTR_FORMAT, allowed, caps);
+ result = gst_caps_is_subset (caps, allowed);
+ }
gst_caps_unref (allowed);
} else {
GST_DEBUG_OBJECT (pad, "no compatible caps allowed on the pad");
@@ -2973,7 +3039,7 @@ query_forward_func (GstPad * pad, QueryData * data)
/**
* gst_pad_query_default:
* @pad: a #GstPad to call the default query handler on.
- * @parent: (allow-none): the parent of @pad or NULL
+ * @parent: (allow-none): the parent of @pad or %NULL
* @query: (transfer none): the #GstQuery to handle.
*
* Invokes the default query handler for the given pad.
@@ -2982,7 +3048,7 @@ query_forward_func (GstPad * pad, QueryData * data)
* @pad, only one will be sent the query.
* Multi-sinkpad elements should implement custom query handlers.
*
- * Returns: TRUE if the query was performed successfully.
+ * Returns: %TRUE if the query was performed successfully.
*/
gboolean
gst_pad_query_default (GstPad * pad, GstObject * parent, GstQuery * query)
@@ -3293,6 +3359,13 @@ gst_pad_get_offset (GstPad * pad)
return result;
}
+static gboolean
+mark_event_not_received (GstPad * pad, PadEvent * ev, gpointer user_data)
+{
+ ev->received = FALSE;
+ return TRUE;
+}
+
/**
* gst_pad_set_offset:
* @pad: a #GstPad
@@ -3303,8 +3376,6 @@ gst_pad_get_offset (GstPad * pad)
void
gst_pad_set_offset (GstPad * pad, gint64 offset)
{
- PadEvent *ev;
-
g_return_if_fail (GST_IS_PAD (pad));
GST_OBJECT_LOCK (pad);
@@ -3315,16 +3386,9 @@ gst_pad_set_offset (GstPad * pad, gint64 offset)
pad->offset = offset;
GST_DEBUG_OBJECT (pad, "changed offset to %" G_GINT64_FORMAT, offset);
- /* sinkpads will apply their offset the next time a segment
- * event is received. */
- if (GST_PAD_IS_SINK (pad))
- goto done;
-
- /* resend the last segment event on next buffer push */
- if ((ev = find_event_by_type (pad, GST_EVENT_SEGMENT, 0))) {
- ev->received = FALSE;
- GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS);
- }
+ /* resend all sticky events with updated offset on next buffer push */
+ events_foreach (pad, mark_event_not_received, NULL);
+ GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS);
done:
GST_OBJECT_UNLOCK (pad);
@@ -3465,7 +3529,7 @@ check_sticky (GstPad * pad, GstEvent * event)
*
* Please also note that some queries might need a running pipeline to work.
*
- * Returns: TRUE if the query could be performed.
+ * Returns: %TRUE if the query could be performed.
*/
gboolean
gst_pad_query (GstPad * pad, GstQuery * query)
@@ -3590,7 +3654,7 @@ probe_stopped:
* The caller is responsible for both the allocation and deallocation of
* the query structure.
*
- * Returns: TRUE if the query could be performed. This function returns %FALSE
+ * Returns: %TRUE if the query could be performed. This function returns %FALSE
* if @pad has no peer.
*/
gboolean
@@ -3624,7 +3688,7 @@ gst_pad_peer_query (GstPad * pad, GstQuery * query)
if (GST_PAD_IS_SRC (pad) && serialized) {
/* all serialized queries on the srcpad trigger push of
* sticky events */
- if (!check_sticky (pad, NULL) == GST_FLOW_OK)
+ if (check_sticky (pad, NULL) != GST_FLOW_OK)
goto sticky_failed;
}
@@ -3723,15 +3787,18 @@ gst_pad_chain_data_unchecked (GstPad * pad, GstPadProbeType type, void *data)
goto wrong_mode;
#ifndef G_DISABLE_ASSERT
- if (!find_event_by_type (pad, GST_EVENT_STREAM_START, 0)) {
- g_warning (G_STRLOC
- ":%s:<%s:%s> Got data flow before stream-start event",
- G_STRFUNC, GST_DEBUG_PAD_NAME (pad));
- }
- if (!find_event_by_type (pad, GST_EVENT_SEGMENT, 0)) {
- g_warning (G_STRLOC
- ":%s:<%s:%s> Got data flow before segment event",
- G_STRFUNC, GST_DEBUG_PAD_NAME (pad));
+ if (G_UNLIKELY (pad->priv->last_cookie != pad->priv->events_cookie)) {
+ if (!find_event_by_type (pad, GST_EVENT_STREAM_START, 0)) {
+ g_warning (G_STRLOC
+ ":%s:<%s:%s> Got data flow before stream-start event",
+ G_STRFUNC, GST_DEBUG_PAD_NAME (pad));
+ }
+ if (!find_event_by_type (pad, GST_EVENT_SEGMENT, 0)) {
+ g_warning (G_STRLOC
+ ":%s:<%s:%s> Got data flow before segment event",
+ G_STRFUNC, GST_DEBUG_PAD_NAME (pad));
+ }
+ pad->priv->last_cookie = pad->priv->events_cookie;
}
#endif
@@ -3822,7 +3889,7 @@ probe_stopped:
ret = GST_FLOW_OK;
break;
default:
- GST_DEBUG_OBJECT (pad, "an error occured %s", gst_flow_get_name (ret));
+ GST_DEBUG_OBJECT (pad, "an error occurred %s", gst_flow_get_name (ret));
break;
}
return ret;
@@ -3848,7 +3915,7 @@ no_function:
* The function returns #GST_FLOW_FLUSHING if the pad was flushing.
*
* If the buffer type is not acceptable for @pad (as negotiated with a
- * preceeding GST_EVENT_CAPS event), this function returns
+ * preceding GST_EVENT_CAPS event), this function returns
* #GST_FLOW_NOT_NEGOTIATED.
*
* The function proceeds calling the chain function installed on @pad (see
@@ -3954,15 +4021,18 @@ gst_pad_push_data (GstPad * pad, GstPadProbeType type, void *data)
goto wrong_mode;
#ifndef G_DISABLE_ASSERT
- if (!find_event_by_type (pad, GST_EVENT_STREAM_START, 0)) {
- g_warning (G_STRLOC
- ":%s:<%s:%s> Got data flow before stream-start event",
- G_STRFUNC, GST_DEBUG_PAD_NAME (pad));
- }
- if (!find_event_by_type (pad, GST_EVENT_SEGMENT, 0)) {
- g_warning (G_STRLOC
- ":%s:<%s:%s> Got data flow before segment event",
- G_STRFUNC, GST_DEBUG_PAD_NAME (pad));
+ if (G_UNLIKELY (pad->priv->last_cookie != pad->priv->events_cookie)) {
+ if (!find_event_by_type (pad, GST_EVENT_STREAM_START, 0)) {
+ g_warning (G_STRLOC
+ ":%s:<%s:%s> Got data flow before stream-start event",
+ G_STRFUNC, GST_DEBUG_PAD_NAME (pad));
+ }
+ if (!find_event_by_type (pad, GST_EVENT_SEGMENT, 0)) {
+ g_warning (G_STRLOC
+ ":%s:<%s:%s> Got data flow before segment event",
+ G_STRFUNC, GST_DEBUG_PAD_NAME (pad));
+ }
+ pad->priv->last_cookie = pad->priv->events_cookie;
}
#endif
@@ -3992,6 +4062,7 @@ gst_pad_push_data (GstPad * pad, GstPadProbeType type, void *data)
gst_object_unref (peer);
GST_OBJECT_LOCK (pad);
+ pad->ABI.abi.last_flowret = ret;
pad->priv->using--;
if (pad->priv->using == 0) {
/* pad is not active anymore, trigger idle callbacks */
@@ -4008,6 +4079,7 @@ flushing:
{
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"pushing, but pad was flushing");
+ pad->ABI.abi.last_flowret = GST_FLOW_FLUSHING;
GST_OBJECT_UNLOCK (pad);
gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
return GST_FLOW_FLUSHING;
@@ -4015,6 +4087,7 @@ flushing:
eos:
{
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pushing, but pad was EOS");
+ pad->ABI.abi.last_flowret = GST_FLOW_EOS;
GST_OBJECT_UNLOCK (pad);
gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
return GST_FLOW_EOS;
@@ -4023,6 +4096,7 @@ wrong_mode:
{
g_critical ("pushing on pad %s:%s but it was not activated in push mode",
GST_DEBUG_PAD_NAME (pad));
+ pad->ABI.abi.last_flowret = GST_FLOW_ERROR;
GST_OBJECT_UNLOCK (pad);
gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
return GST_FLOW_ERROR;
@@ -4031,6 +4105,7 @@ events_error:
{
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"error pushing events, return %s", gst_flow_get_name (ret));
+ pad->ABI.abi.last_flowret = ret;
GST_OBJECT_UNLOCK (pad);
gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
return ret;
@@ -4038,6 +4113,8 @@ events_error:
probe_stopped:
{
GST_OBJECT_UNLOCK (pad);
+ pad->ABI.abi.last_flowret =
+ ret == GST_FLOW_CUSTOM_SUCCESS ? GST_FLOW_OK : ret;
gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
switch (ret) {
@@ -4046,7 +4123,7 @@ probe_stopped:
ret = GST_FLOW_OK;
break;
default:
- GST_DEBUG_OBJECT (pad, "an error occured %s", gst_flow_get_name (ret));
+ GST_DEBUG_OBJECT (pad, "an error occurred %s", gst_flow_get_name (ret));
break;
}
return ret;
@@ -4055,6 +4132,7 @@ not_linked:
{
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"pushing, but it was not linked");
+ pad->ABI.abi.last_flowret = GST_FLOW_NOT_LINKED;
GST_OBJECT_UNLOCK (pad);
gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
return GST_FLOW_NOT_LINKED;
@@ -4177,14 +4255,15 @@ gst_pad_get_range_unchecked (GstPad * pad, guint64 offset, guint size,
RELEASE_PARENT (parent);
+ GST_OBJECT_LOCK (pad);
if (G_UNLIKELY (ret != GST_FLOW_OK))
goto get_range_failed;
/* can only fire the signal if we have a valid buffer */
- GST_OBJECT_LOCK (pad);
probed_data:
PROBE_PULL (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_BUFFER,
res_buf, offset, size, probe_stopped_unref);
+ pad->ABI.abi.last_flowret = ret;
GST_OBJECT_UNLOCK (pad);
GST_PAD_STREAM_UNLOCK (pad);
@@ -4198,6 +4277,7 @@ flushing:
{
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"getrange, but pad was flushing");
+ pad->ABI.abi.last_flowret = GST_FLOW_FLUSHING;
GST_OBJECT_UNLOCK (pad);
GST_PAD_STREAM_UNLOCK (pad);
return GST_FLOW_FLUSHING;
@@ -4206,6 +4286,7 @@ wrong_mode:
{
g_critical ("getrange on pad %s:%s but it was not activated in pull mode",
GST_DEBUG_PAD_NAME (pad));
+ pad->ABI.abi.last_flowret = GST_FLOW_ERROR;
GST_OBJECT_UNLOCK (pad);
GST_PAD_STREAM_UNLOCK (pad);
return GST_FLOW_ERROR;
@@ -4213,6 +4294,7 @@ wrong_mode:
events_error:
{
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "error pushing events");
+ pad->ABI.abi.last_flowret = ret;
GST_OBJECT_UNLOCK (pad);
GST_PAD_STREAM_UNLOCK (pad);
return ret;
@@ -4220,6 +4302,7 @@ events_error:
no_parent:
{
GST_DEBUG_OBJECT (pad, "no parent");
+ pad->ABI.abi.last_flowret = GST_FLOW_FLUSHING;
GST_OBJECT_UNLOCK (pad);
GST_PAD_STREAM_UNLOCK (pad);
return GST_FLOW_FLUSHING;
@@ -4249,6 +4332,7 @@ probe_stopped:
ret = GST_FLOW_EOS;
}
}
+ pad->ABI.abi.last_flowret = ret;
GST_OBJECT_UNLOCK (pad);
GST_PAD_STREAM_UNLOCK (pad);
@@ -4261,6 +4345,7 @@ probe_stopped_unref:
/* if we drop here, it signals EOS */
if (ret == GST_FLOW_CUSTOM_SUCCESS)
ret = GST_FLOW_EOS;
+ pad->ABI.abi.last_flowret = ret;
GST_OBJECT_UNLOCK (pad);
GST_PAD_STREAM_UNLOCK (pad);
if (*buffer == NULL)
@@ -4269,6 +4354,8 @@ probe_stopped_unref:
}
get_range_failed:
{
+ pad->ABI.abi.last_flowret = ret;
+ GST_OBJECT_UNLOCK (pad);
GST_PAD_STREAM_UNLOCK (pad);
GST_CAT_LEVEL_LOG (GST_CAT_SCHEDULING,
(ret >= GST_FLOW_EOS) ? GST_LEVEL_INFO : GST_LEVEL_WARNING,
@@ -4293,7 +4380,7 @@ get_range_failed:
* installed (see gst_pad_set_getrange_function()) this function returns
* #GST_FLOW_NOT_SUPPORTED.
*
- * If @buffer points to a variable holding NULL, a valid new #GstBuffer will be
+ * If @buffer points to a variable holding %NULL, a valid new #GstBuffer will be
* placed in @buffer when this function returns #GST_FLOW_OK. The new buffer
* must be freed with gst_buffer_unref() after usage.
*
@@ -4310,7 +4397,7 @@ get_range_failed:
* When this function returns any other result value than #GST_FLOW_OK, @buffer
* will be unchanged.
*
- * This is a lowlevel function. Usualy gst_pad_pull_range() is used.
+ * This is a lowlevel function. Usually gst_pad_pull_range() is used.
*
* Returns: a #GstFlowReturn from the pad.
*
@@ -4347,10 +4434,10 @@ gst_pad_get_range (GstPad * pad, guint64 offset, guint size,
* See gst_pad_get_range() for a list of return values and for the
* semantics of the arguments of this function.
*
- * If @buffer points to a variable holding NULL, a valid new #GstBuffer will be
+ * If @buffer points to a variable holding %NULL, a valid new #GstBuffer will be
* placed in @buffer when this function returns #GST_FLOW_OK. The new buffer
* must be freed with gst_buffer_unref() after usage. When this function
- * returns any other result value, @buffer will still point to NULL.
+ * returns any other result value, @buffer will still point to %NULL.
*
* When @buffer points to a variable that points to a valid #GstBuffer, the
* buffer will be filled with the result data when this function returns
@@ -4409,6 +4496,7 @@ gst_pad_pull_range (GstPad * pad, guint64 offset, guint size,
GST_OBJECT_LOCK (pad);
pad->priv->using--;
+ pad->ABI.abi.last_flowret = ret;
if (pad->priv->using == 0) {
/* pad is not active anymore, trigger idle callbacks */
PROBE_NO_DATA (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_IDLE,
@@ -4433,6 +4521,7 @@ flushing:
{
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"pullrange, but pad was flushing");
+ pad->ABI.abi.last_flowret = GST_FLOW_FLUSHING;
GST_OBJECT_UNLOCK (pad);
return GST_FLOW_FLUSHING;
}
@@ -4440,6 +4529,7 @@ wrong_mode:
{
g_critical ("pullrange on pad %s:%s but it was not activated in pull mode",
GST_DEBUG_PAD_NAME (pad));
+ pad->ABI.abi.last_flowret = GST_FLOW_ERROR;
GST_OBJECT_UNLOCK (pad);
return GST_FLOW_ERROR;
}
@@ -4460,6 +4550,7 @@ probe_stopped:
ret = GST_FLOW_EOS;
}
}
+ pad->ABI.abi.last_flowret = ret;
GST_OBJECT_UNLOCK (pad);
return ret;
}
@@ -4467,11 +4558,13 @@ not_linked:
{
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"pulling range, but it was not linked");
+ pad->ABI.abi.last_flowret = GST_FLOW_NOT_LINKED;
GST_OBJECT_UNLOCK (pad);
return GST_FLOW_NOT_LINKED;
}
pull_range_failed:
{
+ pad->ABI.abi.last_flowret = ret;
GST_OBJECT_UNLOCK (pad);
GST_CAT_LEVEL_LOG (GST_CAT_SCHEDULING,
(ret >= GST_FLOW_EOS) ? GST_LEVEL_INFO : GST_LEVEL_WARNING,
@@ -4482,10 +4575,14 @@ probe_stopped_unref:
{
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"post probe returned %s", gst_flow_get_name (ret));
- GST_OBJECT_UNLOCK (pad);
+
/* if we drop here, it signals EOS */
if (ret == GST_FLOW_CUSTOM_SUCCESS)
ret = GST_FLOW_EOS;
+
+ pad->ABI.abi.last_flowret = ret;
+ GST_OBJECT_UNLOCK (pad);
+
if (*buffer == NULL)
gst_buffer_unref (res_buf);
return ret;
@@ -4505,7 +4602,7 @@ store_sticky_event (GstPad * pad, GstEvent * event)
type = GST_EVENT_TYPE (event);
- /* Store all sticky events except SEGMENT/SEGMENT when we're flushing,
+ /* Store all sticky events except SEGMENT/EOS when we're flushing,
* otherwise they can be dropped and nothing would ever resend them.
* Only do that for activated pads though, everything else is a bug!
*/
@@ -4583,8 +4680,10 @@ store_sticky_event (GstPad * pad, GstEvent * event)
break;
}
}
- if (type == GST_EVENT_EOS)
+ if (type == GST_EVENT_EOS) {
GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_EOS);
+ pad->ABI.abi.last_flowret = GST_FLOW_EOS;
+ }
return GST_PAD_IS_FLUSHING (pad) ? GST_FLOW_FLUSHING : GST_FLOW_OK;
@@ -4650,6 +4749,10 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event,
GstPad *peerpad;
GstEventType event_type;
+ /* pass the adjusted event on. We need to do this even if
+ * there is no peer pad because of the probes. */
+ event = apply_pad_offset (pad, event, GST_PAD_IS_SINK (pad));
+
/* Two checks to be made:
* . (un)set the FLUSHING flag for flushing events,
* . handle pad blocking */
@@ -4669,6 +4772,7 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event,
remove_event_by_type (pad, GST_EVENT_EOS);
remove_event_by_type (pad, GST_EVENT_SEGMENT);
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
+ pad->ABI.abi.last_flowret = GST_FLOW_OK;
type |= GST_PAD_PROBE_TYPE_EVENT_FLUSH;
break;
@@ -4683,11 +4787,6 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event,
*/
switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_SEGMENT:
- /* pass the adjusted segment event on. We need to do this even if
- * there is no peer pad because of the probes. */
- event = apply_pad_offset (pad, event);
- break;
case GST_EVENT_RECONFIGURE:
if (GST_PAD_IS_SINK (pad))
GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_NEED_RECONFIGURE);
@@ -4726,14 +4825,15 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event,
GST_OBJECT_UNLOCK (pad);
GST_LOG_OBJECT (pad, "sending event %p (%s) to peerpad %" GST_PTR_FORMAT,
- event, GST_EVENT_TYPE_NAME (event), peerpad);
+ event, gst_event_type_get_name (event_type), peerpad);
ret = gst_pad_send_event_unchecked (peerpad, event, type);
/* Note: we gave away ownership of the event at this point but we can still
* print the old pointer */
- GST_LOG_OBJECT (pad, "sent event %p to peerpad %" GST_PTR_FORMAT ", ret %s",
- event, peerpad, gst_flow_get_name (ret));
+ GST_LOG_OBJECT (pad,
+ "sent event %p to (%s) peerpad %" GST_PTR_FORMAT ", ret %s", event,
+ gst_event_type_get_name (event_type), peerpad, gst_flow_get_name (ret));
gst_object_unref (peerpad);
@@ -4763,7 +4863,7 @@ probe_stopped:
GST_DEBUG_OBJECT (pad, "dropped event");
break;
default:
- GST_DEBUG_OBJECT (pad, "an error occured %s", gst_flow_get_name (ret));
+ GST_DEBUG_OBJECT (pad, "an error occurred %s", gst_flow_get_name (ret));
break;
}
return ret;
@@ -4797,10 +4897,10 @@ idle_probe_stopped:
* mainly used by elements to send events to their peer
* elements.
*
- * This function takes owership of the provided event so you should
+ * This function takes ownership of the provided event so you should
* gst_event_ref() it if you want to reuse the event after this call.
*
- * Returns: TRUE if the event was handled.
+ * Returns: %TRUE if the event was handled.
*
* MT safe.
*/
@@ -4940,6 +5040,9 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
GstObject *parent;
GST_OBJECT_LOCK (pad);
+
+ event = apply_pad_offset (pad, event, GST_PAD_IS_SRC (pad));
+
if (GST_PAD_IS_SINK (pad))
serialized = GST_EVENT_IS_SERIALIZED (event);
else
@@ -4968,6 +5071,7 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
remove_event_by_type (pad, GST_EVENT_EOS);
remove_event_by_type (pad, GST_EVENT_SEGMENT);
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
+ pad->ABI.abi.last_flowret = GST_FLOW_OK;
GST_OBJECT_UNLOCK (pad);
/* grab stream lock */
@@ -5002,14 +5106,6 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
goto eos;
}
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_SEGMENT:
- event = apply_pad_offset (pad, event);
- break;
- default:
- break;
- }
break;
}
@@ -5107,7 +5203,7 @@ probe_stopped:
ret = GST_FLOW_OK;
break;
default:
- GST_DEBUG_OBJECT (pad, "an error occured %s", gst_flow_get_name (ret));
+ GST_DEBUG_OBJECT (pad, "an error occurred %s", gst_flow_get_name (ret));
break;
}
return ret;
@@ -5165,10 +5261,10 @@ precheck_failed:
* plugin doesn't need to bother itself with this information; the core handles
* all necessary locks and checks.
*
- * This function takes owership of the provided event so you should
+ * This function takes ownership of the provided event so you should
* gst_event_ref() it if you want to reuse the event after this call.
*
- * Returns: TRUE if the event was handled.
+ * Returns: %TRUE if the event was handled.
*/
gboolean
gst_pad_send_event (GstPad * pad, GstEvent * event)
@@ -5252,7 +5348,7 @@ gst_pad_get_element_private (GstPad * pad)
* Returns a new reference of the sticky event of type @event_type
* from the event.
*
- * Returns: (transfer full): a #GstEvent of type @event_type or NULL when no
+ * Returns: (transfer full): a #GstEvent of type @event_type or %NULL when no
* event of @event_type was on @pad. Unref after usage.
*/
GstEvent *
@@ -5448,7 +5544,7 @@ concurrent_stop:
* function executed by the task is finished if this function is not
* called from the task function.
*
- * Returns: a TRUE if the task could be paused or FALSE when the pad
+ * Returns: a %TRUE if the task could be paused or %FALSE when the pad
* has no task.
*/
gboolean
@@ -5497,7 +5593,7 @@ no_task:
* Regardless of whether the pad has a task, the stream lock is acquired and
* released so as to ensure that streaming through this pad has finished.
*
- * Returns: a TRUE if the task could be stopped or FALSE on error.
+ * Returns: a %TRUE if the task could be stopped or %FALSE on error.
*/
gboolean
gst_pad_stop_task (GstPad * pad)
@@ -5616,3 +5712,23 @@ gst_pad_probe_info_get_buffer_list (GstPadProbeInfo * info)
return GST_PAD_PROBE_INFO_BUFFER_LIST (info);
}
+
+/**
+ * gst_pad_get_last_flow_return:
+ * @pad: the #GstPad
+ *
+ * Gets the #GstFlowReturn return from the last data passed by this pad.
+ *
+ * Since: 1.4
+ */
+GstFlowReturn
+gst_pad_get_last_flow_return (GstPad * pad)
+{
+ GstFlowReturn ret;
+
+ GST_OBJECT_LOCK (pad);
+ ret = GST_PAD_LAST_FLOW_RETURN (pad);
+ GST_OBJECT_UNLOCK (pad);
+
+ return ret;
+}
diff --git a/gst/gstpad.h b/gst/gstpad.h
index 13d4571..bfb8b1a 100644
--- a/gst/gstpad.h
+++ b/gst/gstpad.h
@@ -61,6 +61,8 @@ typedef enum {
GST_PAD_MODE_PULL
} GstPadMode;
+const gchar * gst_pad_mode_get_name (GstPadMode mode);
+
#include <gst/gstobject.h>
#include <gst/gstbuffer.h>
#include <gst/gstbufferlist.h>
@@ -131,7 +133,7 @@ typedef enum {
* @GST_FLOW_FLUSHING: Pad is flushing.
* @GST_FLOW_EOS: Pad is EOS.
* @GST_FLOW_NOT_NEGOTIATED: Pad is not negotiated.
- * @GST_FLOW_ERROR: Some (fatal) error occured. Element generating
+ * @GST_FLOW_ERROR: Some (fatal) error occurred. Element generating
* this error should post an error message with more
* details.
* @GST_FLOW_NOT_SUPPORTED: This operation is not supported.
@@ -177,8 +179,9 @@ typedef enum {
GST_FLOW_CUSTOM_ERROR_2 = -102
} GstFlowReturn;
-const gchar* gst_flow_get_name (GstFlowReturn ret);
-GQuark gst_flow_to_quark (GstFlowReturn ret);
+const gchar* gst_flow_get_name (GstFlowReturn ret);
+GQuark gst_flow_to_quark (GstFlowReturn ret);
+const gchar* gst_pad_link_get_name (GstPadLinkReturn ret);
/**
* GstPadLinkCheck:
@@ -226,7 +229,7 @@ typedef enum {
* activate function that puts the pad in push mode but elements can
* override this function to activate the pad in pull mode if they wish.
*
- * Returns: TRUE if the pad could be activated.
+ * Returns: %TRUE if the pad could be activated.
*/
typedef gboolean (*GstPadActivateFunction) (GstPad *pad, GstObject *parent);
/**
@@ -238,7 +241,7 @@ typedef gboolean (*GstPadActivateFunction) (GstPad *pad, GstObject *parent);
*
* The prototype of the push and pull activate functions.
*
- * Returns: TRUE if the pad could be activated or deactivated.
+ * Returns: %TRUE if the pad could be activated or deactivated.
*/
typedef gboolean (*GstPadActivateModeFunction) (GstPad *pad, GstObject *parent,
GstPadMode mode, gboolean active);
@@ -249,7 +252,7 @@ typedef gboolean (*GstPadActivateModeFunction) (GstPad *pad, GstObject *parent,
* GstPadChainFunction:
* @pad: the sink #GstPad that performed the chain.
* @parent: the parent of @pad. If the #GST_PAD_FLAG_NEED_PARENT flag is set,
- * @parent is guaranteed to be not-NULL and remain valid during the
+ * @parent is guaranteed to be not-%NULL and remain valid during the
* execution of this function.
* @buffer: the #GstBuffer that is chained, not %NULL.
*
@@ -272,7 +275,7 @@ typedef GstFlowReturn (*GstPadChainFunction) (GstPad *pad, GstObject *parent,
* GstPadChainListFunction:
* @pad: the sink #GstPad that performed the chain.
* @parent: the parent of @pad. If the #GST_PAD_FLAG_NEED_PARENT flag is set,
- * @parent is guaranteed to be not-NULL and remain valid during the
+ * @parent is guaranteed to be not-%NULL and remain valid during the
* execution of this function.
* @list: the #GstBufferList that is chained, not %NULL.
*
@@ -295,11 +298,11 @@ typedef GstFlowReturn (*GstPadChainListFunction) (GstPad *pad, GstObject *paren
* GstPadGetRangeFunction:
* @pad: the src #GstPad to perform the getrange on.
* @parent: the parent of @pad. If the #GST_PAD_FLAG_NEED_PARENT flag is set,
- * @parent is guaranteed to be not-NULL and remain valid during the
+ * @parent is guaranteed to be not-%NULL and remain valid during the
* execution of this function.
* @offset: the offset of the range
* @length: the length of the range
- * @buffer: a memory location to hold the result buffer, cannot be NULL.
+ * @buffer: a memory location to hold the result buffer, cannot be %NULL.
*
* This function will be called on source pads when a peer element
* request a buffer at the specified @offset and @length. If this function
@@ -346,13 +349,13 @@ typedef GstFlowReturn (*GstPadGetRangeFunction) (GstPad *pad, GstObject *parent
* GstPadEventFunction:
* @pad: the #GstPad to handle the event.
* @parent: the parent of @pad. If the #GST_PAD_FLAG_NEED_PARENT flag is set,
- * @parent is guaranteed to be not-NULL and remain valid during the
+ * @parent is guaranteed to be not-%NULL and remain valid during the
* execution of this function.
* @event: the #GstEvent to handle.
*
* Function signature to handle an event for the pad.
*
- * Returns: TRUE if the pad could handle the event.
+ * Returns: %TRUE if the pad could handle the event.
*/
typedef gboolean (*GstPadEventFunction) (GstPad *pad, GstObject *parent,
GstEvent *event);
@@ -363,7 +366,7 @@ typedef gboolean (*GstPadEventFunction) (GstPad *pad, GstObject *parent,
* GstPadIterIntLinkFunction:
* @pad: The #GstPad to query.
* @parent: the parent of @pad. If the #GST_PAD_FLAG_NEED_PARENT flag is set,
- * @parent is guaranteed to be not-NULL and remain valid during the
+ * @parent is guaranteed to be not-%NULL and remain valid during the
* execution of this function.
*
* The signature of the internal pad link iterator function.
@@ -380,13 +383,13 @@ typedef GstIterator* (*GstPadIterIntLinkFunction) (GstPad *pad, Gst
* GstPadQueryFunction:
* @pad: the #GstPad to query.
* @parent: the parent of @pad. If the #GST_PAD_FLAG_NEED_PARENT flag is set,
- * @parent is guaranteed to be not-NULL and remain valid during the
+ * @parent is guaranteed to be not-%NULL and remain valid during the
* execution of this function.
* @query: the #GstQuery object to execute
*
* The signature of the query function.
*
- * Returns: TRUE if the query could be performed.
+ * Returns: %TRUE if the query could be performed.
*/
typedef gboolean (*GstPadQueryFunction) (GstPad *pad, GstObject *parent,
GstQuery *query);
@@ -397,7 +400,7 @@ typedef gboolean (*GstPadQueryFunction) (GstPad *pad, GstObject *parent,
* GstPadLinkFunction:
* @pad: the #GstPad that is linked.
* @parent: the parent of @pad. If the #GST_PAD_FLAG_NEED_PARENT flag is set,
- * @parent is guaranteed to be not-NULL and remain valid during the
+ * @parent is guaranteed to be not-%NULL and remain valid during the
* execution of this function.
* @peer: the peer #GstPad of the link
*
@@ -410,7 +413,7 @@ typedef GstPadLinkReturn (*GstPadLinkFunction) (GstPad *pad, GstObject *parent,
* GstPadUnlinkFunction:
* @pad: the #GstPad that is linked.
* @parent: the parent of @pad. If the #GST_PAD_FLAG_NEED_PARENT flag is set,
- * @parent is guaranteed to be not-NULL and remain valid during the
+ * @parent is guaranteed to be not-%NULL and remain valid during the
* execution of this function.
*
* Function signature to handle a unlinking the pad prom its peer.
@@ -427,7 +430,7 @@ typedef void (*GstPadUnlinkFunction) (GstPad *pad, GstObject *parent);
* A forward function is called for all internally linked pads, see
* gst_pad_forward().
*
- * Returns: TRUE if the dispatching procedure has to be stopped.
+ * Returns: %TRUE if the dispatching procedure has to be stopped.
*/
typedef gboolean (*GstPadForwardFunction) (GstPad *pad, gpointer user_data);
@@ -501,7 +504,7 @@ typedef enum
* @GST_PAD_PROBE_DROP: drop data in data probes. For push mode this means that
* the data item is not sent downstream. For pull mode, it means that the
* data item is not passed upstream. In both cases, this result code
- * returns #GST_FLOW_OK or %TRUE to the caller.
+ * means that #GST_FLOW_OK or %TRUE is returned to the caller.
* @GST_PAD_PROBE_REMOVE: remove probe
* @GST_PAD_PROBE_PASS: pass the data item in the block probe and block on
* the next item
@@ -522,7 +525,7 @@ typedef enum
* @type: the current probe type
* @id: the id of the probe
* @data: type specific data, check the @type field to know the datatype.
- * This field can be NULL.
+ * This field can be %NULL.
* @offset: offset of pull probe, this field is valid when @type contains
* #GST_PAD_PROBE_TYPE_PULL
* @size: size of pull probe, this field is valid when @type contains
@@ -586,7 +589,7 @@ typedef GstPadProbeReturn (*GstPadProbeCallback) (GstPad *pad, GstPadProbeIn
* When this function returns %TRUE, the next event will be
* returned. When %FALSE is returned, gst_pad_sticky_events_foreach() will return.
*
- * When @event is set to NULL, the item will be removed from the list of sticky events.
+ * When @event is set to %NULL, the item will be removed from the list of sticky events.
* @event can be replaced by assigning a new reference to it.
* This function is responsible for unreffing the old event when
* removing or modifying.
@@ -608,9 +611,9 @@ typedef gboolean (*GstPadStickyEventsForeachFunction) (GstPad *pad, GstEvent **
* The flag has to be unset manually after
* reconfiguration happened.
* @GST_PAD_FLAG_PENDING_EVENTS: the pad has pending events
- * @GST_PAD_FLAG_FIXED_CAPS: the pad is using fixed caps this means that once the
- * caps are set on the pad, the caps query function only
- * returns those caps.
+ * @GST_PAD_FLAG_FIXED_CAPS: the pad is using fixed caps. This means that
+ * once the caps are set on the pad, the default caps query function
+ * will only return those caps.
* @GST_PAD_FLAG_PROXY_CAPS: the default event and query handler will forward
* all events and queries to the internally linked pads
* instead of discarding them.
@@ -620,6 +623,10 @@ typedef gboolean (*GstPadStickyEventsForeachFunction) (GstPad *pad, GstEvent **
* @GST_PAD_FLAG_PROXY_SCHEDULING: the default query handler will forward
* scheduling queries to the internally linked pads
* instead of discarding them.
+ * @GST_PAD_FLAG_ACCEPT_INTERSECT: the default accept-caps handler will check
+ * it the caps intersect the query-caps result instead
+ * of checking for a subset. This is interesting for
+ * parsers that can accept incompletely specified caps.
* @GST_PAD_FLAG_LAST: offset to define more flags
*
* Pad state flags
@@ -636,6 +643,7 @@ typedef enum {
GST_PAD_FLAG_PROXY_CAPS = (GST_OBJECT_FLAG_LAST << 8),
GST_PAD_FLAG_PROXY_ALLOCATION = (GST_OBJECT_FLAG_LAST << 9),
GST_PAD_FLAG_PROXY_SCHEDULING = (GST_OBJECT_FLAG_LAST << 10),
+ GST_PAD_FLAG_ACCEPT_INTERSECT = (GST_OBJECT_FLAG_LAST << 11),
/* padding */
GST_PAD_FLAG_LAST = (GST_OBJECT_FLAG_LAST << 16)
} GstPadFlags;
@@ -718,7 +726,12 @@ struct _GstPad {
GstPadPrivate *priv;
- gpointer _gst_reserved[GST_PADDING];
+ union {
+ gpointer _gst_reserved[GST_PADDING];
+ struct {
+ GstFlowReturn last_flowret;
+ } abi;
+ } ABI;
};
struct _GstPadClass {
@@ -735,90 +748,412 @@ struct _GstPadClass {
/***** helper macros *****/
/* GstPad */
+
+/**
+ * GST_PAD_NAME:
+ * @pad: a #GstPad
+ *
+ * Get name of the given pad.
+ * No locking is performed in this function, use gst_pad_get_name() instead.
+ */
#define GST_PAD_NAME(pad) (GST_OBJECT_NAME(pad))
+/**
+ * GST_PAD_PARENT:
+ * @pad: a #GstPad
+ *
+ * Get the @pad parent.
+ * No locking is performed in this function, use gst_pad_get_parent() instead.
+ */
#define GST_PAD_PARENT(pad) (GST_ELEMENT_CAST(GST_OBJECT_PARENT(pad)))
+/**
+ * GST_PAD_ELEMENT_PRIVATE:
+ * @pad: a #GstPad
+ *
+ * Get the private data of @pad, which is usually some pad- or stream-specific
+ * structure created by the element and set on the pad when creating it.
+ * No locking is performed in this function.
+ */
#define GST_PAD_ELEMENT_PRIVATE(pad) (GST_PAD_CAST(pad)->element_private)
+/**
+ * GST_PAD_PAD_TEMPLATE:
+ * @pad: a #GstPad
+ *
+ * Get the @pad #GstPadTemplate. It describes the possible media types
+ * a @pad or an element factory can handle.
+ */
#define GST_PAD_PAD_TEMPLATE(pad) (GST_PAD_CAST(pad)->padtemplate)
+/**
+ * GST_PAD_DIRECTION:
+ * @pad: a #GstPad
+ *
+ * Get the #GstPadDirection of the given @pad. Accessor macro, use
+ * gst_pad_get_direction() instead.
+ */
#define GST_PAD_DIRECTION(pad) (GST_PAD_CAST(pad)->direction)
+/**
+ * GST_PAD_TASK:
+ * @pad: a #GstPad
+ *
+ * Get the #GstTask of @pad. Accessor macro used by GStreamer. Use the
+ * gst_pad_start_task(), gst_pad_stop_task() and gst_pad_pause_task()
+ * functions instead.
+ */
#define GST_PAD_TASK(pad) (GST_PAD_CAST(pad)->task)
+/**
+ * GST_PAD_MODE:
+ * @pad: a #GstPad
+ *
+ * Get the #GstPadMode of pad, which will be GST_PAD_MODE_NONE if the pad
+ * has not been activated yet, and otherwise either GST_PAD_MODE_PUSH or
+ * GST_PAD_MODE_PULL depending on which mode the pad was activated in.
+ */
#define GST_PAD_MODE(pad) (GST_PAD_CAST(pad)->mode)
-
+/**
+ * GST_PAD_ACTIVATEFUNC:
+ * @pad: a #GstPad
+ *
+ * Get the #GstPadActivateFunction from @pad.
+ */
#define GST_PAD_ACTIVATEFUNC(pad) (GST_PAD_CAST(pad)->activatefunc)
+/**
+ * GST_PAD_ACTIVATEMODEFUNC:
+ * @pad: a #GstPad
+ *
+ * Get the #GstPadActivateModeFunction from the given @pad.
+ */
#define GST_PAD_ACTIVATEMODEFUNC(pad) (GST_PAD_CAST(pad)->activatemodefunc)
+/**
+ * GST_PAD_CHAINFUNC:
+ * @pad: a #GstPad
+ *
+ * Get the #GstPadChainFunction from the given @pad.
+ */
#define GST_PAD_CHAINFUNC(pad) (GST_PAD_CAST(pad)->chainfunc)
+/**
+ * GST_PAD_CHAINLISTFUNC:
+ * @pad: a #GstPad
+ *
+ * Get the #GstPadChainListFunction from the given @pad.
+ */
#define GST_PAD_CHAINLISTFUNC(pad) (GST_PAD_CAST(pad)->chainlistfunc)
+/**
+ * GST_PAD_GETRANGEFUNC:
+ * @pad: a #GstPad
+ *
+ * Get the #GstPadGetRangeFunction from the given @pad.
+ */
#define GST_PAD_GETRANGEFUNC(pad) (GST_PAD_CAST(pad)->getrangefunc)
+/**
+ * GST_PAD_EVENTFUNC:
+ * @pad: a #GstPad
+ *
+ * Get the #GstPadEventFunction from the given @pad, which
+ * is the function that handles events on the pad. You can
+ * use this to set your own event handling function on a pad
+ * after you create it. If your element derives from a base
+ * class, use the base class's virtual functions instead.
+ */
#define GST_PAD_EVENTFUNC(pad) (GST_PAD_CAST(pad)->eventfunc)
+/**
+ * GST_PAD_QUERYFUNC:
+ * @pad: a #GstPad
+ *
+ * Get the #GstPadQueryFunction from @pad, which is the function
+ * that handles queries on the pad. You can use this to set your
+ * own query handling function on a pad after you create it. If your
+ * element derives from a base class, use the base class's virtual
+ * functions instead.
+ */
#define GST_PAD_QUERYFUNC(pad) (GST_PAD_CAST(pad)->queryfunc)
+/**
+ * GST_PAD_ITERINTLINKFUNC:
+ * @pad: a #GstPad
+ *
+ * Get the #GstPadIterIntLinkFunction from the given @pad.
+ */
#define GST_PAD_ITERINTLINKFUNC(pad) (GST_PAD_CAST(pad)->iterintlinkfunc)
-
+/**
+ * GST_PAD_PEER:
+ * @pad: a #GstPad
+ *
+ * Return the pad's peer member. This member is a pointer to the linked @pad.
+ * No locking is performed in this function, use gst_pad_get_peer() instead.
+ */
#define GST_PAD_PEER(pad) (GST_PAD_CAST(pad)->peer)
+/**
+ * GST_PAD_LINKFUNC:
+ * @pad: a #GstPad
+ *
+ * Get the #GstPadLinkFunction for the given @pad.
+ */
#define GST_PAD_LINKFUNC(pad) (GST_PAD_CAST(pad)->linkfunc)
+/**
+ * GST_PAD_UNLINKFUNC:
+ * @pad: a #GstPad
+ *
+ * Get the #GstPadUnlinkFunction from the given @pad.
+ */
#define GST_PAD_UNLINKFUNC(pad) (GST_PAD_CAST(pad)->unlinkfunc)
-
+/**
+ * GST_PAD_IS_SRC:
+ * @pad: a #GstPad
+ *
+ * Returns: %TRUE if the pad is a source pad (i.e. produces data).
+ */
#define GST_PAD_IS_SRC(pad) (GST_PAD_DIRECTION(pad) == GST_PAD_SRC)
+/**
+ * GST_PAD_IS_SINK:
+ * @pad: a #GstPad
+ *
+ * Returns: %TRUE if the pad is a sink pad (i.e. consumes data).
+ */
#define GST_PAD_IS_SINK(pad) (GST_PAD_DIRECTION(pad) == GST_PAD_SINK)
-
+/**
+ * GST_PAD_IS_LINKED:
+ * @pad: a #GstPad
+ *
+ * Returns: %TRUE if the pad is linked to another pad. Use gst_pad_is_linked()
+ * instead.
+ */
#define GST_PAD_IS_LINKED(pad) (GST_PAD_PEER(pad) != NULL)
-
+/**
+ * GST_PAD_IS_ACTIVE:
+ * @pad: a #GstPad
+ *
+ * Returns: %TRUE if the pad has been activated.
+ */
#define GST_PAD_IS_ACTIVE(pad) (GST_PAD_MODE(pad) != GST_PAD_MODE_NONE)
-
+/**
+ * GST_PAD_IS_BLOCKED:
+ * @pad: a #GstPad
+ *
+ * Check if the dataflow on a @pad is blocked. Use gst_pad_is_blocked() instead.
+ */
#define GST_PAD_IS_BLOCKED(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_BLOCKED))
+/**
+ * GST_PAD_IS_BLOCKING:
+ * @pad: a #GstPad
+ *
+ * Check if the @pad is currently blocking on a buffer or event. Use
+ * gst_pad_is_blocking() instead.
+ */
#define GST_PAD_IS_BLOCKING(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_BLOCKING))
-
+/**
+ * GST_PAD_IS_FLUSHING:
+ * @pad: a #GstPad
+ *
+ * Check if the given @pad is flushing.
+ */
#define GST_PAD_IS_FLUSHING(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_FLUSHING))
+/**
+ * GST_PAD_SET_FLUSHING:
+ * @pad: a #GstPad
+ *
+ * Set the given @pad to flushing state, which means it will not accept any
+ * more events, queries or buffers, and return GST_FLOW_FLUSHING if any buffers
+ * are pushed on it. This usually happens when the pad is shut down or when
+ * a flushing seek happens. This is used inside GStreamer when flush start/stop
+ * events pass through pads, or when an element state is changed and pads are
+ * activated or deactivated.
+ */
#define GST_PAD_SET_FLUSHING(pad) (GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_FLUSHING))
+/**
+ * GST_PAD_UNSET_FLUSHING:
+ * @pad: a #GstPad
+ *
+ * Unset the flushing flag.
+ */
#define GST_PAD_UNSET_FLUSHING(pad) (GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_FLUSHING))
-
+/**
+ * GST_PAD_IS_EOS:
+ * @pad: a #GstPad
+ *
+ * Check if the @pad is in EOS state.
+ */
#define GST_PAD_IS_EOS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_EOS))
-
+/**
+ * GST_PAD_NEEDS_RECONFIGURE:
+ * @pad: a #GstPad
+ *
+ * Check if the @pad should be reconfigured/renegotiated.
+ * The flag has to be unset manually after reconfiguration happened.
+ * Use gst_pad_needs_reconfigure() or gst_pad_check_reconfigure() instead.
+ */
#define GST_PAD_NEEDS_RECONFIGURE(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_NEED_RECONFIGURE))
+/**
+ * GST_PAD_HAS_PENDING_EVENTS:
+ * @pad: a #GstPad
+ *
+ * Check if the given @pad has pending events. This is used internally by
+ * GStreamer.
+ */
#define GST_PAD_HAS_PENDING_EVENTS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_PENDING_EVENTS))
+/**
+ * GST_PAD_IS_FIXED_CAPS:
+ * @pad: a #GstPad
+ *
+ * Check if the given @pad is using fixed caps, which means that
+ * once the caps are set on the @pad, the caps query function will
+ * only return those caps. See gst_pad_use_fixed_caps().
+ */
#define GST_PAD_IS_FIXED_CAPS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_FIXED_CAPS))
+/**
+ * GST_PAD_NEEDS_PARENT:
+ * @pad: a #GstPad
+ *
+ * Check if there is a parent object before calling into the @pad callbacks.
+ * This is used internally by GStreamer.
+ */
#define GST_PAD_NEEDS_PARENT(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_NEED_PARENT))
-
+/**
+ * GST_PAD_IS_PROXY_CAPS:
+ * @pad: a #GstPad
+ *
+ * Check if the given @pad is set to proxy caps. This means that the default
+ * event and query handler will forward all events and queries to the
+ * internally linked @pads instead of discarding them.
+ */
#define GST_PAD_IS_PROXY_CAPS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_PROXY_CAPS))
+/**
+ * GST_PAD_SET_PROXY_CAPS:
+ * @pad: a #GstPad
+ *
+ * Set @pad to proxy caps, so that all caps-related events and queries are
+ * proxied down- or upstream to the other side of the element automatically.
+ * Set this if the element always outputs data in the exact same format as it
+ * receives as input. This is just for convenience to avoid implementing some
+ * standard event and query handling code in an element.
+ */
#define GST_PAD_SET_PROXY_CAPS(pad) (GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PROXY_CAPS))
+/**
+ * GST_PAD_UNSET_PROXY_CAPS:
+ * @pad: a #GstPad
+ *
+ * Unset proxy caps flag.
+ */
#define GST_PAD_UNSET_PROXY_CAPS(pad) (GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_PROXY_CAPS))
-
+/**
+ * GST_PAD_IS_PROXY_ALLOCATION:
+ * @pad: a #GstPad
+ *
+ * Check if the given @pad is set as proxy allocation which means
+ * that the default query handler will forward allocation queries to the
+ * internally linked @pads instead of discarding them.
+ */
#define GST_PAD_IS_PROXY_ALLOCATION(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_PROXY_ALLOCATION))
+/**
+ * GST_PAD_SET_PROXY_ALLOCATION:
+ * @pad: a #GstPad
+ *
+ * Set @pad to proxy allocation queries, which means that the default query
+ * handler will forward allocation queries to the internally linked @pads
+ * instead of discarding them.
+ * Set this if the element always outputs data in the exact same format as it
+ * receives as input. This is just for convenience to avoid implementing some
+ * standard query handling code in an element.
+ */
#define GST_PAD_SET_PROXY_ALLOCATION(pad) (GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PROXY_ALLOCATION))
+/**
+ * GST_PAD_UNSET_PROXY_ALLOCATION:
+ * @pad: a #GstPad
+ *
+ * Unset proxy allocation flag.
+ */
#define GST_PAD_UNSET_PROXY_ALLOCATION(pad) (GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_PROXY_ALLOCATION))
-
+/**
+ * GST_PAD_IS_PROXY_SCHEDULING:
+ * @pad: a #GstPad
+ *
+ * Check if the given @pad is set to proxy scheduling queries, which means that
+ * the default query handler will forward scheduling queries to the internally
+ * linked @pads instead of discarding them.
+ */
#define GST_PAD_IS_PROXY_SCHEDULING(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_PROXY_SCHEDULING))
+/**
+ * GST_PAD_SET_PROXY_SCHEDULING:
+ * @pad: a #GstPad
+ *
+ * Set @pad to proxy scheduling queries, which means that the default query
+ * handler will forward scheduling queries to the internally linked @pads
+ * instead of discarding them. You will usually want to handle scheduling
+ * queries explicitly if your element supports multiple scheduling modes.
+ */
#define GST_PAD_SET_PROXY_SCHEDULING(pad) (GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PROXY_SCHEDULING))
+/**
+ * GST_PAD_UNSET_PROXY_SCHEDULING:
+ * @pad: a #GstPad
+ *
+ * Unset proxy scheduling flag.
+ */
#define GST_PAD_UNSET_PROXY_SCHEDULING(pad) (GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_PROXY_SCHEDULING))
-
+/**
+ * GST_PAD_IS_ACCEPT_INTERSECT:
+ * @pad: a #GstPad
+ *
+ * Check if the pad's accept intersect flag is set. The default accept-caps
+ * handler will check it the caps intersect the query-caps result instead of
+ * checking for a subset. This is interesting for parser elements that can
+ * accept incompletely specified caps.
+ */
+#define GST_PAD_IS_ACCEPT_INTERSECT(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_ACCEPT_INTERSECT))
+/**
+ * GST_PAD_SET_ACCEPT_INTERSECT:
+ * @pad: a #GstPad
+ *
+ * Set @pad to by default accept caps by intersecting the result instead of
+ * checking for a subset. This is interesting for parser elements that can
+ * accept incompletely specified caps.
+ */
+#define GST_PAD_SET_ACCEPT_INTERSECT(pad) (GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_ACCEPT_INTERSECT))
+/**
+ * GST_PAD_UNSET_ACCEPT_INTERSECT:
+ * @pad: a #GstPad
+ *
+ * Unset accept intersect flag.
+ */
+#define GST_PAD_UNSET_ACCEPT_INTERSECT(pad) (GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_ACCEPT_INTERSECT))
/**
* GST_PAD_GET_STREAM_LOCK:
* @pad: a #GstPad
*
* Get the stream lock of @pad. The stream lock is protecting the
- * resources used in the data processing functions of @pad.
+ * resources used in the data processing functions of @pad. Accessor
+ * macro, use GST_PAD_STREAM_LOCK() and GST_PAD_STREAM_UNLOCK() instead
+ * to take/release the pad's stream lock.
*/
#define GST_PAD_GET_STREAM_LOCK(pad) (&(GST_PAD_CAST(pad)->stream_rec_lock))
/**
* GST_PAD_STREAM_LOCK:
* @pad: a #GstPad
*
- * Lock the stream lock of @pad.
+ * Take the pad's stream lock. The stream lock is recursive and will be taken
+ * when buffers or serialized downstream events are pushed on a pad.
*/
#define GST_PAD_STREAM_LOCK(pad) g_rec_mutex_lock(GST_PAD_GET_STREAM_LOCK(pad))
/**
* GST_PAD_STREAM_TRYLOCK:
* @pad: a #GstPad
*
- * Try to Lock the stream lock of the pad, return TRUE if the lock could be
- * taken.
+ * Try to take the pad's stream lock, and return %TRUE if the lock could be
+ * taken, and otherwise %FALSE.
*/
#define GST_PAD_STREAM_TRYLOCK(pad) g_rec_mutex_trylock(GST_PAD_GET_STREAM_LOCK(pad))
/**
* GST_PAD_STREAM_UNLOCK:
* @pad: a #GstPad
*
- * Unlock the stream lock of @pad.
+ * Release the pad's stream lock.
*/
#define GST_PAD_STREAM_UNLOCK(pad) g_rec_mutex_unlock(GST_PAD_GET_STREAM_LOCK(pad))
+/**
+ * GST_PAD_LAST_FLOW_RETURN:
+ * @pad: a #GstPad
+ *
+ * Gets the last flow return on this pad
+ *
+ * Since: 1.4
+ */
+#define GST_PAD_LAST_FLOW_RETURN(pad) (GST_PAD_CAST(pad)->ABI.abi.last_flowret)
#define GST_PAD_BLOCK_GET_COND(pad) (&GST_PAD_CAST(pad)->block_cond)
#define GST_PAD_BLOCK_WAIT(pad) (g_cond_wait(GST_PAD_BLOCK_GET_COND (pad), GST_OBJECT_GET_LOCK (pad)))
@@ -848,7 +1183,7 @@ GstPad* gst_pad_new_from_static_template (GstStaticPadTemplate *templ, const g
*
* Get the parent of @pad. This function increases the refcount
* of the parent object so you should gst_object_unref() it after usage.
- * Can return NULL if the pad did not have a parent.
+ * Can return %NULL if the pad did not have a parent.
*
* MT safe.
*/
@@ -961,6 +1296,7 @@ GstFlowReturn gst_pad_pull_range (GstPad *pad, guint64 offset, guint size,
gboolean gst_pad_push_event (GstPad *pad, GstEvent *event);
gboolean gst_pad_event_default (GstPad *pad, GstObject *parent,
GstEvent *event);
+GstFlowReturn gst_pad_get_last_flow_return (GstPad *pad);
/* data passing functions on pad */
GstFlowReturn gst_pad_chain (GstPad *pad, GstBuffer *buffer);
@@ -1000,8 +1336,6 @@ gboolean gst_pad_query_default (GstPad *pad, GstObject *parent,
gboolean gst_pad_forward (GstPad *pad, GstPadForwardFunction forward,
gpointer user_data);
-const gchar * gst_pad_mode_get_name (GstPadMode mode);
-
G_END_DECLS
#endif /* __GST_PAD_H__ */
diff --git a/gst/gstpadtemplate.c b/gst/gstpadtemplate.c
index c7c4914..8eac996 100644
--- a/gst/gstpadtemplate.c
+++ b/gst/gstpadtemplate.c
@@ -54,9 +54,7 @@
* (see gst_element_class_add_pad_template ()).
*
* The following code example shows the code to create a pad from a padtemplate.
- * <example>
- * <title>Create a pad from a padtemplate</title>
- * <programlisting>
+ * |[
* GstStaticPadTemplate my_template =
* GST_STATIC_PAD_TEMPLATE (
* "sink", // the name of the pad
@@ -74,13 +72,11 @@
* pad = gst_pad_new_from_static_template (&amp;my_template, "sink");
* ...
* }
- * </programlisting>
- * </example>
+ * ]|
*
* The following example shows you how to add the padtemplate to an
* element class, this is usually done in the class_init of the class:
- * <informalexample>
- * <programlisting>
+ * |[
* static void
* my_element_class_init (GstMyElementClass *klass)
* {
@@ -89,10 +85,7 @@
* gst_element_class_add_pad_template (gstelement_class,
* gst_static_pad_template_get (&amp;my_template));
* }
- * </programlisting>
- * </informalexample>
- *
- * Last reviewed on 2006-02-14 (0.10.3)
+ * ]|
*/
#include "gst_private.h"
diff --git a/gst/gstpadtemplate.h b/gst/gstpadtemplate.h
index 2700e9b..636b143 100644
--- a/gst/gstpadtemplate.h
+++ b/gst/gstpadtemplate.h
@@ -52,7 +52,7 @@ G_BEGIN_DECLS
* @GST_PAD_ALWAYS: the pad is always available
* @GST_PAD_SOMETIMES: the pad will become available depending on the media stream
* @GST_PAD_REQUEST: the pad is only available on request with
- * gst_element_get_request_pad().
+ * gst_element_request_pad().
*
* Indicates when this pad will become available.
*/
diff --git a/gst/gstparamspecs.c b/gst/gstparamspecs.c
index 0777c6a..6425e18 100644
--- a/gst/gstparamspecs.c
+++ b/gst/gstparamspecs.c
@@ -22,8 +22,6 @@
* to GStreamer
*
* GParamSpec implementations specific to GStreamer.
- *
- * Last reviewed on 2008-03-11 (0.10.18)
*/
#ifdef HAVE_CONFIG_H
diff --git a/gst/gstparse.c b/gst/gstparse.c
index a23cafa..dd22113 100644
--- a/gst/gstparse.c
+++ b/gst/gstparse.c
@@ -139,7 +139,7 @@ gst_parse_context_free (GstParseContext * context)
* of %GST_PARSE_ERROR_NO_SUCH_ELEMENT was returned.
*
* Returns: (transfer full) (array zero-terminated=1) (element-type gchar*): a
- * NULL-terminated array of element factory name strings of missing
+ * %NULL-terminated array of element factory name strings of missing
* elements. Free with g_strfreev() when no longer needed.
*/
gchar **
@@ -204,7 +204,7 @@ _gst_parse_escape (const gchar * str)
* @error: pointer to a #GError
*
* Create a new element based on command line syntax.
- * @error will contain an error message if an erroneuos pipeline is specified.
+ * @error will contain an error message if an erroneous pipeline is specified.
* An error does not mean that the pipeline could not be constructed.
*
* Returns: (transfer floating): a new element on success and %NULL on failure.
@@ -314,6 +314,7 @@ gst_parse_launch_full (const gchar * pipeline_description,
{
#ifndef GST_DISABLE_PARSE
GstElement *element;
+ GError *myerror = NULL;
g_return_val_if_fail (pipeline_description != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
@@ -321,16 +322,20 @@ gst_parse_launch_full (const gchar * pipeline_description,
GST_CAT_INFO (GST_CAT_PIPELINE, "parsing pipeline description '%s'",
pipeline_description);
- element = priv_gst_parse_launch (pipeline_description, error, context, flags);
+ element = priv_gst_parse_launch (pipeline_description, &myerror, context,
+ flags);
/* don't return partially constructed pipeline if FATAL_ERRORS was given */
- if (G_UNLIKELY (error != NULL && *error != NULL && element != NULL)) {
+ if (G_UNLIKELY (myerror != NULL && element != NULL)) {
if ((flags & GST_PARSE_FLAG_FATAL_ERRORS)) {
gst_object_unref (element);
element = NULL;
}
}
+ if (myerror)
+ g_propagate_error (error, myerror);
+
return element;
#else
gchar *msg;
diff --git a/gst/gstparse.h b/gst/gstparse.h
index de437b1..b1ec83d 100644
--- a/gst/gstparse.h
+++ b/gst/gstparse.h
@@ -37,7 +37,7 @@ GQuark gst_parse_error_quark (void);
/**
* GstParseError:
- * @GST_PARSE_ERROR_SYNTAX: A syntax error occured.
+ * @GST_PARSE_ERROR_SYNTAX: A syntax error occurred.
* @GST_PARSE_ERROR_NO_SUCH_ELEMENT: The description contained an unknown element
* @GST_PARSE_ERROR_NO_SUCH_PROPERTY: An element did not have a specified property
* @GST_PARSE_ERROR_LINK: There was an error linking two pads.
@@ -61,7 +61,7 @@ typedef enum
/**
* GstParseFlags:
* @GST_PARSE_FLAG_NONE: Do not use any special parsing options.
- * @GST_PARSE_FLAG_FATAL_ERRORS: Always return NULL when an error occurs
+ * @GST_PARSE_FLAG_FATAL_ERRORS: Always return %NULL when an error occurs
* (default behaviour is to return partially constructed bins or elements
* in some cases)
* @GST_PARSE_FLAG_NO_SINGLE_ELEMENT_BINS: If a bin only has a single element,
diff --git a/gst/gstpipeline.c b/gst/gstpipeline.c
index 5d1d4ae..21e0620 100644
--- a/gst/gstpipeline.c
+++ b/gst/gstpipeline.c
@@ -71,8 +71,6 @@
* between the clock time and the base time) will count how much time was spent
* in the PLAYING state. This default behaviour can be changed with the
* gst_element_set_start_time() method.
- *
- * Last reviewed on 2012-03-29 (0.11.3)
*/
#include "gst_private.h"
@@ -654,7 +652,7 @@ gst_pipeline_get_clock (GstPipeline * pipeline)
* always use the given clock even if new clock providers are added
* to this pipeline.
*
- * If @clock is NULL all clocking will be disabled which will make
+ * If @clock is %NULL all clocking will be disabled which will make
* the pipeline run as fast as possible.
*
* MT safe.
@@ -685,7 +683,7 @@ gst_pipeline_use_clock (GstPipeline * pipeline, GstClock * clock)
* Set the clock for @pipeline. The clock will be distributed
* to all the elements managed by the pipeline.
*
- * Returns: TRUE if the clock could be set on the pipeline. FALSE if
+ * Returns: %TRUE if the clock could be set on the pipeline. %FALSE if
* some element did not accept the clock.
*
* MT safe.
diff --git a/gst/gstplugin.c b/gst/gstplugin.c
index d6a9b76..9bfacc1 100644
--- a/gst/gstplugin.c
+++ b/gst/gstplugin.c
@@ -39,7 +39,7 @@
* Once you have a handle to a #GstPlugin (e.g. from the #GstRegistry), you
* can add any object that subclasses #GstPluginFeature.
*
- * Usually plugins are always automaticlly loaded so you don't need to call
+ * Usually plugins are always automatically loaded so you don't need to call
* gst_plugin_load() explicitly to bring it into memory. There are options to
* statically link plugins to an app or even use GStreamer without a plugin
* repository in which case gst_plugin_load() can be needed to bring the plugin
@@ -193,7 +193,7 @@ gst_plugin_error_quark (void)
* You must make sure that GStreamer has been initialised (with gst_init() or
* via gst_init_get_option_group()) before calling this function.
*
- * Returns: TRUE if the plugin was registered correctly, otherwise FALSE.
+ * Returns: %TRUE if the plugin was registered correctly, otherwise %FALSE.
*/
gboolean
gst_plugin_register_static (gint major_version, gint minor_version,
@@ -258,7 +258,7 @@ gst_plugin_register_static (gint major_version, gint minor_version,
* You must make sure that GStreamer has been initialised (with gst_init() or
* via gst_init_get_option_group()) before calling this function.
*
- * Returns: TRUE if the plugin was registered correctly, otherwise FALSE.
+ * Returns: %TRUE if the plugin was registered correctly, otherwise %FALSE.
*/
gboolean
gst_plugin_register_static_full (gint major_version, gint minor_version,
@@ -657,18 +657,21 @@ static GMutex gst_plugin_loading_mutex;
#define CHECK_PLUGIN_DESC_FIELD(desc,field,fn) \
if (G_UNLIKELY ((desc)->field == NULL || *(desc)->field == '\0')) { \
g_warning ("Plugin description for '%s' has no valid %s field", fn, G_STRINGIFY (field)); \
+ g_set_error (error, GST_PLUGIN_ERROR, GST_PLUGIN_ERROR_MODULE, \
+ "Plugin %s has invalid plugin description field '%s'", \
+ filename, G_STRINGIFY (field)); \
goto return_error; \
}
/**
* gst_plugin_load_file:
* @filename: the plugin filename to load
- * @error: pointer to a NULL-valued GError
+ * @error: pointer to a %NULL-valued GError
*
* Loads the given plugin and refs it. Caller needs to unref after use.
*
* Returns: (transfer full): a reference to the existing loaded GstPlugin, a
- * reference to the newly-loaded GstPlugin, or NULL if an error occurred.
+ * reference to the newly-loaded GstPlugin, or %NULL if an error occurred.
*/
GstPlugin *
gst_plugin_load_file (const gchar * filename, GError ** error)
@@ -1019,7 +1022,7 @@ gst_plugin_get_release_date_string (GstPlugin * plugin)
*
* queries if the plugin is loaded into memory
*
- * Returns: TRUE is loaded, FALSE otherwise
+ * Returns: %TRUE is loaded, %FALSE otherwise
*/
gboolean
gst_plugin_is_loaded (GstPlugin * plugin)
@@ -1162,7 +1165,7 @@ gst_plugin_list_feature_filter (GList * list,
*
* Find a feature of the given name and type in the given plugin.
*
- * Returns: a GstPluginFeature or NULL if the feature was not found.
+ * Returns: a GstPluginFeature or %NULL if the feature was not found.
*/
GstPluginFeature *
gst_plugin_find_feature (GstPlugin * plugin, const gchar * name, GType type)
@@ -1206,7 +1209,7 @@ gst_plugin_feature_name_filter (GstPluginFeature * feature, const gchar * name)
*
* Find a feature of the given name in the given plugin.
*
- * Returns: a GstPluginFeature or NULL if the feature was not found.
+ * Returns: a GstPluginFeature or %NULL if the feature was not found.
*/
GstPluginFeature *
gst_plugin_find_feature_by_name (GstPlugin * plugin, const gchar * name)
@@ -1236,7 +1239,7 @@ gst_plugin_find_feature_by_name (GstPlugin * plugin, const gchar * name)
*
* Load the named plugin. Refs the plugin.
*
- * Returns: (transfer full): a reference to a loaded plugin, or NULL on error.
+ * Returns: (transfer full): a reference to a loaded plugin, or %NULL on error.
*/
GstPlugin *
gst_plugin_load_by_name (const gchar * name)
@@ -1279,7 +1282,7 @@ gst_plugin_load_by_name (const gchar * name)
* plugin = loaded_plugin;
* </programlisting>
*
- * Returns: (transfer full): a reference to a loaded plugin, or NULL on error.
+ * Returns: (transfer full): a reference to a loaded plugin, or %NULL on error.
*/
GstPlugin *
gst_plugin_load (GstPlugin * plugin)
@@ -1708,18 +1711,18 @@ gst_plugin_ext_dep_equals (GstPluginDep * dep, const gchar ** env_vars,
/**
* gst_plugin_add_dependency:
* @plugin: a #GstPlugin
- * @env_vars: (allow-none): NULL-terminated array of environment variables affecting the
+ * @env_vars: (allow-none): %NULL-terminated array of environment variables affecting the
* feature set of the plugin (e.g. an environment variable containing
* paths where to look for additional modules/plugins of a library),
- * or NULL. Environment variable names may be followed by a path component
+ * or %NULL. Environment variable names may be followed by a path component
* which will be added to the content of the environment variable, e.g.
* "HOME/.mystuff/plugins".
- * @paths: (allow-none): NULL-terminated array of directories/paths where dependent files
- * may be, or NULL.
- * @names: (allow-none): NULL-terminated array of file names (or file name suffixes,
+ * @paths: (allow-none): %NULL-terminated array of directories/paths where dependent files
+ * may be, or %NULL.
+ * @names: (allow-none): %NULL-terminated array of file names (or file name suffixes,
* depending on @flags) to be used in combination with the paths from
* @paths and/or the paths extracted from the environment variables in
- * @env_vars, or NULL.
+ * @env_vars, or %NULL.
* @flags: optional flags, or #GST_PLUGIN_DEPENDENCY_FLAG_NONE
*
* Make GStreamer aware of external dependencies which affect the feature
@@ -1780,13 +1783,13 @@ gst_plugin_add_dependency (GstPlugin * plugin, const gchar ** env_vars,
* gst_plugin_add_dependency_simple:
* @plugin: the #GstPlugin
* @env_vars: (allow-none): one or more environment variables (separated by ':', ';' or ','),
- * or NULL. Environment variable names may be followed by a path component
+ * or %NULL. Environment variable names may be followed by a path component
* which will be added to the content of the environment variable, e.g.
* "HOME/.mystuff/plugins:MYSTUFF_PLUGINS_PATH"
* @paths: (allow-none): one ore more directory paths (separated by ':' or ';' or ','),
- * or NULL. Example: "/usr/lib/mystuff/plugins"
+ * or %NULL. Example: "/usr/lib/mystuff/plugins"
* @names: (allow-none): one or more file names or file name suffixes (separated by commas),
- * or NULL
+ * or %NULL
* @flags: optional flags, or #GST_PLUGIN_DEPENDENCY_FLAG_NONE
*
* Make GStreamer aware of external dependencies which affect the feature
diff --git a/gst/gstplugin.h b/gst/gstplugin.h
index 66ede12..500be30 100644
--- a/gst/gstplugin.h
+++ b/gst/gstplugin.h
@@ -146,7 +146,7 @@ typedef gboolean (*GstPluginInitFullFunc) (GstPlugin *plugin, gpointer user_data
* @package: shipped package plugin belongs to
* @origin: URL to provider of plugin
* @release_datetime: date time string in ISO 8601 format (or rather, a
- * subset thereof), or NULL. Allowed are the following formats:
+ * subset thereof), or %NULL. Allowed are the following formats:
* "YYYY-MM-DD" and "YYY-MM-DDTHH:MMZ" (with 'T' a separator and 'Z'
* indicating UTC/Zulu time). This field should be set via the
* GST_PACKAGE_RELEASE_DATETIME preprocessor macro.
@@ -198,7 +198,7 @@ struct _GstPluginDesc {
* and must be placed outside any block to declare the plugin initialization
* function.
*
- * Since: 1.2.0
+ * Since: 1.2
*/
#define GST_PLUGIN_STATIC_DECLARE(name) \
extern void G_PASTE(gst_plugin_, G_PASTE(name, _register)) (void)
@@ -212,7 +212,7 @@ struct _GstPluginDesc {
* It has to be used in combination with GST_PLUGIN_STATIC_DECLARE and
* calls the plugin initialization function.
*
- * Since: 1.2.0
+ * Since: 1.2
*/
#define GST_PLUGIN_STATIC_REGISTER(name) G_PASTE(gst_plugin_, G_PASTE(name, _register)) ()
@@ -277,7 +277,7 @@ G_END_DECLS
/**
* GST_LICENSE_UNKNOWN:
*
- * To be used in GST_PLUGIN_DEFINE if usure about the licence.
+ * To be used in GST_PLUGIN_DEFINE if unsure about the licence.
*/
#define GST_LICENSE_UNKNOWN "unknown"
@@ -291,7 +291,7 @@ G_END_DECLS
* A function that can be used with e.g. gst_registry_plugin_filter()
* to get a list of plugins that match certain criteria.
*
- * Returns: TRUE for a positive match, FALSE otherwise
+ * Returns: %TRUE for a positive match, %FALSE otherwise
*/
typedef gboolean (*GstPluginFilter) (GstPlugin *plugin,
gpointer user_data);
diff --git a/gst/gstpluginfeature.c b/gst/gstpluginfeature.c
index 6dd5e56..6672f7b 100644
--- a/gst/gstpluginfeature.c
+++ b/gst/gstpluginfeature.c
@@ -90,7 +90,7 @@ gst_plugin_feature_finalize (GObject * object)
* feature = loaded_feature;
* ]|
*
- * Returns: (transfer full): a reference to the loaded feature, or NULL on error
+ * Returns: (transfer full): a reference to the loaded feature, or %NULL on error
*/
GstPluginFeature *
gst_plugin_feature_load (GstPluginFeature * feature)
@@ -208,7 +208,7 @@ gst_plugin_feature_get_plugin (GstPluginFeature * feature)
* Returns: the name of the plugin that provides this feature, or %NULL if
* the feature is not associated with a plugin.
*
- * Since: 1.2.0
+ * Since: 1.2
*/
const gchar *
gst_plugin_feature_get_plugin_name (GstPluginFeature * feature)
@@ -307,8 +307,8 @@ gst_plugin_feature_list_debug (GList * list)
* Checks whether the given plugin feature is at least
* the required version
*
- * Returns: #TRUE if the plugin feature has at least
- * the required version, otherwise #FALSE.
+ * Returns: %TRUE if the plugin feature has at least
+ * the required version, otherwise %FALSE.
*/
gboolean
gst_plugin_feature_check_version (GstPluginFeature * feature,
diff --git a/gst/gstpluginfeature.h b/gst/gstpluginfeature.h
index ca9f0d3..bc01969 100644
--- a/gst/gstpluginfeature.h
+++ b/gst/gstpluginfeature.h
@@ -73,7 +73,7 @@ typedef enum {
* @feature: a #GstPluginFeature to get the name of @feature.
*
* Returns the name of @feature.
- * For a nameless plugin feature, this returns NULL.
+ * For a nameless plugin feature, this returns %NULL.
*
* Returns: (transfer none): the name of @feature. MT safe.
*
diff --git a/gst/gstpluginloader.c b/gst/gstpluginloader.c
index 13a8fd5..96d4994 100644
--- a/gst/gstpluginloader.c
+++ b/gst/gstpluginloader.c
@@ -33,8 +33,13 @@
#include <fcntl.h>
#include <unistd.h>
#else
+#define WIN32_LEAN_AND_MEAN
+
#define fsync(fd) _commit(fd)
#include <io.h>
+
+#include <windows.h>
+extern HMODULE _priv_gst_dll_handle;
#endif
#ifdef HAVE_SYS_UTSNAME_H
@@ -470,7 +475,22 @@ gst_plugin_loader_spawn (GstPluginLoader * loader)
if (!res) {
GST_LOG ("Trying installed plugin scanner");
+
+#ifdef G_OS_WIN32
+ {
+ gchar *basedir;
+
+ basedir = g_win32_get_package_installation_directory_of_module (_priv_gst_dll_handle);
+ helper_bin = g_build_filename (basedir,
+ "lib",
+ "gstreamer-" GST_API_VERSION,
+ "gst-plugin-scanner.exe",
+ NULL);
+ g_free (basedir);
+ }
+#else
helper_bin = g_strdup (GST_PLUGIN_SCANNER_INSTALLED);
+#endif
res = gst_plugin_loader_try_helper (loader, helper_bin);
g_free (helper_bin);
@@ -508,6 +528,7 @@ plugin_loader_cleanup_child (GstPluginLoader * l)
gboolean
_gst_plugin_loader_client_run (void)
{
+ gboolean res = TRUE;
GstPluginLoader *l;
l = plugin_loader_new (NULL);
@@ -524,7 +545,8 @@ _gst_plugin_loader_client_run (void)
dup_fd = dup (0); /* STDIN */
if (dup_fd == -1) {
GST_ERROR ("Failed to start. Could no dup STDIN, errno %d", errno);
- return FALSE;
+ res = FALSE;
+ goto beach;
}
l->fd_r.fd = dup_fd;
close (0);
@@ -532,7 +554,8 @@ _gst_plugin_loader_client_run (void)
dup_fd = dup (1); /* STDOUT */
if (dup_fd == -1) {
GST_ERROR ("Failed to start. Could no dup STDOUT, errno %d", errno);
- return FALSE;
+ res = FALSE;
+ goto beach;
}
l->fd_w.fd = dup_fd;
close (1);
@@ -558,9 +581,13 @@ _gst_plugin_loader_client_run (void)
/* Loop, listening for incoming packets on the fd and writing responses */
while (!l->rx_done && exchange_packets (l));
+#ifndef G_OS_WIN32
+beach:
+#endif
+
plugin_loader_free (l);
- return TRUE;
+ return res;
}
static void
diff --git a/gst/gstpoll.c b/gst/gstpoll.c
index 03c2a14..6694a87 100644
--- a/gst/gstpoll.c
+++ b/gst/gstpoll.c
@@ -24,7 +24,7 @@
/**
* SECTION:gstpoll
* @short_description: Keep track of file descriptors and make it possible
- * to wait on them in a cancelable way
+ * to wait on them in a cancellable way
*
* A #GstPoll keeps track of file descriptors much like fd_set (used with
* select()) or a struct pollfd array (used with poll()). Once created with
@@ -553,9 +553,8 @@ gst_poll_new (gboolean controllable)
{
GstPoll *nset;
- GST_DEBUG ("controllable : %d", controllable);
-
nset = g_slice_new0 (GstPoll);
+ GST_DEBUG ("%p: new controllable : %d", nset, controllable);
g_mutex_init (&nset->lock);
#ifndef G_OS_WIN32
nset->mode = GST_POLL_MODE_AUTO;
@@ -870,7 +869,7 @@ gst_poll_fd_ctl_write (GstPoll * set, GstPollFD * fd, gboolean active)
else
pfd->events &= ~POLLOUT;
- GST_LOG ("pfd->events now %d (POLLOUT:%d)", pfd->events, POLLOUT);
+ GST_LOG ("%p: pfd->events now %d (POLLOUT:%d)", set, pfd->events, POLLOUT);
#else
gst_poll_update_winsock_event_mask (set, idx, FD_WRITE | FD_CONNECT,
active);
@@ -1193,7 +1192,7 @@ gst_poll_wait (GstPoll * set, GstClockTime timeout)
g_return_val_if_fail (set != NULL, -1);
- GST_DEBUG ("timeout :%" GST_TIME_FORMAT, GST_TIME_ARGS (timeout));
+ GST_DEBUG ("%p: timeout :%" GST_TIME_FORMAT, set, GST_TIME_ARGS (timeout));
is_timer = set->timer;
@@ -1304,9 +1303,9 @@ gst_poll_wait (GstPoll * set, GstClockTime timeout)
tvptr = NULL;
}
- GST_DEBUG ("Calling select");
+ GST_DEBUG ("%p: Calling select", set);
res = select (max_fd + 1, &readfds, &writefds, &errorfds, tvptr);
- GST_DEBUG ("After select, res:%d", res);
+ GST_DEBUG ("%p: After select, res:%d", set, res);
} else {
#ifdef HAVE_PSELECT
struct timespec ts;
@@ -1319,10 +1318,10 @@ gst_poll_wait (GstPoll * set, GstClockTime timeout)
tsptr = NULL;
}
- GST_DEBUG ("Calling pselect");
+ GST_DEBUG ("%p: Calling pselect", set);
res =
pselect (max_fd + 1, &readfds, &writefds, &errorfds, tsptr, NULL);
- GST_DEBUG ("After pselect, res:%d", res);
+ GST_DEBUG ("%p: After pselect, res:%d", set, res);
#endif
}
diff --git a/gst/gstpreset.c b/gst/gstpreset.c
index 6a0b181..19f0fbb 100644
--- a/gst/gstpreset.c
+++ b/gst/gstpreset.c
@@ -78,6 +78,13 @@
#endif
#include <glib/gstdio.h>
+#ifdef G_OS_WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+extern HMODULE _priv_gst_dll_handle;
+#endif
+
#define GST_CAT_DEFAULT preset_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
@@ -175,8 +182,18 @@ preset_get_paths (GstPreset * preset, const gchar ** preset_user_path,
gchar *preset_dir;
/* system presets in '$GST_DATADIR/gstreamer-1.0/presets/GstAudioPanorama.prs' */
+#ifdef G_OS_WIN32
+ gchar *basedir =
+ g_win32_get_package_installation_directory_of_module
+ (_priv_gst_dll_handle);
+ preset_dir =
+ g_build_filename (basedir, "share", "gstreamer-" GST_API_VERSION,
+ "presets", NULL);
+ g_free (basedir);
+#else
preset_dir = g_build_filename (GST_DATADIR, "gstreamer-" GST_API_VERSION,
"presets", NULL);
+#endif
GST_INFO_OBJECT (preset, "system_preset_dir: '%s'", preset_dir);
preset_path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s.prs",
preset_dir, element_name);
@@ -514,6 +531,8 @@ gst_preset_default_get_property_names (GstPreset * preset)
}
g_free (props);
}
+
+ g_object_unref (child);
}
}
if (!result) {
@@ -937,10 +956,10 @@ no_presets:
* gst_preset_get_preset_names:
* @preset: a #GObject that implements #GstPreset
*
- * Get a copy of preset names as a NULL terminated string array.
+ * Get a copy of preset names as a %NULL terminated string array.
*
* Returns: (transfer full) (array zero-terminated=1) (element-type gchar*):
- * list with names, ue g_strfreev() after usage.
+ * list with names, use g_strfreev() after usage.
*/
gchar **
gst_preset_get_preset_names (GstPreset * preset)
diff --git a/gst/gstquark.c b/gst/gstquark.c
index 5598b99..cf5c766 100644
--- a/gst/gstquark.c
+++ b/gst/gstquark.c
@@ -68,7 +68,9 @@ static const gchar *_quark_strings[] = {
"GstEventSegmentDone",
"GstEventStreamStart", "stream-id", "GstQueryContext",
"GstMessageNeedContext", "GstMessageHaveContext", "context", "context-type",
- "GstMessageStreamStart", "group-id", "uri-redirection"
+ "GstMessageStreamStart", "group-id", "uri-redirection",
+ "GstMessageDeviceAdded", "GstMessageDeviceRemoved", "device",
+ "uri-redirection-permanent"
};
GQuark _priv_gst_quark_table[GST_QUARK_MAX];
diff --git a/gst/gstquark.h b/gst/gstquark.h
index 025f508..98bfdd0 100644
--- a/gst/gstquark.h
+++ b/gst/gstquark.h
@@ -196,7 +196,11 @@ typedef enum _GstQuarkId
GST_QUARK_MESSAGE_STREAM_START = 167,
GST_QUARK_GROUP_ID = 168,
GST_QUARK_URI_REDIRECTION = 169,
- GST_QUARK_MAX = 170
+ GST_QUARK_MESSAGE_DEVICE_ADDED = 170,
+ GST_QUARK_MESSAGE_DEVICE_REMOVED = 171,
+ GST_QUARK_DEVICE = 172,
+ GST_QUARK_URI_REDIRECTION_PERMANENT = 173,
+ GST_QUARK_MAX = 174
} GstQuarkId;
extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];
diff --git a/gst/gstquery.c b/gst/gstquery.c
index 48a9022..78a04fa 100644
--- a/gst/gstquery.c
+++ b/gst/gstquery.c
@@ -36,27 +36,20 @@
* gst_query_parse_*() helpers.
*
* The following example shows how to query the duration of a pipeline:
- *
- * <example>
- * <title>Query duration on a pipeline</title>
- * <programlisting>
- * GstQuery *query;
- * gboolean res;
- * query = gst_query_new_duration (GST_FORMAT_TIME);
- * res = gst_element_query (pipeline, query);
- * if (res) {
- * gint64 duration;
- * gst_query_parse_duration (query, NULL, &amp;duration);
- * g_print ("duration = %"GST_TIME_FORMAT, GST_TIME_ARGS (duration));
- * }
- * else {
- * g_print ("duration query failed...");
- * }
- * gst_query_unref (query);
- * </programlisting>
- * </example>
- *
- * Last reviewed on 2012-03-29 (0.11.3)
+ * |[
+ * GstQuery *query;
+ * gboolean res;
+ * query = gst_query_new_duration (GST_FORMAT_TIME);
+ * res = gst_element_query (pipeline, query);
+ * if (res) {
+ * gint64 duration;
+ * gst_query_parse_duration (query, NULL, &amp;duration);
+ * g_print ("duration = %"GST_TIME_FORMAT, GST_TIME_ARGS (duration));
+ * } else {
+ * g_print ("duration query failed...");
+ * }
+ * gst_query_unref (query);
+ * ]|
*/
@@ -72,7 +65,7 @@
GST_DEBUG_CATEGORY_STATIC (gst_query_debug);
#define GST_CAT_DEFAULT gst_query_debug
-static GType _gst_query_type = 0;
+GType _gst_query_type = 0;
typedef struct
{
@@ -275,11 +268,11 @@ gst_query_set_position (GstQuery * query, GstFormat format, gint64 cur)
* gst_query_parse_position:
* @query: a #GstQuery
* @format: (out) (allow-none): the storage for the #GstFormat of the
- * position values (may be NULL)
- * @cur: (out) (allow-none): the storage for the current position (may be NULL)
+ * position values (may be %NULL)
+ * @cur: (out) (allow-none): the storage for the current position (may be %NULL)
*
* Parse a position query, writing the format into @format, and the position
- * into @cur, if the respective parameters are non-NULL.
+ * into @cur, if the respective parameters are non-%NULL.
*/
void
gst_query_parse_position (GstQuery * query, GstFormat * format, gint64 * cur)
@@ -352,11 +345,11 @@ gst_query_set_duration (GstQuery * query, GstFormat format, gint64 duration)
* gst_query_parse_duration:
* @query: a #GstQuery
* @format: (out) (allow-none): the storage for the #GstFormat of the duration
- * value, or NULL.
- * @duration: (out) (allow-none): the storage for the total duration, or NULL.
+ * value, or %NULL.
+ * @duration: (out) (allow-none): the storage for the total duration, or %NULL.
*
* Parse a duration query answer. Write the format of the duration into @format,
- * and the value into @duration, if the respective variables are non-NULL.
+ * and the value into @duration, if the respective variables are non-%NULL.
*/
void
gst_query_parse_duration (GstQuery * query, GstFormat * format,
@@ -431,9 +424,9 @@ gst_query_set_latency (GstQuery * query, gboolean live,
/**
* gst_query_parse_latency:
* @query: a #GstQuery
- * @live: (out) (allow-none): storage for live or NULL
- * @min_latency: (out) (allow-none): the storage for the min latency or NULL
- * @max_latency: (out) (allow-none): the storage for the max latency or NULL
+ * @live: (out) (allow-none): storage for live or %NULL
+ * @min_latency: (out) (allow-none): the storage for the min latency or %NULL
+ * @max_latency: (out) (allow-none): the storage for the max latency or %NULL
*
* Parse a latency query answer.
*/
@@ -520,15 +513,15 @@ gst_query_set_convert (GstQuery * query, GstFormat src_format, gint64 src_value,
* gst_query_parse_convert:
* @query: a #GstQuery
* @src_format: (out) (allow-none): the storage for the #GstFormat of the
- * source value, or NULL
- * @src_value: (out) (allow-none): the storage for the source value, or NULL
+ * source value, or %NULL
+ * @src_value: (out) (allow-none): the storage for the source value, or %NULL
* @dest_format: (out) (allow-none): the storage for the #GstFormat of the
- * destination value, or NULL
+ * destination value, or %NULL
* @dest_value: (out) (allow-none): the storage for the destination value,
- * or NULL
+ * or %NULL
*
* Parse a convert query answer. Any of @src_format, @src_value, @dest_format,
- * and @dest_value may be NULL, in which case that value is omitted.
+ * and @dest_value may be %NULL, in which case that value is omitted.
*/
void
gst_query_parse_convert (GstQuery * query, GstFormat * src_format,
@@ -623,14 +616,14 @@ gst_query_set_segment (GstQuery * query, gdouble rate, GstFormat format,
/**
* gst_query_parse_segment:
* @query: a #GstQuery
- * @rate: (out) (allow-none): the storage for the rate of the segment, or NULL
+ * @rate: (out) (allow-none): the storage for the rate of the segment, or %NULL
* @format: (out) (allow-none): the storage for the #GstFormat of the values,
- * or NULL
- * @start_value: (out) (allow-none): the storage for the start value, or NULL
- * @stop_value: (out) (allow-none): the storage for the stop value, or NULL
+ * or %NULL
+ * @start_value: (out) (allow-none): the storage for the start value, or %NULL
+ * @stop_value: (out) (allow-none): the storage for the stop value, or %NULL
*
* Parse a segment query answer. Any of @rate, @format, @start_value, and
- * @stop_value may be NULL, which will cause this value to be omitted.
+ * @stop_value may be %NULL, which will cause this value to be omitted.
*
* See gst_query_set_segment() for an explanation of the function arguments.
*/
@@ -727,7 +720,7 @@ gst_query_get_structure (GstQuery * query)
* @query: a #GstQuery
*
* Get the structure of a query. This method should be called with a writable
- * @query so that the returned structure is guranteed to be writable.
+ * @query so that the returned structure is guaranteed to be writable.
*
* Returns: (transfer none): the #GstStructure of the query. The structure is
* still owned by the query and will therefore be freed when the query
@@ -801,14 +794,14 @@ gst_query_set_seeking (GstQuery * query, GstFormat format,
* gst_query_parse_seeking:
* @query: a GST_QUERY_SEEKING type query #GstQuery
* @format: (out) (allow-none): the format to set for the @segment_start
- * and @segment_end values, or NULL
- * @seekable: (out) (allow-none): the seekable flag to set, or NULL
- * @segment_start: (out) (allow-none): the segment_start to set, or NULL
- * @segment_end: (out) (allow-none): the segment_end to set, or NULL
+ * and @segment_end values, or %NULL
+ * @seekable: (out) (allow-none): the seekable flag to set, or %NULL
+ * @segment_start: (out) (allow-none): the segment_start to set, or %NULL
+ * @segment_end: (out) (allow-none): the segment_end to set, or %NULL
*
* Parse a seeking query, writing the format into @format, and
* other results into the passed parameters, if the respective parameters
- * are non-NULL
+ * are non-%NULL
*/
void
gst_query_parse_seeking (GstQuery * query, GstFormat * format,
@@ -1081,8 +1074,8 @@ gst_query_set_buffering_percent (GstQuery * query, gboolean busy, gint percent)
/**
* gst_query_parse_buffering_percent:
* @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
- * @busy: (out) (allow-none): if buffering is busy, or NULL
- * @percent: (out) (allow-none): a buffering percent, or NULL
+ * @busy: (out) (allow-none): if buffering is busy, or %NULL
+ * @percent: (out) (allow-none): a buffering percent, or %NULL
*
* Get the percentage of buffered data. This is a value between 0 and 100.
* The @busy indicator is %TRUE when the buffering is in progress.
@@ -1134,11 +1127,11 @@ gst_query_set_buffering_stats (GstQuery * query, GstBufferingMode mode,
/**
* gst_query_parse_buffering_stats:
* @query: A valid #GstQuery of type GST_QUERY_BUFFERING.
- * @mode: (out) (allow-none): a buffering mode, or NULL
- * @avg_in: (out) (allow-none): the average input rate, or NULL
- * @avg_out: (out) (allow-none): the average output rat, or NULLe
+ * @mode: (out) (allow-none): a buffering mode, or %NULL
+ * @avg_in: (out) (allow-none): the average input rate, or %NULL
+ * @avg_out: (out) (allow-none): the average output rat, or %NULL
* @buffering_left: (out) (allow-none): amount of buffering time left in
- * milliseconds, or NULL
+ * milliseconds, or %NULL
*
* Extracts the buffering stats values from @query.
*/
@@ -1175,7 +1168,7 @@ gst_query_parse_buffering_stats (GstQuery * query,
* @start: the start to set
* @stop: the stop to set
* @estimated_total: estimated total amount of download time remaining in
- * miliseconds
+ * milliseconds
*
* Set the available query result fields in @query.
*/
@@ -1200,15 +1193,15 @@ gst_query_set_buffering_range (GstQuery * query, GstFormat format,
* gst_query_parse_buffering_range:
* @query: a GST_QUERY_BUFFERING type query #GstQuery
* @format: (out) (allow-none): the format to set for the @segment_start
- * and @segment_end values, or NULL
- * @start: (out) (allow-none): the start to set, or NULL
- * @stop: (out) (allow-none): the stop to set, or NULL
+ * and @segment_end values, or %NULL
+ * @start: (out) (allow-none): the start to set, or %NULL
+ * @stop: (out) (allow-none): the stop to set, or %NULL
* @estimated_total: (out) (allow-none): estimated total amount of download
- * time remaining in miliseconds, or NULL
+ * time remaining in milliseconds, or %NULL
*
* Parse an available query, writing the format into @format, and
* other results into the passed parameters, if the respective parameters
- * are non-NULL
+ * are non-%NULL
*/
void
gst_query_parse_buffering_range (GstQuery * query, GstFormat * format,
@@ -1315,8 +1308,8 @@ gst_query_get_n_buffering_ranges (GstQuery * query)
* gst_query_parse_nth_buffering_range:
* @query: a GST_QUERY_BUFFERING type query #GstQuery
* @index: position in the buffered-ranges array to read
- * @start: (out) (allow-none): the start position to set, or NULL
- * @stop: (out) (allow-none): the stop position to set, or NULL
+ * @start: (out) (allow-none): the start position to set, or %NULL
+ * @stop: (out) (allow-none): the stop position to set, or %NULL
*
* Parse an available query and get the start and stop values stored
* at the @index of the buffered ranges array.
@@ -1399,10 +1392,10 @@ gst_query_set_uri (GstQuery * query, const gchar * uri)
* gst_query_parse_uri:
* @query: a #GstQuery
* @uri: (out) (transfer full) (allow-none): the storage for the current URI
- * (may be NULL)
+ * (may be %NULL)
*
* Parse an URI query, writing the URI into @uri as a newly
- * allocated string, if the respective parameters are non-NULL.
+ * allocated string, if the respective parameters are non-%NULL.
* Free the string with g_free() after usage.
*/
void
@@ -1445,10 +1438,10 @@ gst_query_set_uri_redirection (GstQuery * query, const gchar * uri)
* gst_query_parse_uri_redirection:
* @query: a #GstQuery
* @uri: (out) (transfer full) (allow-none): the storage for the redirect URI
- * (may be NULL)
+ * (may be %NULL)
*
* Parse an URI query, writing the URI into @uri as a newly
- * allocated string, if the respective parameters are non-NULL.
+ * allocated string, if the respective parameters are non-%NULL.
* Free the string with g_free() after usage.
*
* Since: 1.2
@@ -1469,6 +1462,58 @@ gst_query_parse_uri_redirection (GstQuery * query, gchar ** uri)
}
/**
+ * gst_query_set_uri_redirection_permanent:
+ * @query: a #GstQuery with query type GST_QUERY_URI
+ * @permanent: whether the redirect is permanent or not
+ *
+ * Answer a URI query by setting the requested URI redirection
+ * to permanent or not.
+ *
+ * Since: 1.4
+ */
+void
+gst_query_set_uri_redirection_permanent (GstQuery * query, gboolean permanent)
+{
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
+ g_return_if_fail (gst_query_is_writable (query));
+
+ structure = GST_QUERY_STRUCTURE (query);
+ gst_structure_id_set (structure, GST_QUARK (URI_REDIRECTION_PERMANENT),
+ G_TYPE_BOOLEAN, permanent, NULL);
+}
+
+/**
+ * gst_query_parse_uri_redirection_permanent:
+ * @query: a #GstQuery
+ * @permanent: (out) (allow-none): if the URI redirection is permanent
+ * (may be %NULL)
+ *
+ * Parse an URI query, and set @permanent to %TRUE if there is a redirection
+ * and it should be considered permanent. If a redirection is permanent,
+ * applications should update their internal storage of the URI, otherwise
+ * they should make all future requests to the original URI.
+ *
+ * Since: 1.4
+ */
+void
+gst_query_parse_uri_redirection_permanent (GstQuery * query,
+ gboolean * permanent)
+{
+ GstStructure *structure;
+
+ g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
+
+ structure = GST_QUERY_STRUCTURE (query);
+ if (permanent) {
+ if (!gst_structure_id_get (structure, GST_QUARK (URI_REDIRECTION_PERMANENT),
+ G_TYPE_BOOLEAN, permanent, NULL))
+ *permanent = FALSE;
+ }
+}
+
+/**
* gst_query_new_allocation:
* @caps: the negotiated caps
* @need_pool: return a pool
@@ -1502,7 +1547,7 @@ gst_query_new_allocation (GstCaps * caps, gboolean need_pool)
*
* Parse an allocation query, writing the requested caps in @caps and
* whether a pool is needed in @need_pool, if the respective parameters
- * are non-NULL.
+ * are non-%NULL.
*/
void
gst_query_parse_allocation (GstQuery * query, GstCaps ** caps,
@@ -1838,11 +1883,11 @@ gst_query_remove_nth_allocation_meta (GstQuery * query, guint index)
* @api: the metadata API
* @index: (out) (transfer none) (allow-none): the index
*
- * Check if @query has metadata @api set. When this function returns TRUE,
+ * Check if @query has metadata @api set. When this function returns %TRUE,
* @index will contain the index where the requested API and the flags can be
* found.
*
- * Returns: TRUE when @api is in the list of metadata.
+ * Returns: %TRUE when @api is in the list of metadata.
*/
gboolean
gst_query_find_allocation_meta (GstQuery * query, GType api, guint * index)
@@ -1954,7 +1999,7 @@ gst_query_get_n_allocation_params (GstQuery * query)
* @allocator: (out) (transfer full) (allow-none): variable to hold the result
* @params: (out) (allow-none): parameters for the allocator
*
- * Parse an available query and get the alloctor and its params
+ * Parse an available query and get the allocator and its params
* at @index of the allocator array.
*/
void
@@ -1988,7 +2033,7 @@ gst_query_parse_nth_allocation_param (GstQuery * query, guint index,
* @allocator: (transfer none) (allow-none): new allocator to set
* @params: (transfer none) (allow-none): parameters for the allocator
*
- * Parse an available query and get the alloctor and its params
+ * Parse an available query and get the allocator and its params
* at @index of the allocator array.
*/
void
@@ -2129,7 +2174,7 @@ gst_query_parse_scheduling (GstQuery * query, GstSchedulingFlags * flags,
* @query: a GST_QUERY_SCHEDULING type query #GstQuery
* @mode: a #GstPadMode
*
- * Add @mode as aone of the supported scheduling modes to @query.
+ * Add @mode as one of the supported scheduling modes to @query.
*/
void
gst_query_add_scheduling_mode (GstQuery * query, GstPadMode mode)
@@ -2215,7 +2260,7 @@ gst_query_parse_nth_scheduling_mode (GstQuery * query, guint index)
* </para>
* </note>
*
- * Returns: TRUE when @mode is in the list of scheduling modes.
+ * Returns: %TRUE when @mode is in the list of scheduling modes.
*/
gboolean
gst_query_has_scheduling_mode (GstQuery * query, GstPadMode mode)
@@ -2247,7 +2292,7 @@ gst_query_has_scheduling_mode (GstQuery * query, GstPadMode mode)
* Check if @query has scheduling mode set and @flags is set in
* query scheduling flags.
*
- * Returns: TRUE when @mode is in the list of scheduling modes
+ * Returns: %TRUE when @mode is in the list of scheduling modes
* and @flags are compatible with query flags.
*/
gboolean
@@ -2571,7 +2616,7 @@ gst_query_parse_context (GstQuery * query, GstContext ** context)
/**
* gst_query_parse_context_type:
* @query: a GST_QUERY_CONTEXT type query
- * @context_type: (out) (transfer none) (allow-none): the context type, or NULL
+ * @context_type: (out) (transfer none) (allow-none): the context type, or %NULL
*
* Parse a context type from an existing GST_QUERY_CONTEXT query.
*
diff --git a/gst/gstquery.h b/gst/gstquery.h
index 8943b86..3750a19 100644
--- a/gst/gstquery.h
+++ b/gst/gstquery.h
@@ -132,7 +132,9 @@ typedef enum {
} GstQueryType;
#undef FLAG
-#define GST_TYPE_QUERY (gst_query_get_type())
+GST_EXPORT GType _gst_query_type;
+
+#define GST_TYPE_QUERY (_gst_query_type)
#define GST_IS_QUERY(obj) (GST_IS_MINI_OBJECT_TYPE (obj, GST_TYPE_QUERY))
#define GST_QUERY_CAST(obj) ((GstQuery*)(obj))
#define GST_QUERY(obj) (GST_QUERY_CAST(obj))
@@ -284,9 +286,9 @@ gst_query_copy (const GstQuery * q)
* in some cases), and the reference counts are updated appropriately (the old
* query is unreffed, the new one is reffed).
*
- * Either @new_query or the #GstQuery pointed to by @old_query may be NULL.
+ * Either @new_query or the #GstQuery pointed to by @old_query may be %NULL.
*
- * Returns: TRUE if @new_query was different from @old_query
+ * Returns: %TRUE if @new_query was different from @old_query
*/
#ifdef _FOOL_GTK_DOC_
G_INLINE_FUNC gboolean gst_query_replace (GstQuery **old_query, GstQuery *new_query);
@@ -399,6 +401,8 @@ void gst_query_parse_uri (GstQuery *query, gchar **u
void gst_query_set_uri (GstQuery *query, const gchar *uri);
void gst_query_parse_uri_redirection (GstQuery *query, gchar **uri);
void gst_query_set_uri_redirection (GstQuery *query, const gchar *uri);
+void gst_query_parse_uri_redirection_permanent (GstQuery *query, gboolean * permanent);
+void gst_query_set_uri_redirection_permanent (GstQuery *query, gboolean permanent);
/* allocation query */
GstQuery * gst_query_new_allocation (GstCaps *caps, gboolean need_pool) G_GNUC_MALLOC;
diff --git a/gst/gstregistry.c b/gst/gstregistry.c
index c03a1ef..2838737 100644
--- a/gst/gstregistry.c
+++ b/gst/gstregistry.c
@@ -57,15 +57,21 @@
* <listitem>
* <para>default locations (if GST_PLUGIN_SYSTEM_PATH is not set). Those
* default locations are:
- * <filename>~/.gstreamer-$GST_API_VERSION/plugins/</filename>
+ * <filename>$XDG_DATA_HOME/gstreamer-$GST_API_VERSION/plugins/</filename>
* and <filename>$prefix/libs/gstreamer-$GST_API_VERSION/</filename>.
+ * <ulink url="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">
+ * <filename>$XDG_DATA_HOME</filename></ulink> defaults to
+ * <filename>$HOME/.local/share</filename>.
* </para>
* </listitem>
* </itemizedlist>
* The registry cache file is loaded from
- * <filename>~/.gstreamer-$GST_API_VERSION/registry-$ARCH.bin</filename> or the
- * file listed in the GST_REGISTRY env var. One reason to change the registry
- * location is for testing.
+ * <filename>$XDG_CACHE_HOME/gstreamer-$GST_API_VERSION/registry-$ARCH.bin</filename>
+ * (where
+ * <ulink url="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">
+ * <filename>$XDG_CACHE_HOME</filename></ulink> defaults to
+ * <filename>$HOME/.cache</filename>) or the file listed in the GST_REGISTRY
+ * env var. One reason to change the registry location is for testing.
*
* For each plugin that is found in the plugin search path, there could be 3
* possibilities for cached information:
@@ -98,8 +104,6 @@
* stored in the default registry, and plugins not relevant to the current
* process are marked with the %GST_PLUGIN_FLAG_CACHED bit. These plugins are
* removed at the end of initialization.
- *
- * Last reviewed on 2012-03-29 (0.11.3)
*/
#ifdef HAVE_CONFIG_H
@@ -123,6 +127,7 @@
#include "gstinfo.h"
#include "gsterror.h"
#include "gstregistry.h"
+#include "gstdevicemonitorfactory.h"
#include "gstpluginloader.h"
@@ -161,6 +166,8 @@ struct _GstRegistryPrivate
guint32 efl_cookie;
GList *typefind_factory_list;
guint32 tfl_cookie;
+ GList *device_monitor_factory_list;
+ guint32 dmfl_cookie;
};
/* the one instance of the default registry and the mutex protecting the
@@ -310,6 +317,12 @@ gst_registry_finalize (GObject * object)
gst_plugin_feature_list_free (registry->priv->typefind_factory_list);
}
+ if (registry->priv->device_monitor_factory_list) {
+ GST_DEBUG_OBJECT (registry,
+ "Cleaning up cached device monitor factory list");
+ gst_plugin_feature_list_free (registry->priv->device_monitor_factory_list);
+ }
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -417,7 +430,7 @@ gst_registry_get_path_list (GstRegistry * registry)
* Add the plugin to the registry. The plugin-added signal will be emitted.
* This function will sink @plugin.
*
- * Returns: TRUE on success.
+ * Returns: %TRUE on success.
*
* MT safe.
*/
@@ -543,7 +556,7 @@ gst_registry_remove_plugin (GstRegistry * registry, GstPlugin * plugin)
* Add the feature to the registry. The feature-added signal will be emitted.
* This function sinks @feature.
*
- * Returns: TRUE on success.
+ * Returns: %TRUE on success.
*
* MT safe.
*/
@@ -774,6 +787,28 @@ gst_registry_get_typefind_factory_list (GstRegistry * registry)
return list;
}
+
+static GList *
+gst_registry_get_device_monitor_factory_list (GstRegistry * registry)
+{
+ GList *list;
+
+ GST_OBJECT_LOCK (registry);
+
+ gst_registry_get_feature_list_or_create (registry,
+ &registry->priv->device_monitor_factory_list,
+ &registry->priv->dmfl_cookie, GST_TYPE_DEVICE_MONITOR_FACTORY);
+
+ /* Return reffed copy */
+ list =
+ gst_plugin_feature_list_copy (registry->
+ priv->device_monitor_factory_list);
+
+ GST_OBJECT_UNLOCK (registry);
+
+ return list;
+}
+
/**
* gst_registry_feature_filter:
* @registry: registry to query
@@ -833,7 +868,7 @@ gst_registry_plugin_name_filter (GstPlugin * plugin, const gchar * name)
* Find the plugin with the given name in the registry.
* The plugin will be reffed; caller is responsible for unreffing.
*
- * Returns: (transfer full): the plugin with the given name or NULL if the
+ * Returns: (transfer full): the plugin with the given name or %NULL if the
* plugin was not found. gst_object_unref() after usage.
*
* MT safe.
@@ -868,7 +903,7 @@ gst_registry_find_plugin (GstRegistry * registry, const gchar * name)
* Find the pluginfeature with the given name and type in the registry.
*
* Returns: (transfer full): the pluginfeature with the given name and type
- * or NULL if the plugin was not found. gst_object_unref() after usage.
+ * or %NULL if the plugin was not found. gst_object_unref() after usage.
*
* MT safe.
*/
@@ -916,6 +951,8 @@ gst_registry_get_feature_list (GstRegistry * registry, GType type)
return gst_registry_get_element_factory_list (registry);
else if (type == GST_TYPE_TYPE_FIND_FACTORY)
return gst_registry_get_typefind_factory_list (registry);
+ else if (type == GST_TYPE_DEVICE_MONITOR_FACTORY)
+ return gst_registry_get_device_monitor_factory_list (registry);
data.type = type;
data.name = NULL;
@@ -1018,7 +1055,7 @@ gst_registry_lookup_bn (GstRegistry * registry, const char *basename)
* Look up a plugin in the given registry with the given filename.
* If found, plugin is reffed.
*
- * Returns: (transfer full): the #GstPlugin if found, or NULL if not.
+ * Returns: (transfer full): the #GstPlugin if found, or %NULL if not.
* gst_object_unref() after usage.
*/
GstPlugin *
@@ -1415,8 +1452,8 @@ _priv_gst_registry_cleanup (void)
* @registry and whether its version is at least the
* version required.
*
- * Returns: #TRUE if the feature could be found and the version is
- * the same as the required version or newer, and #FALSE otherwise.
+ * Returns: %TRUE if the feature could be found and the version is
+ * the same as the required version or newer, and %FALSE otherwise.
*/
gboolean
gst_registry_check_feature_version (GstRegistry * registry,
@@ -1471,7 +1508,7 @@ load_plugin_func (gpointer data, gpointer user_data)
#ifndef GST_DISABLE_REGISTRY
/* Unref all plugins marked 'cached', to clear old plugins that no
- * longer exist. Returns TRUE if any plugins were removed */
+ * longer exist. Returns %TRUE if any plugins were removed */
static gboolean
gst_registry_remove_cache_plugins (GstRegistry * registry)
{
@@ -1593,8 +1630,6 @@ scan_and_update_registry (GstRegistry * default_registry,
g_free (home_plugins);
/* add the main (installed) library path */
- GST_DEBUG ("scanning main plugins %s", PLUGINDIR);
- changed |= gst_registry_scan_path_internal (&context, PLUGINDIR);
#ifdef G_OS_WIN32
{
@@ -1605,9 +1640,11 @@ scan_and_update_registry (GstRegistry * default_registry,
g_win32_get_package_installation_directory_of_module
(_priv_gst_dll_handle);
- dir =
- g_build_filename (base_dir, "lib", "gstreamer-" GST_API_VERSION,
- NULL);
+ dir = g_build_filename (base_dir,
+#ifdef _DEBUG
+ "debug"
+#endif
+ "lib", "gstreamer-" GST_API_VERSION, NULL);
GST_DEBUG ("scanning DLL dir %s", dir);
changed |= gst_registry_scan_path_internal (&context, dir);
@@ -1615,6 +1652,9 @@ scan_and_update_registry (GstRegistry * default_registry,
g_free (dir);
g_free (base_dir);
}
+#else
+ GST_DEBUG ("scanning main plugins %s", PLUGINDIR);
+ changed |= gst_registry_scan_path_internal (&context, PLUGINDIR);
#endif
} else {
gchar **list;
@@ -1807,7 +1847,7 @@ gst_update_registry (void)
* gst_registry_get_feature_list_cookie:
* @registry: the registry
*
- * Returns the registrys feature list cookie. This changes
+ * Returns the registry's feature list cookie. This changes
* every time a feature is added or removed from the registry.
*
* Returns: the feature list cookie.
diff --git a/gst/gstregistrybinary.c b/gst/gstregistrybinary.c
index 837e3b4..ee4a7a0 100644
--- a/gst/gstregistrybinary.c
+++ b/gst/gstregistrybinary.c
@@ -56,6 +56,7 @@
#include <gst/gstelement.h>
#include <gst/gsttypefind.h>
#include <gst/gsttypefindfactory.h>
+#include <gst/gstdevicemonitorfactory.h>
#include <gst/gsturi.h>
#include <gst/gstinfo.h>
#include <gst/gstenumtypes.h>
@@ -525,6 +526,7 @@ priv_gst_registry_binary_read_cache (GstRegistry * registry,
/* make sure these types exist */
GST_TYPE_ELEMENT_FACTORY;
GST_TYPE_TYPE_FIND_FACTORY;
+ GST_TYPE_DEVICE_MONITOR_FACTORY;
#ifndef GST_DISABLE_GST_DEBUG
timer = g_timer_new ();
diff --git a/gst/gstregistrychunks.c b/gst/gstregistrychunks.c
index 571f6be..fcacd6b 100644
--- a/gst/gstregistrychunks.c
+++ b/gst/gstregistrychunks.c
@@ -33,6 +33,7 @@
#include <gst/gstelement.h>
#include <gst/gsttypefind.h>
#include <gst/gsttypefindfactory.h>
+#include <gst/gstdevicemonitorfactory.h>
#include <gst/gsturi.h>
#include <gst/gstinfo.h>
#include <gst/gstenumtypes.h>
@@ -227,10 +228,11 @@ G_STMT_START { \
static gboolean
gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
{
- const gchar *type_name = g_type_name (G_OBJECT_TYPE (feature));
+ const gchar *type_name = G_OBJECT_TYPE_NAME (feature);
GstRegistryChunkPluginFeature *pf = NULL;
GstRegistryChunk *chk = NULL;
GList *walk;
+ gsize pf_size = 0;
if (!type_name) {
GST_ERROR ("NULL feature type_name, aborting.");
@@ -245,9 +247,8 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
* valgrind complaining about copying unitialized memory
*/
ef = g_slice_new0 (GstRegistryChunkElementFactory);
- chk =
- gst_registry_chunks_make_data (ef,
- sizeof (GstRegistryChunkElementFactory));
+ pf_size = sizeof (GstRegistryChunkElementFactory);
+ chk = gst_registry_chunks_make_data (ef, pf_size);
ef->npadtemplates = ef->ninterfaces = ef->nuriprotocols = 0;
pf = (GstRegistryChunkPluginFeature *) ef;
@@ -256,8 +257,8 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
walk = g_list_next (walk), ef->ninterfaces++) {
gst_registry_chunks_save_const_string (list, (gchar *) walk->data);
}
- GST_DEBUG ("Feature %s: saved %d interfaces %d pad templates",
- GST_OBJECT_NAME (feature), ef->ninterfaces, ef->npadtemplates);
+ GST_DEBUG_OBJECT (feature, "saved %d interfaces %d pad templates",
+ ef->ninterfaces, ef->npadtemplates);
/* save uritypes */
if (GST_URI_TYPE_IS_VALID (factory->uri_type)) {
@@ -276,7 +277,7 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
ef->nuriprotocols++;
}
*list = g_list_prepend (*list, subchk);
- GST_DEBUG ("Saved %d UriTypes", ef->nuriprotocols);
+ GST_DEBUG_OBJECT (feature, "Saved %d UriTypes", ef->nuriprotocols);
} else {
g_warning ("GStreamer feature '%s' is URI handler but does not provide"
" any protocols it can handle", GST_OBJECT_NAME (feature));
@@ -289,7 +290,7 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
GstStaticPadTemplate *template = walk->data;
if (!gst_registry_chunks_save_pad_template (list, template)) {
- GST_ERROR ("Can't fill pad template, aborting.");
+ GST_ERROR_OBJECT (feature, "Can't fill pad template, aborting.");
goto fail;
}
}
@@ -306,9 +307,8 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
* valgrind complaining about copying unitialized memory
*/
tff = g_slice_new0 (GstRegistryChunkTypeFindFactory);
- chk =
- gst_registry_chunks_make_data (tff,
- sizeof (GstRegistryChunkTypeFindFactory));
+ pf_size = sizeof (GstRegistryChunkTypeFindFactory);
+ chk = gst_registry_chunks_make_data (tff, pf_size);
tff->nextensions = 0;
pf = (GstRegistryChunkPluginFeature *) tff;
@@ -319,6 +319,7 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
factory->extensions[tff->nextensions++]);
}
}
+ GST_DEBUG_OBJECT (feature, "saved %d extensions", tff->nextensions);
/* save caps */
if (factory->caps) {
GstCaps *fcaps = gst_caps_ref (factory->caps);
@@ -332,8 +333,25 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
} else {
gst_registry_chunks_save_const_string (list, "");
}
+ } else if (GST_IS_DEVICE_MONITOR_FACTORY (feature)) {
+ GstRegistryChunkDeviceMonitorFactory *tff;
+ GstDeviceMonitorFactory *factory = GST_DEVICE_MONITOR_FACTORY (feature);
+
+ /* Initialize with zeroes because of struct padding and
+ * valgrind complaining about copying unitialized memory
+ */
+ tff = g_slice_new0 (GstRegistryChunkDeviceMonitorFactory);
+ chk =
+ gst_registry_chunks_make_data (tff,
+ sizeof (GstRegistryChunkDeviceMonitorFactory));
+ pf = (GstRegistryChunkPluginFeature *) tff;
+
+
+ /* pack element metadata strings */
+ gst_registry_chunks_save_string (list,
+ gst_structure_to_string (factory->metadata));
} else {
- GST_WARNING ("unhandled feature type '%s'", type_name);
+ GST_WARNING_OBJECT (feature, "unhandled feature type '%s'", type_name);
}
if (pf) {
@@ -349,8 +367,8 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
/* Errors */
fail:
- g_free (chk);
- g_free (pf);
+ g_slice_free (GstRegistryChunk, chk);
+ g_slice_free1 (pf_size, pf);
return FALSE;
}
@@ -465,8 +483,8 @@ _priv_gst_registry_chunks_save_plugin (GList ** list, GstRegistry * registry,
/* Errors */
fail:
gst_plugin_feature_list_free (plugin_features);
- g_free (chk);
- g_free (pe);
+ g_slice_free (GstRegistryChunk, chk);
+ g_slice_free (GstRegistryChunkPluginElement, pe);
return FALSE;
}
@@ -650,6 +668,30 @@ gst_registry_chunks_load_feature (GstRegistry * registry, gchar ** in,
factory->extensions[i - 1] = str;
}
}
+ } else if (GST_IS_DEVICE_MONITOR_FACTORY (feature)) {
+ GstRegistryChunkDeviceMonitorFactory *dmf;
+ GstDeviceMonitorFactory *factory = GST_DEVICE_MONITOR_FACTORY (feature);
+ const gchar *meta_data_str;
+
+ align (*in);
+ GST_DEBUG
+ ("Reading/casting for GstRegistryChunkPluginFeature at address %p",
+ *in);
+ unpack_element (*in, dmf, GstRegistryChunkDeviceMonitorFactory, end, fail);
+
+ pf = (GstRegistryChunkPluginFeature *) dmf;
+
+ /* unpack element factory strings */
+ unpack_string_nocopy (*in, meta_data_str, end, fail);
+ if (meta_data_str && *meta_data_str) {
+ factory->metadata = gst_structure_from_string (meta_data_str, NULL);
+ if (!factory->metadata) {
+ GST_ERROR
+ ("Error when trying to deserialize structure for metadata '%s'",
+ meta_data_str);
+ goto fail;
+ }
+ }
} else {
GST_WARNING ("unhandled factory type : %s", G_OBJECT_TYPE_NAME (feature));
goto fail;
diff --git a/gst/gstregistrychunks.h b/gst/gstregistrychunks.h
index 3e6e923..e2c86ba 100644
--- a/gst/gstregistrychunks.h
+++ b/gst/gstregistrychunks.h
@@ -122,7 +122,7 @@ typedef struct _GstRegistryChunkElementFactory
* GstRegistryChunkTypeFindFactory:
* @nextensions: stores the number of typefind extensions
*
- * A structure containing the element factory fields
+ * A structure containing the type find factory fields
*/
typedef struct _GstRegistryChunkTypeFindFactory
{
@@ -132,6 +132,17 @@ typedef struct _GstRegistryChunkTypeFindFactory
} GstRegistryChunkTypeFindFactory;
/*
+ * GstRegistryChunkDeviceMonitorFactory:
+ *
+ * A structure containing the device monitor factory fields
+ */
+typedef struct _GstRegistryChunkDeviceMonitorFactory
+{
+ GstRegistryChunkPluginFeature plugin_feature;
+
+} GstRegistryChunkDeviceMonitorFactory;
+
+/*
* GstRegistryChunkPadTemplate:
*
* A structure containing the static pad templates of a plugin feature
diff --git a/gst/gstsample.c b/gst/gstsample.c
index 9517af0..76b76bd 100644
--- a/gst/gstsample.c
+++ b/gst/gstsample.c
@@ -26,8 +26,6 @@
*
* A #GstSample is a small object containing data, a type, timing and
* extra arbitrary information.
- *
- * Last reviewed on 2012-03-29 (0.11.3)
*/
#include "gst_private.h"
@@ -87,10 +85,10 @@ _gst_sample_free (GstSample * sample)
/**
* gst_sample_new:
- * @buffer: (transfer none) (allow-none): a #GstBuffer, or NULL
- * @caps: (transfer none) (allow-none): a #GstCaps, or NULL
- * @segment: (transfer none) (allow-none): a #GstSegment, or NULL
- * @info: (transfer full) (allow-none): a #GstStructure, or NULL
+ * @buffer: (transfer none) (allow-none): a #GstBuffer, or %NULL
+ * @caps: (transfer none) (allow-none): a #GstCaps, or %NULL
+ * @segment: (transfer none) (allow-none): a #GstSegment, or %NULL
+ * @info: (transfer full) (allow-none): a #GstStructure, or %NULL
*
* Create a new #GstSample with the provided details.
*
@@ -145,7 +143,7 @@ had_parent:
*
* Get the buffer associated with @sample
*
- * Returns: (transfer none): the buffer of @sample or NULL when there
+ * Returns: (transfer none): the buffer of @sample or %NULL when there
* is no buffer. The buffer remains valid as long as @sample is valid.
* If you need to hold on to it for longer than that, take a ref to
* the buffer with gst_buffer_ref().
@@ -164,7 +162,7 @@ gst_sample_get_buffer (GstSample * sample)
*
* Get the caps associated with @sample
*
- * Returns: (transfer none): the caps of @sample or NULL when there
+ * Returns: (transfer none): the caps of @sample or %NULL when there
* is no caps. The caps remain valid as long as @sample is valid.
* If you need to hold on to the caps for longer than that, take a ref to
* the caps with gst_caps_ref().
diff --git a/gst/gstsegment.c b/gst/gstsegment.c
index cb6d19c..3c4081b 100644
--- a/gst/gstsegment.c
+++ b/gst/gstsegment.c
@@ -79,8 +79,6 @@
* For elements that need to perform operations on media data in stream_time,
* gst_segment_to_stream_time() can be used to convert a timestamp and the segment
* info to stream time (which is always between 0 and the duration of the stream).
- *
- * Last reviewed on 2012-03-29 (0.11.3)
*/
/**
@@ -218,8 +216,8 @@ gst_segment_init (GstSegment * segment, GstFormat format)
* If the caller can apply a rate change, it should update @segment
* rate and applied_rate after calling this function.
*
- * @update will be set to TRUE if a seek should be performed to the segment
- * position field. This field can be FALSE if, for example, only the @rate
+ * @update will be set to %TRUE if a seek should be performed to the segment
+ * position field. This field can be %FALSE if, for example, only the @rate
* has been changed but not the playback position.
*
* Returns: %TRUE if the seek could be performed.
@@ -460,7 +458,7 @@ gst_segment_to_stream_time (const GstSegment * segment, GstFormat format,
* segment. Position is a value between @segment start and stop time.
*
* This function is typically used by elements that need to synchronize to the
- * global clock in a pipeline. The runnning time is a constantly increasing value
+ * global clock in a pipeline. The running time is a constantly increasing value
* starting from 0. When gst_segment_init() is called, this value will reset to
* 0.
*
@@ -553,18 +551,18 @@ gst_segment_to_running_time (const GstSegment * segment, GstFormat format,
* in @segment. @start and @stop are compared and clipped to @segment
* start and stop values.
*
- * If the function returns FALSE, @start and @stop are known to fall
+ * If the function returns %FALSE, @start and @stop are known to fall
* outside of @segment and @clip_start and @clip_stop are not updated.
*
- * When the function returns TRUE, @clip_start and @clip_stop will be
+ * When the function returns %TRUE, @clip_start and @clip_stop will be
* updated. If @clip_start or @clip_stop are different from @start or @stop
* respectively, the region fell partially in the segment.
*
* Note that when @stop is -1, @clip_stop will be set to the end of the
* segment. Depending on the use case, this may or may not be what you want.
*
- * Returns: TRUE if the given @start and @stop times fall partially or
- * completely in @segment, FALSE if the values are completely outside
+ * Returns: %TRUE if the given @start and @stop times fall partially or
+ * completely in @segment, %FALSE if the values are completely outside
* of the segment.
*/
gboolean
diff --git a/gst/gstsegment.h b/gst/gstsegment.h
index 0f08eb5..c9ec1e4 100644
--- a/gst/gstsegment.h
+++ b/gst/gstsegment.h
@@ -56,7 +56,7 @@ typedef enum {
* @GST_SEEK_FLAG_KEY_UNIT: seek to the nearest keyframe. This might be
* faster but less accurate.
* @GST_SEEK_FLAG_SEGMENT: perform a segment seek.
- * @GST_SEEK_FLAG_SKIP: when doing fast foward or fast reverse playback, allow
+ * @GST_SEEK_FLAG_SKIP: when doing fast forward or fast reverse playback, allow
* elements to skip frames instead of generating all
* frames.
* @GST_SEEK_FLAG_SNAP_BEFORE: go to a location before the requested position,
@@ -81,7 +81,7 @@ typedef enum {
* complete scan of the file in those cases.
*
* When performing a segment seek: after the playback of the segment completes,
- * no EOS will be emmited by the element that performed the seek, but a
+ * no EOS will be emitted by the element that performed the seek, but a
* #GST_MESSAGE_SEGMENT_DONE message will be posted on the bus by the element.
* When this message is posted, it is possible to send a new seek event to
* continue playback. With this seek method it is possible to perform seamless
diff --git a/gst/gststructure.c b/gst/gststructure.c
index 48b7031..5013860 100644
--- a/gst/gststructure.c
+++ b/gst/gststructure.c
@@ -51,9 +51,13 @@
* gst_structure_remove_fields().
*
* Strings in structures must be ASCII or UTF-8 encoded. Other encodings are
- * not allowed. Strings must not be empty either, but may be NULL.
+ * not allowed. Strings may be %NULL however.
*
- * Last reviewed on 2012-03-29 (0.11.3)
+ * Be aware that the current #GstCaps / #GstStructure serialization into string
+ * has limited support for nested #GstCaps / #GstStructure fields. It can only
+ * support one level of nesting. Using more levels will lead to unexpected
+ * behavior when using serialization features, such as gst_caps_to_string() or
+ * gst_value_serialize() and their counterparts.
*/
#ifdef HAVE_CONFIG_H
@@ -233,7 +237,7 @@ gst_structure_new_empty (const gchar * name)
* Creates a new #GstStructure with the given name. Parses the
* list of variable arguments and sets fields to the values listed.
* Variable arguments should be passed as field name, field type,
- * and value. Last variable argument should be NULL.
+ * and value. Last variable argument should be %NULL.
*
* Free-function: gst_structure_free
*
@@ -411,7 +415,7 @@ gst_structure_get_name (const GstStructure * structure)
*
* Checks if the structure has the given name
*
- * Returns: TRUE if @name matches the name of the structure.
+ * Returns: %TRUE if @name matches the name of the structure.
*/
gboolean
gst_structure_has_name (const GstStructure * structure, const gchar * name)
@@ -617,7 +621,7 @@ gst_structure_set_valist_internal (GstStructure * structure,
*
* Parses the variable arguments and sets fields accordingly.
* Variable arguments should be in the form field name, field type
- * (as a GType), value(s). The last variable argument should be NULL.
+ * (as a GType), value(s). The last variable argument should be %NULL.
*/
void
gst_structure_set (GstStructure * structure, const gchar * field, ...)
@@ -690,7 +694,7 @@ gst_structure_id_set_valist_internal (GstStructure * structure,
* passed using the GQuark for the field name. This allows more efficient
* setting of the structure if the caller already knows the associated
* quark values.
- * The last variable argument must be NULL.
+ * The last variable argument must be %NULL.
*/
void
gst_structure_id_set (GstStructure * structure, GQuark field, ...)
@@ -733,7 +737,7 @@ gst_structure_id_set_valist (GstStructure * structure,
* gst_structure_id_set(). Basically a convenience wrapper around
* gst_structure_new_id_empty() and gst_structure_id_set().
*
- * The last variable argument must be NULL (or 0).
+ * The last variable argument must be %NULL (or 0).
*
* Free-function: gst_structure_free
*
@@ -771,9 +775,13 @@ static void
gst_structure_set_field (GstStructure * structure, GstStructureField * field)
{
GstStructureField *f;
- guint i, len = GST_STRUCTURE_FIELDS (structure)->len;
+ GType field_value_type;
+ guint i, len;
+
+ len = GST_STRUCTURE_FIELDS (structure)->len;
- if (G_UNLIKELY (G_VALUE_HOLDS_STRING (&field->value))) {
+ field_value_type = G_VALUE_TYPE (&field->value);
+ if (field_value_type == G_TYPE_STRING) {
const gchar *s;
s = g_value_get_string (&field->value);
@@ -800,7 +808,7 @@ gst_structure_set_field (GstStructure * structure, GstStructureField * field)
g_value_unset (&field->value);
return;
}
- } else if (G_UNLIKELY (G_VALUE_HOLDS (&field->value, G_TYPE_DATE))) {
+ } else if (G_UNLIKELY (field_value_type == G_TYPE_DATE)) {
const GDate *d;
d = g_value_get_boxed (&field->value);
@@ -956,7 +964,7 @@ gst_structure_remove_field (GstStructure * structure, const gchar * fieldname)
* gst_structure_remove_fields:
* @structure: a #GstStructure
* @fieldname: the name of the field to remove
- * @...: NULL-terminated list of more fieldnames to remove
+ * @...: %NULL-terminated list of more fieldnames to remove
*
* Removes the fields with the given names. If a field does not exist, the
* argument is ignored.
@@ -980,7 +988,7 @@ gst_structure_remove_fields (GstStructure * structure,
* gst_structure_remove_fields_valist:
* @structure: a #GstStructure
* @fieldname: the name of the field to remove
- * @varargs: NULL-terminated list of more fieldnames to remove
+ * @varargs: %NULL-terminated list of more fieldnames to remove
*
* va_list form of gst_structure_remove_fields().
*/
@@ -1100,8 +1108,8 @@ gst_structure_nth_field_name (const GstStructure * structure, guint index)
* Calls the provided function once for each field in the #GstStructure. The
* function must not modify the fields. Also see gst_structure_map_in_place().
*
- * Returns: TRUE if the supplied function returns TRUE For each of the fields,
- * FALSE otherwise.
+ * Returns: %TRUE if the supplied function returns %TRUE For each of the fields,
+ * %FALSE otherwise.
*/
gboolean
gst_structure_foreach (const GstStructure * structure,
@@ -1137,8 +1145,8 @@ gst_structure_foreach (const GstStructure * structure,
* contrast to gst_structure_foreach(), the function may modify but not delete the
* fields. The structure must be mutable.
*
- * Returns: TRUE if the supplied function returns TRUE For each of the fields,
- * FALSE otherwise.
+ * Returns: %TRUE if the supplied function returns %TRUE For each of the fields,
+ * %FALSE otherwise.
*/
gboolean
gst_structure_map_in_place (GstStructure * structure,
@@ -1171,7 +1179,7 @@ gst_structure_map_in_place (GstStructure * structure,
*
* Check if @structure contains a field named @field.
*
- * Returns: TRUE if the structure contains a field with the given name
+ * Returns: %TRUE if the structure contains a field with the given name
*/
gboolean
gst_structure_id_has_field (const GstStructure * structure, GQuark field)
@@ -1193,7 +1201,7 @@ gst_structure_id_has_field (const GstStructure * structure, GQuark field)
*
* Check if @structure contains a field named @fieldname.
*
- * Returns: TRUE if the structure contains a field with the given name
+ * Returns: %TRUE if the structure contains a field with the given name
*/
gboolean
gst_structure_has_field (const GstStructure * structure,
@@ -1214,7 +1222,7 @@ gst_structure_has_field (const GstStructure * structure,
*
* Check if @structure contains a field named @field and with GType @type.
*
- * Returns: TRUE if the structure contains a field with the given name and type
+ * Returns: %TRUE if the structure contains a field with the given name and type
*/
gboolean
gst_structure_id_has_field_typed (const GstStructure * structure,
@@ -1240,7 +1248,7 @@ gst_structure_id_has_field_typed (const GstStructure * structure,
*
* Check if @structure contains a field named @fieldname and with GType @type.
*
- * Returns: TRUE if the structure contains a field with the given name and type
+ * Returns: %TRUE if the structure contains a field with the given name and type
*/
gboolean
gst_structure_has_field_typed (const GstStructure * structure,
@@ -1265,9 +1273,9 @@ gst_structure_has_field_typed (const GstStructure * structure,
* given field. Caller is responsible for making sure the field exists
* and has the correct type.
*
- * Returns: TRUE if the value could be set correctly. If there was no field
+ * Returns: %TRUE if the value could be set correctly. If there was no field
* with @fieldname or the existing field did not contain a boolean, this
- * function returns FALSE.
+ * function returns %FALSE.
*/
gboolean
gst_structure_get_boolean (const GstStructure * structure,
@@ -1280,9 +1288,7 @@ gst_structure_get_boolean (const GstStructure * structure,
field = gst_structure_get_field (structure, fieldname);
- if (field == NULL)
- return FALSE;
- if (!G_VALUE_HOLDS_BOOLEAN (&field->value))
+ if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_BOOLEAN)
return FALSE;
*value = gst_g_value_get_boolean_unchecked (&field->value);
@@ -1316,9 +1322,7 @@ gst_structure_get_int (const GstStructure * structure,
field = gst_structure_get_field (structure, fieldname);
- if (field == NULL)
- return FALSE;
- if (!G_VALUE_HOLDS_INT (&field->value))
+ if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_INT)
return FALSE;
*value = gst_g_value_get_int_unchecked (&field->value);
@@ -1352,9 +1356,7 @@ gst_structure_get_uint (const GstStructure * structure,
field = gst_structure_get_field (structure, fieldname);
- if (field == NULL)
- return FALSE;
- if (!G_VALUE_HOLDS_UINT (&field->value))
+ if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_UINT)
return FALSE;
*value = gst_g_value_get_uint_unchecked (&field->value);
@@ -1363,6 +1365,78 @@ gst_structure_get_uint (const GstStructure * structure,
}
/**
+ * gst_structure_get_int64:
+ * @structure: a #GstStructure
+ * @fieldname: the name of a field
+ * @value: (out): a pointer to an int64 to set
+ *
+ * Sets the int64 pointed to by @value corresponding to the value of the
+ * given field. Caller is responsible for making sure the field exists
+ * and has the correct type.
+ *
+ * Returns: %TRUE if the value could be set correctly. If there was no field
+ * with @fieldname or the existing field did not contain an int64, this function
+ * returns %FALSE.
+ *
+ * Since: 1.4
+ */
+gboolean
+gst_structure_get_int64 (const GstStructure * structure,
+ const gchar * fieldname, gint64 * value)
+{
+ GstStructureField *field;
+
+ g_return_val_if_fail (structure != NULL, FALSE);
+ g_return_val_if_fail (fieldname != NULL, FALSE);
+ g_return_val_if_fail (value != NULL, FALSE);
+
+ field = gst_structure_get_field (structure, fieldname);
+
+ if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_INT64)
+ return FALSE;
+
+ *value = gst_g_value_get_int64_unchecked (&field->value);
+
+ return TRUE;
+}
+
+/**
+ * gst_structure_get_uint64:
+ * @structure: a #GstStructure
+ * @fieldname: the name of a field
+ * @value: (out): a pointer to a uint64 to set
+ *
+ * Sets the uint64 pointed to by @value corresponding to the value of the
+ * given field. Caller is responsible for making sure the field exists
+ * and has the correct type.
+ *
+ * Returns: %TRUE if the value could be set correctly. If there was no field
+ * with @fieldname or the existing field did not contain a uint64, this function
+ * returns %FALSE.
+ *
+ * Since: 1.4
+ */
+gboolean
+gst_structure_get_uint64 (const GstStructure * structure,
+ const gchar * fieldname, guint64 * value)
+{
+ GstStructureField *field;
+
+ g_return_val_if_fail (structure != NULL, FALSE);
+ g_return_val_if_fail (fieldname != NULL, FALSE);
+ g_return_val_if_fail (value != NULL, FALSE);
+
+ field = gst_structure_get_field (structure, fieldname);
+
+ if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_UINT64)
+ return FALSE;
+
+ *value = gst_g_value_get_uint64_unchecked (&field->value);
+
+ return TRUE;
+}
+
+/**
* gst_structure_get_date:
* @structure: a #GstStructure
* @fieldname: the name of a field
@@ -1377,9 +1451,9 @@ gst_structure_get_uint (const GstStructure * structure,
* inconsistent with e.g. gst_structure_get_string() which doesn't return a
* copy of the string).
*
- * Returns: TRUE if the value could be set correctly. If there was no field
+ * Returns: %TRUE if the value could be set correctly. If there was no field
* with @fieldname or the existing field did not contain a data, this function
- * returns FALSE.
+ * returns %FALSE.
*/
gboolean
gst_structure_get_date (const GstStructure * structure, const gchar * fieldname,
@@ -1393,12 +1467,10 @@ gst_structure_get_date (const GstStructure * structure, const gchar * fieldname,
field = gst_structure_get_field (structure, fieldname);
- if (field == NULL)
- return FALSE;
- if (!G_VALUE_HOLDS (&field->value, G_TYPE_DATE))
+ if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_DATE)
return FALSE;
- /* FIXME: 0.11 g_value_dup_boxed() -> g_value_get_boxed() */
+ /* FIXME: 2.0 g_value_dup_boxed() -> g_value_get_boxed() */
*value = g_value_dup_boxed (&field->value);
return TRUE;
@@ -1419,9 +1491,9 @@ gst_structure_get_date (const GstStructure * structure, const gchar * fieldname,
* (note: this is inconsistent with e.g. gst_structure_get_string()
* which doesn't return a copy of the string).
*
- * Returns: TRUE if the value could be set correctly. If there was no field
+ * Returns: %TRUE if the value could be set correctly. If there was no field
* with @fieldname or the existing field did not contain a data, this function
- * returns FALSE.
+ * returns %FALSE.
*/
gboolean
gst_structure_get_date_time (const GstStructure * structure,
@@ -1456,30 +1528,15 @@ gst_structure_get_date_time (const GstStructure * structure,
* of the given field. Caller is responsible for making sure the field exists
* and has the correct type.
*
- * Returns: TRUE if the value could be set correctly. If there was no field
+ * Returns: %TRUE if the value could be set correctly. If there was no field
* with @fieldname or the existing field did not contain a #GstClockTime, this
- * function returns FALSE.
+ * function returns %FALSE.
*/
gboolean
gst_structure_get_clock_time (const GstStructure * structure,
const gchar * fieldname, GstClockTime * value)
{
- GstStructureField *field;
-
- g_return_val_if_fail (structure != NULL, FALSE);
- g_return_val_if_fail (fieldname != NULL, FALSE);
- g_return_val_if_fail (value != NULL, FALSE);
-
- field = gst_structure_get_field (structure, fieldname);
-
- if (field == NULL)
- return FALSE;
- if (!G_VALUE_HOLDS_UINT64 (&field->value))
- return FALSE;
-
- *value = gst_g_value_get_uint64_unchecked (&field->value);
-
- return TRUE;
+ return gst_structure_get_uint64 (structure, fieldname, value);
}
/**
@@ -1492,9 +1549,9 @@ gst_structure_get_clock_time (const GstStructure * structure,
* given field. Caller is responsible for making sure the field exists
* and has the correct type.
*
- * Returns: TRUE if the value could be set correctly. If there was no field
+ * Returns: %TRUE if the value could be set correctly. If there was no field
* with @fieldname or the existing field did not contain a double, this
- * function returns FALSE.
+ * function returns %FALSE.
*/
gboolean
gst_structure_get_double (const GstStructure * structure,
@@ -1508,9 +1565,7 @@ gst_structure_get_double (const GstStructure * structure,
field = gst_structure_get_field (structure, fieldname);
- if (field == NULL)
- return FALSE;
- if (!G_VALUE_HOLDS_DOUBLE (&field->value))
+ if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_DOUBLE)
return FALSE;
*value = gst_g_value_get_double_unchecked (&field->value);
@@ -1530,7 +1585,7 @@ gst_structure_get_double (const GstStructure * structure,
* The string should not be modified, and remains valid until the next
* call to a gst_structure_*() function with the given structure.
*
- * Returns: a pointer to the string or NULL when the field did not exist
+ * Returns: a pointer to the string or %NULL when the field did not exist
* or did not contain a string.
*/
const gchar *
@@ -1544,9 +1599,7 @@ gst_structure_get_string (const GstStructure * structure,
field = gst_structure_get_field (structure, fieldname);
- if (field == NULL)
- return NULL;
- if (!G_VALUE_HOLDS_STRING (&field->value))
+ if (field == NULL || G_VALUE_TYPE (&field->value) != G_TYPE_STRING)
return NULL;
return gst_g_value_get_string_unchecked (&field->value);
@@ -1563,9 +1616,9 @@ gst_structure_get_string (const GstStructure * structure,
* given field. Caller is responsible for making sure the field exists,
* has the correct type and that the enumtype is correct.
*
- * Returns: TRUE if the value could be set correctly. If there was no field
+ * Returns: %TRUE if the value could be set correctly. If there was no field
* with @fieldname or the existing field did not contain an enum of the given
- * type, this function returns FALSE.
+ * type, this function returns %FALSE.
*/
gboolean
gst_structure_get_enum (const GstStructure * structure,
@@ -1601,9 +1654,9 @@ gst_structure_get_enum (const GstStructure * structure,
* corresponding to the value of the given field. Caller is responsible
* for making sure the field exists and has the correct type.
*
- * Returns: TRUE if the values could be set correctly. If there was no field
+ * Returns: %TRUE if the values could be set correctly. If there was no field
* with @fieldname or the existing field did not contain a GstFraction, this
- * function returns FALSE.
+ * function returns %FALSE.
*/
gboolean
gst_structure_get_fraction (const GstStructure * structure,
@@ -1618,9 +1671,7 @@ gst_structure_get_fraction (const GstStructure * structure,
field = gst_structure_get_field (structure, fieldname);
- if (field == NULL)
- return FALSE;
- if (!GST_VALUE_HOLDS_FRACTION (&field->value))
+ if (field == NULL || G_VALUE_TYPE (&field->value) != GST_TYPE_FRACTION)
return FALSE;
*value_numerator = gst_value_get_fraction_numerator (&field->value);
@@ -1815,7 +1866,10 @@ priv_gst_structure_append_to_gstring (const GstStructure * structure,
* |[
* GST_LOG ("structure is %" GST_PTR_FORMAT, structure);
* ]|
- * This prints the structure in human readble form.
+ * This prints the structure in human readable form.
+ *
+ * The current implementation of serialization will lead to unexpected results
+ * when there are nested #GstCaps / #GstStructure deeper than one level.
*
* Free-function: g_free
*
@@ -2312,12 +2366,15 @@ priv_gst_structure_parse_fields (gchar * str, gchar ** end,
* @string: a string representation of a #GstStructure
*
* Creates a #GstStructure from a string representation.
- * If end is not NULL, a pointer to the place inside the given string
+ * If end is not %NULL, a pointer to the place inside the given string
* where parsing ended will be returned.
*
+ * The current implementation of serialization will lead to unexpected results
+ * when there are nested #GstCaps / #GstStructure deeper than one level.
+ *
* Free-function: gst_structure_free
*
- * Returns: (transfer full): a new #GstStructure or NULL when the string could
+ * Returns: (transfer full): a new #GstStructure or %NULL when the string could
* not be parsed. Free with gst_structure_free() after use.
*
* Since: 1.2
@@ -2334,12 +2391,12 @@ gst_structure_new_from_string (const gchar * string)
* @end: (out) (allow-none) (transfer none) (skip): pointer to store the end of the string in.
*
* Creates a #GstStructure from a string representation.
- * If end is not NULL, a pointer to the place inside the given string
+ * If end is not %NULL, a pointer to the place inside the given string
* where parsing ended will be returned.
*
* Free-function: gst_structure_free
*
- * Returns: (transfer full): a new #GstStructure or NULL when the string could
+ * Returns: (transfer full): a new #GstStructure or %NULL when the string could
* not be parsed. Free with gst_structure_free() after use.
*/
GstStructure *
@@ -2417,7 +2474,7 @@ gst_structure_copy_conditional (const GstStructure * structure)
* Fixates a #GstStructure by changing the given field to the nearest
* integer to @target that is a subset of the existing field.
*
- * Returns: TRUE if the structure could be fixated
+ * Returns: %TRUE if the structure could be fixated
*/
gboolean
gst_structure_fixate_field_nearest_int (GstStructure * structure,
@@ -2481,7 +2538,7 @@ gst_structure_fixate_field_nearest_int (GstStructure * structure,
* Fixates a #GstStructure by changing the given field to the nearest
* double to @target that is a subset of the existing field.
*
- * Returns: TRUE if the structure could be fixated
+ * Returns: %TRUE if the structure could be fixated
*/
gboolean
gst_structure_fixate_field_nearest_double (GstStructure * structure,
@@ -2546,7 +2603,7 @@ gst_structure_fixate_field_nearest_double (GstStructure * structure,
* Fixates a #GstStructure by changing the given @field_name field to the given
* @target boolean if that field is not fixed yet.
*
- * Returns: TRUE if the structure could be fixated
+ * Returns: %TRUE if the structure could be fixated
*/
gboolean
gst_structure_fixate_field_boolean (GstStructure * structure,
@@ -2599,7 +2656,7 @@ gst_structure_fixate_field_boolean (GstStructure * structure,
* Fixates a #GstStructure by changing the given @field_name field to the given
* @target string if that field is not fixed yet.
*
- * Returns: TRUE if the structure could be fixated
+ * Returns: %TRUE if the structure could be fixated
*/
gboolean
gst_structure_fixate_field_string (GstStructure * structure,
@@ -2654,7 +2711,7 @@ gst_structure_fixate_field_string (GstStructure * structure,
* fraction to @target_numerator/@target_denominator that is a subset
* of the existing field.
*
- * Returns: TRUE if the structure could be fixated
+ * Returns: %TRUE if the structure could be fixated
*/
gboolean
gst_structure_fixate_field_nearest_fraction (GstStructure * structure,
@@ -2756,7 +2813,7 @@ default_fixate (GQuark field_id, const GValue * value, gpointer data)
*
* Fixates a #GstStructure by changing the given field with its fixated value.
*
- * Returns: TRUE if the structure field could be fixated
+ * Returns: %TRUE if the structure field could be fixated
*/
gboolean
gst_structure_fixate_field (GstStructure * structure, const char *field_name)
@@ -2774,7 +2831,7 @@ gst_structure_fixate_field (GstStructure * structure, const char *field_name)
/* our very own version of G_VALUE_LCOPY that allows NULL return locations
* (useful for message parsing functions where the return location is user
- * supplied and the user may pass NULL if the value isn't of interest) */
+ * supplied and the user may pass %NULL if the value isn't of interest) */
#define GST_VALUE_LCOPY(value, var_args, flags, __error, fieldname) \
G_STMT_START { \
const GValue *_value = (value); \
@@ -2808,7 +2865,7 @@ G_STMT_START { \
* valist-variant of gst_structure_get(). Look at the documentation of
* gst_structure_get() for more details.
*
- * Returns: TRUE, or FALSE if there was a problem reading any of the fields
+ * Returns: %TRUE, or %FALSE if there was a problem reading any of the fields
*/
gboolean
gst_structure_get_valist (const GstStructure * structure,
@@ -2875,7 +2932,7 @@ wrong_type:
* valist-variant of gst_structure_id_get(). Look at the documentation of
* gst_structure_id_get() for more details.
*
- * Returns: TRUE, or FALSE if there was a problem reading any of the fields
+ * Returns: %TRUE, or %FALSE if there was a problem reading any of the fields
*/
gboolean
gst_structure_id_get_valist (const GstStructure * structure,
@@ -2942,16 +2999,16 @@ wrong_type:
* Parses the variable arguments and reads fields from @structure accordingly.
* Variable arguments should be in the form field name, field type
* (as a GType), pointer(s) to a variable(s) to hold the return value(s).
- * The last variable argument should be NULL.
+ * The last variable argument should be %NULL.
*
* For refcounted (mini)objects you will receive a new reference which
* you must release with a suitable _unref() when no longer needed. For
* strings and boxed types you will receive a copy which you will need to
* release with either g_free() or the suitable function for the boxed type.
*
- * Returns: FALSE if there was a problem reading any of the fields (e.g.
+ * Returns: %FALSE if there was a problem reading any of the fields (e.g.
* because the field requested did not exist, or was of a type other
- * than the type specified), otherwise TRUE.
+ * than the type specified), otherwise %TRUE.
*/
gboolean
gst_structure_get (const GstStructure * structure, const char *first_fieldname,
@@ -2979,9 +3036,9 @@ gst_structure_get (const GstStructure * structure, const char *first_fieldname,
* Parses the variable arguments and reads fields from @structure accordingly.
* Variable arguments should be in the form field id quark, field type
* (as a GType), pointer(s) to a variable(s) to hold the return value(s).
- * The last variable argument should be NULL (technically it should be a
- * 0 quark, but we require NULL so compilers that support it can check for
- * the NULL terminator and warn if it's not there).
+ * The last variable argument should be %NULL (technically it should be a
+ * 0 quark, but we require %NULL so compilers that support it can check for
+ * the %NULL terminator and warn if it's not there).
*
* This function is just like gst_structure_get() only that it is slightly
* more efficient since it saves the string-to-quark lookup in the global
@@ -2992,9 +3049,9 @@ gst_structure_get (const GstStructure * structure, const char *first_fieldname,
* strings and boxed types you will receive a copy which you will need to
* release with either g_free() or the suitable function for the boxed type.
*
- * Returns: FALSE if there was a problem reading any of the fields (e.g.
+ * Returns: %FALSE if there was a problem reading any of the fields (e.g.
* because the field requested did not exist, or was of a type other
- * than the type specified), otherwise TRUE.
+ * than the type specified), otherwise %TRUE.
*/
gboolean
gst_structure_id_get (const GstStructure * structure, GQuark first_field_id,
@@ -3036,7 +3093,7 @@ gst_structure_is_equal_foreach (GQuark field_id, const GValue * val2,
*
* Tests if the two #GstStructure are equal.
*
- * Returns: TRUE if the two structures have the same name and field.
+ * Returns: %TRUE if the two structures have the same name and field.
**/
gboolean
gst_structure_is_equal (const GstStructure * structure1,
@@ -3104,7 +3161,7 @@ gst_structure_intersect_field2 (GQuark id, const GValue * val1, gpointer data)
* @struct1: a #GstStructure
* @struct2: a #GstStructure
*
- * Interesects @struct1 and @struct2 and returns the intersection.
+ * Intersects @struct1 and @struct2 and returns the intersection.
*
* Returns: Intersection of @struct1 and @struct2
*/
diff --git a/gst/gststructure.h b/gst/gststructure.h
index f7cc61b..6687970 100644
--- a/gst/gststructure.h
+++ b/gst/gststructure.h
@@ -47,8 +47,8 @@ typedef struct _GstStructure GstStructure;
* A function that will be called in gst_structure_foreach(). The function may
* not modify @value.
*
- * Returns: TRUE if the foreach operation should continue, FALSE if
- * the foreach operation should stop with FALSE.
+ * Returns: %TRUE if the foreach operation should continue, %FALSE if
+ * the foreach operation should stop with %FALSE.
*/
typedef gboolean (*GstStructureForeachFunc) (GQuark field_id,
const GValue * value,
@@ -63,8 +63,8 @@ typedef gboolean (*GstStructureForeachFunc) (GQuark field_id,
* A function that will be called in gst_structure_map_in_place(). The function
* may modify @value.
*
- * Returns: TRUE if the map operation should continue, FALSE if
- * the map operation should stop with FALSE.
+ * Returns: %TRUE if the map operation should continue, %FALSE if
+ * the map operation should stop with %FALSE.
*/
typedef gboolean (*GstStructureMapFunc) (GQuark field_id,
GValue * value,
@@ -230,6 +230,14 @@ gboolean gst_structure_get_uint (const GstStructure *
const gchar * fieldname,
guint * value);
+gboolean gst_structure_get_int64 (const GstStructure * structure,
+ const gchar * fieldname,
+ gint64 * value);
+
+gboolean gst_structure_get_uint64 (const GstStructure * structure,
+ const gchar * fieldname,
+ guint64 * value);
+
gboolean gst_structure_get_double (const GstStructure * structure,
const gchar * fieldname,
gdouble * value);
diff --git a/gst/gstsystemclock.c b/gst/gstsystemclock.c
index 5e7f6b1..01beee7 100644
--- a/gst/gstsystemclock.c
+++ b/gst/gstsystemclock.c
@@ -34,8 +34,6 @@
* Subclasses can however override all of the important methods for sync and
* async notifications to implement their own callback methods or blocking
* wait operations.
- *
- * Last reviewed on 2006-03-08 (0.10.4)
*/
#include "gst_private.h"
@@ -112,6 +110,7 @@ enum
/* the one instance of the systemclock */
static GstClock *_the_system_clock = NULL;
+static gboolean _external_default_clock = FALSE;
static void gst_system_clock_dispose (GObject * object);
static void gst_system_clock_set_property (GObject * object, guint prop_id,
@@ -281,6 +280,45 @@ gst_system_clock_get_property (GObject * object, guint prop_id, GValue * value,
}
/**
+ * gst_system_clock_set_default:
+ * @new_clock: a #GstClock
+ *
+ * Sets the default system clock that can be obtained with
+ * gst_system_clock_obtain.
+ *
+ * This is mostly used for testing and debugging purposes when you
+ * want to have control over the time reported by the default system
+ * clock.
+ *
+ * MT safe.
+ *
+ * Since: 1.4
+ */
+void
+gst_system_clock_set_default (GstClock * new_clock)
+{
+ GstClock *clock;
+
+ g_mutex_lock (&_gst_sysclock_mutex);
+ clock = _the_system_clock;
+
+ if (clock != NULL)
+ g_object_unref (clock);
+
+ if (new_clock == NULL) {
+ GST_CAT_DEBUG (GST_CAT_CLOCK, "resetting default system clock");
+ _external_default_clock = FALSE;
+ } else {
+ GST_CAT_DEBUG (GST_CAT_CLOCK, "setting new default system clock to %p",
+ new_clock);
+ _external_default_clock = TRUE;
+ g_object_ref (new_clock);
+ }
+ _the_system_clock = new_clock;
+ g_mutex_unlock (&_gst_sysclock_mutex);
+}
+
+/**
* gst_system_clock_obtain:
*
* Get a handle to the default system clock. The refcount of the
@@ -301,6 +339,7 @@ gst_system_clock_obtain (void)
if (clock == NULL) {
GST_CAT_DEBUG (GST_CAT_CLOCK, "creating new static system clock");
+ g_assert (_external_default_clock == FALSE);
clock = g_object_new (GST_TYPE_SYSTEM_CLOCK,
"name", "GstSystemClock", NULL);
diff --git a/gst/gstsystemclock.h b/gst/gstsystemclock.h
index aa9dc14..fe5d009 100644
--- a/gst/gstsystemclock.h
+++ b/gst/gstsystemclock.h
@@ -81,6 +81,7 @@ struct _GstSystemClockClass {
GType gst_system_clock_get_type (void);
GstClock* gst_system_clock_obtain (void);
+void gst_system_clock_set_default (GstClock *new_clock);
G_END_DECLS
diff --git a/gst/gsttaglist.c b/gst/gsttaglist.c
index 5cff28d..c96cb56 100644
--- a/gst/gsttaglist.c
+++ b/gst/gsttaglist.c
@@ -25,9 +25,8 @@
*
* List of tags and values used to describe media metadata.
*
- * Strings must be in ASCII or UTF-8 encoding. No other encodings are allowed.
- *
- * Last reviewed on 2009-06-09 (0.10.23)
+ * Strings in structures must be ASCII or UTF-8 encoded. Other encodings are
+ * not allowed. Strings must not be empty or %NULL.
*/
#ifdef HAVE_CONFIG_H
@@ -85,6 +84,7 @@ static GMutex __tag_mutex;
/* tags hash table: maps tag name string => GstTagInfo */
static GHashTable *__tags;
+GType _gst_tag_list_type = 0;
GST_DEFINE_MINI_OBJECT_TYPE (GstTagList, gst_tag_list);
static void __gst_tag_list_free (GstTagList * list);
@@ -99,6 +99,8 @@ _priv_gst_tag_initialize (void)
{
g_mutex_init (&__tag_mutex);
+ _gst_tag_list_type = gst_tag_list_get_type ();
+
__tags = g_hash_table_new (g_str_hash, g_str_equal);
gst_tag_register_static (GST_TAG_TITLE, GST_TAG_FLAG_META,
G_TYPE_STRING,
@@ -396,6 +398,9 @@ _priv_gst_tag_initialize (void)
_("interpreted-by"),
_("Information about the people behind a remix and similar "
"interpretations"), gst_tag_merge_strings_with_comma);
+ gst_tag_register_static (GST_TAG_MIDI_BASE_NOTE, GST_TAG_FLAG_META,
+ G_TYPE_UINT,
+ _("midi-base-note"), _("Midi note number of the audio track."), NULL);
}
/**
@@ -463,7 +468,7 @@ gst_tag_lookup (const gchar * tag_name)
* @type: the type this data is in
* @nick: human-readable name
* @blurb: a human-readable description about this tag
- * @func: (allow-none): function for merging multiple values of this tag, or NULL
+ * @func: (allow-none): function for merging multiple values of this tag, or %NULL
*
* 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.
@@ -472,7 +477,7 @@ gst_tag_lookup (const gchar * tag_name)
*
* Important: if you do not supply a merge function the implication will be
* that there can only be one single value for this tag in a tag list and
- * any additional values will silenty be discarded when being added (unless
+ * any additional values will silently be discarded when being added (unless
* #GST_TAG_MERGE_REPLACE, #GST_TAG_MERGE_REPLACE_ALL, or
* #GST_TAG_MERGE_PREPEND is used as merge mode, in which case the new
* value will replace the old one in the list).
@@ -507,7 +512,7 @@ gst_tag_register (const gchar * name, GstTagFlag flag, GType type,
* @type: the type this data is in
* @nick: human-readable name or short description (string constant)
* @blurb: a human-readable description for this tag (string constant)
- * @func: (allow-none): function for merging multiple values of this tag, or NULL
+ * @func: (allow-none): function for merging multiple values of this tag, or %NULL
*
* Registers a new tag type for the use with GStreamer's type system.
*
@@ -553,7 +558,7 @@ gst_tag_register_static (const gchar * name, GstTagFlag flag, GType type,
*
* Checks if the given type is already registered.
*
- * Returns: TRUE if the type is already registered
+ * Returns: %TRUE if the type is already registered
*/
gboolean
gst_tag_exists (const gchar * tag)
@@ -652,7 +657,7 @@ gst_tag_get_flag (const gchar * tag)
* 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.
+ * Returns: %TRUE, if the given tag is fixed.
*/
gboolean
gst_tag_is_fixed (const gchar * tag)
@@ -738,10 +743,10 @@ gst_tag_list_new_empty (void)
/**
* gst_tag_list_new:
* @tag: tag
- * @...: NULL-terminated list of values to set
+ * @...: %NULL-terminated list of values to set
*
* Creates a new taglist and appends the values for the given tags. It expects
- * tag-value pairs like gst_tag_list_add(), and a NULL terminator after the
+ * tag-value pairs like gst_tag_list_add(), and a %NULL terminator after the
* last pair. The type of the values is implicit and is documented in the API
* reference, but can also be queried at runtime with gst_tag_get_type(). It
* is an error to pass a value of a type not matching the tag type into this
@@ -839,7 +844,7 @@ gst_tag_list_get_scope (const GstTagList * list)
*
* Serializes a tag list to a string.
*
- * Returns: a newly-allocated string, or NULL in case of an error. The
+ * Returns: a newly-allocated string, or %NULL in case of an error. The
* string must be freed with g_free() when no longer needed.
*/
gchar *
@@ -856,7 +861,7 @@ gst_tag_list_to_string (const GstTagList * list)
*
* Deserializes a tag list.
*
- * Returns: a new #GstTagList, or NULL in case of an error.
+ * Returns: a new #GstTagList, or %NULL in case of an error.
*/
GstTagList *
gst_tag_list_new_from_string (const gchar * str)
@@ -917,7 +922,7 @@ gst_tag_list_nth_tag_name (const GstTagList * list, guint index)
*
* Checks if the given taglist is empty.
*
- * Returns: TRUE if the taglist is empty, otherwise FALSE.
+ * Returns: %TRUE if the taglist is empty, otherwise %FALSE.
*/
gboolean
gst_tag_list_is_empty (const GstTagList * list)
@@ -956,7 +961,7 @@ gst_tag_list_fields_equal (const GValue * value1, const GValue * value2)
*
* Checks if the two given taglists are equal.
*
- * Returns: TRUE if the taglists are equal, otherwise FALSE
+ * Returns: %TRUE if the taglists are equal, otherwise %FALSE
*/
gboolean
gst_tag_list_is_equal (const GstTagList * list1, const GstTagList * list2)
@@ -1130,8 +1135,8 @@ gst_tag_list_insert (GstTagList * into, const GstTagList * from,
* @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.
+ * 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.
*
* Free-function: gst_tag_list_unref
*
@@ -1195,7 +1200,7 @@ gst_tag_list_get_tag_size (const GstTagList * list, const gchar * tag)
* @list: list to set tags in
* @mode: the mode to use
* @tag: tag
- * @...: NULL-terminated list of values to set
+ * @...: %NULL-terminated list of values to set
*
* Sets the values for the given tags using the specified mode.
*/
@@ -1419,7 +1424,7 @@ gst_tag_list_foreach (const GstTagList * list, GstTagForeachFunc func,
* Gets the value that is at the given index for the given tag in the given
* list.
*
- * Returns: (transfer none): The GValue for the specified entry or NULL if the
+ * Returns: (transfer none): The GValue for the specified entry or %NULL if the
* tag wasn't available or the tag doesn't have as many entries
*/
const GValue *
@@ -1457,7 +1462,7 @@ gst_tag_list_get_value_index (const GstTagList * list, const gchar * tag,
* 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
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
gboolean
@@ -1547,7 +1552,7 @@ gst_tag_list_get_ ## name ## _index (const GstTagList *list, \
* Copies the contents for the given tag into the value, merging multiple values
* into one if multiple values are associated with the tag.
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
/**
@@ -1560,7 +1565,7 @@ gst_tag_list_get_ ## name ## _index (const GstTagList *list, \
* Gets the value that is at the given index for the given tag in the given
* list.
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
TAG_MERGE_FUNCS (boolean, gboolean, TRUE);
@@ -1573,7 +1578,7 @@ TAG_MERGE_FUNCS (boolean, gboolean, TRUE);
* Copies the contents for the given tag into the value, merging multiple values
* into one if multiple values are associated with the tag.
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
/**
@@ -1586,7 +1591,7 @@ TAG_MERGE_FUNCS (boolean, gboolean, TRUE);
* Gets the value that is at the given index for the given tag in the given
* list.
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
TAG_MERGE_FUNCS (int, gint, TRUE);
@@ -1599,7 +1604,7 @@ TAG_MERGE_FUNCS (int, gint, TRUE);
* Copies the contents for the given tag into the value, merging multiple values
* into one if multiple values are associated with the tag.
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
/**
@@ -1612,7 +1617,7 @@ TAG_MERGE_FUNCS (int, gint, TRUE);
* Gets the value that is at the given index for the given tag in the given
* list.
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
TAG_MERGE_FUNCS (uint, guint, TRUE);
@@ -1626,7 +1631,7 @@ TAG_MERGE_FUNCS (uint, guint, TRUE);
* Gets the value that is at the given index for the given tag in the given
* list.
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
TAG_MERGE_FUNCS (int64, gint64, TRUE);
@@ -1639,7 +1644,7 @@ TAG_MERGE_FUNCS (int64, gint64, TRUE);
* Copies the contents for the given tag into the value, merging multiple values
* into one if multiple values are associated with the tag.
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
/**
@@ -1652,7 +1657,7 @@ TAG_MERGE_FUNCS (int64, gint64, TRUE);
* Gets the value that is at the given index for the given tag in the given
* list.
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
TAG_MERGE_FUNCS (uint64, guint64, TRUE);
@@ -1665,7 +1670,7 @@ TAG_MERGE_FUNCS (uint64, guint64, TRUE);
* Copies the contents for the given tag into the value, merging multiple values
* into one if multiple values are associated with the tag.
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
/**
@@ -1678,7 +1683,7 @@ TAG_MERGE_FUNCS (uint64, guint64, TRUE);
* Gets the value that is at the given index for the given tag in the given
* list.
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
TAG_MERGE_FUNCS (float, gfloat, TRUE);
@@ -1691,7 +1696,7 @@ TAG_MERGE_FUNCS (float, gfloat, TRUE);
* Copies the contents for the given tag into the value, merging multiple values
* into one if multiple values are associated with the tag.
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
/**
@@ -1704,7 +1709,7 @@ TAG_MERGE_FUNCS (float, gfloat, TRUE);
* Gets the value that is at the given index for the given tag in the given
* list.
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
TAG_MERGE_FUNCS (double, gdouble, TRUE);
@@ -1717,7 +1722,7 @@ TAG_MERGE_FUNCS (double, gdouble, TRUE);
* Copies the contents for the given tag into the value, merging multiple values
* into one if multiple values are associated with the tag.
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
/**
@@ -1730,7 +1735,7 @@ TAG_MERGE_FUNCS (double, gdouble, TRUE);
* Gets the value that is at the given index for the given tag in the given
* list.
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
TAG_MERGE_FUNCS (pointer, gpointer, (*value != NULL));
@@ -1761,11 +1766,11 @@ _gst_strdup0 (const gchar * s)
*
* The resulting string in @value will be in UTF-8 encoding and should be
* freed by the caller using g_free when no longer needed. The
- * returned string is also guaranteed to be non-NULL and non-empty.
+ * returned string is also guaranteed to be non-%NULL and non-empty.
*
* Free-function: g_free
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
/**
@@ -1780,11 +1785,11 @@ _gst_strdup0 (const gchar * s)
*
* The resulting string in @value will be in UTF-8 encoding and should be
* freed by the caller using g_free when no longer needed. The
- * returned string is also guaranteed to be non-NULL and non-empty.
+ * returned string is also guaranteed to be non-%NULL and non-empty.
*
* Free-function: g_free
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
* given list.
*/
TAG_MERGE_FUNCS (string, gchar *, (*value != NULL));
@@ -1806,9 +1811,9 @@ TAG_MERGE_FUNCS (string, gchar *, (*value != NULL));
*
* The resulting string in @value will be in UTF-8 encoding and doesn't need
* to be freed by the caller. The returned string is also guaranteed to
- * be non-NULL and non-empty.
+ * be non-%NULL and non-empty.
*
- * Returns: TRUE, if a value was set, FALSE if the tag didn't exist in the
+ * Returns: %TRUE, if a value was set, %FALSE if the tag didn't exist in the
* given list.
*/
gboolean
@@ -1840,8 +1845,8 @@ gst_tag_list_peek_string_index (const GstTagList * list,
*
* Free-function: g_date_free
*
- * Returns: TRUE, if a date was copied, FALSE if the tag didn't exist in the
- * given list or if it was #NULL.
+ * Returns: %TRUE, if a date was copied, %FALSE if the tag didn't exist in the
+ * given list or if it was %NULL.
*/
gboolean
gst_tag_list_get_date (const GstTagList * list, const gchar * tag,
@@ -1873,8 +1878,8 @@ gst_tag_list_get_date (const GstTagList * list, const gchar * tag,
*
* Free-function: g_date_free
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
- * given list or if it was #NULL.
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
+ * given list or if it was %NULL.
*/
gboolean
gst_tag_list_get_date_index (const GstTagList * list,
@@ -1905,8 +1910,8 @@ gst_tag_list_get_date_index (const GstTagList * list,
*
* Free-function: gst_date_time_unref
*
- * Returns: TRUE, if a datetime was copied, FALSE if the tag didn't exist in
- * thegiven list or if it was #NULL.
+ * Returns: %TRUE, if a datetime was copied, %FALSE if the tag didn't exist in
+ * the given list or if it was %NULL.
*/
gboolean
gst_tag_list_get_date_time (const GstTagList * list, const gchar * tag,
@@ -1921,8 +1926,6 @@ gst_tag_list_get_date_time (const GstTagList * list, const gchar * tag,
if (!gst_tag_list_copy_value (&v, list, tag))
return FALSE;
- g_return_val_if_fail (GST_VALUE_HOLDS_DATE_TIME (&v), FALSE);
-
*value = (GstDateTime *) g_value_dup_boxed (&v);
g_value_unset (&v);
return (*value != NULL);
@@ -1941,8 +1944,8 @@ gst_tag_list_get_date_time (const GstTagList * list, const gchar * tag,
*
* Free-function: gst_date_time_unref
*
- * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
- * given list or if it was #NULL.
+ * Returns: %TRUE, if a value was copied, %FALSE if the tag didn't exist in the
+ * given list or if it was %NULL.
*/
gboolean
gst_tag_list_get_date_time_index (const GstTagList * list,
@@ -1975,8 +1978,8 @@ gst_tag_list_get_date_time_index (const GstTagList * list,
*
* Free-function: gst_sample_unref
*
- * Returns: TRUE, if a sample was returned, FALSE if the tag didn't exist in
- * the given list or if it was #NULL.
+ * Returns: %TRUE, if a sample was returned, %FALSE if the tag didn't exist in
+ * the given list or if it was %NULL.
*/
gboolean
gst_tag_list_get_sample (const GstTagList * list, const gchar * tag,
@@ -2004,15 +2007,15 @@ gst_tag_list_get_sample (const GstTagList * list, const gchar * tag,
* pointer variable to store the result into
*
* Gets the sample that is at the given index for the given tag in the given
- * list and copies it into the variable pointed to by @smple. Free the sample
+ * list and copies it into the variable pointed to by @sample. Free the sample
* with gst_sample_unref() when it is no longer needed. You can retrieve the
* buffer from the sample using gst_sample_get_buffer() and the associated
* caps (if any) with gst_sample_get_caps().
*
* Free-function: gst_sample_unref
*
- * Returns: TRUE, if a sample was copied, FALSE if the tag didn't exist in the
- * given list or if it was #NULL.
+ * Returns: %TRUE, if a sample was copied, %FALSE if the tag didn't exist in the
+ * given list or if it was %NULL.
*/
gboolean
gst_tag_list_get_sample_index (const GstTagList * list,
diff --git a/gst/gsttaglist.h b/gst/gsttaglist.h
index b5e683e..42f944b 100644
--- a/gst/gsttaglist.h
+++ b/gst/gsttaglist.h
@@ -154,8 +154,10 @@ struct _GstTagList {
GstMiniObject mini_object;
};
+GST_EXPORT GType _gst_tag_list_type;
+
#define GST_TAG_LIST(x) ((GstTagList *) (x))
-#define GST_TYPE_TAG_LIST (gst_tag_list_get_type ())
+#define GST_TYPE_TAG_LIST (_gst_tag_list_type)
#define GST_IS_TAG_LIST(obj) (GST_IS_MINI_OBJECT_TYPE((obj), GST_TYPE_TAG_LIST))
/**
@@ -1060,6 +1062,16 @@ gst_tag_list_copy (const GstTagList * taglist)
* Since: 1.2
*/
#define GST_TAG_INTERPRETED_BY "interpreted-by"
+/**
+ * GST_TAG_MIDI_BASE_NOTE:
+ *
+ * <ulink url="http://en.wikipedia.org/wiki/Note#Note_designation_in_accordance_with_octave_name">Midi note number</ulink>
+ * of the audio track. This is useful for sample instruments and in particular
+ * for multi-samples.
+ *
+ * Since: 1.4
+ */
+#define GST_TAG_MIDI_BASE_NOTE "midi-base-note"
G_END_DECLS
diff --git a/gst/gsttagsetter.c b/gst/gsttagsetter.c
index cd402cb..b2955d6 100644
--- a/gst/gsttagsetter.c
+++ b/gst/gsttagsetter.c
@@ -64,8 +64,6 @@
*
* GST_LOG_OBJECT (tagsetter, "final tags: %" GST_PTR_FORMAT, result);
* ]|
- *
- * Last reviewed on 2006-05-18 (0.10.6)
*/
#ifdef HAVE_CONFIG_H
@@ -202,7 +200,7 @@ gst_tag_setter_merge_tags (GstTagSetter * setter, const GstTagList * list,
* @...: more tag / value pairs to set
*
* Adds the given tag / value pairs on the setter using the given merge mode.
- * The list must be terminated with NULL.
+ * The list must be terminated with %NULL.
*/
void
gst_tag_setter_add_tags (GstTagSetter * setter, GstTagMergeMode mode,
@@ -226,7 +224,7 @@ gst_tag_setter_add_tags (GstTagSetter * setter, GstTagMergeMode mode,
* @...: more tag / GValue pairs to set
*
* Adds the given tag / GValue pairs on the setter using the given merge mode.
- * The list must be terminated with NULL.
+ * The list must be terminated with %NULL.
*/
void
gst_tag_setter_add_tag_values (GstTagSetter * setter, GstTagMergeMode mode,
@@ -250,7 +248,7 @@ gst_tag_setter_add_tag_values (GstTagSetter * setter, GstTagMergeMode mode,
* @var_args: tag / value pairs to set
*
* Adds the given tag / value pairs on the setter using the given merge mode.
- * The list must be terminated with NULL.
+ * The list must be terminated with %NULL.
*/
void
gst_tag_setter_add_tag_valist (GstTagSetter * setter, GstTagMergeMode mode,
@@ -280,7 +278,7 @@ gst_tag_setter_add_tag_valist (GstTagSetter * setter, GstTagMergeMode mode,
* @var_args: tag / GValue pairs to set
*
* Adds the given tag / GValue pairs on the setter using the given merge mode.
- * The list must be terminated with NULL.
+ * The list must be terminated with %NULL.
*/
void
gst_tag_setter_add_tag_valist_values (GstTagSetter * setter,
@@ -343,7 +341,7 @@ gst_tag_setter_add_tag_value (GstTagSetter * setter,
* This function is not thread-safe.
*
* Returns: (transfer none): a current snapshot of the taglist used in the
- * setter or NULL if none is used.
+ * setter or %NULL if none is used.
*/
const GstTagList *
gst_tag_setter_get_tag_list (GstTagSetter * setter)
diff --git a/gst/gsttask.c b/gst/gsttask.c
index 993eb70..b562f6c 100644
--- a/gst/gsttask.c
+++ b/gst/gsttask.c
@@ -64,8 +64,6 @@
* name on Linux. Please note that the object name should be configured before the
* task is started; changing the object name after the task has been started, has
* no effect on the thread name.
- *
- * Last reviewed on 2012-03-29 (0.11.3)
*/
#include "gst_private.h"
@@ -197,6 +195,9 @@ gst_task_init (GstTask * task)
g_mutex_lock (&pool_lock);
task->priv->pool = gst_object_ref (klass->pool);
g_mutex_unlock (&pool_lock);
+
+ /* clear floating flag */
+ gst_object_ref_sink (task);
}
static void
@@ -330,7 +331,7 @@ exit:
GST_OBJECT_LOCK (task);
}
/* now we allow messing with the lock again by setting the running flag to
- * FALSE. Together with the SIGNAL this is the sign for the _join() to
+ * %FALSE. Together with the SIGNAL this is the sign for the _join() to
* complete.
* Note that we still have not dropped the final ref on the task. We could
* check here if there is a pending join() going on and drop the last ref
diff --git a/gst/gsttaskpool.c b/gst/gsttaskpool.c
index e08f2a3..d7ff344 100644
--- a/gst/gsttaskpool.c
+++ b/gst/gsttaskpool.c
@@ -28,8 +28,6 @@
* implementation uses a regular GThreadPool to start tasks.
*
* Subclasses can be made to create custom threads.
- *
- * Last reviewed on 2009-04-23 (0.10.24)
*/
#include "gst_private.h"
@@ -141,6 +139,8 @@ gst_task_pool_class_init (GstTaskPoolClass * klass)
static void
gst_task_pool_init (GstTaskPool * pool)
{
+ /* clear floating flag */
+ gst_object_ref_sink (pool);
}
#ifndef GST_DISABLE_GST_DEBUG
@@ -224,7 +224,7 @@ gst_task_pool_cleanup (GstTaskPool * pool)
* Start the execution of a new thread from @pool.
*
* Returns: (transfer none): a pointer that should be used for the
- * gst_task_pool_join function. This pointer can be NULL, you must
+ * gst_task_pool_join function. This pointer can be %NULL, you must
* check @error to detect errors.
*/
gpointer
diff --git a/gst/gsttoc.c b/gst/gsttoc.c
index 6da7ad8..bee13cb 100644
--- a/gst/gsttoc.c
+++ b/gst/gsttoc.c
@@ -96,6 +96,8 @@ struct _GstTocEntry
GstClockTime start, stop;
GList *subentries;
GstTagList *tags;
+ GstTocLoopType loop_type;
+ gint repeat_count;
};
struct _GstToc
@@ -114,6 +116,9 @@ static void gst_toc_free (GstToc * toc);
static GstTocEntry *gst_toc_entry_copy (const GstTocEntry * toc);
static void gst_toc_entry_free (GstTocEntry * toc);
+GType _gst_toc_type = 0;
+GType _gst_toc_entry_type = 0;
+
GST_DEFINE_MINI_OBJECT_TYPE (GstToc, gst_toc);
GST_DEFINE_MINI_OBJECT_TYPE (GstTocEntry, gst_toc_entry);
@@ -355,7 +360,7 @@ gst_toc_entry_find_sub_entry (const GstTocEntry * entry, const gchar * uid)
*
* Find #GstTocEntry with given @uid in the @toc.
*
- * Returns: (transfer none): #GstTocEntry with specified @uid from the @toc, or NULL if not found.
+ * Returns: (transfer none): #GstTocEntry with specified @uid from the @toc, or %NULL if not found.
*/
GstTocEntry *
gst_toc_find_entry (const GstToc * toc, const gchar * uid)
@@ -388,7 +393,7 @@ gst_toc_find_entry (const GstToc * toc, const gchar * uid)
*
* Copy #GstTocEntry with all subentries (deep copy).
*
- * Returns: newly allocated #GstTocEntry in case of success, NULL otherwise;
+ * Returns: newly allocated #GstTocEntry in case of success, %NULL otherwise;
* free it when done with gst_toc_entry_unref().
*/
static GstTocEntry *
@@ -432,7 +437,7 @@ gst_toc_entry_copy (const GstTocEntry * entry)
*
* Copy #GstToc with all subentries (deep copy).
*
- * Returns: newly allocated #GstToc in case of success, NULL otherwise;
+ * Returns: newly allocated #GstToc in case of success, %NULL otherwise;
* free it when done with gst_toc_unref().
*/
static GstToc *
@@ -487,20 +492,19 @@ gst_toc_entry_set_start_stop_times (GstTocEntry * entry, gint64 start,
/**
* gst_toc_entry_get_start_stop_times:
* @entry: #GstTocEntry to get values from.
- * @start: (out): the storage for the start value, leave #NULL if not need.
- * @stop: (out): the storage for the stop value, leave #NULL if not need.
+ * @start: (out): the storage for the start value, leave %NULL if not need.
+ * @stop: (out): the storage for the stop value, leave %NULL if not need.
*
- * Get start and stop values from the @entry and write them into appropriate storages.
+ * Get @start and @stop values from the @entry and write them into appropriate
+ * storages.
*
- * Returns: TRUE if all non-NULL storage pointers were filled with appropriate values,
- * FALSE otherwise.
+ * Returns: %TRUE if all non-%NULL storage pointers were filled with appropriate
+ * values, %FALSE otherwise.
*/
gboolean
gst_toc_entry_get_start_stop_times (const GstTocEntry * entry, gint64 * start,
gint64 * stop)
{
- gboolean ret = TRUE;
-
g_return_val_if_fail (entry != NULL, FALSE);
if (start != NULL)
@@ -508,9 +512,62 @@ gst_toc_entry_get_start_stop_times (const GstTocEntry * entry, gint64 * start,
if (stop != NULL)
*stop = entry->stop;
- return ret;
+ return TRUE;
+}
+
+/**
+ * gst_toc_entry_set_loop:
+ * @entry: #GstTocEntry to set values.
+ * @loop_type: loop_type value to set.
+ * @repeat_count: repeat_count value to set.
+ *
+ * Set @loop_type and @repeat_count values for the @entry.
+ *
+ * Since: 1.4
+ */
+void
+gst_toc_entry_set_loop (GstTocEntry * entry, GstTocLoopType loop_type,
+ gint repeat_count)
+{
+ g_return_if_fail (entry != NULL);
+
+ entry->loop_type = loop_type;
+ entry->repeat_count = repeat_count;
+}
+
+/**
+ * gst_toc_entry_get_loop:
+ * @entry: #GstTocEntry to get values from.
+ * @loop_type: (out): the storage for the loop_type value, leave %NULL if not
+ * need.
+ * @repeat_count: (out): the storage for the repeat_count value, leave %NULL if
+ * not need.
+ *
+ * Get @loop_type and @repeat_count values from the @entry and write them into
+ * appropriate storages. Loops are e.g. used by sampled instruments. GStreamer
+ * is not automatically applying the loop. The application can process this
+ * meta data and use it e.g. to send a seek-event to loop a section.
+ *
+ * Returns: %TRUE if all non-%NULL storage pointers were filled with appropriate
+ * values, %FALSE otherwise.
+ *
+ * Since: 1.4
+ */
+gboolean
+gst_toc_entry_get_loop (const GstTocEntry * entry, GstTocLoopType * loop_type,
+ gint * repeat_count)
+{
+ g_return_val_if_fail (entry != NULL, FALSE);
+
+ if (loop_type != NULL)
+ *loop_type = entry->loop_type;
+ if (repeat_count != NULL)
+ *repeat_count = entry->repeat_count;
+
+ return TRUE;
}
+
/**
* gst_toc_entry_type_get_nick:
* @type: a #GstTocEntryType.
@@ -766,3 +823,10 @@ gst_toc_dump (GstToc * toc)
gst_toc_dump_entries (toc->entries, 2);
#endif
}
+
+void
+_priv_gst_toc_initialize (void)
+{
+ _gst_toc_type = gst_toc_get_type ();
+ _gst_toc_entry_type = gst_toc_entry_get_type ();
+}
diff --git a/gst/gsttoc.h b/gst/gsttoc.h
index 632435a..39469c1 100644
--- a/gst/gsttoc.h
+++ b/gst/gsttoc.h
@@ -30,8 +30,11 @@
G_BEGIN_DECLS
-#define GST_TYPE_TOC (gst_toc_get_type ())
-#define GST_TYPE_TOC_ENTRY (gst_toc_entry_get_type ())
+GST_EXPORT GType _gst_toc_type;
+GST_EXPORT GType _gst_toc_entry_type;
+
+#define GST_TYPE_TOC (_gst_toc_type)
+#define GST_TYPE_TOC_ENTRY (_gst_toc_entry_type)
typedef struct _GstTocEntry GstTocEntry;
typedef struct _GstToc GstToc;
@@ -81,6 +84,35 @@ typedef enum {
#define GST_TOC_ENTRY_TYPE_IS_ALTERNATIVE(entry_type) (entry_type < 0)
#define GST_TOC_ENTRY_TYPE_IS_SEQUENCE(entry_type) (entry_type > 0)
+/**
+ * GstTocLoopType:
+ * @GST_TOC_LOOP_NONE: single forward playback
+ * @GST_TOC_LOOP_FORWARD: repeat forward
+ * @GST_TOC_LOOP_REVERSE: repeat backward
+ * @GST_TOC_LOOP_PING_PONG: repeat forward and backward
+ *
+ * How a #GstTocEntry should be repeated. By default, entries are played a
+ * single time.
+ *
+ * Since: 1.4
+ */
+typedef enum {
+ GST_TOC_LOOP_NONE = 0,
+ GST_TOC_LOOP_FORWARD,
+ GST_TOC_LOOP_REVERSE,
+ GST_TOC_LOOP_PING_PONG
+} GstTocLoopType;
+
+/**
+ * GST_TOC_REPEAT_COUNT_INFINITE:
+ *
+ * Special value for the repeat_count set in gst_toc_entry_set_loop() or
+ * returned by gst_toc_entry_set_loop() to indicate infinite looping.
+ *
+ * Since: 1.4
+ */
+#define GST_TOC_REPEAT_COUNT_INFINITE (-1)
+
/* functions to return type structures */
GType gst_toc_get_type (void);
GType gst_toc_entry_get_type (void);
@@ -130,6 +162,9 @@ gboolean gst_toc_entry_is_sequence (const GstTocEntry *ent
void gst_toc_entry_set_start_stop_times (GstTocEntry *entry, gint64 start, gint64 stop);
gboolean gst_toc_entry_get_start_stop_times (const GstTocEntry *entry, gint64 *start, gint64 *stop);
+void gst_toc_entry_set_loop (GstTocEntry *entry, GstTocLoopType loop_type, gint repeat_count);
+gboolean gst_toc_entry_get_loop (const GstTocEntry *entry, GstTocLoopType *loop_type, gint *repeat_count);
+
GstToc * gst_toc_entry_get_toc (GstTocEntry *entry);
GstTocEntry * gst_toc_entry_get_parent (GstTocEntry *entry);
diff --git a/gst/gsttocsetter.c b/gst/gsttocsetter.c
index 182a98c..42839d2 100644
--- a/gst/gsttocsetter.c
+++ b/gst/gsttocsetter.c
@@ -128,7 +128,7 @@ gst_toc_setter_reset (GstTocSetter * setter)
* modified without making it writable first.
*
*
- * Returns: (transfer full): TOC set, or NULL. Unref with gst_toc_unref()
+ * Returns: (transfer full): TOC set, or %NULL. Unref with gst_toc_unref()
* when no longer needed
*/
GstToc *
@@ -155,8 +155,8 @@ gst_toc_setter_get_toc (GstTocSetter * setter)
* @setter: a #GstTocSetter.
* @toc: (allow-none): a #GstToc to set.
*
- * Set the given TOC on the setter. Previously setted TOC will be
- * unrefed before setting a new one.
+ * Set the given TOC on the setter. Previously set TOC will be
+ * unreffed before setting a new one.
*/
void
gst_toc_setter_set_toc (GstTocSetter * setter, GstToc * toc)
diff --git a/gst/gsttypefind.c b/gst/gsttypefind.c
index c414810..1fcbea1 100644
--- a/gst/gsttypefind.c
+++ b/gst/gsttypefind.c
@@ -25,8 +25,6 @@
*
* The following functions allow you to detect the media type of an unknown
* stream.
- *
- * Last reviewed on 2005-11-09 (0.9.4)
*/
#include "gst_private.h"
@@ -42,7 +40,7 @@ G_DEFINE_POINTER_TYPE (GstTypeFind, gst_type_find);
/**
* gst_type_find_register:
- * @plugin: (allow-none): A #GstPlugin, or NULL for a static typefind function
+ * @plugin: (allow-none): A #GstPlugin, or %NULL for a static typefind function
* @name: The name for registering
* @rank: The rank (or importance) of this typefind function
* @func: The #GstTypeFindFunction to use
@@ -59,7 +57,7 @@ G_DEFINE_POINTER_TYPE (GstTypeFind, gst_type_find);
* registering this function will be available for typefinding.
* This function is typically called during an element's plugin initialization.
*
- * Returns: TRUE on success, FALSE otherwise
+ * Returns: %TRUE on success, %FALSE otherwise
*/
gboolean
gst_type_find_register (GstPlugin * plugin, const gchar * name, guint rank,
@@ -121,7 +119,7 @@ gst_type_find_register (GstPlugin * plugin, const gchar * name, guint rank,
* the stream. The returned memory is valid until the typefinding function
* returns and must not be freed.
*
- * Returns: (transfer none) (array length=size): the requested data, or NULL
+ * Returns: (transfer none) (array length=size): the requested data, or %NULL
* if that data is not available.
*/
const guint8 *
@@ -159,7 +157,7 @@ gst_type_find_suggest (GstTypeFind * find, guint probability, GstCaps * caps)
* @find: The #GstTypeFind object the function was called with
* @probability: The probability in percent that the suggestion is right
* @media_type: the media type of the suggested caps
- * @fieldname: (allow-none): first field of the suggested caps, or NULL
+ * @fieldname: (allow-none): first field of the suggested caps, or %NULL
* @...: additional arguments to the suggested caps in the same format as the
* arguments passed to gst_structure_new() (ie. triplets of field name,
* field GType and field value)
@@ -173,7 +171,7 @@ gst_type_find_suggest (GstTypeFind * find, guint probability, GstCaps * caps)
* passing a #GstCaps argument you can create the caps on the fly in the same
* way as you can with gst_caps_new_simple().
*
- * Make sure you terminate the list of arguments with a NULL argument and that
+ * Make sure you terminate the list of arguments with a %NULL argument and that
* the values passed have the correct type (in terms of width in bytes when
* passed to the vararg function - this applies particularly to gdouble and
* guint64 arguments).
diff --git a/gst/gsttypefind.h b/gst/gsttypefind.h
index f596f30..4431b1c 100644
--- a/gst/gsttypefind.h
+++ b/gst/gsttypefind.h
@@ -36,7 +36,7 @@ typedef struct _GstTypeFind GstTypeFind;
/**
* GstTypeFindFunction:
* @find: A #GstTypeFind structure
- * @user_data: optionnal data to pass to the function
+ * @user_data: optional data to pass to the function
*
* A function that will be called by typefinding.
*/
diff --git a/gst/gsttypefindfactory.c b/gst/gsttypefindfactory.c
index 92eb52b..c216eb3 100644
--- a/gst/gsttypefindfactory.c
+++ b/gst/gsttypefindfactory.c
@@ -28,9 +28,10 @@
* the section <link linkend="gstreamer-Writing-typefind-functions">
* "Writing typefind functions"</link>.
*
- * <example>
- * <title>how to write a simple typefinder</title>
- * <programlisting>
+ * The following example shows how to write a very simple typefinder that
+ * identifies the given data. You can get quite a bit more complicated than
+ * that though.
+ * |[
* typedef struct {
* guint8 *data;
* guint size;
@@ -70,14 +71,7 @@
* g_list_free (type_list);
* return find.caps;
* };
- * </programlisting>
- * </example>
- *
- * The above example shows how to write a very simple typefinder that
- * identifies the given data. You can get quite a bit more complicated than
- * that though.
- *
- * Last reviewed on 2005-11-09 (0.9.4)
+ * ]|
*/
#include "gst_private.h"
@@ -180,11 +174,11 @@ gst_type_find_factory_get_caps (GstTypeFindFactory * factory)
*
* Gets the extensions associated with a #GstTypeFindFactory. The returned
* array should not be changed. If you need to change stuff in it, you should
- * copy it using g_strdupv(). This function may return NULL to indicate
+ * copy it using g_strdupv(). This function may return %NULL to indicate
* a 0-length list.
*
* Returns: (transfer none) (array zero-terminated=1) (element-type utf8): a
- * NULL-terminated array of extensions associated with this factory
+ * %NULL-terminated array of extensions associated with this factory
*/
const gchar *const *
gst_type_find_factory_get_extensions (GstTypeFindFactory * factory)
@@ -231,7 +225,7 @@ gst_type_find_factory_call_function (GstTypeFindFactory * factory,
* without typefind functions are a last-effort fallback mechanism to
* e.g. assume a certain media type based on the file extension.
*
- * Returns: TRUE if the factory has a typefind functions set, otherwise FALSE
+ * Returns: %TRUE if the factory has a typefind functions set, otherwise %FALSE
*/
gboolean
gst_type_find_factory_has_function (GstTypeFindFactory * factory)
diff --git a/gst/gsturi.c b/gst/gsturi.c
index 234a27d..00a496f 100644
--- a/gst/gsturi.c
+++ b/gst/gsturi.c
@@ -33,8 +33,6 @@
* (gst_element_make_from_uri()).
*
* Source and Sink plugins should implement this interface when possible.
- *
- * Last reviewed on 2005-11-09 (0.9.4)
*/
#ifdef HAVE_CONFIG_H
@@ -303,7 +301,7 @@ gst_uri_protocol_check_internal (const gchar * uri, gchar ** endptr)
* must consist of alphanumeric characters, '+', '-' and '.' and must
* start with a alphabetic character. See RFC 3986 Section 3.1.
*
- * Returns: TRUE if the string is a valid protocol identifier, FALSE otherwise.
+ * Returns: %TRUE if the string is a valid protocol identifier, %FALSE otherwise.
*/
gboolean
gst_uri_protocol_is_valid (const gchar * protocol)
@@ -324,7 +322,7 @@ gst_uri_protocol_is_valid (const gchar * protocol)
* Tests if the given string is a valid URI identifier. URIs start with a valid
* scheme followed by ":" and maybe a string identifying the location.
*
- * Returns: TRUE if the string is a valid URI
+ * Returns: %TRUE if the string is a valid URI
*/
gboolean
gst_uri_is_valid (const gchar * uri)
@@ -397,7 +395,7 @@ gst_uri_has_protocol (const gchar * uri, const gchar * protocol)
*
* Free-function: g_free
*
- * Returns: (transfer full): the location for this URI. Returns NULL if the
+ * Returns: (transfer full): the location for this URI. Returns %NULL if the
* URI isn't valid. If the URI does not contain a location, an empty
* string is returned.
*/
@@ -426,7 +424,7 @@ gst_uri_get_location (const gchar * uri)
g_ascii_isalpha (unescaped[1]) &&
(unescaped[2] == ':' || unescaped[2] == '|')) {
unescaped[2] = ':';
- g_memmove (unescaped, unescaped + 1, strlen (unescaped + 1) + 1);
+ memmove (unescaped, unescaped + 1, strlen (unescaped + 1) + 1);
}
#endif
@@ -444,8 +442,8 @@ gst_uri_get_location (const gchar * uri)
*
* Free-function: g_free
*
- * Returns: (transfer full): a new string for this URI. Returns NULL if the
- * given URI protocol is not valid, or the given location is NULL.
+ * Returns: (transfer full): a new string for this URI. Returns %NULL if the
+ * given URI protocol is not valid, or the given location is %NULL.
*/
gchar *
gst_uri_construct (const gchar * protocol, const gchar * location)
@@ -535,7 +533,7 @@ get_element_factories_from_uri_protocol (const GstURIType type,
* that a positive return value does not imply that a subsequent call to
* gst_element_make_from_uri() is guaranteed to work.
*
- * Returns: TRUE
+ * Returns: %TRUE
*/
gboolean
gst_uri_protocol_is_supported (const GstURIType type, const gchar * protocol)
@@ -557,12 +555,12 @@ gst_uri_protocol_is_supported (const GstURIType type, const gchar * protocol)
* gst_element_make_from_uri:
* @type: Whether to create a source or a sink
* @uri: URI to create an element for
- * @elementname: (allow-none): Name of created element, can be NULL.
- * @error: (allow-none): address where to store error information, or NULL.
+ * @elementname: (allow-none): Name of created element, can be %NULL.
+ * @error: (allow-none): address where to store error information, or %NULL.
*
* Creates an element for handling the given URI.
*
- * Returns: (transfer floating): a new element or NULL if none could be created
+ * Returns: (transfer floating): a new element or %NULL if none could be created
*/
GstElement *
gst_element_make_from_uri (const GstURIType type, const gchar * uri,
@@ -667,7 +665,7 @@ gst_uri_handler_get_uri_type (GstURIHandler * handler)
* modified.
*
* Returns: (transfer none) (element-type utf8): the supported protocols.
- * Returns NULL if the @handler isn't implemented properly, or the @handler
+ * Returns %NULL if the @handler isn't implemented properly, or the @handler
* doesn't support any protocols.
*/
const gchar *const *
@@ -695,7 +693,7 @@ gst_uri_handler_get_protocols (GstURIHandler * handler)
* Gets the currently handled URI.
*
* Returns: (transfer full): the URI currently handled by the @handler.
- * Returns NULL if there are no URI currently handled. The
+ * Returns %NULL if there are no URI currently handled. The
* returned string must be freed with g_free() when no longer needed.
*/
gchar *
@@ -721,11 +719,11 @@ gst_uri_handler_get_uri (GstURIHandler * handler)
* @handler: A #GstURIHandler
* @uri: URI to set
* @error: (allow-none): address where to store a #GError in case of
- * an error, or NULL
+ * an error, or %NULL
*
* Tries to set the URI of the given handler.
*
- * Returns: TRUE if the URI was set successfully, else FALSE.
+ * Returns: %TRUE if the URI was set successfully, else %FALSE.
*/
gboolean
gst_uri_handler_set_uri (GstURIHandler * handler, const gchar * uri,
@@ -801,7 +799,7 @@ gst_file_utils_canonicalise_path (const gchar * path)
if (strcmp (*p, ".") == 0) {
/* just move all following parts on top of this, incl. NUL terminator */
g_free (*p);
- g_memmove (p, p + 1, (g_strv_length (p + 1) + 1) * sizeof (gchar *));
+ memmove (p, p + 1, (g_strv_length (p + 1) + 1) * sizeof (gchar *));
/* re-check the new current part again in the next iteration */
continue;
} else if (strcmp (*p, "..") == 0 && p > parts) {
@@ -809,7 +807,7 @@ gst_file_utils_canonicalise_path (const gchar * path)
* NUL terminator */
g_free (*(p - 1));
g_free (*p);
- g_memmove (p - 1, p + 1, (g_strv_length (p + 1) + 1) * sizeof (gchar *));
+ memmove (p - 1, p + 1, (g_strv_length (p + 1) + 1) * sizeof (gchar *));
/* re-check the new current part again in the next iteration */
--p;
continue;
@@ -821,7 +819,7 @@ gst_file_utils_canonicalise_path (const gchar * path)
num_parts = g_strv_length (parts) + 1; /* incl. terminator */
parts = g_renew (gchar *, parts, num_parts + 1);
- g_memmove (parts + 1, parts, num_parts * sizeof (gchar *));
+ memmove (parts + 1, parts, num_parts * sizeof (gchar *));
parts[0] = g_strdup ("/");
}
@@ -841,7 +839,7 @@ file_path_contains_relatives (const gchar * path)
/**
* gst_filename_to_uri:
* @filename: absolute or relative file name path
- * @error: pointer to error, or NULL
+ * @error: pointer to error, or %NULL
*
* Similar to g_filename_to_uri(), but attempts to handle relative file paths
* as well. Before converting @filename into an URI, it will be prefixed by
diff --git a/gst/gstutils.c b/gst/gstutils.c
index 24aa66a..c411631 100644
--- a/gst/gstutils.c
+++ b/gst/gstutils.c
@@ -117,7 +117,7 @@ gst_util_set_value_from_string (GValue * value, const gchar * value_str)
* @name: the name of the argument to set
* @value: the string value to set
*
- * Convertes the string value to the type of the objects argument and
+ * Converts the string value to the type of the objects argument and
* sets the argument with it.
*
* Note that this function silently returns if @object has no property named
@@ -150,7 +150,7 @@ gst_util_set_object_arg (GObject * object, const gchar * name,
g_value_init (&v, value_type);
/* special case for element <-> xml (de)serialisation */
- if (GST_VALUE_HOLDS_STRUCTURE (&v) && strcmp (value, "NULL") == 0) {
+ if (value_type == GST_TYPE_STRUCTURE && strcmp (value, "NULL") == 0) {
g_value_set_boxed (&v, NULL);
goto done;
}
@@ -773,7 +773,7 @@ gst_element_create_all_pads (GstElement * element)
* Retrieves a pad template from @element that is compatible with @compattempl.
* Pads from compatible templates can be linked together.
*
- * Returns: (transfer none): a compatible #GstPadTemplate, or NULL if none
+ * Returns: (transfer none): a compatible #GstPadTemplate, or %NULL if none
* was found. No unreferencing is necessary.
*/
GstPadTemplate *
@@ -1505,10 +1505,10 @@ pad_link_maybe_ghosting (GstPad * src, GstPad * sink, GstPadLinkCheck flags)
* gst_element_link_pads_full:
* @src: a #GstElement containing the source pad.
* @srcpadname: (allow-none): the name of the #GstPad in source element
- * or NULL for any pad.
+ * or %NULL for any pad.
* @dest: (transfer none): the #GstElement containing the destination pad.
* @destpadname: (allow-none): the name of the #GstPad in destination element,
- * or NULL for any pad.
+ * or %NULL for any pad.
* @flags: the #GstPadLinkCheck to be performed when linking pads.
*
* Links the two named pads of the source and destination elements.
@@ -1522,7 +1522,7 @@ pad_link_maybe_ghosting (GstPad * src, GstPad * sink, GstPadLinkCheck flags)
*
* This is a convenience function for gst_pad_link_full().
*
- * Returns: TRUE if the pads could be linked, FALSE otherwise.
+ * Returns: %TRUE if the pads could be linked, %FALSE otherwise.
*/
gboolean
gst_element_link_pads_full (GstElement * src, const gchar * srcpadname,
@@ -1784,17 +1784,17 @@ gst_element_link_pads_full (GstElement * src, const gchar * srcpadname,
* gst_element_link_pads:
* @src: a #GstElement containing the source pad.
* @srcpadname: (allow-none): the name of the #GstPad in source element
- * or NULL for any pad.
+ * or %NULL for any pad.
* @dest: (transfer none): the #GstElement containing the destination pad.
* @destpadname: (allow-none): the name of the #GstPad in destination element,
- * or NULL for any pad.
+ * or %NULL for any pad.
*
* Links the two named pads of the source and destination elements.
* Side effect is that if one of the pads has no parent, it becomes a
* child of the parent of the other element. If they have different
* parents, the link fails.
*
- * Returns: TRUE if the pads could be linked, FALSE otherwise.
+ * Returns: %TRUE if the pads could be linked, %FALSE otherwise.
*/
gboolean
gst_element_link_pads (GstElement * src, const gchar * srcpadname,
@@ -1808,19 +1808,19 @@ gst_element_link_pads (GstElement * src, const gchar * srcpadname,
* gst_element_link_pads_filtered:
* @src: a #GstElement containing the source pad.
* @srcpadname: (allow-none): the name of the #GstPad in source element
- * or NULL for any pad.
+ * or %NULL for any pad.
* @dest: (transfer none): the #GstElement containing the destination pad.
* @destpadname: (allow-none): the name of the #GstPad in destination element
- * or NULL for any pad.
+ * or %NULL for any pad.
* @filter: (transfer none) (allow-none): the #GstCaps to filter the link,
- * or #NULL for no filter.
+ * or %NULL for no filter.
*
* Links the two named pads of the source and destination elements. Side effect
* is that if one of the pads has no parent, it becomes a child of the parent of
* the other element. If they have different parents, the link fails. If @caps
- * is not #NULL, makes sure that the caps of the link is a subset of @caps.
+ * is not %NULL, makes sure that the caps of the link is a subset of @caps.
*
- * Returns: TRUE if the pads could be linked, FALSE otherwise.
+ * Returns: %TRUE if the pads could be linked, %FALSE otherwise.
*/
gboolean
gst_element_link_pads_filtered (GstElement * src, const gchar * srcpadname,
@@ -1906,7 +1906,7 @@ gst_element_link_pads_filtered (GstElement * src, const gchar * srcpadname,
* Make sure you have added your elements to a bin or pipeline with
* gst_bin_add() before trying to link them.
*
- * Returns: TRUE if the elements could be linked, FALSE otherwise.
+ * Returns: %TRUE if the elements could be linked, %FALSE otherwise.
*/
gboolean
gst_element_link (GstElement * src, GstElement * dest)
@@ -1918,13 +1918,13 @@ gst_element_link (GstElement * src, GstElement * dest)
* gst_element_link_many:
* @element_1: (transfer none): the first #GstElement in the link chain.
* @element_2: (transfer none): the second #GstElement in the link chain.
- * @...: the NULL-terminated list of elements to link in order.
+ * @...: the %NULL-terminated list of elements to link in order.
*
* Chain together a series of elements. Uses gst_element_link().
* Make sure you have added your elements to a bin or pipeline with
* gst_bin_add() before trying to link them.
*
- * Returns: TRUE on success, FALSE otherwise.
+ * Returns: %TRUE on success, %FALSE otherwise.
*/
gboolean
gst_element_link_many (GstElement * element_1, GstElement * element_2, ...)
@@ -1957,7 +1957,7 @@ gst_element_link_many (GstElement * element_1, GstElement * element_2, ...)
* @src: a #GstElement containing the source pad.
* @dest: (transfer none): the #GstElement containing the destination pad.
* @filter: (transfer none) (allow-none): the #GstCaps to filter the link,
- * or #NULL for no filter.
+ * or %NULL for no filter.
*
* Links @src to @dest using the given caps as filtercaps.
* The link must be from source to
@@ -1968,7 +1968,7 @@ gst_element_link_many (GstElement * element_1, GstElement * element_2, ...)
* Make sure you have added your elements to a bin or pipeline with
* gst_bin_add() before trying to link them.
*
- * Returns: TRUE if the pads could be linked, FALSE otherwise.
+ * Returns: %TRUE if the pads could be linked, %FALSE otherwise.
*/
gboolean
gst_element_link_filtered (GstElement * src, GstElement * dest,
@@ -2038,7 +2038,7 @@ free_src:
* gst_element_unlink_many:
* @element_1: (transfer none): the first #GstElement in the link chain.
* @element_2: (transfer none): the second #GstElement in the link chain.
- * @...: the NULL-terminated list of elements to unlink in order.
+ * @...: the %NULL-terminated list of elements to unlink in order.
*
* Unlinks a series of elements. Uses gst_element_unlink().
*/
@@ -2134,7 +2134,7 @@ gst_element_unlink (GstElement * src, GstElement * dest)
* @element: a #GstElement to invoke the position query on.
* @format: the #GstFormat requested
* @cur: (out) (allow-none): a location in which to store the current
- * position, or NULL.
+ * position, or %NULL.
*
* Queries an element (usually top-level pipeline or playbin element) for the
* stream position in nanoseconds. This will be a value between 0 and the
@@ -2146,7 +2146,7 @@ gst_element_unlink (GstElement * src, GstElement * dest)
* If one repeatedly calls this function one can also create a query and reuse
* it in gst_element_query().
*
- * Returns: TRUE if the query could be performed.
+ * Returns: %TRUE if the query could be performed.
*/
gboolean
gst_element_query_position (GstElement * element, GstFormat format,
@@ -2173,7 +2173,7 @@ gst_element_query_position (GstElement * element, GstFormat format,
* gst_element_query_duration:
* @element: a #GstElement to invoke the duration query on.
* @format: the #GstFormat requested
- * @duration: (out) (allow-none): A location in which to store the total duration, or NULL.
+ * @duration: (out) (allow-none): A location in which to store the total duration, or %NULL.
*
* Queries an element (usually top-level pipeline or playbin element) for the
* total stream duration in nanoseconds. This query will only work once the
@@ -2184,7 +2184,7 @@ gst_element_query_position (GstElement * element, GstFormat format,
* message on the pipeline bus, in which case you should re-query the duration
* using this function.
*
- * Returns: TRUE if the query could be performed.
+ * Returns: %TRUE if the query could be performed.
*/
gboolean
gst_element_query_duration (GstElement * element, GstFormat format,
@@ -2217,7 +2217,7 @@ gst_element_query_duration (GstElement * element, GstFormat format,
*
* Queries an element to convert @src_val in @src_format to @dest_format.
*
- * Returns: TRUE if the query could be performed.
+ * Returns: %TRUE if the query could be performed.
*/
gboolean
gst_element_query_convert (GstElement * element, GstFormat src_format,
@@ -2309,7 +2309,7 @@ gst_pad_use_fixed_caps (GstPad * pad)
* @pad: a pad
*
* Gets the parent of @pad, cast to a #GstElement. If a @pad has no parent or
- * its parent is not an element, return NULL.
+ * its parent is not an element, return %NULL.
*
* Returns: (transfer full): the parent of the pad. The caller has a
* reference on the parent, so unref when you're finished with it.
@@ -2336,7 +2336,7 @@ gst_pad_get_parent_element (GstPad * pad)
* gst_object_default_error:
* @source: the #GstObject that initiated the error.
* @error: (in): the GError.
- * @debug: (in) (allow-none): an additional debug information string, or NULL
+ * @debug: (in) (allow-none): an additional debug information string, or %NULL
*
* A default error function that uses g_printerr() to display the error message
* and the optional debug sting..
@@ -2362,7 +2362,7 @@ gst_object_default_error (GstObject * source, const GError * error,
* @element_1: (transfer full): the #GstElement element to add to the bin
* @...: (transfer full): additional elements to add to the bin
*
- * Adds a NULL-terminated list of elements to a bin. This function is
+ * Adds a %NULL-terminated list of elements to a bin. This function is
* equivalent to calling gst_bin_add() for each member of the list. The return
* value of each gst_bin_add() is ignored.
*/
@@ -2389,7 +2389,7 @@ gst_bin_add_many (GstBin * bin, GstElement * element_1, ...)
* gst_bin_remove_many:
* @bin: a #GstBin
* @element_1: (transfer none): the first #GstElement to remove from the bin
- * @...: (transfer none): NULL-terminated list of elements to remove from the bin
+ * @...: (transfer none): %NULL-terminated list of elements to remove from the bin
*
* Remove a list of elements from a bin. This function is equivalent
* to calling gst_bin_remove() with each member of the list.
@@ -2436,14 +2436,14 @@ query_accept_caps_func (GstPad * pad, QueryAcceptCapsData * data)
* @pad: a #GstPad to proxy.
* @query: an ACCEPT_CAPS #GstQuery.
*
- * Calls gst_pad_accept_caps() for all internally linked pads of @pad and
+ * Checks if all internally linked pads of @pad accepts the caps in @query and
* returns the intersection of the results.
*
* This function is useful as a default accept caps query function for an element
* that can handle any stream format, but requires caps that are acceptable for
- * all oposite pads.
+ * all opposite pads.
*
- * Returns: TRUE if @query could be executed
+ * Returns: %TRUE if @query could be executed
*/
gboolean
gst_pad_proxy_query_accept_caps (GstPad * pad, GstQuery * query)
@@ -2459,12 +2459,16 @@ gst_pad_proxy_query_accept_caps (GstPad * pad, GstQuery * query)
data.query = query;
/* value to hold the return, by default it holds TRUE */
+ /* FIXME: TRUE is wrong when there are no pads */
data.ret = TRUE;
gst_pad_forward (pad, (GstPadForwardFunction) query_accept_caps_func, &data);
gst_query_set_accept_caps_result (query, data.ret);
- return TRUE;
+ GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "proxying accept caps query: %d",
+ data.ret);
+
+ return data.ret;
}
typedef struct
@@ -2500,14 +2504,14 @@ query_caps_func (GstPad * pad, QueryCapsData * data)
* @pad: a #GstPad to proxy.
* @query: a CAPS #GstQuery.
*
- * Calls gst_pad_query_caps() for all internally linked pads fof @pad and returns
+ * Calls gst_pad_query_caps() for all internally linked pads of @pad and returns
* the intersection of the results.
*
* This function is useful as a default caps query function for an element
* that can handle any stream format, but requires all its pads to have
* the same caps. Two such elements are tee and adder.
*
- * Returns: TRUE if @query could be executed
+ * Returns: %TRUE if @query could be executed
*/
gboolean
gst_pad_proxy_query_caps (GstPad * pad, GstQuery * query)
@@ -2538,6 +2542,7 @@ gst_pad_proxy_query_caps (GstPad * pad, GstQuery * query)
gst_query_set_caps_result (query, result);
gst_caps_unref (result);
+ /* FIXME: return something depending on the processing */
return TRUE;
}
@@ -2545,11 +2550,11 @@ gst_pad_proxy_query_caps (GstPad * pad, GstQuery * query)
* gst_pad_query_position:
* @pad: a #GstPad to invoke the position query on.
* @format: the #GstFormat requested
- * @cur: (out) (allow-none): A location in which to store the current position, or NULL.
+ * @cur: (out) (allow-none): A location in which to store the current position, or %NULL.
*
* Queries a pad for the stream position.
*
- * Returns: TRUE if the query could be performed.
+ * Returns: %TRUE if the query could be performed.
*/
gboolean
gst_pad_query_position (GstPad * pad, GstFormat format, gint64 * cur)
@@ -2574,11 +2579,11 @@ gst_pad_query_position (GstPad * pad, GstFormat format, gint64 * cur)
* Must be a sink pad.
* @format: the #GstFormat requested
* @cur: (out) (allow-none): a location in which to store the current
- * position, or NULL.
+ * position, or %NULL.
*
* Queries the peer of a given sink pad for the stream position.
*
- * Returns: TRUE if the query could be performed.
+ * Returns: %TRUE if the query could be performed.
*/
gboolean
gst_pad_peer_query_position (GstPad * pad, GstFormat format, gint64 * cur)
@@ -2602,11 +2607,11 @@ gst_pad_peer_query_position (GstPad * pad, GstFormat format, gint64 * cur)
* @pad: a #GstPad to invoke the duration query on.
* @format: the #GstFormat requested
* @duration: (out) (allow-none): a location in which to store the total
- * duration, or NULL.
+ * duration, or %NULL.
*
* Queries a pad for the total stream duration.
*
- * Returns: TRUE if the query could be performed.
+ * Returns: %TRUE if the query could be performed.
*/
gboolean
gst_pad_query_duration (GstPad * pad, GstFormat format, gint64 * duration)
@@ -2631,11 +2636,11 @@ gst_pad_query_duration (GstPad * pad, GstFormat format, gint64 * duration)
* Must be a sink pad.
* @format: the #GstFormat requested
* @duration: (out) (allow-none): a location in which to store the total
- * duration, or NULL.
+ * duration, or %NULL.
*
* Queries the peer pad of a given sink pad for the total stream duration.
*
- * Returns: TRUE if the query could be performed.
+ * Returns: %TRUE if the query could be performed.
*/
gboolean
gst_pad_peer_query_duration (GstPad * pad, GstFormat format, gint64 * duration)
@@ -2665,7 +2670,7 @@ gst_pad_peer_query_duration (GstPad * pad, GstFormat format, gint64 * duration)
*
* Queries a pad to convert @src_val in @src_format to @dest_format.
*
- * Returns: TRUE if the query could be performed.
+ * Returns: %TRUE if the query could be performed.
*/
gboolean
gst_pad_query_convert (GstPad * pad, GstFormat src_format, gint64 src_val,
@@ -2703,7 +2708,7 @@ gst_pad_query_convert (GstPad * pad, GstFormat src_format, gint64 src_val,
* Queries the peer pad of a given sink pad to convert @src_val in @src_format
* to @dest_format.
*
- * Returns: TRUE if the query could be performed.
+ * Returns: %TRUE if the query could be performed.
*/
gboolean
gst_pad_peer_query_convert (GstPad * pad, GstFormat src_format, gint64 src_val,
@@ -2728,19 +2733,19 @@ gst_pad_peer_query_convert (GstPad * pad, GstFormat src_format, gint64 src_val,
/**
* gst_pad_query_caps:
* @pad: a #GstPad to get the capabilities of.
- * @filter: (allow-none): suggested #GstCaps, or NULL
+ * @filter: (allow-none): suggested #GstCaps, or %NULL
*
* Gets the capabilities this pad can produce or consume.
* Note that this method doesn't necessarily return the caps set by sending a
* gst_event_new_caps() - use gst_pad_get_current_caps() for that instead.
* gst_pad_query_caps returns all possible caps a pad can operate with, using
* the pad's CAPS query function, If the query fails, this function will return
- * @filter, if not #NULL, otherwise ANY.
+ * @filter, if not %NULL, otherwise ANY.
*
* When called on sinkpads @filter contains the caps that
* upstream could produce in the order preferred by upstream. When
* called on srcpads @filter contains the caps accepted by
- * downstream in the preffered order. @filter might be %NULL but
+ * downstream in the preferred order. @filter might be %NULL but
* if it is not %NULL the returned caps will be a subset of @filter.
*
* Note that this function does not return writable #GstCaps, use
@@ -2779,7 +2784,7 @@ gst_pad_query_caps (GstPad * pad, GstCaps * filter)
/**
* gst_pad_peer_query_caps:
* @pad: a #GstPad to get the capabilities of.
- * @filter: (allow-none): a #GstCaps filter, or NULL.
+ * @filter: (allow-none): a #GstCaps filter, or %NULL.
*
* Gets the capabilities of the peer connected to this pad. Similar to
* gst_pad_query_caps().
@@ -2787,7 +2792,7 @@ gst_pad_query_caps (GstPad * pad, GstCaps * filter)
* When called on srcpads @filter contains the caps that
* upstream could produce in the order preferred by upstream. When
* called on sinkpads @filter contains the caps accepted by
- * downstream in the preffered order. @filter might be %NULL but
+ * downstream in the preferred order. @filter might be %NULL but
* if it is not %NULL the returned caps will be a subset of @filter.
*
* Returns: the caps of the peer pad with incremented ref-count. When there is
@@ -2829,7 +2834,7 @@ gst_pad_peer_query_caps (GstPad * pad, GstCaps * filter)
*
* Check if the given pad accepts the caps.
*
- * Returns: TRUE if the pad can accept the caps.
+ * Returns: %TRUE if the pad can accept the caps.
*/
gboolean
gst_pad_query_accept_caps (GstPad * pad, GstCaps * caps)
@@ -2859,9 +2864,9 @@ gst_pad_query_accept_caps (GstPad * pad, GstCaps * caps)
* @caps: a #GstCaps to check on the pad
*
* Check if the peer of @pad accepts @caps. If @pad has no peer, this function
- * returns TRUE.
+ * returns %TRUE.
*
- * Returns: TRUE if the peer of @pad can accept the caps or @pad has no peer.
+ * Returns: %TRUE if the peer of @pad can accept the caps or @pad has no peer.
*/
gboolean
gst_pad_peer_query_accept_caps (GstPad * pad, GstCaps * caps)
@@ -2948,11 +2953,11 @@ element_find_unlinked_pad (GstElement * element, GstPadDirection direction)
*
* Recursively looks for elements with an unlinked pad of the given
* direction within the specified bin and returns an unlinked pad
- * if one is found, or NULL otherwise. If a pad is found, the caller
+ * if one is found, or %NULL otherwise. If a pad is found, the caller
* owns a reference to it and should use gst_object_unref() on the
* pad when it is not needed any longer.
*
- * Returns: (transfer full): unlinked pad of the given direction, or NULL.
+ * Returns: (transfer full): unlinked pad of the given direction, %NULL.
*/
GstPad *
gst_bin_find_unlinked_pad (GstBin * bin, GstPadDirection direction)
@@ -3000,7 +3005,7 @@ gst_bin_find_unlinked_pad (GstBin * bin, GstPadDirection direction)
* @bin_description: command line describing the bin
* @ghost_unlinked_pads: whether to automatically create ghost pads
* for unlinked source or sink pads within the bin
- * @err: where to store the error message in case of an error, or NULL
+ * @err: where to store the error message in case of an error, or %NULL
*
* This is a convenience wrapper around gst_parse_launch() to create a
* #GstBin from a gst-launch-style pipeline description. See
@@ -3031,7 +3036,7 @@ gst_parse_bin_from_description (const gchar * bin_description,
* @context: (transfer none) (allow-none): a parse context allocated with
* gst_parse_context_new(), or %NULL
* @flags: parsing options, or #GST_PARSE_FLAG_NONE
- * @err: where to store the error message in case of an error, or NULL
+ * @err: where to store the error message in case of an error, or %NULL
*
* This is a convenience wrapper around gst_parse_launch() to create a
* #GstBin from a gst-launch-style pipeline description. See
@@ -3043,9 +3048,10 @@ gst_parse_bin_from_description (const gchar * bin_description,
* and want them all ghosted, you will have to create the ghost pads
* yourself).
*
- * Returns: (transfer full) (type Gst.Element): a newly-created element, which
- * is guaranteed to be a bin unless GST_FLAG_NO_SINGLE_ELEMENT_BINS was
- * passed, or %NULL if an error occurred.
+ * Returns: (transfer floating) (type Gst.Element): a newly-created
+ * element, which is guaranteed to be a bin unless
+ * GST_FLAG_NO_SINGLE_ELEMENT_BINS was passed, or %NULL if an error
+ * occurred.
*/
GstElement *
gst_parse_bin_from_description_full (const gchar * bin_description,
@@ -3417,6 +3423,13 @@ gst_util_fraction_multiply (gint a_n, gint a_d, gint b_n, gint b_d,
g_return_val_if_fail (a_d != 0, FALSE);
g_return_val_if_fail (b_d != 0, FALSE);
+ /* early out if either is 0, as its gcd would be 0 */
+ if (a_n == 0 || b_n == 0) {
+ *res_n = 0;
+ *res_d = 1;
+ return TRUE;
+ }
+
gcd = gst_util_greatest_common_divisor (a_n, a_d);
a_n /= gcd;
a_d /= gcd;
@@ -3562,32 +3575,9 @@ gst_util_fraction_compare (gint a_n, gint a_d, gint b_n, gint b_d)
g_return_val_if_reached (0);
}
-/**
- * gst_pad_create_stream_id_printf_valist:
- * @pad: A source #GstPad
- * @parent: Parent #GstElement of @pad
- * @stream_id: (allow-none): The stream-id
- * @var_args: parameters for the @stream_id format string
- *
- * Creates a stream-id for the source #GstPad @pad by combining the
- * upstream information with the optional @stream_id of the stream
- * of @pad. @pad must have a parent #GstElement and which must have zero
- * or one sinkpad. @stream_id can only be %NULL if the parent element
- * of @pad has only a single source pad.
- *
- * This function generates an unique stream-id by getting the upstream
- * stream-start event stream ID and appending @stream_id to it. If the
- * element has no sinkpad it will generate an upstream stream-id by
- * doing an URI query on the element and in the worst case just uses
- * a random number. Source elements that don't implement the URI
- * handler interface should ideally generate a unique, deterministic
- * stream-id manually instead.
- *
- * Returns: A stream-id for @pad. g_free() after usage.
- */
-gchar *
-gst_pad_create_stream_id_printf_valist (GstPad * pad, GstElement * parent,
- const gchar * stream_id, va_list var_args)
+static gchar *
+gst_pad_create_stream_id_internal (GstPad * pad, GstElement * parent,
+ const gchar * stream_id)
{
GstEvent *upstream_event;
gchar *upstream_stream_id = NULL, *new_stream_id;
@@ -3655,9 +3645,7 @@ gst_pad_create_stream_id_printf_valist (GstPad * pad, GstElement * parent,
}
if (stream_id) {
- gchar *expanded = g_strdup_vprintf (stream_id, var_args);
- new_stream_id = g_strconcat (upstream_stream_id, "/", expanded, NULL);
- g_free (expanded);
+ new_stream_id = g_strconcat (upstream_stream_id, "/", stream_id, NULL);
} else {
new_stream_id = g_strdup (upstream_stream_id);
}
@@ -3668,6 +3656,45 @@ gst_pad_create_stream_id_printf_valist (GstPad * pad, GstElement * parent,
}
/**
+ * gst_pad_create_stream_id_printf_valist:
+ * @pad: A source #GstPad
+ * @parent: Parent #GstElement of @pad
+ * @stream_id: (allow-none): The stream-id
+ * @var_args: parameters for the @stream_id format string
+ *
+ * Creates a stream-id for the source #GstPad @pad by combining the
+ * upstream information with the optional @stream_id of the stream
+ * of @pad. @pad must have a parent #GstElement and which must have zero
+ * or one sinkpad. @stream_id can only be %NULL if the parent element
+ * of @pad has only a single source pad.
+ *
+ * This function generates an unique stream-id by getting the upstream
+ * stream-start event stream ID and appending @stream_id to it. If the
+ * element has no sinkpad it will generate an upstream stream-id by
+ * doing an URI query on the element and in the worst case just uses
+ * a random number. Source elements that don't implement the URI
+ * handler interface should ideally generate a unique, deterministic
+ * stream-id manually instead.
+ *
+ * Returns: A stream-id for @pad. g_free() after usage.
+ */
+gchar *
+gst_pad_create_stream_id_printf_valist (GstPad * pad, GstElement * parent,
+ const gchar * stream_id, va_list var_args)
+{
+ gchar *expanded = NULL, *new_stream_id;
+
+ if (stream_id)
+ expanded = g_strdup_vprintf (stream_id, var_args);
+
+ new_stream_id = gst_pad_create_stream_id_internal (pad, parent, expanded);
+
+ g_free (expanded);
+
+ return new_stream_id;
+}
+
+/**
* gst_pad_create_stream_id_printf:
* @pad: A source #GstPad
* @parent: Parent #GstElement of @pad
@@ -3735,7 +3762,7 @@ gchar *
gst_pad_create_stream_id (GstPad * pad, GstElement * parent,
const gchar * stream_id)
{
- return gst_pad_create_stream_id_printf (pad, parent, stream_id, NULL);
+ return gst_pad_create_stream_id_internal (pad, parent, stream_id);
}
/**
@@ -3751,7 +3778,7 @@ gst_pad_create_stream_id (GstPad * pad, GstElement * parent,
* The returned stream-id string should be treated as an opaque string, its
* contents should not be interpreted.
*
- * Returns: a newly-allocated copy of the stream-idfor @pad, or %NULL.
+ * Returns: a newly-allocated copy of the stream-id for @pad, or %NULL.
* g_free() the returned string when no longer needed.
*
* Since: 1.2
diff --git a/gst/gstutils.h b/gst/gstutils.h
index 1530807..a935883 100644
--- a/gst/gstutils.h
+++ b/gst/gstutils.h
@@ -113,6 +113,7 @@ guint gst_util_group_id_next (void);
#define _GST_PUT(__data, __idx, __size, __shift, __num) \
(((guint8 *) (__data))[__idx] = (((guint##__size) (__num)) >> (__shift)) & 0xff)
+#ifndef __GTK_DOC_IGNORE__
#if GST_HAVE_UNALIGNED_ACCESS
static inline guint16 __gst_fast_read16(const guint8 *v) {
return *(const guint16*)(v);
@@ -135,6 +136,7 @@ static inline guint64 __gst_fast_read_swap64(const guint8 *v) {
# define _GST_FAST_READ(s, d) __gst_fast_read##s((const guint8 *)(d))
# define _GST_FAST_READ_SWAP(s, d) __gst_fast_read_swap##s((const guint8 *)(d))
#endif
+#endif
/**
@@ -814,6 +816,24 @@ GST_WRITE_DOUBLE_BE(guint8 *data, gdouble num)
* Rounds an integer value up to the next multiple of 64.
*/
#define GST_ROUND_UP_64(num) (((num)+63)&~63)
+/**
+ * GST_ROUND_UP_128:
+ * @num: integer value to round up
+ *
+ * Rounds an integer value up to the next multiple of 128.
+ * Since: 1.4
+ */
+#define GST_ROUND_UP_128(num) (((num)+127)&~127)
+/**
+ * GST_ROUND_UP_N:
+ * @num: integrer value to round up
+ * @align: a power of two to round up to
+ *
+ * Rounds an integer value up to the next multiple of @align. @align MUST be a
+ * power of two.
+ */
+#define GST_ROUND_UP_N(num,align) ((((num) + ((align) - 1)) & ~((align) - 1)))
+
/**
* GST_ROUND_DOWN_2:
@@ -857,6 +877,24 @@ GST_WRITE_DOUBLE_BE(guint8 *data, gdouble num)
* Rounds an integer value down to the next multiple of 64.
*/
#define GST_ROUND_DOWN_64(num) ((num)&(~63))
+/**
+ * GST_ROUND_DOWN_128:
+ * @num: integer value to round down
+ *
+ * Rounds an integer value down to the next multiple of 128.
+ * Since: 1.4
+ */
+#define GST_ROUND_DOWN_128(num) ((num)&(~127))
+/**
+ * GST_ROUND_DOWN_N:
+ * @num: integrer value to round down
+ * @align: a power of two to round down to
+ *
+ * Rounds an integer value down to the next multiple of @align. @align MUST be a
+ * power of two.
+ */
+#define GST_ROUND_DOWN_N(num,align) (((num) & ~((align) - 1)))
+
void gst_object_default_error (GstObject * source,
const GError * error,
@@ -934,9 +972,9 @@ gboolean gst_pad_peer_query_convert (GstPad *pad, GstFormat
GstCaps * gst_pad_peer_query_caps (GstPad * pad, GstCaps *filter);
gboolean gst_pad_peer_query_accept_caps (GstPad * pad, GstCaps *caps);
-gchar * gst_pad_create_stream_id (GstPad * pad, GstElement * parent, const gchar *stream_id);
-gchar * gst_pad_create_stream_id_printf (GstPad * pad, GstElement * parent, const gchar *stream_id, ...);
-gchar * gst_pad_create_stream_id_printf_valist (GstPad * pad, GstElement * parent, const gchar *stream_id, va_list var_args);
+gchar * gst_pad_create_stream_id (GstPad * pad, GstElement * parent, const gchar *stream_id) G_GNUC_MALLOC;
+gchar * gst_pad_create_stream_id_printf (GstPad * pad, GstElement * parent, const gchar *stream_id, ...) G_GNUC_PRINTF (3, 4) G_GNUC_MALLOC;
+gchar * gst_pad_create_stream_id_printf_valist (GstPad * pad, GstElement * parent, const gchar *stream_id, va_list var_args) G_GNUC_PRINTF (3, 0) G_GNUC_MALLOC;
gchar * gst_pad_get_stream_id (GstPad * pad);
diff --git a/gst/gstvalue.c b/gst/gstvalue.c
index c2885cd..f088cca 100644
--- a/gst/gstvalue.c
+++ b/gst/gstvalue.c
@@ -26,8 +26,6 @@
*
* Note that operations on the same #GValue from multiple threads may lead to
* undefined behaviour.
- *
- * Last reviewed on 2008-03-11 (0.10.18)
*/
#ifdef HAVE_CONFIG_H
@@ -65,8 +63,8 @@ typedef gboolean (*GstValueUnionFunc) (GValue * dest,
*
* Used by gst_value_intersect() to perform intersection for a specific #GValue
* type. If the intersection is non-empty, the result is
- * placed in @dest and TRUE is returned. If the intersection is
- * empty, @dest is unmodified and FALSE is returned.
+ * placed in @dest and %TRUE is returned. If the intersection is
+ * empty, @dest is unmodified and %FALSE is returned.
* Register a new implementation with gst_value_register_intersect_func().
*
* Returns: %TRUE if the values can intersect
@@ -123,8 +121,9 @@ struct _GstValueSubtractInfo
#define FUNDAMENTAL_TYPE_ID(type) \
((type) >> G_TYPE_FUNDAMENTAL_SHIFT)
-#define VALUE_LIST_SIZE(v) (((GArray *) (v)->data[0].v_pointer)->len)
-#define VALUE_LIST_GET_VALUE(v, index) ((const GValue *) &g_array_index ((GArray *) (v)->data[0].v_pointer, GValue, (index)))
+#define VALUE_LIST_ARRAY(v) ((GArray *) (v)->data[0].v_pointer)
+#define VALUE_LIST_SIZE(v) (VALUE_LIST_ARRAY(v)->len)
+#define VALUE_LIST_GET_VALUE(v, index) ((const GValue *) &g_array_index (VALUE_LIST_ARRAY(v), GValue, (index)))
static GArray *gst_value_table;
static GHashTable *gst_value_hash;
@@ -533,6 +532,56 @@ gst_value_list_concat (GValue * dest, const GValue * value1,
}
}
+/* same as gst_value_list_concat() but takes ownership of GValues */
+static void
+gst_value_list_concat_and_take_values (GValue * dest, GValue * val1,
+ GValue * val2)
+{
+ guint i, val1_length, val2_length;
+ gboolean val1_is_list;
+ gboolean val2_is_list;
+ GArray *array;
+
+ g_assert (dest != NULL);
+ g_assert (G_VALUE_TYPE (dest) == 0);
+ g_assert (G_IS_VALUE (val1));
+ g_assert (G_IS_VALUE (val2));
+ g_assert (gst_value_list_or_array_are_compatible (val1, val2));
+
+ val1_is_list = GST_VALUE_HOLDS_LIST (val1);
+ val1_length = (val1_is_list ? VALUE_LIST_SIZE (val1) : 1);
+
+ val2_is_list = GST_VALUE_HOLDS_LIST (val2);
+ val2_length = (val2_is_list ? VALUE_LIST_SIZE (val2) : 1);
+
+ g_value_init (dest, GST_TYPE_LIST);
+ array = (GArray *) dest->data[0].v_pointer;
+ g_array_set_size (array, val1_length + val2_length);
+
+ if (val1_is_list) {
+ for (i = 0; i < val1_length; i++) {
+ g_array_index (array, GValue, i) = *VALUE_LIST_GET_VALUE (val1, i);
+ }
+ g_array_set_size (VALUE_LIST_ARRAY (val1), 0);
+ g_value_unset (val1);
+ } else {
+ g_array_index (array, GValue, 0) = *val1;
+ G_VALUE_TYPE (val1) = G_TYPE_INVALID;
+ }
+
+ if (val2_is_list) {
+ for (i = 0; i < val2_length; i++) {
+ const GValue *v2 = VALUE_LIST_GET_VALUE (val2, i);
+ g_array_index (array, GValue, i + val1_length) = *v2;
+ }
+ g_array_set_size (VALUE_LIST_ARRAY (val2), 0);
+ g_value_unset (val2);
+ } else {
+ g_array_index (array, GValue, val1_length) = *val2;
+ G_VALUE_TYPE (val2) = G_TYPE_INVALID;
+ }
+}
+
/**
* gst_value_list_merge:
* @dest: (out caller-allocates): an uninitialized #GValue to take the result
@@ -899,52 +948,36 @@ gst_value_deserialize_array (GValue * dest, const gchar * s)
* Values in the range are defined as any value greater or equal
* to min*step, AND lesser or equal to max*step.
* For step == 1, this falls back to the traditional range semantics.
+ *
+ * data[0] = (min << 32) | (max)
+ * data[1] = step
+ *
*************/
-#define INT_RANGE_MIN(v) (((gint *)((v)->data[0].v_pointer))[0])
-#define INT_RANGE_MAX(v) (((gint *)((v)->data[0].v_pointer))[1])
-#define INT_RANGE_STEP(v) (((gint *)((v)->data[0].v_pointer))[2])
+#define INT_RANGE_MIN(v) ((gint) (((v)->data[0].v_uint64) >> 32))
+#define INT_RANGE_MAX(v) ((gint) (((v)->data[0].v_uint64) & 0xffffffff))
+#define INT_RANGE_STEP(v) ((v)->data[1].v_int)
static void
gst_value_init_int_range (GValue * value)
{
- gint *vals = g_slice_alloc0 (3 * sizeof (gint));
- value->data[0].v_pointer = vals;
- INT_RANGE_MIN (value) = 0;
- INT_RANGE_MAX (value) = 0;
- INT_RANGE_STEP (value) = 1;
-}
+ G_STATIC_ASSERT (sizeof (gint) <= 2 * sizeof (guint64));
-static void
-gst_value_free_int_range (GValue * value)
-{
- g_return_if_fail (GST_VALUE_HOLDS_INT_RANGE (value));
- g_slice_free1 (3 * sizeof (gint), value->data[0].v_pointer);
- value->data[0].v_pointer = NULL;
+ value->data[0].v_uint64 = 0;
+ value->data[1].v_int = 1;
}
static void
gst_value_copy_int_range (const GValue * src_value, GValue * dest_value)
{
- gint *vals = (gint *) dest_value->data[0].v_pointer;
- gint *src_vals = (gint *) src_value->data[0].v_pointer;
-
- if (vals == NULL) {
- gst_value_init_int_range (dest_value);
- }
- if (src_vals != NULL) {
- INT_RANGE_MIN (dest_value) = INT_RANGE_MIN (src_value);
- INT_RANGE_MAX (dest_value) = INT_RANGE_MAX (src_value);
- INT_RANGE_STEP (dest_value) = INT_RANGE_STEP (src_value);
- }
+ dest_value->data[0].v_uint64 = src_value->data[0].v_uint64;
+ dest_value->data[1].v_int = src_value->data[1].v_int;
}
static gchar *
gst_value_collect_int_range (GValue * value, guint n_collect_values,
GTypeCValue * collect_values, guint collect_flags)
{
- gint *vals = value->data[0].v_pointer;
-
if (n_collect_values != 2)
return g_strdup_printf ("not enough value locations for `%s' passed",
G_VALUE_TYPE_NAME (value));
@@ -952,10 +985,6 @@ gst_value_collect_int_range (GValue * value, guint n_collect_values,
return g_strdup_printf ("range start is not smaller than end for `%s'",
G_VALUE_TYPE_NAME (value));
- if (vals == NULL) {
- gst_value_init_int_range (value);
- }
-
gst_value_set_int_range_step (value, collect_values[0].v_int,
collect_values[1].v_int, 1);
@@ -968,8 +997,6 @@ gst_value_lcopy_int_range (const GValue * value, guint n_collect_values,
{
guint32 *int_range_start = collect_values[0].v_pointer;
guint32 *int_range_end = collect_values[1].v_pointer;
- guint32 *int_range_step = collect_values[2].v_pointer;
- gint *vals = (gint *) value->data[0].v_pointer;
if (!int_range_start)
return g_strdup_printf ("start value location for `%s' passed as NULL",
@@ -977,18 +1004,9 @@ gst_value_lcopy_int_range (const GValue * value, guint n_collect_values,
if (!int_range_end)
return g_strdup_printf ("end value location for `%s' passed as NULL",
G_VALUE_TYPE_NAME (value));
- if (!int_range_step)
- return g_strdup_printf ("step value location for `%s' passed as NULL",
- G_VALUE_TYPE_NAME (value));
-
- if (G_UNLIKELY (vals == NULL)) {
- return g_strdup_printf ("Uninitialised `%s' passed",
- G_VALUE_TYPE_NAME (value));
- }
*int_range_start = INT_RANGE_MIN (value);
*int_range_end = INT_RANGE_MAX (value);
- *int_range_step = INT_RANGE_STEP (value);
return NULL;
}
@@ -1005,15 +1023,18 @@ gst_value_lcopy_int_range (const GValue * value, guint n_collect_values,
void
gst_value_set_int_range_step (GValue * value, gint start, gint end, gint step)
{
+ guint64 sstart, sstop;
+
g_return_if_fail (GST_VALUE_HOLDS_INT_RANGE (value));
g_return_if_fail (start < end);
g_return_if_fail (step > 0);
g_return_if_fail (start % step == 0);
g_return_if_fail (end % step == 0);
- INT_RANGE_MIN (value) = start / step;
- INT_RANGE_MAX (value) = end / step;
- INT_RANGE_STEP (value) = step;
+ sstart = (guint) (start / step);
+ sstop = (guint) (end / step);
+ value->data[0].v_uint64 = (sstart << 32) | sstop;
+ value->data[1].v_int = step;
}
/**
@@ -1052,7 +1073,7 @@ gst_value_get_int_range_min (const GValue * value)
*
* Gets the maximum of the range specified by @value.
*
- * Returns: the maxumum of the range
+ * Returns: the maximum of the range
*/
gint
gst_value_get_int_range_max (const GValue * value)
@@ -1111,8 +1132,8 @@ gst_value_compare_int_range (const GValue * value1, const GValue * value2)
and bounds lie on the same value */
if (n1 > 1) {
if (INT_RANGE_STEP (value1) == INT_RANGE_STEP (value2) &&
- INT_RANGE_STEP (value1) == INT_RANGE_STEP (value2) &&
- INT_RANGE_STEP (value1) == INT_RANGE_STEP (value2)) {
+ INT_RANGE_MIN (value1) == INT_RANGE_MIN (value2) &&
+ INT_RANGE_MAX (value1) == INT_RANGE_MAX (value2)) {
return GST_VALUE_EQUAL;
}
return GST_VALUE_UNORDERED;
@@ -1304,7 +1325,7 @@ gst_value_get_int64_range_min (const GValue * value)
*
* Gets the maximum of the range specified by @value.
*
- * Returns: the maxumum of the range
+ * Returns: the maximum of the range
*/
gint64
gst_value_get_int64_range_max (const GValue * value)
@@ -1366,8 +1387,8 @@ gst_value_compare_int64_range (const GValue * value1, const GValue * value2)
and bounds lie on the same value */
if (n1 > 1) {
if (INT64_RANGE_STEP (value1) == INT64_RANGE_STEP (value2) &&
- INT64_RANGE_STEP (value1) == INT64_RANGE_STEP (value2) &&
- INT64_RANGE_STEP (value1) == INT64_RANGE_STEP (value2)) {
+ INT64_RANGE_MIN (value1) == INT64_RANGE_MIN (value2) &&
+ INT64_RANGE_MAX (value1) == INT64_RANGE_MAX (value2)) {
return GST_VALUE_EQUAL;
}
return GST_VALUE_UNORDERED;
@@ -1495,7 +1516,7 @@ gst_value_get_double_range_min (const GValue * value)
*
* Gets the maximum of the range specified by @value.
*
- * Returns: the maxumum of the range
+ * Returns: the maximum of the range
*/
gdouble
gst_value_get_double_range_max (const GValue * value)
@@ -1522,7 +1543,7 @@ static gint
gst_value_compare_double_range (const GValue * value1, const GValue * value2)
{
if (value2->data[0].v_double == value1->data[0].v_double &&
- value2->data[0].v_double == value1->data[0].v_double)
+ value2->data[1].v_double == value1->data[1].v_double)
return GST_VALUE_EQUAL;
return GST_VALUE_UNORDERED;
}
@@ -1724,6 +1745,15 @@ gst_value_set_fraction_range_full (GValue * value,
/* g_value_unset (&end); */
}
+/* FIXME 2.0: Don't leak the internal representation of fraction
+ * ranges but instead return the numerator and denominator
+ * separately.
+ * This would allow to store fraction ranges as
+ * data[0] = (min_n << 32) | (min_d)
+ * data[1] = (max_n << 32) | (max_d)
+ * without requiring an additional allocation for each value.
+ */
+
/**
* gst_value_get_fraction_range_min:
* @value: a GValue initialized to GST_TYPE_FRACTION_RANGE
@@ -1887,8 +1917,7 @@ static gchar *
gst_value_serialize_caps (const GValue * value)
{
GstCaps *caps = g_value_get_boxed (value);
-
- return gst_caps_to_string (caps);
+ return gst_string_take_and_wrap (gst_caps_to_string (caps));
}
static gboolean
@@ -1896,7 +1925,17 @@ gst_value_deserialize_caps (GValue * dest, const gchar * s)
{
GstCaps *caps;
- caps = gst_caps_from_string (s);
+ if (*s != '"') {
+ caps = gst_caps_from_string (s);
+ } else {
+ gchar *str = gst_string_unwrap (s);
+
+ if (G_UNLIKELY (!str))
+ return FALSE;
+
+ caps = gst_caps_from_string (str);
+ g_free (str);
+ }
if (caps) {
g_value_take_boxed (dest, caps);
@@ -2523,7 +2562,7 @@ gst_value_deserialize_int_helper (gint64 * to, const gchar * s,
{
gboolean ret = FALSE;
gchar *end;
- gint64 mask = -1;
+ guint64 mask = ~0;
errno = 0;
*to = g_ascii_strtoull (s, &end, 0);
@@ -2886,7 +2925,7 @@ gst_string_take_and_wrap (gchar * s)
* 0->3, y is copied unescaped.
*
* If \xyy is found where x is an octal number but y is not, an
- * error is encountered and NULL is returned.
+ * error is encountered and %NULL is returned.
*
* the input string must be \0 terminated.
*/
@@ -3352,15 +3391,23 @@ gst_value_union_int_int_range (GValue * dest, const GValue * src1,
/* check if it extends the range */
if (v == (INT_RANGE_MIN (src2) - 1) * INT_RANGE_STEP (src2)) {
if (dest) {
+ guint64 new_min =
+ (guint) ((INT_RANGE_MIN (src2) - 1) * INT_RANGE_STEP (src2));
+ guint64 new_max = (guint) (INT_RANGE_MAX (src2) * INT_RANGE_STEP (src2));
+
gst_value_init_and_copy (dest, src2);
- --INT_RANGE_MIN (src2);
+ dest->data[0].v_uint64 = (new_min << 32) | (new_max);
}
return TRUE;
}
if (v == (INT_RANGE_MAX (src2) + 1) * INT_RANGE_STEP (src2)) {
if (dest) {
+ guint64 new_min = (guint) (INT_RANGE_MIN (src2) * INT_RANGE_STEP (src2));
+ guint64 new_max =
+ (guint) ((INT_RANGE_MAX (src2) + 1) * INT_RANGE_STEP (src2));
+
gst_value_init_and_copy (dest, src2);
- ++INT_RANGE_MAX (src2);
+ dest->data[0].v_uint64 = (new_min << 32) | (new_max);
}
return TRUE;
}
@@ -3426,15 +3473,26 @@ gst_value_union_int_range_int_range (GValue * dest, const GValue * src1,
if (scalar ==
(INT_RANGE_MIN (range_value) - 1) * INT_RANGE_STEP (range_value)) {
if (dest) {
+ guint64 new_min = (guint)
+ ((INT_RANGE_MIN (range_value) -
+ 1) * INT_RANGE_STEP (range_value));
+ guint64 new_max = (guint)
+ (INT_RANGE_MAX (range_value) * INT_RANGE_STEP (range_value));
+
gst_value_init_and_copy (dest, range_value);
- --INT_RANGE_MIN (range_value);
+ dest->data[0].v_uint64 = (new_min << 32) | (new_max);
}
return TRUE;
} else if (scalar ==
(INT_RANGE_MAX (range_value) + 1) * INT_RANGE_STEP (range_value)) {
if (dest) {
+ guint64 new_min = (guint)
+ (INT_RANGE_MIN (range_value) * INT_RANGE_STEP (range_value));
+ guint64 new_max = (guint)
+ ((INT_RANGE_MAX (range_value) +
+ 1) * INT_RANGE_STEP (range_value));
gst_value_init_and_copy (dest, range_value);
- ++INT_RANGE_MIN (range_value);
+ dest->data[0].v_uint64 = (new_min << 32) | (new_max);
}
return TRUE;
}
@@ -3784,6 +3842,9 @@ gst_value_subtract_int_int_range (GValue * dest, const GValue * minuend,
gint step = gst_value_get_int_range_step (subtrahend);
gint val = g_value_get_int (minuend);
+ if (step == 0)
+ return FALSE;
+
/* subtracting a range from an int only works if the int is not in the
* range */
if (val < min || val > max || val % step) {
@@ -3843,9 +3904,7 @@ gst_value_create_new_range (GValue * dest, gint min1, gint max1, gint min2,
}
if (min1 <= max1 && min2 <= max2) {
- gst_value_list_concat (dest, pv1, pv2);
- g_value_unset (pv1);
- g_value_unset (pv2);
+ gst_value_list_concat_and_take_values (dest, pv1, pv2);
}
return TRUE;
}
@@ -3861,6 +3920,9 @@ gst_value_subtract_int_range_int (GValue * dest, const GValue * minuend,
g_return_val_if_fail (min < max, FALSE);
+ if (step == 0)
+ return FALSE;
+
/* value is outside of the range, return range unchanged */
if (val < min || val > max || val % step) {
if (dest)
@@ -3902,6 +3964,9 @@ gst_value_subtract_int_range_int_range (GValue * dest, const GValue * minuend,
}
step = step1;
+ if (step == 0)
+ return FALSE;
+
if (max2 >= max1 && min2 <= min1) {
return FALSE;
} else if (max2 >= max1) {
@@ -3925,6 +3990,8 @@ gst_value_subtract_int64_int64_range (GValue * dest, const GValue * minuend,
gint64 step = gst_value_get_int64_range_step (subtrahend);
gint64 val = g_value_get_int64 (minuend);
+ if (step == 0)
+ return FALSE;
/* subtracting a range from an int64 only works if the int64 is not in the
* range */
if (val < min || val > max || val % step) {
@@ -3984,9 +4051,7 @@ gst_value_create_new_int64_range (GValue * dest, gint64 min1, gint64 max1,
}
if (min1 <= max1 && min2 <= max2) {
- gst_value_list_concat (dest, pv1, pv2);
- g_value_unset (pv1);
- g_value_unset (pv2);
+ gst_value_list_concat_and_take_values (dest, pv1, pv2);
}
return TRUE;
}
@@ -4002,6 +4067,9 @@ gst_value_subtract_int64_range_int64 (GValue * dest, const GValue * minuend,
g_return_val_if_fail (min < max, FALSE);
+ if (step == 0)
+ return FALSE;
+
/* value is outside of the range, return range unchanged */
if (val < min || val > max || val % step) {
if (dest)
@@ -4042,6 +4110,10 @@ gst_value_subtract_int64_range_int64_range (GValue * dest,
g_assert (FALSE);
return FALSE;
}
+
+ if (step1 == 0)
+ return FALSE;
+
step = step1;
if (max2 >= max1 && min2 <= min1) {
@@ -4125,9 +4197,7 @@ gst_value_subtract_double_range_double_range (GValue * dest,
}
if (min1 < max1 && min2 < max2) {
- gst_value_list_concat (dest, pv1, pv2);
- g_value_unset (pv1);
- g_value_unset (pv2);
+ gst_value_list_concat_and_take_values (dest, pv1, pv2);
}
return TRUE;
}
@@ -4139,9 +4209,6 @@ gst_value_subtract_from_list (GValue * dest, const GValue * minuend,
guint i, size;
GValue subtraction = { 0, };
gboolean ret = FALSE;
- GType ltype;
-
- ltype = gst_value_list_get_type ();
size = VALUE_LIST_SIZE (minuend);
for (i = 0; i < size; i++) {
@@ -4160,16 +4227,14 @@ gst_value_subtract_from_list (GValue * dest, const GValue * minuend,
if (!ret) {
gst_value_move (dest, &subtraction);
ret = TRUE;
- } else if (G_VALUE_HOLDS (dest, ltype)
- && !G_VALUE_HOLDS (&subtraction, ltype)) {
+ } else if (G_VALUE_TYPE (dest) == GST_TYPE_LIST
+ && G_VALUE_TYPE (&subtraction) != GST_TYPE_LIST) {
_gst_value_list_append_and_take_value (dest, &subtraction);
} else {
GValue temp;
gst_value_move (&temp, dest);
- gst_value_list_concat (dest, &temp, &subtraction);
- g_value_unset (&temp);
- g_value_unset (&subtraction);
+ gst_value_list_concat_and_take_values (dest, &temp, &subtraction);
}
}
}
@@ -4303,9 +4368,7 @@ gst_value_subtract_fraction_range_fraction_range (GValue * dest,
}
if (cmp1 == GST_VALUE_LESS_THAN && cmp2 == GST_VALUE_LESS_THAN) {
- gst_value_list_concat (dest, pv1, pv2);
- g_value_unset (pv1);
- g_value_unset (pv2);
+ gst_value_list_concat_and_take_values (dest, pv1, pv2);
}
return TRUE;
}
@@ -4355,6 +4418,15 @@ gst_value_get_compare_func (const GValue * value1)
return NULL;
}
+static inline gboolean
+gst_value_can_compare_unchecked (const GValue * value1, const GValue * value2)
+{
+ if (G_VALUE_TYPE (value1) != G_VALUE_TYPE (value2))
+ return FALSE;
+
+ return gst_value_get_compare_func (value1) != NULL;
+}
+
/**
* gst_value_can_compare:
* @value1: a value to compare
@@ -4362,7 +4434,7 @@ gst_value_get_compare_func (const GValue * value1)
*
* Determines if @value1 and @value2 can be compared.
*
- * Returns: TRUE if the values can be compared
+ * Returns: %TRUE if the values can be compared
*/
gboolean
gst_value_can_compare (const GValue * value1, const GValue * value2)
@@ -4370,10 +4442,7 @@ gst_value_can_compare (const GValue * value1, const GValue * value2)
g_return_val_if_fail (G_IS_VALUE (value1), FALSE);
g_return_val_if_fail (G_IS_VALUE (value2), FALSE);
- if (G_VALUE_TYPE (value1) != G_VALUE_TYPE (value2))
- return FALSE;
-
- return gst_value_get_compare_func (value1) != NULL;
+ return gst_value_can_compare_unchecked (value1, value2);
}
static gboolean
@@ -4382,9 +4451,9 @@ gst_value_list_equals_range (const GValue * list, const GValue * value)
const GValue *first;
guint list_size, n;
- g_return_val_if_fail (G_IS_VALUE (list), FALSE);
- g_return_val_if_fail (G_IS_VALUE (value), FALSE);
- g_return_val_if_fail (GST_VALUE_HOLDS_LIST (list), FALSE);
+ g_assert (G_IS_VALUE (list));
+ g_assert (G_IS_VALUE (value));
+ g_assert (GST_VALUE_HOLDS_LIST (list));
/* TODO: compare against an empty list ? No type though... */
list_size = VALUE_LIST_SIZE (list);
@@ -4399,6 +4468,8 @@ gst_value_list_equals_range (const GValue * list, const GValue * value)
const gint rmin = gst_value_get_int_range_min (value);
const gint rmax = gst_value_get_int_range_max (value);
const gint rstep = gst_value_get_int_range_step (value);
+ if (rstep == 0)
+ return FALSE;
/* note: this will overflow for min 0 and max INT_MAX, but this
would only be equal to a list of INT_MAX elements, which seems
very unlikely */
@@ -4416,6 +4487,8 @@ gst_value_list_equals_range (const GValue * list, const GValue * value)
const gint64 rmax = gst_value_get_int64_range_max (value);
const gint64 rstep = gst_value_get_int64_range_step (value);
GST_DEBUG ("List/range of int64s");
+ if (rstep == 0)
+ return FALSE;
if (list_size != rmax / rstep - rmin / rstep + 1)
return FALSE;
for (n = 0; n < list_size; ++n) {
@@ -4431,6 +4504,27 @@ gst_value_list_equals_range (const GValue * list, const GValue * value)
return FALSE;
}
+/* "Pure" variant of gst_value_compare which is guaranteed to
+ * not have list arguments and therefore does basic comparisions
+ */
+static inline gint
+_gst_value_compare_nolist (const GValue * value1, const GValue * value2)
+{
+ GstValueCompareFunc compare;
+
+ if (G_VALUE_TYPE (value1) != G_VALUE_TYPE (value2))
+ return GST_VALUE_UNORDERED;
+
+ compare = gst_value_get_compare_func (value1);
+ if (compare) {
+ return compare (value1, value2);
+ }
+
+ g_critical ("unable to compare values of type %s\n",
+ g_type_name (G_VALUE_TYPE (value1)));
+ return GST_VALUE_UNORDERED;
+}
+
/**
* gst_value_compare:
* @value1: a value to compare
@@ -4447,47 +4541,67 @@ gst_value_list_equals_range (const GValue * list, const GValue * value)
gint
gst_value_compare (const GValue * value1, const GValue * value2)
{
- GstValueCompareFunc compare;
- GType ltype;
+ gboolean value1_is_list;
+ gboolean value2_is_list;
g_return_val_if_fail (G_IS_VALUE (value1), GST_VALUE_LESS_THAN);
g_return_val_if_fail (G_IS_VALUE (value2), GST_VALUE_GREATER_THAN);
+ value1_is_list = G_VALUE_TYPE (value1) == GST_TYPE_LIST;
+ value2_is_list = G_VALUE_TYPE (value2) == GST_TYPE_LIST;
+
/* Special cases: lists and scalar values ("{ 1 }" and "1" are equal),
as well as lists and ranges ("{ 1, 2 }" and "[ 1, 2 ]" are equal) */
- ltype = gst_value_list_get_type ();
- if (G_VALUE_HOLDS (value1, ltype) && !G_VALUE_HOLDS (value2, ltype)) {
+ if (value1_is_list && !value2_is_list) {
+ gint i, n, ret;
if (gst_value_list_equals_range (value1, value2)) {
return GST_VALUE_EQUAL;
- } else if (gst_value_list_get_size (value1) == 1) {
+ }
+
+ n = gst_value_list_get_size (value1);
+ if (n == 0)
+ return GST_VALUE_UNORDERED;
+
+ for (i = 0; i < n; i++) {
const GValue *elt;
- elt = gst_value_list_get_value (value1, 0);
- return gst_value_compare (elt, value2);
+ elt = gst_value_list_get_value (value1, i);
+ ret = gst_value_compare (elt, value2);
+ if (ret != GST_VALUE_EQUAL && n == 1)
+ return ret;
+ else if (ret != GST_VALUE_EQUAL)
+ return GST_VALUE_UNORDERED;
}
- } else if (G_VALUE_HOLDS (value2, ltype) && !G_VALUE_HOLDS (value1, ltype)) {
+
+ return GST_VALUE_EQUAL;
+ } else if (value2_is_list && !value1_is_list) {
+ gint i, n, ret;
+
if (gst_value_list_equals_range (value2, value1)) {
return GST_VALUE_EQUAL;
- } else if (gst_value_list_get_size (value2) == 1) {
+ }
+
+ n = gst_value_list_get_size (value2);
+ if (n == 0)
+ return GST_VALUE_UNORDERED;
+
+ for (i = 0; i < n; i++) {
const GValue *elt;
- elt = gst_value_list_get_value (value2, 0);
- return gst_value_compare (elt, value1);
+ elt = gst_value_list_get_value (value2, i);
+ ret = gst_value_compare (elt, value1);
+ if (ret != GST_VALUE_EQUAL && n == 1)
+ return ret;
+ else if (ret != GST_VALUE_EQUAL)
+ return GST_VALUE_UNORDERED;
}
- }
- if (G_VALUE_TYPE (value1) != G_VALUE_TYPE (value2))
- return GST_VALUE_UNORDERED;
-
- compare = gst_value_get_compare_func (value1);
- if (compare) {
- return compare (value1, value2);
+ return GST_VALUE_EQUAL;
}
- g_critical ("unable to compare values of type %s\n",
- g_type_name (G_VALUE_TYPE (value1)));
- return GST_VALUE_UNORDERED;
+ /* And now handle the generic case */
+ return _gst_value_compare_nolist (value1, value2);
}
/*
@@ -4523,13 +4637,13 @@ gst_value_compare_with_func (const GValue * value1, const GValue * value2,
*
* Determines if @value1 and @value2 can be non-trivially unioned.
* Any two values can be trivially unioned by adding both of them
- * to a GstValueList. However, certain types have the possibility
+ * to a #GstValueList. However, certain types have the possibility
* to be unioned in a simpler way. For example, an integer range
* and an integer can be unioned if the integer is a subset of the
* integer range. If there is the possibility that two values can
- * be unioned, this function returns TRUE.
+ * be unioned, this function returns %TRUE.
*
- * Returns: TRUE if there is a function allowing the two values to
+ * Returns: %TRUE if there is a function allowing the two values to
* be unioned.
*/
gboolean
@@ -4564,7 +4678,7 @@ gst_value_can_union (const GValue * value1, const GValue * value2)
*
* Creates a GValue corresponding to the union of @value1 and @value2.
*
- * Returns: TRUE if the union suceeded.
+ * Returns: %TRUE if the union succeeded.
*/
gboolean
gst_value_union (GValue * dest, const GValue * value1, const GValue * value2)
@@ -4630,35 +4744,32 @@ gst_value_register_union_func (GType type1, GType type2, GstValueUnionFunc func)
*
* Determines if intersecting two values will produce a valid result.
* Two values will produce a valid intersection if they have the same
- * type, or if there is a method (registered by
- * gst_value_register_intersect_func()) to calculate the intersection.
+ * type.
*
- * Returns: TRUE if the values can intersect
+ * Returns: %TRUE if the values can intersect
*/
gboolean
gst_value_can_intersect (const GValue * value1, const GValue * value2)
{
GstValueIntersectInfo *intersect_info;
guint i, len;
- GType ltype, type1, type2;
+ GType type1, type2;
g_return_val_if_fail (G_IS_VALUE (value1), FALSE);
g_return_val_if_fail (G_IS_VALUE (value2), FALSE);
- ltype = gst_value_list_get_type ();
-
- /* special cases */
- if (G_VALUE_HOLDS (value1, ltype) || G_VALUE_HOLDS (value2, ltype))
- return TRUE;
-
type1 = G_VALUE_TYPE (value1);
type2 = G_VALUE_TYPE (value2);
/* practically all GstValue types have a compare function (_can_compare=TRUE)
- * GstStructure and GstCaps have npot, but are intersectable */
+ * GstStructure and GstCaps have not, but are intersectable */
if (type1 == type2)
return TRUE;
+ /* special cases */
+ if (type1 == GST_TYPE_LIST || type2 == GST_TYPE_LIST)
+ return TRUE;
+
/* check registered intersect functions */
len = gst_value_intersect_funcs->len;
for (i = 0; i < len; i++) {
@@ -4669,22 +4780,22 @@ gst_value_can_intersect (const GValue * value1, const GValue * value2)
return TRUE;
}
- return gst_value_can_compare (value1, value2);
+ return gst_value_can_compare_unchecked (value1, value2);
}
/**
* gst_value_intersect:
* @dest: (out caller-allocates) (transfer full): a uninitialized #GValue that will hold the calculated
- * intersection value. May be NULL if the resulting set if not needed.
+ * intersection value. May be %NULL if the resulting set if not needed.
* @value1: a value to intersect
* @value2: another value to intersect
*
* Calculates the intersection of two values. If the values have
* a non-empty intersection, the value representing the intersection
- * is placed in @dest, unless NULL. If the intersection is non-empty,
+ * is placed in @dest, unless %NULL. If the intersection is non-empty,
* @dest is not modified.
*
- * Returns: TRUE if the intersection is non-empty
+ * Returns: %TRUE if the intersection is non-empty
*/
gboolean
gst_value_intersect (GValue * dest, const GValue * value1,
@@ -4692,28 +4803,26 @@ gst_value_intersect (GValue * dest, const GValue * value1,
{
GstValueIntersectInfo *intersect_info;
guint i, len;
- GType ltype, type1, type2;
+ GType type1, type2;
g_return_val_if_fail (G_IS_VALUE (value1), FALSE);
g_return_val_if_fail (G_IS_VALUE (value2), FALSE);
- ltype = gst_value_list_get_type ();
+ type1 = G_VALUE_TYPE (value1);
+ type2 = G_VALUE_TYPE (value2);
/* special cases first */
- if (G_VALUE_HOLDS (value1, ltype))
+ if (type1 == GST_TYPE_LIST)
return gst_value_intersect_list (dest, value1, value2);
- if (G_VALUE_HOLDS (value2, ltype))
+ if (type2 == GST_TYPE_LIST)
return gst_value_intersect_list (dest, value2, value1);
- if (gst_value_compare (value1, value2) == GST_VALUE_EQUAL) {
+ if (_gst_value_compare_nolist (value1, value2) == GST_VALUE_EQUAL) {
if (dest)
gst_value_init_and_copy (dest, value1);
return TRUE;
}
- type1 = G_VALUE_TYPE (value1);
- type2 = G_VALUE_TYPE (value2);
-
len = gst_value_intersect_funcs->len;
for (i = 0; i < len; i++) {
intersect_info = &g_array_index (gst_value_intersect_funcs,
@@ -4762,7 +4871,7 @@ gst_value_register_intersect_func (GType type1, GType type2,
/**
* gst_value_subtract:
* @dest: (out caller-allocates): the destination value for the result if the
- * subtraction is not empty. May be NULL, in which case the resulting set
+ * subtraction is not empty. May be %NULL, in which case the resulting set
* will not be computed, which can give a fair speedup.
* @minuend: the value to subtract from
* @subtrahend: the value to subtract
@@ -4778,22 +4887,20 @@ gst_value_subtract (GValue * dest, const GValue * minuend,
{
GstValueSubtractInfo *info;
guint i, len;
- GType ltype, mtype, stype;
+ GType mtype, stype;
g_return_val_if_fail (G_IS_VALUE (minuend), FALSE);
g_return_val_if_fail (G_IS_VALUE (subtrahend), FALSE);
- ltype = gst_value_list_get_type ();
+ mtype = G_VALUE_TYPE (minuend);
+ stype = G_VALUE_TYPE (subtrahend);
/* special cases first */
- if (G_VALUE_HOLDS (minuend, ltype))
+ if (mtype == GST_TYPE_LIST)
return gst_value_subtract_from_list (dest, minuend, subtrahend);
- if (G_VALUE_HOLDS (subtrahend, ltype))
+ if (stype == GST_TYPE_LIST)
return gst_value_subtract_list (dest, minuend, subtrahend);
- mtype = G_VALUE_TYPE (minuend);
- stype = G_VALUE_TYPE (subtrahend);
-
len = gst_value_subtract_funcs->len;
for (i = 0; i < len; i++) {
info = &g_array_index (gst_value_subtract_funcs, GstValueSubtractInfo, i);
@@ -4802,7 +4909,7 @@ gst_value_subtract (GValue * dest, const GValue * minuend,
}
}
- if (gst_value_compare (minuend, subtrahend) != GST_VALUE_EQUAL) {
+ if (_gst_value_compare_nolist (minuend, subtrahend) != GST_VALUE_EQUAL) {
if (dest)
gst_value_init_and_copy (dest, minuend);
return TRUE;
@@ -4832,27 +4939,25 @@ gst_value_subtract (GValue * dest, const GValue * minuend,
*
* Checks if it's possible to subtract @subtrahend from @minuend.
*
- * Returns: TRUE if a subtraction is possible
+ * Returns: %TRUE if a subtraction is possible
*/
gboolean
gst_value_can_subtract (const GValue * minuend, const GValue * subtrahend)
{
GstValueSubtractInfo *info;
guint i, len;
- GType ltype, mtype, stype;
+ GType mtype, stype;
g_return_val_if_fail (G_IS_VALUE (minuend), FALSE);
g_return_val_if_fail (G_IS_VALUE (subtrahend), FALSE);
- ltype = gst_value_list_get_type ();
+ mtype = G_VALUE_TYPE (minuend);
+ stype = G_VALUE_TYPE (subtrahend);
/* special cases */
- if (G_VALUE_HOLDS (minuend, ltype) || G_VALUE_HOLDS (subtrahend, ltype))
+ if (mtype == GST_TYPE_LIST || stype == GST_TYPE_LIST)
return TRUE;
- mtype = G_VALUE_TYPE (minuend);
- stype = G_VALUE_TYPE (subtrahend);
-
len = gst_value_subtract_funcs->len;
for (i = 0; i < len; i++) {
info = &g_array_index (gst_value_subtract_funcs, GstValueSubtractInfo, i);
@@ -4860,7 +4965,7 @@ gst_value_can_subtract (const GValue * minuend, const GValue * subtrahend)
return TRUE;
}
- return gst_value_can_compare (minuend, subtrahend);
+ return gst_value_can_compare_unchecked (minuend, subtrahend);
}
/* gst_value_register_subtract_func: (skip)
@@ -4954,7 +5059,7 @@ gst_value_move (GValue * dest, GValue * src)
*
* Free-function: g_free
*
- * Returns: (transfer full): the serialization for @value or NULL if none exists
+ * Returns: (transfer full): the serialization for @value or %NULL if none exists
*/
gchar *
gst_value_serialize (const GValue * value)
@@ -5003,9 +5108,9 @@ gst_value_serialize (const GValue * value)
* @src: string to deserialize
*
* Tries to deserialize a string into the type specified by the given GValue.
- * If the operation succeeds, TRUE is returned, FALSE otherwise.
+ * If the operation succeeds, %TRUE is returned, %FALSE otherwise.
*
- * Returns: TRUE on success
+ * Returns: %TRUE on success
*/
gboolean
gst_value_deserialize (GValue * dest, const gchar * src)
@@ -5087,9 +5192,9 @@ gst_value_is_fixed (const GValue * value)
* Fixate @src into a new value @dest.
* For ranges, the first element is taken. For lists and arrays, the
* first item is fixated and returned.
- * If @src is already fixed, this function returns FALSE.
+ * If @src is already fixed, this function returns %FALSE.
*
- * Returns: true if @dest contains a fixated version of @src.
+ * Returns: %TRUE if @dest contains a fixated version of @src.
*/
gboolean
gst_value_fixate (GValue * dest, const GValue * src)
@@ -5293,7 +5398,7 @@ gst_value_get_fraction_denominator (const GValue * value)
* Multiplies the two #GValue items containing a #GST_TYPE_FRACTION and sets
* @product to the product of the two fractions.
*
- * Returns: FALSE in case of an error (like integer overflow), TRUE otherwise.
+ * Returns: %FALSE in case of an error (like integer overflow), %TRUE otherwise.
*/
gboolean
gst_value_fraction_multiply (GValue * product, const GValue * factor1,
@@ -5327,7 +5432,7 @@ gst_value_fraction_multiply (GValue * product, const GValue * factor1,
*
* Subtracts the @subtrahend from the @minuend and sets @dest to the result.
*
- * Returns: FALSE in case of an error (like integer overflow), TRUE otherwise.
+ * Returns: %FALSE in case of an error (like integer overflow), %TRUE otherwise.
*/
gboolean
gst_value_fraction_subtract (GValue * dest,
@@ -5785,6 +5890,51 @@ gst_value_compare_bitmask (const GValue * value1, const GValue * value2)
return GST_VALUE_UNORDERED;
}
+
+/***********************
+ * GstAllocationParams *
+ ***********************/
+static gint
+gst_value_compare_allocation_params (const GValue * value1,
+ const GValue * value2)
+{
+ GstAllocationParams *v1, *v2;
+
+ v1 = value1->data[0].v_pointer;
+ v2 = value2->data[0].v_pointer;
+
+ if (v1 == NULL && v1 == v2)
+ return GST_VALUE_EQUAL;
+
+ if (v1 == NULL || v2 == NULL)
+ return GST_VALUE_UNORDERED;
+
+ if (v1->flags == v2->flags && v1->align == v2->align &&
+ v1->prefix == v2->prefix && v1->padding == v2->padding)
+ return GST_VALUE_EQUAL;
+
+ return GST_VALUE_UNORDERED;
+}
+
+
+/************
+ * GObject *
+ ************/
+
+static gint
+gst_value_compare_object (const GValue * value1, const GValue * value2)
+{
+ gpointer v1, v2;
+
+ v1 = value1->data[0].v_pointer;
+ v2 = value2->data[0].v_pointer;
+
+ if (v1 == v2)
+ return GST_VALUE_EQUAL;
+
+ return GST_VALUE_UNORDERED;
+}
+
static void
gst_value_transform_object_string (const GValue * src_value,
GValue * dest_value)
@@ -5822,17 +5972,20 @@ static GTypeFundamentalInfo _finfo = {
};
#define FUNC_VALUE_GET_TYPE(type, name) \
+GType _gst_ ## type ## _type = 0; \
+ \
GType gst_ ## type ## _get_type (void) \
{ \
- static volatile GType gst_ ## type ## _type = 0; \
+ static volatile GType gst_ ## type ## _type = 0; \
\
- if (g_once_init_enter (&gst_ ## type ## _type)) { \
- GType _type; \
+ if (g_once_init_enter (&gst_ ## type ## _type)) { \
+ GType _type; \
_info.value_table = & _gst_ ## type ## _value_table; \
- _type = g_type_register_fundamental ( \
+ _type = g_type_register_fundamental ( \
g_type_fundamental_next (), \
name, &_info, &_finfo, 0); \
- g_once_init_leave(&gst_ ## type ## _type, _type); \
+ _gst_ ## type ## _type = _type; \
+ g_once_init_leave(&gst_ ## type ## _type, _type); \
} \
\
return gst_ ## type ## _type; \
@@ -5840,7 +5993,7 @@ GType gst_ ## type ## _get_type (void) \
static const GTypeValueTable _gst_int_range_value_table = {
gst_value_init_int_range,
- gst_value_free_int_range,
+ NULL,
gst_value_copy_int_range,
NULL,
(char *) "ii",
@@ -5929,9 +6082,6 @@ static const GTypeValueTable _gst_fraction_value_table = {
FUNC_VALUE_GET_TYPE (fraction, "GstFraction");
-G_DEFINE_BOXED_TYPE (GstDateTime, gst_date_time,
- (GBoxedCopyFunc) gst_date_time_ref, (GBoxedFreeFunc) gst_date_time_unref);
-
static const GTypeValueTable _gst_bitmask_value_table = {
gst_value_init_bitmask,
NULL,
@@ -6184,6 +6334,30 @@ _priv_gst_value_initialize (void)
gst_value_register (&gst_value);
}
+ {
+ static GstValueTable gst_value = {
+ 0,
+ gst_value_compare_allocation_params,
+ NULL,
+ NULL,
+ };
+
+ gst_value.type = gst_allocation_params_get_type ();
+ gst_value_register (&gst_value);
+ }
+
+ {
+ static GstValueTable gst_value = {
+ 0,
+ gst_value_compare_object,
+ NULL,
+ NULL,
+ };
+
+ gst_value.type = G_TYPE_OBJECT;
+ gst_value_register (&gst_value);
+ }
+
REGISTER_SERIALIZATION (G_TYPE_DOUBLE, double);
REGISTER_SERIALIZATION (G_TYPE_FLOAT, float);
diff --git a/gst/gstvalue.h b/gst/gstvalue.h
index d03d22e..de01abc 100644
--- a/gst/gstvalue.h
+++ b/gst/gstvalue.h
@@ -92,7 +92,7 @@ G_BEGIN_DECLS
*
* Checks if the given #GValue contains a #GST_TYPE_INT_RANGE value.
*/
-#define GST_VALUE_HOLDS_INT_RANGE(x) (G_VALUE_HOLDS((x), gst_int_range_get_type ()))
+#define GST_VALUE_HOLDS_INT_RANGE(x) ((x) != NULL && G_VALUE_TYPE(x) == _gst_int_range_type)
/**
* GST_VALUE_HOLDS_INT64_RANGE:
@@ -100,7 +100,7 @@ G_BEGIN_DECLS
*
* Checks if the given #GValue contains a #GST_TYPE_INT64_RANGE value.
*/
-#define GST_VALUE_HOLDS_INT64_RANGE(x) (G_VALUE_HOLDS((x), gst_int64_range_get_type ()))
+#define GST_VALUE_HOLDS_INT64_RANGE(x) ((x) != NULL && G_VALUE_TYPE(x) == _gst_int64_range_type)
/**
* GST_VALUE_HOLDS_DOUBLE_RANGE:
@@ -108,7 +108,7 @@ G_BEGIN_DECLS
*
* Checks if the given #GValue contains a #GST_TYPE_DOUBLE_RANGE value.
*/
-#define GST_VALUE_HOLDS_DOUBLE_RANGE(x) (G_VALUE_HOLDS((x), gst_double_range_get_type ()))
+#define GST_VALUE_HOLDS_DOUBLE_RANGE(x) ((x) != NULL && G_VALUE_TYPE(x) == _gst_double_range_type)
/**
* GST_VALUE_HOLDS_FRACTION_RANGE:
@@ -116,7 +116,7 @@ G_BEGIN_DECLS
*
* Checks if the given #GValue contains a #GST_TYPE_FRACTION_RANGE value.
*/
-#define GST_VALUE_HOLDS_FRACTION_RANGE(x) (G_VALUE_HOLDS((x), gst_fraction_range_get_type ()))
+#define GST_VALUE_HOLDS_FRACTION_RANGE(x) ((x) != NULL && G_VALUE_TYPE(x) == _gst_fraction_range_type)
/**
* GST_VALUE_HOLDS_LIST:
@@ -124,7 +124,7 @@ G_BEGIN_DECLS
*
* Checks if the given #GValue contains a #GST_TYPE_LIST value.
*/
-#define GST_VALUE_HOLDS_LIST(x) (G_VALUE_HOLDS((x), gst_value_list_get_type ()))
+#define GST_VALUE_HOLDS_LIST(x) ((x) != NULL && G_VALUE_TYPE(x) == _gst_value_list_type)
/**
* GST_VALUE_HOLDS_ARRAY:
@@ -132,7 +132,7 @@ G_BEGIN_DECLS
*
* Checks if the given #GValue contains a #GST_TYPE_ARRAY value.
*/
-#define GST_VALUE_HOLDS_ARRAY(x) (G_VALUE_HOLDS((x), gst_value_array_get_type ()))
+#define GST_VALUE_HOLDS_ARRAY(x) ((x) != NULL && G_VALUE_TYPE(x) == _gst_value_array_type)
/**
* GST_VALUE_HOLDS_CAPS:
@@ -140,7 +140,7 @@ G_BEGIN_DECLS
*
* Checks if the given #GValue contains a #GST_TYPE_CAPS value.
*/
-#define GST_VALUE_HOLDS_CAPS(x) (G_VALUE_HOLDS((x), GST_TYPE_CAPS))
+#define GST_VALUE_HOLDS_CAPS(x) ((x) != NULL && G_VALUE_TYPE(x) == _gst_caps_type)
/**
* GST_VALUE_HOLDS_STRUCTURE:
@@ -148,7 +148,7 @@ G_BEGIN_DECLS
*
* Checks if the given #GValue contains a #GST_TYPE_STRUCTURE value.
*/
-#define GST_VALUE_HOLDS_STRUCTURE(x) (G_VALUE_HOLDS((x), GST_TYPE_STRUCTURE))
+#define GST_VALUE_HOLDS_STRUCTURE(x) (G_VALUE_HOLDS((x), _gst_structure_type))
/**
* GST_VALUE_HOLDS_CAPS_FEATURES:
@@ -156,7 +156,7 @@ G_BEGIN_DECLS
*
* Checks if the given #GValue contains a #GST_TYPE_CAPS_FEATURES value.
*/
-#define GST_VALUE_HOLDS_CAPS_FEATURES(x) (G_VALUE_HOLDS((x), GST_TYPE_CAPS_FEATURES))
+#define GST_VALUE_HOLDS_CAPS_FEATURES(x) (G_VALUE_HOLDS((x), _gst_caps_features_type))
/**
* GST_VALUE_HOLDS_BUFFER:
@@ -164,7 +164,7 @@ G_BEGIN_DECLS
*
* Checks if the given #GValue contains a #GST_TYPE_BUFFER value.
*/
-#define GST_VALUE_HOLDS_BUFFER(x) (G_VALUE_HOLDS((x), GST_TYPE_BUFFER))
+#define GST_VALUE_HOLDS_BUFFER(x) ((x) != NULL && G_VALUE_TYPE(x) == _gst_buffer_type)
/**
* GST_VALUE_HOLDS_SAMPLE:
@@ -172,7 +172,7 @@ G_BEGIN_DECLS
*
* Checks if the given #GValue contains a #GST_TYPE_SAMPLE value.
*/
-#define GST_VALUE_HOLDS_SAMPLE(x) (G_VALUE_HOLDS((x), GST_TYPE_SAMPLE))
+#define GST_VALUE_HOLDS_SAMPLE(x) ((x) != NULL && G_VALUE_TYPE(x) == _gst_sample_type)
/**
* GST_VALUE_HOLDS_FRACTION:
@@ -180,7 +180,7 @@ G_BEGIN_DECLS
*
* Checks if the given #GValue contains a #GST_TYPE_FRACTION value.
*/
-#define GST_VALUE_HOLDS_FRACTION(x) (G_VALUE_HOLDS((x), gst_fraction_get_type ()))
+#define GST_VALUE_HOLDS_FRACTION(x) ((x) != NULL && G_VALUE_TYPE(x) == _gst_fraction_type)
/**
* GST_VALUE_HOLDS_DATE_TIME:
@@ -188,7 +188,7 @@ G_BEGIN_DECLS
*
* Checks if the given #GValue contains a #GST_TYPE_DATE_TIME value.
*/
-#define GST_VALUE_HOLDS_DATE_TIME(x) (G_VALUE_HOLDS((x), gst_date_time_get_type ()))
+#define GST_VALUE_HOLDS_DATE_TIME(x) ((x) != NULL && G_VALUE_TYPE(x) == _gst_date_time_type)
/**
* GST_VALUE_HOLDS_BITMASK:
@@ -196,7 +196,9 @@ G_BEGIN_DECLS
*
* Checks if the given #GValue contains a #GST_TYPE_BITMASK value.
*/
-#define GST_VALUE_HOLDS_BITMASK(x) (G_VALUE_HOLDS((x), gst_bitmask_get_type ()))
+#define GST_VALUE_HOLDS_BITMASK(x) ((x) != NULL && G_VALUE_TYPE(x) == _gst_bitmask_type)
+
+GST_EXPORT GType _gst_int_range_type;
/**
* GST_TYPE_INT_RANGE:
@@ -205,7 +207,9 @@ G_BEGIN_DECLS
*
* Returns: the #GType of GstIntRange
*/
-#define GST_TYPE_INT_RANGE gst_int_range_get_type ()
+#define GST_TYPE_INT_RANGE (_gst_int_range_type)
+
+GST_EXPORT GType _gst_int64_range_type;
/**
* GST_TYPE_INT64_RANGE:
@@ -214,16 +218,20 @@ G_BEGIN_DECLS
*
* Returns: the #GType of GstInt64Range
*/
-#define GST_TYPE_INT64_RANGE gst_int64_range_get_type ()
+#define GST_TYPE_INT64_RANGE (_gst_int64_range_type)
+
+GST_EXPORT GType _gst_double_range_type;
/**
* GST_TYPE_DOUBLE_RANGE:
*
- * a #GValue type that represents a floating point range with double precission
+ * a #GValue type that represents a floating point range with double precision
*
* Returns: the #GType of GstIntRange
*/
-#define GST_TYPE_DOUBLE_RANGE gst_double_range_get_type ()
+#define GST_TYPE_DOUBLE_RANGE (_gst_double_range_type)
+
+GST_EXPORT GType _gst_fraction_range_type;
/**
* GST_TYPE_FRACTION_RANGE:
@@ -232,7 +240,9 @@ G_BEGIN_DECLS
*
* Returns: the #GType of GstFractionRange
*/
-#define GST_TYPE_FRACTION_RANGE gst_fraction_range_get_type ()
+#define GST_TYPE_FRACTION_RANGE (_gst_fraction_range_type)
+
+GST_EXPORT GType _gst_value_list_type;
/**
* GST_TYPE_LIST:
@@ -245,7 +255,9 @@ G_BEGIN_DECLS
*
* Returns: the #GType of GstValueList (which is not explicitly typed)
*/
-#define GST_TYPE_LIST gst_value_list_get_type ()
+#define GST_TYPE_LIST (_gst_value_list_type)
+
+GST_EXPORT GType _gst_value_array_type;
/**
* GST_TYPE_ARRAY:
@@ -259,7 +271,9 @@ G_BEGIN_DECLS
*
* Returns: the #GType of GstArrayList (which is not explicitly typed)
*/
-#define GST_TYPE_ARRAY gst_value_array_get_type ()
+#define GST_TYPE_ARRAY (_gst_value_array_type)
+
+GST_EXPORT GType _gst_fraction_type;
/**
* GST_TYPE_FRACTION:
@@ -270,17 +284,9 @@ G_BEGIN_DECLS
* Returns: the #GType of GstFraction (which is not explicitly typed)
*/
-#define GST_TYPE_FRACTION gst_fraction_get_type ()
+#define GST_TYPE_FRACTION (_gst_fraction_type)
-/**
- * GST_TYPE_DATE_TIME:
- *
- * a boxed #GValue type for #GstDateTime that represents a date and time.
- *
- * Returns: the #GType of GstDateTime
- */
-
-#define GST_TYPE_DATE_TIME gst_date_time_get_type ()
+GST_EXPORT GType _gst_bitmask_type;
/**
* GST_TYPE_BITMASK:
@@ -290,7 +296,7 @@ G_BEGIN_DECLS
* Returns: the #GType of GstBitmask (which is not explicitly typed)
*/
-#define GST_TYPE_BITMASK gst_bitmask_get_type ()
+#define GST_TYPE_BITMASK (_gst_bitmask_type)
/**
* GST_TYPE_G_THREAD:
@@ -405,8 +411,6 @@ GType gst_bitmask_get_type (void);
GType gst_g_thread_get_type (void);
#endif
-GType gst_date_time_get_type (void);
-
void gst_value_register (const GstValueTable *table);
void gst_value_init_and_copy (GValue *dest,
const GValue *src);
diff --git a/gst/parse/Makefile.am b/gst/parse/Makefile.am
index 7b5fd27..a26d471 100644
--- a/gst/parse/Makefile.am
+++ b/gst/parse/Makefile.am
@@ -1,22 +1,20 @@
# libgstparse.la is an optionally built helper library linked into core
noinst_LTLIBRARIES = libgstparse.la
-CLEANFILES = grammar.tab.h grammar.output
+CLEANFILES = grammar.tab.h parse_lex.h grammar.output
EXTRA_DIST = \
grammar.y \
parse.l
# uncomment these lines to dist the generated sources
-#BUILT_SOURCES = grammar.tab.h grammar.tab.c lex.priv_gst_parse_yy.c
+#BUILT_SOURCES = grammar.tab.h grammar.tab.c parse_lex.h lex.priv_gst_parse_yy.c
#libgstparse_la_SOURCES = lex.priv_gst_parse_yy.c grammar.tab.c
# uncomment these lines to _NOT_ dist the generated sources
-nodist_libgstparse_la_SOURCES = lex.priv_gst_parse_yy.c grammar.tab.c grammar.tab.h
+nodist_libgstparse_la_SOURCES = lex.priv_gst_parse_yy.c grammar.tab.c grammar.tag.h parse_lex.h
CLEANFILES += grammar.tab.c lex.priv_gst_parse_yy.c
-# can't use GST_ALL_CFLAGS here because that'd pull in -Werror
-libgstparse_la_CFLAGS = -I$(top_srcdir) -I$(top_builddir) \
- $(GLIB_CFLAGS) $(GST_OPTION_CFLAGS)
+libgstparse_la_CFLAGS = $(GST_ALL_CFLAGS) -DYYMALLOC=g_malloc -DYYFREE=g_free
libgstparse_la_LIBADD = $(GST_ALL_LIBS)
noinst_HEADERS = types.h
@@ -39,14 +37,15 @@ grammar.tab.c grammar.tab.h: grammar.y
rm grammar.tab_tmp.c && \
mv grammar.tab_tmp2.c grammar.tab.c
-lex.priv_gst_parse_yy.c: parse.l grammar.tab.h
- $(AM_V_GEN)$(FLEX_PATH) -Ppriv_gst_parse_yy $^ && \
+lex.priv_gst_parse_yy.c parse_lex.h: parse.l grammar.tab.h
+ $(AM_V_GEN)$(FLEX_PATH) --header-file=parse_lex.h -Ppriv_gst_parse_yy $^ && \
mv lex.priv_gst_parse_yy.c lex.priv_gst_parse_yy_tmp.c && \
echo '#ifdef HAVE_CONFIG_H' > lex.priv_gst_parse_yy_tmp2.c && \
echo '#include <config.h>' >> lex.priv_gst_parse_yy_tmp2.c && \
echo '#endif' >> lex.priv_gst_parse_yy_tmp2.c && \
- echo 'static inline int priv_gst_parse_yyget_column (void * yyscanner);' >> lex.priv_gst_parse_yy_tmp2.c && \
- echo 'static inline void priv_gst_parse_yyset_column (int column_no , void * yyscanner);' >> lex.priv_gst_parse_yy_tmp2.c && \
+ { grep -q priv_gst_parse_yyget_column parse_lex.h || \
+ { echo 'int priv_gst_parse_yyget_column (void * yyscanner);' >> lex.priv_gst_parse_yy_tmp2.c && \
+ echo 'void priv_gst_parse_yyset_column (int column_no , void * yyscanner);' >> lex.priv_gst_parse_yy_tmp2.c; }; } && \
cat lex.priv_gst_parse_yy_tmp.c >> lex.priv_gst_parse_yy_tmp2.c && \
rm lex.priv_gst_parse_yy_tmp.c && \
mv lex.priv_gst_parse_yy_tmp2.c lex.priv_gst_parse_yy.c
diff --git a/gst/parse/Makefile.in b/gst/parse/Makefile.in
index 0dd9b73..517775a 100644
--- a/gst/parse/Makefile.in
+++ b/gst/parse/Makefile.in
@@ -89,7 +89,6 @@ am__aclocal_m4_deps = $(top_srcdir)/common/m4/as-ac-expand.m4 \
$(top_srcdir)/common/m4/as-compiler-flag.m4 \
$(top_srcdir)/common/m4/as-docbook.m4 \
$(top_srcdir)/common/m4/as-libtool.m4 \
- $(top_srcdir)/common/m4/as-scrub-include.m4 \
$(top_srcdir)/common/m4/as-version.m4 \
$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
$(top_srcdir)/common/m4/gst-arch.m4 \
@@ -482,7 +481,7 @@ top_srcdir = @top_srcdir@
# libgstparse.la is an optionally built helper library linked into core
noinst_LTLIBRARIES = libgstparse.la
-CLEANFILES = grammar.tab.h grammar.output grammar.tab.c \
+CLEANFILES = grammar.tab.h parse_lex.h grammar.output grammar.tab.c \
lex.priv_gst_parse_yy.c
EXTRA_DIST = \
grammar.y \
@@ -490,16 +489,12 @@ EXTRA_DIST = \
# uncomment these lines to dist the generated sources
-#BUILT_SOURCES = grammar.tab.h grammar.tab.c lex.priv_gst_parse_yy.c
+#BUILT_SOURCES = grammar.tab.h grammar.tab.c parse_lex.h lex.priv_gst_parse_yy.c
#libgstparse_la_SOURCES = lex.priv_gst_parse_yy.c grammar.tab.c
# uncomment these lines to _NOT_ dist the generated sources
-nodist_libgstparse_la_SOURCES = lex.priv_gst_parse_yy.c grammar.tab.c grammar.tab.h
-
-# can't use GST_ALL_CFLAGS here because that'd pull in -Werror
-libgstparse_la_CFLAGS = -I$(top_srcdir) -I$(top_builddir) \
- $(GLIB_CFLAGS) $(GST_OPTION_CFLAGS)
-
+nodist_libgstparse_la_SOURCES = lex.priv_gst_parse_yy.c grammar.tab.c grammar.tag.h parse_lex.h
+libgstparse_la_CFLAGS = $(GST_ALL_CFLAGS) -DYYMALLOC=g_malloc -DYYFREE=g_free
libgstparse_la_LIBADD = $(GST_ALL_LIBS)
noinst_HEADERS = types.h
all: all-am
@@ -827,14 +822,15 @@ grammar.tab.c grammar.tab.h: grammar.y
rm grammar.tab_tmp.c && \
mv grammar.tab_tmp2.c grammar.tab.c
-lex.priv_gst_parse_yy.c: parse.l grammar.tab.h
- $(AM_V_GEN)$(FLEX_PATH) -Ppriv_gst_parse_yy $^ && \
+lex.priv_gst_parse_yy.c parse_lex.h: parse.l grammar.tab.h
+ $(AM_V_GEN)$(FLEX_PATH) --header-file=parse_lex.h -Ppriv_gst_parse_yy $^ && \
mv lex.priv_gst_parse_yy.c lex.priv_gst_parse_yy_tmp.c && \
echo '#ifdef HAVE_CONFIG_H' > lex.priv_gst_parse_yy_tmp2.c && \
echo '#include <config.h>' >> lex.priv_gst_parse_yy_tmp2.c && \
echo '#endif' >> lex.priv_gst_parse_yy_tmp2.c && \
- echo 'static inline int priv_gst_parse_yyget_column (void * yyscanner);' >> lex.priv_gst_parse_yy_tmp2.c && \
- echo 'static inline void priv_gst_parse_yyset_column (int column_no , void * yyscanner);' >> lex.priv_gst_parse_yy_tmp2.c && \
+ { grep -q priv_gst_parse_yyget_column parse_lex.h || \
+ { echo 'int priv_gst_parse_yyget_column (void * yyscanner);' >> lex.priv_gst_parse_yy_tmp2.c && \
+ echo 'void priv_gst_parse_yyset_column (int column_no , void * yyscanner);' >> lex.priv_gst_parse_yy_tmp2.c; }; } && \
cat lex.priv_gst_parse_yy_tmp.c >> lex.priv_gst_parse_yy_tmp2.c && \
rm lex.priv_gst_parse_yy_tmp.c && \
mv lex.priv_gst_parse_yy_tmp2.c lex.priv_gst_parse_yy.c
diff --git a/gst/parse/grammar.y b/gst/parse/grammar.y
index f533389..3f0513e 100644
--- a/gst/parse/grammar.y
+++ b/gst/parse/grammar.y
@@ -33,14 +33,9 @@
#define YYLTYPE_IS_TRIVIAL 0
#endif
-typedef void* yyscan_t;
-
-int priv_gst_parse_yylex (void * yylval_param , yyscan_t yyscanner);
-int priv_gst_parse_yylex_init (yyscan_t scanner);
-int priv_gst_parse_yylex_destroy (yyscan_t scanner);
-struct yy_buffer_state * priv_gst_parse_yy_scan_string (char* , yyscan_t);
-void _gst_parse_yypush_buffer_state (void * new_buffer ,yyscan_t yyscanner );
-void _gst_parse_yypop_buffer_state (yyscan_t yyscanner );
+/*******************************************************************************************
+*** Tracing memory leaks
+*******************************************************************************************/
#ifdef __GST_PARSE_TRACE
static guint __strings;
@@ -65,7 +60,7 @@ __gst_parse_strfree (gchar *str)
__strings--;
}
}
-link_t *__gst_parse_link_new ()
+link_t *__gst_parse_link_new (void)
{
link_t *ret;
__links++;
@@ -84,18 +79,18 @@ __gst_parse_link_free (link_t *data)
}
}
chain_t *
-__gst_parse_chain_new ()
+__gst_parse_chain_new (void)
{
chain_t *ret;
__chains++;
ret = g_slice_new0 (chain_t);
- /* g_print ("ALLOCATED CHAIN (%3u): %p\n", __chains, ret); */
+ /* g_print ("@%p: ALLOCATED CHAIN (%3u):\n", ret, __chains); */
return ret;
}
void
__gst_parse_chain_free (chain_t *data)
{
- /* g_print ("FREEING CHAIN (%3u): %p\n", __chains - 1, data); */
+ /* g_print ("@%p: FREEING CHAIN (%3u):\n", data, __chains - 1); */
g_slice_free (chain_t, data);
g_return_if_fail (__chains > 0);
__chains--;
@@ -103,22 +98,9 @@ __gst_parse_chain_free (chain_t *data)
#endif /* __GST_PARSE_TRACE */
-typedef struct {
- gchar *src_pad;
- gchar *sink_pad;
- GstElement *sink;
- GstCaps *caps;
- gulong signal_id;
-} DelayedLink;
-
-typedef struct {
- gchar *name;
- gchar *value_str;
- gulong signal_id;
-} DelayedSet;
-
-/*** define SET_ERROR macro/function */
-
+/*******************************************************************************************
+*** define SET_ERROR macro/function
+*******************************************************************************************/
#ifdef G_HAVE_ISO_VARARGS
# define SET_ERROR(error, type, ...) \
@@ -206,79 +188,77 @@ YYPRINTF(const char *format, ...)
#endif /* GST_DISABLE_GST_DEBUG */
-#define ADD_MISSING_ELEMENT(graph,name) G_STMT_START { \
- if ((graph)->ctx) { \
- (graph)->ctx->missing_elements = \
- g_list_append ((graph)->ctx->missing_elements, g_strdup (name)); \
- } } G_STMT_END
-static void
-no_free (gconstpointer foo)
-{
- /* do nothing */
+/*
+ * include headers generated by bison & flex, after defining (or not defining) YYDEBUG
+ */
+#include "grammar.tab.h"
+#include "parse_lex.h"
+
+/*******************************************************************************************
+*** report missing elements/bins/..
+*******************************************************************************************/
+
+
+static void add_missing_element(graph_t *graph,gchar *name){
+ if ((graph)->ctx){
+ (graph)->ctx->missing_elements = g_list_append ((graph)->ctx->missing_elements, g_strdup (name));
+ }
}
-#define GST_BIN_MAKE(res, type, chainval, assign, type_string_free_func) \
-G_STMT_START { \
- chain_t *chain = chainval; \
- GSList *walk; \
- GstBin *bin = (GstBin *) gst_element_factory_make (type, NULL); \
- if (!chain) { \
- SET_ERROR (graph->error, GST_PARSE_ERROR_EMPTY_BIN, \
- _("specified empty bin \"%s\", not allowed"), type); \
- g_slist_foreach (assign, (GFunc) gst_parse_strfree, NULL); \
- g_slist_free (assign); \
- gst_object_unref (bin); \
- type_string_free_func (type); /* Need to clean up the string */ \
- YYERROR; \
- } else if (!bin) { \
- ADD_MISSING_ELEMENT(graph, type); \
- SET_ERROR (graph->error, GST_PARSE_ERROR_NO_SUCH_ELEMENT, \
- _("no bin \"%s\", skipping"), type); \
- g_slist_foreach (assign, (GFunc) gst_parse_strfree, NULL); \
- g_slist_free (assign); \
- res = chain; \
- } else { \
- for (walk = chain->elements; walk; walk = walk->next ) \
- gst_bin_add (bin, GST_ELEMENT (walk->data)); \
- g_slist_free (chain->elements); \
- chain->elements = g_slist_prepend (NULL, bin); \
- res = chain; \
- /* set the properties now */ \
- for (walk = assign; walk; walk = walk->next) \
- gst_parse_element_set ((gchar *) walk->data, GST_ELEMENT (bin), graph); \
- g_slist_free (assign); \
- } \
-} G_STMT_END
-#define MAKE_LINK(link, _src, _src_name, _src_pads, _sink, _sink_name, _sink_pads) \
-G_STMT_START { \
- link = gst_parse_link_new (); \
- link->src = _src; \
- link->sink = _sink; \
- link->src_name = _src_name; \
- link->sink_name = _sink_name; \
- link->src_pads = _src_pads; \
- link->sink_pads = _sink_pads; \
- link->caps = NULL; \
+/*******************************************************************************************
+*** helpers for pipeline-setup
+*******************************************************************************************/
+
+#define TRY_SETUP_LINK(l) G_STMT_START { \
+ if( (!(l)->src.element) && (!(l)->src.name) ){ \
+ SET_ERROR (graph->error, GST_PARSE_ERROR_LINK, _("link has no source [sink=%s@%p]"), \
+ (l)->sink.name ? (l)->sink.name : _(""), \
+ (l)->sink.element); \
+ gst_parse_free_link (l); \
+ }else if( (!(l)->sink.element) && (!(l)->sink.name) ){ \
+ SET_ERROR (graph->error, GST_PARSE_ERROR_LINK, _("link has no sink [source=%s@%p]"), \
+ (l)->src.name ? (l)->src.name :_(""), \
+ (l)->src.element); \
+ gst_parse_free_link (l); \
+ }else{ \
+ graph->links = g_slist_append (graph->links, l ); \
+ } \
} G_STMT_END
-#define MAKE_REF(link, _src, _pads) \
-G_STMT_START { \
- gchar *padname = _src; \
- GSList *pads = _pads; \
- if (padname) { \
- while (*padname != '.') padname++; \
- *padname = '\0'; \
- padname++; \
- if (*padname != '\0') \
- pads = g_slist_prepend (pads, gst_parse_strdup (padname)); \
- } \
- MAKE_LINK (link, NULL, _src, pads, NULL, NULL, NULL); \
-} G_STMT_END
+typedef struct {
+ gchar *src_pad;
+ gchar *sink_pad;
+ GstElement *sink;
+ GstCaps *caps;
+ gulong signal_id;
+} DelayedLink;
-static void
-gst_parse_free_delayed_set (DelayedSet *set)
+typedef struct {
+ gchar *name;
+ gchar *value_str;
+ gulong signal_id;
+} DelayedSet;
+
+static int gst_resolve_reference(reference_t *rr, GstElement *pipeline){
+ GstBin *bin;
+
+ if(rr->element) return 0; /* already resolved! */
+ if(!rr->name) return -2; /* no chance! */
+
+ if (GST_IS_BIN (pipeline)){
+ bin = GST_BIN (pipeline);
+ rr->element = gst_bin_get_by_name_recurse_up (bin, rr->name);
+ } else {
+ rr->element = strcmp (GST_ELEMENT_NAME (pipeline), rr->name) == 0 ?
+ gst_object_ref(pipeline) : NULL;
+ }
+ if(rr->element) return 0; /* resolved */
+ else return -1; /* not found */
+}
+
+static void gst_parse_free_delayed_set (DelayedSet *set)
{
g_free(set->name);
g_free(set->value_str);
@@ -288,8 +268,7 @@ gst_parse_free_delayed_set (DelayedSet *set)
static void gst_parse_new_child(GstChildProxy *child_proxy, GObject *object,
const gchar * name, gpointer data);
-static void
-gst_parse_add_delayed_set (GstElement *element, gchar *name, gchar *value_str)
+static void gst_parse_add_delayed_set (GstElement *element, gchar *name, gchar *value_str)
{
DelayedSet *data = g_slice_new0 (DelayedSet);
@@ -325,8 +304,7 @@ gst_parse_add_delayed_set (GstElement *element, gchar *name, gchar *value_str)
}
}
-static void
-gst_parse_new_child(GstChildProxy *child_proxy, GObject *object,
+static void gst_parse_new_child(GstChildProxy *child_proxy, GObject *object,
const gchar * name, gpointer data)
{
DelayedSet *set = (DelayedSet *) data;
@@ -385,8 +363,7 @@ error:
goto out;
}
-static void
-gst_parse_element_set (gchar *value, GstElement *element, graph_t *graph)
+static void gst_parse_element_set (gchar *value, GstElement *element, graph_t *graph)
{
GParamSpec *pspec = NULL;
gchar *pos = value;
@@ -474,21 +451,34 @@ error:
goto out;
}
-static inline void
-gst_parse_free_link (link_t *link)
+static void gst_parse_free_reference (reference_t *rr)
{
- gst_parse_strfree (link->src_name);
- gst_parse_strfree (link->sink_name);
- g_slist_foreach (link->src_pads, (GFunc) gst_parse_strfree, NULL);
- g_slist_foreach (link->sink_pads, (GFunc) gst_parse_strfree, NULL);
- g_slist_free (link->src_pads);
- g_slist_free (link->sink_pads);
+ if(rr->element) gst_object_unref(rr->element);
+ gst_parse_strfree (rr->name);
+ g_slist_foreach (rr->pads, (GFunc) gst_parse_strfree, NULL);
+ g_slist_free (rr->pads);
+}
+
+static void gst_parse_free_link (link_t *link)
+{
+ gst_parse_free_reference (&(link->src));
+ gst_parse_free_reference (&(link->sink));
if (link->caps) gst_caps_unref (link->caps);
gst_parse_link_free (link);
}
-static void
-gst_parse_free_delayed_link (DelayedLink *link)
+static void gst_parse_free_chain (chain_t *ch)
+{
+ GSList *walk;
+ gst_parse_free_reference (&(ch->first));
+ gst_parse_free_reference (&(ch->last));
+ for(walk=ch->elements;walk;walk=walk->next)
+ gst_object_unref (walk->data);
+ g_slist_free (ch->elements);
+ gst_parse_chain_free (ch);
+}
+
+static void gst_parse_free_delayed_link (DelayedLink *link)
{
g_free (link->src_pad);
g_free (link->sink_pad);
@@ -496,8 +486,7 @@ gst_parse_free_delayed_link (DelayedLink *link)
g_slice_free (DelayedLink, link);
}
-static void
-gst_parse_found_pad (GstElement *src, GstPad *pad, gpointer data)
+static void gst_parse_found_pad (GstElement *src, GstPad *pad, gpointer data)
{
DelayedLink *link = data;
@@ -564,17 +553,17 @@ gst_parse_perform_delayed_link (GstElement *src, const gchar *src_pad,
static gint
gst_parse_perform_link (link_t *link, graph_t *graph)
{
- GstElement *src = link->src;
- GstElement *sink = link->sink;
- GSList *srcs = link->src_pads;
- GSList *sinks = link->sink_pads;
+ GstElement *src = link->src.element;
+ GstElement *sink = link->sink.element;
+ GSList *srcs = link->src.pads;
+ GSList *sinks = link->sink.pads;
g_assert (GST_IS_ELEMENT (src));
g_assert (GST_IS_ELEMENT (sink));
GST_CAT_INFO (GST_CAT_PIPELINE,
"linking %s:%s to %s:%s (%u/%u) with caps \"%" GST_PTR_FORMAT "\"",
- GST_ELEMENT_NAME (src), link->src_name ? link->src_name : "(any)",
- GST_ELEMENT_NAME (sink), link->sink_name ? link->sink_name : "(any)",
+ GST_ELEMENT_NAME (src), link->src.name ? link->src.name : "(any)",
+ GST_ELEMENT_NAME (sink), link->sink.name ? link->sink.name : "(any)",
g_slist_length (srcs), g_slist_length (sinks), link->caps);
if (!srcs || !sinks) {
@@ -592,7 +581,7 @@ gst_parse_perform_link (link_t *link, graph_t *graph)
}
}
}
- if (g_slist_length (link->src_pads) != g_slist_length (link->sink_pads)) {
+ if (g_slist_length (link->src.pads) != g_slist_length (link->sink.pads)) {
goto error;
}
while (srcs && sinks) {
@@ -631,27 +620,44 @@ static int yyerror (void *scanner, graph_t *graph, const char *s);
%}
%union {
- gchar *s;
- chain_t *c;
- link_t *l;
- GstElement *e;
- GSList *p;
- graph_t *g;
+ gchar *ss;
+ chain_t *cc;
+ link_t *ll;
+ reference_t rr;
+ GstElement *ee;
+ GSList *pp;
+ graph_t *gg;
}
-%token <s> PARSE_URL
-%token <s> IDENTIFIER
-%left <s> REF PADREF BINREF
-%token <s> ASSIGNMENT
-%token <s> LINK
+/* No grammar ambiguities expected, FAIL otherwise */
+%expect 0
+
+%token <ss> PARSE_URL
+%token <ss> IDENTIFIER
+%left <ss> REF PADREF BINREF
+%token <ss> ASSIGNMENT
+%token <ss> LINK
+
+%type <ss> binopener
+%type <gg> graph
+%type <cc> chain bin chainlist openchain elementary
+%type <rr> reference
+%type <ll> link
+%type <ee> element
+%type <pp> morepads pads assignments
+
+%destructor { gst_parse_strfree ($$); } <ss>
+%destructor { if($$)
+ gst_parse_free_chain($$); } <cc>
+%destructor { gst_parse_free_link ($$); } <ll>
+%destructor { gst_parse_free_reference(&($$));} <rr>
+%destructor { gst_object_unref ($$); } <ee>
+%destructor { GSList *walk;
+ for(walk=$$;walk;walk=walk->next)
+ gst_parse_strfree (walk->data);
+ g_slist_free ($$); } <pp>
+
-%type <g> graph
-%type <c> chain bin
-%type <l> reference
-%type <l> linkpart link
-%type <p> linklist
-%type <e> element
-%type <p> padlist pads assignments
%left '(' ')'
%left ','
@@ -666,17 +672,19 @@ static int yyerror (void *scanner, graph_t *graph, const char *s);
%start graph
%%
+/*************************************************************
+* Grammar explanation:
+* _element_s are specified by an identifier of their type.
+* a name can be give in the optional property-assignments
+* coffeeelement
+* fakesrc name=john
+* identity silence=false name=frodo
+* (cont'd)
+**************************************************************/
element: IDENTIFIER { $$ = gst_element_factory_make ($1, NULL);
if ($$ == NULL) {
- ADD_MISSING_ELEMENT (graph, $1);
+ add_missing_element(graph, $1);
SET_ERROR (graph->error, GST_PARSE_ERROR_NO_SUCH_ELEMENT, _("no element \"%s\""), $1);
- /* if FATAL_ERRORS flag is set, we don't have to worry about backwards
- * compatibility and can continue parsing and check for other missing
- * elements */
- if ((graph->flags & GST_PARSE_FLAG_FATAL_ERRORS) == 0) {
- gst_parse_strfree ($1);
- YYERROR;
- }
}
gst_parse_strfree ($1);
}
@@ -684,211 +692,307 @@ element: IDENTIFIER { $$ = gst_element_factory_make ($1, NULL);
$$ = $1;
}
;
-assignments: /* NOP */ { $$ = NULL; }
- | assignments ASSIGNMENT { $$ = g_slist_prepend ($1, $2); }
+
+/*************************************************************
+* Grammar explanation: (cont'd)
+* a graph has (pure) _element_s, _bin_s and _link_s.
+* since bins are special elements, bins and elements can
+* be generalized as _elementary_.
+* The construction of _bin_s will be discussed later.
+* (cont'd)
+*
+**************************************************************/
+elementary:
+ element { $$ = gst_parse_chain_new ();
+ /* g_print ("@%p: CHAINing elementary\n", $$); */
+ $$->first.element = $1? gst_object_ref($1) : NULL;
+ $$->last.element = $1? gst_object_ref($1) : NULL;
+ $$->first.name = $$->last.name = NULL;
+ $$->first.pads = $$->last.pads = NULL;
+ $$->elements = $1 ? g_slist_prepend (NULL, $1) : NULL;
+ }
+ | bin { $$=$1; }
;
-bin: '(' assignments chain ')' { GST_BIN_MAKE ($$, "bin", $3, $2, no_free); }
- | BINREF assignments chain ')' { GST_BIN_MAKE ($$, $1, $3, $2, gst_parse_strfree);
- gst_parse_strfree ($1);
+
+/*************************************************************
+* Grammar explanation: (cont'd)
+* a _chain_ is a list of _elementary_s that have _link_s inbetween
+* which are represented through infix-notation.
+*
+* fakesrc ! sometransformation ! fakesink
+*
+* every _link_ can be augmented with _pads_.
+*
+* coffeesrc .sound ! speakersink
+* multisrc .movie,ads ! .projector,smallscreen multisink
+*
+* and every _link_ can be setup to filter media-types
+* mediasrc ! audio/x-raw, signed=TRUE ! stereosink
+*
+* User HINT:
+* if the lexer does not recognize your media-type it
+* will make it an element name. that results in errors
+* like
+* NO SUCH ELEMENT: no element audio7x-raw
+* '7' vs. '/' in https://en.wikipedia.org/wiki/QWERTZ
+*
+* Parsing HINT:
+* in the parser we need to differ between chains that can
+* be extended by more elementaries (_openchain_) and others
+* that are syntactically closed (handled later in this file).
+* (e.g. fakesrc ! sinkreferencename.padname)
+**************************************************************/
+chain: openchain { $$=$1;
+ if($$->last.name){
+ SET_ERROR (graph->error, GST_PARSE_ERROR_SYNTAX,
+ _("unexpected reference \"%s\" - ignoring"), $$->last.name);
+ gst_parse_strfree($$->last.name);
+ $$->last.name=NULL;
+ }
+ if($$->last.pads){
+ SET_ERROR (graph->error, GST_PARSE_ERROR_SYNTAX,
+ _("unexpected pad-reference \"%s\" - ignoring"), (gchar*)$$->last.pads->data);
+ g_slist_foreach ($$->last.pads, (GFunc) gst_parse_strfree, NULL);
+ g_slist_free ($$->last.pads);
+ $$->last.pads=NULL;
+ }
}
- | BINREF assignments ')' { GST_BIN_MAKE ($$, $1, NULL, $2, gst_parse_strfree);
- gst_parse_strfree ($1);
+ ;
+
+openchain:
+ elementary pads { $$=$1;
+ $$->last.pads = g_slist_concat ($$->last.pads, $2);
+ /* g_print ("@%p@%p: FKI elementary pads\n", $1, $$->last.pads); */
}
- | BINREF assignments error ')' { GST_BIN_MAKE ($$, $1, NULL, $2, gst_parse_strfree);
- gst_parse_strfree ($1);
+ | openchain link pads elementary pads
+ {
+ $2->src = $1->last;
+ $2->sink = $4->first;
+ $2->sink.pads = g_slist_concat ($3, $2->sink.pads);
+ TRY_SETUP_LINK($2);
+ $4->first = $1->first;
+ $4->elements = g_slist_concat ($1->elements, $4->elements);
+ gst_parse_chain_free($1);
+ $$ = $4;
+ $$->last.pads = g_slist_concat ($$->last.pads, $5);
}
+
;
-pads: PADREF { $$ = g_slist_prepend (NULL, $1); }
- | PADREF padlist { $$ = $2;
- $$ = g_slist_prepend ($$, $1);
+link: LINK { $$ = gst_parse_link_new ();
+ $$->src.element = NULL;
+ $$->sink.element = NULL;
+ $$->src.name = NULL;
+ $$->sink.name = NULL;
+ $$->src.pads = NULL;
+ $$->sink.pads = NULL;
+ $$->caps = NULL;
+ if ($1) {
+ $$->caps = gst_caps_from_string ($1);
+ if ($$->caps == NULL)
+ SET_ERROR (graph->error, GST_PARSE_ERROR_LINK, _("could not parse caps \"%s\""), $1);
+ gst_parse_strfree ($1);
+ }
}
;
-padlist: ',' IDENTIFIER { $$ = g_slist_prepend (NULL, $2); }
- | ',' IDENTIFIER padlist { $$ = g_slist_prepend ($3, $2); }
+pads: /* NOP */ { $$ = NULL; }
+ | PADREF morepads { $$ = $2;
+ $$ = g_slist_prepend ($$, $1);
+ }
;
-
-reference: REF { MAKE_REF ($$, $1, NULL); }
- | REF padlist { MAKE_REF ($$, $1, $2); }
+morepads: /* NOP */ { $$ = NULL; }
+ | ',' IDENTIFIER morepads { $$ = g_slist_prepend ($3, $2); }
;
-linkpart: reference { $$ = $1; }
- | pads { MAKE_REF ($$, NULL, $1); }
- | /* NOP */ { MAKE_REF ($$, NULL, NULL); }
+/*************************************************************
+* Grammar explanation: (cont'd)
+* the first and last elements of a _chain_ can be give
+* as URL. This creates special elements that fit the URL.
+*
+* fakesrc ! http://fake-sink.org
+* http://somesource.org ! fakesink
+**************************************************************/
+
+chain: openchain link PARSE_URL { GstElement *element =
+ gst_element_make_from_uri (GST_URI_SINK, $3, NULL, NULL);
+ /* FIXME: get and parse error properly */
+ if (!element) {
+ SET_ERROR (graph->error, GST_PARSE_ERROR_NO_SUCH_ELEMENT,
+ _("no sink element for URI \"%s\""), $3);
+ }
+ $$ = $1;
+ $2->sink.element = element?gst_object_ref(element):NULL;
+ $2->src = $1->last;
+ TRY_SETUP_LINK($2);
+ $$->last.element = NULL;
+ $$->last.name = NULL;
+ $$->last.pads = NULL;
+ if(element) $$->elements = g_slist_append ($$->elements, element);
+ g_free ($3);
+ }
;
-
-link: linkpart LINK linkpart { $$ = $1;
- if ($2) {
- $$->caps = gst_caps_from_string ($2);
- if ($$->caps == NULL)
- SET_ERROR (graph->error, GST_PARSE_ERROR_LINK, _("could not parse caps \"%s\""), $2);
- gst_parse_strfree ($2);
+openchain:
+ PARSE_URL { GstElement *element =
+ gst_element_make_from_uri (GST_URI_SRC, $1, NULL, NULL);
+ /* FIXME: get and parse error properly */
+ if (!element) {
+ SET_ERROR (graph->error, GST_PARSE_ERROR_NO_SUCH_ELEMENT,
+ _("no source element for URI \"%s\""), $1);
}
- $$->sink_name = $3->src_name;
- $$->sink_pads = $3->src_pads;
- gst_parse_link_free ($3);
+ $$ = gst_parse_chain_new ();
+ /* g_print ("@%p: CHAINing srcURL\n", $$); */
+ $$->first.element = NULL;
+ $$->first.name = NULL;
+ $$->first.pads = NULL;
+ $$->last.element = element ? gst_object_ref(element):NULL;
+ $$->last.name = NULL;
+ $$->last.pads = NULL;
+ $$->elements = element ? g_slist_prepend (NULL, element) : NULL;
+ g_free($1);
}
;
-linklist: link { $$ = g_slist_prepend (NULL, $1); }
- | link linklist { $$ = g_slist_prepend ($2, $1); }
- | linklist error { $$ = $1; }
- ;
-chain: element { $$ = gst_parse_chain_new ();
- $$->first = $$->last = $1;
- $$->front = $$->back = NULL;
- $$->elements = g_slist_prepend (NULL, $1);
+/*************************************************************
+* Grammar explanation: (cont'd)
+* the first and last elements of a _chain_ can be linked
+* to a named _reference_ (with optional pads).
+*
+* fakesrc ! nameOfSinkElement.
+* fakesrc ! nameOfSinkElement.Padname
+* fakesrc ! nameOfSinkElement.Padname, anotherPad
+* nameOfSource.Padname ! fakesink
+**************************************************************/
+
+chain: openchain link reference { $$ = $1;
+ $2->sink= $3;
+ $2->src = $1->last;
+ TRY_SETUP_LINK($2);
+ $$->last.element = NULL;
+ $$->last.name = NULL;
+ $$->last.pads = NULL;
}
- | bin { $$ = $1; }
- | chain chain { if ($1->back && $2->front) {
- if (!$1->back->sink_name) {
- SET_ERROR (graph->error, GST_PARSE_ERROR_LINK, _("link without source element"));
- gst_parse_free_link ($1->back);
- } else {
- graph->links = g_slist_prepend (graph->links, $1->back);
- }
- if (!$2->front->src_name) {
- SET_ERROR (graph->error, GST_PARSE_ERROR_LINK, _("link without sink element"));
- gst_parse_free_link ($2->front);
- } else {
- graph->links = g_slist_prepend (graph->links, $2->front);
- }
- $1->back = NULL;
- } else if ($1->back) {
- if (!$1->back->sink_name) {
- $1->back->sink = $2->first;
- }
- } else if ($2->front) {
- if (!$2->front->src_name) {
- $2->front->src = $1->last;
- }
- $1->back = $2->front;
- }
+ ;
- if ($1->back) {
- graph->links = g_slist_prepend (graph->links, $1->back);
- }
- $1->last = $2->last;
- $1->back = $2->back;
- $1->elements = g_slist_concat ($1->elements, $2->elements);
- if ($2)
- gst_parse_chain_free ($2);
- $$ = $1;
+
+openchain:
+ reference { $$ = gst_parse_chain_new ();
+ $$->last=$1;
+ $$->first.element = NULL;
+ $$->first.name = NULL;
+ $$->first.pads = NULL;
+ $$->elements = NULL;
}
- | chain linklist { GSList *walk;
- if ($1->back) {
- $2 = g_slist_prepend ($2, $1->back);
- $1->back = NULL;
- } else {
- if (!((link_t *) $2->data)->src_name) {
- ((link_t *) $2->data)->src = $1->last;
- }
- }
- for (walk = $2; walk; walk = walk->next) {
- link_t *link = (link_t *) walk->data;
- if (!link->sink_name && walk->next) {
- SET_ERROR (graph->error, GST_PARSE_ERROR_LINK, _("link without sink element"));
- gst_parse_free_link (link);
- } else if (!link->src_name && !link->src) {
- SET_ERROR (graph->error, GST_PARSE_ERROR_LINK, _("link without source element"));
- gst_parse_free_link (link);
- } else {
- if (walk->next) {
- graph->links = g_slist_prepend (graph->links, link);
- } else {
- $1->back = link;
- }
- }
+ ;
+reference: REF morepads {
+ gchar *padname = $1;
+ GSList *pads = $2;
+ if (padname) {
+ while (*padname != '.') padname++;
+ *padname = '\0';
+ padname++;
+ if (*padname != '\0')
+ pads = g_slist_prepend (pads, gst_parse_strdup (padname));
}
- g_slist_free ($2);
- $$ = $1;
+ $$.element=NULL;
+ $$.name=$1;
+ $$.pads=pads;
}
- | chain error { $$ = $1; }
- | link chain { if ($2->front) {
- if (!$2->front->src_name) {
- SET_ERROR (graph->error, GST_PARSE_ERROR_LINK, _("link without source element"));
- gst_parse_free_link ($2->front);
- } else {
- graph->links = g_slist_prepend (graph->links, $2->front);
- }
- }
- if (!$1->sink_name) {
- $1->sink = $2->first;
+ ;
+
+
+/*************************************************************
+* Grammar explanation: (cont'd)
+* a _chainlist_ is just a list of _chain_s.
+*
+* You can specify _link_s with named
+* _reference_ on each side. That
+* works already after the explanations above.
+* someSourceName.Pad ! someSinkName.
+* someSourceName.Pad,anotherPad ! someSinkName.Apad,Bpad
+*
+* If a syntax error occurs, the already finished _chain_s
+* and _links_ are kept intact.
+*************************************************************/
+
+chainlist: /* NOP */ { $$ = NULL; }
+ | chainlist chain { if ($1){
+ gst_parse_free_reference(&($1->last));
+ gst_parse_free_reference(&($2->first));
+ $2->first = $1->first;
+ $2->elements = g_slist_concat ($1->elements, $2->elements);
+ gst_parse_chain_free ($1);
}
- $2->front = $1;
$$ = $2;
}
- | PARSE_URL chain { $$ = $2;
- if ($$->front) {
- GstElement *element =
- gst_element_make_from_uri (GST_URI_SRC, $1, NULL, NULL);
- /* FIXME: get and parse error properly */
- if (!element) {
- SET_ERROR (graph->error, GST_PARSE_ERROR_NO_SUCH_ELEMENT,
- _("no source element for URI \"%s\""), $1);
- } else {
- $$->front->src = element;
- graph->links = g_slist_prepend (
- graph->links, $$->front);
- $$->front = NULL;
- $$->elements = g_slist_prepend ($$->elements, element);
- }
- } else {
- SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
- _("no element to link URI \"%s\" to"), $1);
- }
- g_free ($1);
+ | chainlist error { $$=$1;
+ GST_CAT_DEBUG (GST_CAT_PIPELINE,"trying to recover from syntax error");
+ SET_ERROR (graph->error, GST_PARSE_ERROR_SYNTAX, _("syntax error"));
}
- | link PARSE_URL { GstElement *element =
- gst_element_make_from_uri (GST_URI_SINK, $2, NULL, NULL);
- /* FIXME: get and parse error properly */
- if (!element) {
+ ;
+
+/*************************************************************
+* Grammar explanation: (cont'd)
+* _bins_
+*************************************************************/
+
+
+assignments: /* NOP */ { $$ = NULL; }
+ | ASSIGNMENT assignments { $$ = g_slist_prepend ($2, $1); }
+ ;
+
+binopener: '(' { $$ = gst_parse_strdup(_("bin")); }
+ | BINREF { $$ = $1; }
+ ;
+bin: binopener assignments chainlist ')' {
+ chain_t *chain = $3;
+ GSList *walk;
+ GstBin *bin = (GstBin *) gst_element_factory_make ($1, NULL);
+ if (!chain) {
+ SET_ERROR (graph->error, GST_PARSE_ERROR_EMPTY_BIN,
+ _("specified empty bin \"%s\", not allowed"), $1);
+ chain = gst_parse_chain_new ();
+ chain->first.element = chain->last.element = NULL;
+ chain->first.name = chain->last.name = NULL;
+ chain->first.pads = chain->last.pads = NULL;
+ chain->elements = NULL;
+ }
+ if (!bin) {
+ add_missing_element(graph, $1);
SET_ERROR (graph->error, GST_PARSE_ERROR_NO_SUCH_ELEMENT,
- _("no sink element for URI \"%s\""), $2);
- gst_parse_link_free ($1);
- g_free ($2);
- YYERROR;
- } else if ($1->sink_name || $1->sink_pads) {
- gst_object_unref (element);
- SET_ERROR (graph->error, GST_PARSE_ERROR_LINK,
- _("could not link sink element for URI \"%s\""), $2);
- gst_parse_link_free ($1);
- g_free ($2);
- YYERROR;
+ _("no bin \"%s\", unpacking elements"), $1);
+ /* clear property-list */
+ g_slist_foreach ($2, (GFunc) gst_parse_strfree, NULL);
+ g_slist_free ($2);
+ $2 = NULL;
} else {
- $$ = gst_parse_chain_new ();
- $$->first = $$->last = element;
- $$->front = $1;
- $$->front->sink = element;
- $$->elements = g_slist_prepend (NULL, element);
+ for (walk = chain->elements; walk; walk = walk->next )
+ gst_bin_add (bin, GST_ELEMENT (walk->data));
+ g_slist_free (chain->elements);
+ chain->elements = g_slist_prepend (NULL, bin);
}
- g_free ($2);
+ $$ = chain;
+ /* set the properties now
+ * HINT: property-list cleared above, if bin==NULL
+ */
+ for (walk = $2; walk; walk = walk->next)
+ gst_parse_element_set ((gchar *) walk->data,
+ GST_ELEMENT (bin), graph);
+ g_slist_free ($2);
+ gst_parse_strfree ($1);
}
;
-graph: /* NOP */ { SET_ERROR (graph->error, GST_PARSE_ERROR_EMPTY, _("empty pipeline not allowed"));
- $$ = graph;
- }
- | chain { $$ = graph;
- if ($1->front) {
- if (!$1->front->src_name) {
- SET_ERROR (graph->error, GST_PARSE_ERROR_LINK, _("link without source element"));
- gst_parse_free_link ($1->front);
- } else {
- $$->links = g_slist_prepend ($$->links, $1->front);
- }
- $1->front = NULL;
- }
- if ($1->back) {
- if (!$1->back->sink_name) {
- SET_ERROR (graph->error, GST_PARSE_ERROR_LINK, _("link without sink element"));
- gst_parse_free_link ($1->back);
- } else {
- $$->links = g_slist_prepend ($$->links, $1->back);
- }
- $1->back = NULL;
- }
+
+/*************************************************************
+* Grammar explanation: (cont'd)
+* _graph_
+*************************************************************/
+
+graph: chainlist { $$ = graph;
$$->chain = $1;
+ if(!$1) {
+ SET_ERROR (graph->error, GST_PARSE_ERROR_EMPTY, _("empty pipeline not allowed"));
+ }
}
;
@@ -929,11 +1033,13 @@ priv_gst_parse_launch (const gchar *str, GError **error, GstParseContext *ctx,
__strings = __chains = __links = 0;
#endif /* __GST_PARSE_TRACE */
+ /* g_print("Now scanning: %s\n", str); */
+
dstr = g_strdup (str);
priv_gst_parse_yylex_init (&scanner);
priv_gst_parse_yy_scan_string (dstr, scanner);
-#ifndef YYDEBUG
+#if YYDEBUG
yydebug = 1;
#endif
@@ -953,17 +1059,25 @@ priv_gst_parse_launch (const gchar *str, GError **error, GstParseContext *ctx,
g.chain ? g_slist_length (g.chain->elements) : 0,
g_slist_length (g.links));
- if (!g.chain) {
- ret = NULL;
- } else if (!g.chain->elements->next) {
- /* only one toplevel element */
- ret = (GstElement *) g.chain->elements->data;
- g_slist_free (g.chain->elements);
- if (GST_IS_BIN (ret))
- bin = GST_BIN (ret);
- gst_parse_chain_free (g.chain);
- } else {
- /* put all elements in our bin */
+ /* ensure chain is not NULL */
+ if (!g.chain){
+ g.chain=gst_parse_chain_new ();
+ g.chain->elements=NULL;
+ g.chain->first.element=NULL;
+ g.chain->first.name=NULL;
+ g.chain->first.pads=NULL;
+ g.chain->last.element=NULL;
+ g.chain->last.name=NULL;
+ g.chain->last.pads=NULL;
+ };
+
+ /* ensure elements is not empty */
+ if(!g.chain->elements){
+ g.chain->elements= g_slist_prepend (NULL, NULL);
+ };
+
+ /* put all elements in our bin if necessary */
+ if(g.chain->elements->next){
bin = GST_BIN (gst_element_factory_make ("pipeline", NULL));
g_assert (bin);
@@ -971,56 +1085,49 @@ priv_gst_parse_launch (const gchar *str, GError **error, GstParseContext *ctx,
if (walk->data != NULL)
gst_bin_add (bin, GST_ELEMENT (walk->data));
}
-
g_slist_free (g.chain->elements);
- ret = GST_ELEMENT (bin);
- gst_parse_chain_free (g.chain);
- }
+ g.chain->elements = g_slist_prepend (NULL, bin);
+ }
+
+ ret = (GstElement *) g.chain->elements->data;
+ g_slist_free (g.chain->elements);
+ g.chain->elements=NULL;
+ if (GST_IS_BIN (ret))
+ bin = GST_BIN (ret);
+ gst_parse_free_chain (g.chain);
+ g.chain = NULL;
- /* remove links */
+
+ /* resolve and perform links */
for (walk = g.links; walk; walk = walk->next) {
link_t *l = (link_t *) walk->data;
- if (!l->src) {
- if (l->src_name) {
- if (bin) {
- l->src = gst_bin_get_by_name_recurse_up (bin, l->src_name);
- if (l->src)
- gst_object_unref (l->src);
- } else {
- l->src = strcmp (GST_ELEMENT_NAME (ret), l->src_name) == 0 ? ret : NULL;
- }
- }
- if (!l->src) {
- if (l->src_name) {
+ int err;
+ err=gst_resolve_reference( &(l->src), ret);
+ if (err) {
+ if(-1==err){
SET_ERROR (error, GST_PARSE_ERROR_NO_SUCH_ELEMENT,
- "No element named \"%s\" - omitting link", l->src_name);
- } else {
+ "No src-element named \"%s\" - omitting link", l->src.name);
+ }else{
/* probably a missing element which we've handled already */
- }
- gst_parse_free_link (l);
- continue;
- }
+ SET_ERROR (error, GST_PARSE_ERROR_NO_SUCH_ELEMENT,
+ "No src-element found - omitting link");
+ }
+ gst_parse_free_link (l);
+ continue;
}
- if (!l->sink) {
- if (l->sink_name) {
- if (bin) {
- l->sink = gst_bin_get_by_name_recurse_up (bin, l->sink_name);
- if (l->sink)
- gst_object_unref (l->sink);
- } else {
- l->sink = strcmp (GST_ELEMENT_NAME (ret), l->sink_name) == 0 ? ret : NULL;
- }
- }
- if (!l->sink) {
- if (l->sink_name) {
+
+ err=gst_resolve_reference( &(l->sink), ret);
+ if (err) {
+ if(-1==err){
SET_ERROR (error, GST_PARSE_ERROR_NO_SUCH_ELEMENT,
- "No element named \"%s\" - omitting link", l->sink_name);
- } else {
+ "No sink-element named \"%s\" - omitting link", l->src.name);
+ }else{
/* probably a missing element which we've handled already */
- }
- gst_parse_free_link (l);
- continue;
- }
+ SET_ERROR (error, GST_PARSE_ERROR_NO_SUCH_ELEMENT,
+ "No sink-element found - omitting link");
+ }
+ gst_parse_free_link (l);
+ continue;
}
gst_parse_perform_link (l, &g);
}
@@ -1041,9 +1148,8 @@ out:
error1:
if (g.chain) {
- g_slist_foreach (g.chain->elements, (GFunc)gst_object_unref, NULL);
- g_slist_free (g.chain->elements);
- gst_parse_chain_free (g.chain);
+ gst_parse_free_chain (g.chain);
+ g.chain=NULL;
}
g_slist_foreach (g.links, (GFunc)gst_parse_free_link, NULL);
diff --git a/gst/parse/parse.l b/gst/parse/parse.l
index bcd6527..53afba8 100644
--- a/gst/parse/parse.l
+++ b/gst/parse/parse.l
@@ -11,6 +11,22 @@
#include "../gsturi.h"
#include "grammar.tab.h"
+#ifdef malloc
+#undef malloc
+#endif
+
+#ifdef free
+#undef free
+#endif
+
+#ifdef realloc
+#undef realloc
+#endif
+
+#define malloc g_malloc
+#define free g_free
+#define realloc g_realloc
+
/* Override the default ECHO so as to avoid fortify warnings. Ignore the
embedded-NUL case for now. We know yytext is NUL-terminated. */
#define ECHO g_fprintf(yyout, "%s", yytext)
@@ -73,7 +89,7 @@ _link ("!"[[:space:]]*{_caps}([[:space:]]*(";"[[:space:]]*{_caps})*[[:space:]]*)
{_assignment} {
/* "=" */
PRINT ("ASSIGNMENT: %s", yytext);
- yylval->s = gst_parse_strdup (yytext);
+ yylval->ss = gst_parse_strdup (yytext);
BEGIN (INITIAL);
return ASSIGNMENT;
}
@@ -81,14 +97,14 @@ _link ("!"[[:space:]]*{_caps}([[:space:]]*(";"[[:space:]]*{_caps})*[[:space:]]*)
{_padref} {
yytext++;
PRINT ("PADREF: %s", yytext);
- yylval->s = gst_parse_strdup (yytext);
+ yylval->ss = gst_parse_strdup (yytext);
BEGIN (INITIAL);
return PADREF;
}
{_ref} {
PRINT ("REF: %s", yytext);
- yylval->s = gst_parse_strdup (yytext);
+ yylval->ss = gst_parse_strdup (yytext);
BEGIN (INITIAL);
return REF;
}
@@ -98,14 +114,14 @@ _link ("!"[[:space:]]*{_caps}([[:space:]]*(";"[[:space:]]*{_caps})*[[:space:]]*)
while (!g_ascii_isspace (*pos) && (*pos != '.')) pos++;
*pos = '\0';
PRINT ("BINREF: %s", yytext);
- yylval->s = gst_parse_strdup (yytext);
+ yylval->ss = gst_parse_strdup (yytext);
BEGIN (INITIAL);
return BINREF;
}
{_identifier} {
PRINT ("IDENTIFIER: %s", yytext);
- yylval->s = gst_parse_strdup (yytext);
+ yylval->ss = gst_parse_strdup (yytext);
BEGIN (INITIAL);
return IDENTIFIER;
}
@@ -116,22 +132,22 @@ _link ("!"[[:space:]]*{_caps}([[:space:]]*(";"[[:space:]]*{_caps})*[[:space:]]*)
c++;
if (*c) {
while (g_ascii_isspace (*c)) c++;
- c = yylval->s = gst_parse_strdup (c);
+ c = yylval->ss = gst_parse_strdup (c);
while (*c) c++;
if (*--c != '!')
g_assert_not_reached ();
while (g_ascii_isspace (*--c));
*++c = '\0';
} else {
- yylval->s = NULL;
+ yylval->ss = NULL;
}
BEGIN (INITIAL);
return LINK;
}
{_url} {
PRINT ("URL: %s", yytext);
- yylval->s = g_strdup (yytext);
- gst_parse_unescape (yylval->s);
+ yylval->ss = g_strdup (yytext);
+ gst_parse_unescape (yylval->ss);
BEGIN (INITIAL);
return PARSE_URL;
}
diff --git a/gst/parse/types.h b/gst/parse/types.h
index 79a14c6..fbeaf20 100644
--- a/gst/parse/types.h
+++ b/gst/parse/types.h
@@ -6,21 +6,21 @@
#include "../gstparse.h"
typedef struct {
- GstElement *src;
- GstElement *sink;
- gchar *src_name;
- gchar *sink_name;
- GSList *src_pads;
- GSList *sink_pads;
+ GstElement *element;
+ gchar *name;
+ GSList *pads;
+} reference_t;
+
+typedef struct {
+ reference_t src;
+ reference_t sink;
GstCaps *caps;
} link_t;
typedef struct {
GSList *elements;
- GstElement *first;
- GstElement *last;
- link_t *front;
- link_t *back;
+ reference_t first;
+ reference_t last;
} chain_t;
typedef struct _graph_t graph_t;
@@ -38,17 +38,21 @@ struct _graph_t {
* doesn't really work.
* This is not safe from reentrance issues, but that doesn't matter as long as
* we lock a mutex before parsing anyway.
+ *
+ * FIXME: Disable this for now for the above reasons
*/
+#if 0
#ifdef GST_DEBUG_ENABLED
# define __GST_PARSE_TRACE
#endif
+#endif
#ifdef __GST_PARSE_TRACE
G_GNUC_INTERNAL gchar *__gst_parse_strdup (gchar *org);
G_GNUC_INTERNAL void __gst_parse_strfree (gchar *str);
-G_GNUC_INTERNAL link_t *__gst_parse_link_new ();
+G_GNUC_INTERNAL link_t *__gst_parse_link_new (void);
G_GNUC_INTERNAL void __gst_parse_link_free (link_t *data);
-G_GNUC_INTERNAL chain_t *__gst_parse_chain_new ();
+G_GNUC_INTERNAL chain_t *__gst_parse_chain_new (void);
G_GNUC_INTERNAL void __gst_parse_chain_free (chain_t *data);
# define gst_parse_strdup __gst_parse_strdup
# define gst_parse_strfree __gst_parse_strfree
@@ -59,10 +63,10 @@ G_GNUC_INTERNAL void __gst_parse_chain_free (chain_t *data);
#else /* __GST_PARSE_TRACE */
# define gst_parse_strdup g_strdup
# define gst_parse_strfree g_free
-# define gst_parse_link_new() g_new0 (link_t, 1)
-# define gst_parse_link_free g_free
-# define gst_parse_chain_new() g_new0 (chain_t, 1)
-# define gst_parse_chain_free g_free
+# define gst_parse_link_new() g_slice_new0 (link_t)
+# define gst_parse_link_free(l) g_slice_free (link_t, l)
+# define gst_parse_chain_new() g_slice_new0 (chain_t)
+# define gst_parse_chain_free(c) g_slice_free (chain_t, c)
#endif /* __GST_PARSE_TRACE */
static inline void
diff --git a/gst/printf/Makefile.in b/gst/printf/Makefile.in
index 895cb68..092dcea 100644
--- a/gst/printf/Makefile.in
+++ b/gst/printf/Makefile.in
@@ -88,7 +88,6 @@ am__aclocal_m4_deps = $(top_srcdir)/common/m4/as-ac-expand.m4 \
$(top_srcdir)/common/m4/as-compiler-flag.m4 \
$(top_srcdir)/common/m4/as-docbook.m4 \
$(top_srcdir)/common/m4/as-libtool.m4 \
- $(top_srcdir)/common/m4/as-scrub-include.m4 \
$(top_srcdir)/common/m4/as-version.m4 \
$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
$(top_srcdir)/common/m4/gst-arch.m4 \