summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Matthew <notverysmart@gmail.com>2008-08-06 15:34:55 +0000
committerSebastian Dröge <slomo@circular-chaos.org>2008-08-06 15:34:55 +0000
commit8ced1b35ff4080df103333b58caa27ae86c78f2a (patch)
treeef3db0a72db35975417de4b94a7ec0f8191c9cef
parentdfd580b2075a15b0a7994d31287d9d8bfc13a954 (diff)
ext/flac/: Port flactag to 0.10, add documentation for it and clean it up a bit.
Original commit message from CVS: Based on a patch by: Jonathan Matthew <notverysmart at gmail dot com> * ext/flac/Makefile.am: * ext/flac/gstflac.c: (plugin_init): * ext/flac/gstflactag.c: (gst_flac_tag_setup_interfaces), (gst_flac_tag_base_init), (gst_flac_tag_class_init), (gst_flac_tag_dispose), (gst_flac_tag_init), (gst_flac_tag_sink_setcaps), (gst_flac_tag_chain), (gst_flac_tag_change_state): * ext/flac/gstflactag.h: Port flactag to 0.10, add documentation for it and clean it up a bit. Fixes bug #413841. * docs/plugins/Makefile.am: * docs/plugins/gst-plugins-good-plugins-docs.sgml: * docs/plugins/gst-plugins-good-plugins-sections.txt: * docs/plugins/gst-plugins-good-plugins.hierarchy: * docs/plugins/gst-plugins-good-plugins.interfaces: * docs/plugins/gst-plugins-good-plugins.prerequisites: * docs/plugins/inspect/plugin-flac.xml: * ext/flac/gstflacdec.c: (gst_flac_dec_base_init): * ext/flac/gstflacdec.h: * ext/flac/gstflacenc.c: (gst_flac_enc_base_init): * ext/flac/gstflacenc.h: Add flactag and flacenc to the documentation and mark the private parts of the flacdec instance structure as private. Also use gst_element_class_set_details_simple() in flacdec and flacenc.
-rw-r--r--ChangeLog32
-rw-r--r--docs/plugins/Makefile.am2
-rw-r--r--docs/plugins/gst-plugins-good-plugins-docs.sgml2
-rw-r--r--docs/plugins/gst-plugins-good-plugins-sections.txt28
-rw-r--r--docs/plugins/gst-plugins-good-plugins.hierarchy231
-rw-r--r--docs/plugins/gst-plugins-good-plugins.interfaces47
-rw-r--r--docs/plugins/gst-plugins-good-plugins.prerequisites6
-rw-r--r--docs/plugins/inspect/plugin-flac.xml39
-rw-r--r--ext/flac/Makefile.am4
-rw-r--r--ext/flac/gstflac.c4
-rw-r--r--ext/flac/gstflacdec.c12
-rw-r--r--ext/flac/gstflacdec.h2
-rw-r--r--ext/flac/gstflacenc.c11
-rw-r--r--ext/flac/gstflacenc.h2
-rw-r--r--ext/flac/gstflactag.c460
-rw-r--r--ext/flac/gstflactag.h72
16 files changed, 497 insertions, 457 deletions
diff --git a/ChangeLog b/ChangeLog
index 17664d47..3ed39f6c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2008-08-06 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+
+ Based on a patch by: Jonathan Matthew <notverysmart at gmail dot com>
+
+ * ext/flac/Makefile.am:
+ * ext/flac/gstflac.c: (plugin_init):
+ * ext/flac/gstflactag.c: (gst_flac_tag_setup_interfaces),
+ (gst_flac_tag_base_init), (gst_flac_tag_class_init),
+ (gst_flac_tag_dispose), (gst_flac_tag_init),
+ (gst_flac_tag_sink_setcaps), (gst_flac_tag_chain),
+ (gst_flac_tag_change_state):
+ * ext/flac/gstflactag.h:
+ Port flactag to 0.10, add documentation for it and clean it up a bit.
+ Fixes bug #413841.
+
+ * docs/plugins/Makefile.am:
+ * docs/plugins/gst-plugins-good-plugins-docs.sgml:
+ * docs/plugins/gst-plugins-good-plugins-sections.txt:
+ * docs/plugins/gst-plugins-good-plugins.hierarchy:
+ * docs/plugins/gst-plugins-good-plugins.interfaces:
+ * docs/plugins/gst-plugins-good-plugins.prerequisites:
+ * docs/plugins/inspect/plugin-flac.xml:
+ * ext/flac/gstflacdec.c: (gst_flac_dec_base_init):
+ * ext/flac/gstflacdec.h:
+ * ext/flac/gstflacenc.c: (gst_flac_enc_base_init):
+ * ext/flac/gstflacenc.h:
+ Add flactag and flacenc to the documentation and mark
+ the private parts of the flacdec instance structure as private.
+
+ Also use gst_element_class_set_details_simple() in flacdec and
+ flacenc.
+
2008-08-06 Stefan Kost <ensonic@users.sf.net>
* gst/qtdemux/qtdemux.c:
diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am
index 2eebe763..b5cb41af 100644
--- a/docs/plugins/Makefile.am
+++ b/docs/plugins/Makefile.am
@@ -84,6 +84,8 @@ EXTRA_HFILES = \
$(top_srcdir)/ext/dv/gstdvdemux.h \
$(top_srcdir)/ext/esd/esdsink.h \
$(top_srcdir)/ext/flac/gstflacdec.h \
+ $(top_srcdir)/ext/flac/gstflacenc.h \
+ $(top_srcdir)/ext/flac/gstflactag.h \
$(top_srcdir)/ext/gdk_pixbuf/gstgdkpixbufsink.h \
$(top_srcdir)/ext/hal/gsthalaudiosink.h \
$(top_srcdir)/ext/hal/gsthalaudiosrc.h \
diff --git a/docs/plugins/gst-plugins-good-plugins-docs.sgml b/docs/plugins/gst-plugins-good-plugins-docs.sgml
index f54d1330..72b54c5b 100644
--- a/docs/plugins/gst-plugins-good-plugins-docs.sgml
+++ b/docs/plugins/gst-plugins-good-plugins-docs.sgml
@@ -46,6 +46,8 @@
<xi:include href="xml/element-equalizer-nbands.xml" />
<xi:include href="xml/element-esdsink.xml" />
<xi:include href="xml/element-flacdec.xml" />
+ <xi:include href="xml/element-flacenc.xml" />
+ <xi:include href="xml/element-flactag.xml" />
<xi:include href="xml/element-gamma.xml" />
<xi:include href="xml/element-gdkpixbufsink.xml" />
<xi:include href="xml/element-goom.xml" />
diff --git a/docs/plugins/gst-plugins-good-plugins-sections.txt b/docs/plugins/gst-plugins-good-plugins-sections.txt
index 60b3ba40..712c0c8d 100644
--- a/docs/plugins/gst-plugins-good-plugins-sections.txt
+++ b/docs/plugins/gst-plugins-good-plugins-sections.txt
@@ -539,6 +539,34 @@ LEGACY_FLAC
</SECTION>
<SECTION>
+<FILE>element-flacenc</FILE>
+<TITLE>flacenc</TITLE>
+GstFlacEnc
+<SUBSECTION Standard>
+GstFlacEncClass
+GST_TYPE_FLAC_ENC
+GST_FLAC_ENC
+GST_FLAC_ENC_CLASS
+GST_IS_FLAC_ENC
+GST_IS_FLAC_ENC_CLASS
+gst_flac_enc_get_type
+</SECTION>
+
+<SECTION>
+<FILE>element-flactag</FILE>
+<TITLE>flactag</TITLE>
+GstFlacTag
+<SUBSECTION Standard>
+GstFlacTagClass
+GST_TYPE_FLAC_TAG
+GST_FLAC_TAG
+GST_FLAC_TAG_CLASS
+GST_IS_FLAC_TAG
+GST_IS_FLAC_TAG_CLASS
+gst_flac_tag_get_type
+</SECTION>
+
+<SECTION>
<FILE>element-gamma</FILE>
<TITLE>gamma</TITLE>
GstGamma
diff --git a/docs/plugins/gst-plugins-good-plugins.hierarchy b/docs/plugins/gst-plugins-good-plugins.hierarchy
index ef19bd52..78d644e3 100644
--- a/docs/plugins/gst-plugins-good-plugins.hierarchy
+++ b/docs/plugins/gst-plugins-good-plugins.hierarchy
@@ -11,34 +11,89 @@ GObject
GstElement
GstBin
GstPipeline
- GstRTSPSrc
- GstRgVolume
- GstAutoVideoSink
- GstAutoAudioSink
+ GstHalAudioSink
+ GstHalAudioSrc
GstGConfVideoSink
GstGConfVideoSrc
GstSwitchSink
GstGConfAudioSink
GstGConfAudioSrc
- GstHalAudioSink
- GstHalAudioSrc
- GstAviDemux
- GstAviMux
- GstAviSubtitle
- GstGoom2k1
- GstEbmlRead
- GstMatroskaDemux
- GstMatroskaMux
- GstFlxDec
+ GstAutoVideoSink
+ GstAutoAudioSink
+ GstRgVolume
+ GstRTSPSrc
+ GstPngDec
+ GstPngEnc
+ GstJpegEnc
+ GstJpegDec
+ GstSmokeEnc
+ GstSmokeDec
+ GstBaseSink
+ GstBaseAudioSink
+ GstAudioSink
+ GstEsdSink
+ GstPulseSink
+ GstOssSink
+ GstAASink
+ GstCACASink
+ GstVideoSink
+ GstGdkPixbufSink
+ GstShout2send
+ GstTest
+ GstMultiUDPSink
+ GstUDPSink
+ GstDynUDPSink
+ GstMultiFileSink
+ GstCmmlEnc
+ GstCmmlDec
+ GstWavpackParse
+ GstWavpackDec
+ GstWavpackEnc
+ GstBaseSrc
+ GstPushSrc
+ GstDV1394Src
+ GstSoupHTTPSrc
+ GstBaseAudioSrc
+ GstAudioSrc
+ GstPulseSrc
+ GstOssSrc
+ GstCddaBaseSrc
+ GstCdioCddaSrc
+ GstV4l2Src
+ GstXImageSrc
+ GstUDPSrc
+ GstMultiFileSrc
+ GstPulseMixer
+ GstFlacEnc
+ GstFlacDec
+ GstFlacTag
+ GstCairoTextOverlay
GstBaseTransform
+ GstCairoTimeOverlay
+ GstPixbufScale
GstVideoCrop
+ GstAudioFilter
+ GstSpectrum
+ GstIirEqualizer
+ GstIirEqualizerNBands
+ GstIirEqualizer3Bands
+ GstIirEqualizer10Bands
+ GstAudioInvert
+ GstAudioKaraoke
+ GstAudioAmplify
+ GstAudioDynamic
+ GstAudioChebLimit
+ GstAudioChebBand
+ GstAudioWSincLimit
+ GstAudioWSincBand
GstVideoBox
+ GstLevel
GstVideoFilter
- GstSMPTEAlpha
GstNavigationtest
GstGamma
- GstVideoFlip
GstVideoBalance
+ GstVideoFlip
+ GstSMPTEAlpha
GstEdgeTV
GstAgingTV
GstDiceTV
@@ -52,77 +107,46 @@ GObject
GstProgressReport
GstTagInject
GstAudioPanorama
- GstAudioFilter
- GstAudioInvert
- GstAudioKaraoke
- GstAudioAmplify
- GstAudioDynamic
- GstAudioChebLimit
- GstAudioChebBand
- GstAudioWSincLimit
- GstAudioWSincBand
- GstIirEqualizer
- GstIirEqualizerNBands
- GstIirEqualizer3Bands
- GstIirEqualizer10Bands
- GstSpectrum
- GstAlphaColor
- GstAlpha
GstRgAnalysis
GstRgLimiter
- GstLevel
- GstPixbufScale
- GstCairoTimeOverlay
- GstMonoscope
- GstAuParse
+ GstAlphaColor
+ GstAlpha
+ GstDVDemux
+ GstDVDec
+ GstGdkPixbuf
+ GstSpeexEnc
+ GstSpeexDec
+ GstTagLibMux
+ GstId3v2Mux
+ GstApev2Mux
+ GstOssMixerElement
+ GstCutter
+ GstAviDemux
+ GstAviMux
+ GstAviSubtitle
+ GstGoom2k1
+ GstALawEnc
+ GstALawDec
+ GstMuLawEnc
+ GstMuLawDec
+ GstWavEnc
+ GstWavParse
+ GstICYDemux
GstVideoMixer
- GstBaseSrc
- GstPushSrc
- GstMultiFileSrc
- GstUDPSrc
- GstXImageSrc
- GstV4l2Src
- GstBaseAudioSrc
- GstAudioSrc
- GstOssSrc
- GstPulseSrc
- GstDV1394Src
- GstSoupHTTPSrc
- GstCddaBaseSrc
- GstCdioCddaSrc
- GstBaseSink
- GstMultiFileSink
- GstMultiUDPSink
- GstUDPSink
- GstDynUDPSink
- GstTest
- GstBaseAudioSink
- GstAudioSink
- GstOssSink
- GstPulseSink
- GstEsdSink
- GstAASink
- GstVideoSink
- GstGdkPixbufSink
- GstCACASink
- GstShout2send
- GstInterleave
- GstDeinterleave
- GstRTPDec
- GstSMPTE
GstRndBufferSize
GstEFence
+ GstFlxDec
GstTagDemux
GstApeDemux
GstID3Demux
- GstGoom
+ GstAuParse
+ GstSMPTE
GstMultipartDemux
GstMultipartMux
- GstCutter
- GstWavParse
- GstQTDemux
+ GstInterleave
+ GstDeinterleave
+ GstRTPDepay
GstBaseRTPDepayload
- GstRtpXQTDepay
GstRtpAC3Depay
GstRTPDVDepay
GstRTPiLBCDepay
@@ -147,12 +171,7 @@ GObject
GstRtpTheoraDepay
GstRtpVorbisDepay
GstRtpVRawDepay
- GstMuLawEnc
- GstMuLawDec
- GstALawEnc
- GstALawDec
- GstICYDemux
- GstRTPDepay
+ GstRtpXQTDepay
GstBaseRTPPayload
GstRTPDVPay
GstBaseRTPAudioPayload
@@ -177,31 +196,13 @@ GObject
GstRtpVorbisPay
GstRtpVRawPay
GstAsteriskh263
- GstWavEnc
- GstOssMixerElement
- GstDVDemux
- GstDVDec
- GstSpeexEnc
- GstSpeexDec
- GstCmmlEnc
- GstCmmlDec
- GstGdkPixbuf
- GstWavpackParse
- GstWavpackDec
- GstWavpackEnc
- GstPngDec
- GstPngEnc
- GstCairoTextOverlay
- GstTagLibMux
- GstId3v2Mux
- GstApev2Mux
- GstFlacEnc
- GstFlacDec
- GstPulseMixer
- GstJpegEnc
- GstJpegDec
- GstSmokeEnc
- GstSmokeDec
+ GstRTPDec
+ GstEbmlRead
+ GstMatroskaDemux
+ GstMatroskaMux
+ GstMonoscope
+ GstGoom
+ GstQTDemux
GstBus
GstTask
GstClock
@@ -211,23 +212,21 @@ GObject
GstRegistry
GstRingBuffer
GstSignalObject
- GstColorBalanceChannel
- GstTunerNorm
- GstTunerChannel
- GstMixerTrack
- GstMixerOptions
GstCmmlTagStream
GstCmmlTagHead
GstCmmlTagClip
GdkPixbuf
+ GstTunerNorm
+ GstTunerChannel
+ GstColorBalanceChannel
GInterface
GTypePlugin
GstChildProxy
GstURIHandler
- GstTagSetter
+ GstPropertyProbe
GstImplementsInterface
- GstColorBalance
+ GstMixer
+ GstTagSetter
GstTuner
+ GstColorBalance
GstVideoOrientation
- GstPropertyProbe
- GstMixer
diff --git a/docs/plugins/gst-plugins-good-plugins.interfaces b/docs/plugins/gst-plugins-good-plugins.interfaces
index 252a2a39..c431d34f 100644
--- a/docs/plugins/gst-plugins-good-plugins.interfaces
+++ b/docs/plugins/gst-plugins-good-plugins.interfaces
@@ -1,38 +1,39 @@
GstBin GstChildProxy
GstPipeline GstChildProxy
-GstRTSPSrc GstChildProxy GstURIHandler
-GstRgVolume GstChildProxy
-GstAutoVideoSink GstChildProxy
-GstAutoAudioSink GstChildProxy
+GstHalAudioSink GstChildProxy
+GstHalAudioSrc GstChildProxy
GstGConfVideoSink GstChildProxy
GstGConfVideoSrc GstChildProxy
GstSwitchSink GstChildProxy
GstGConfAudioSink GstChildProxy
GstGConfAudioSrc GstChildProxy
-GstHalAudioSink GstChildProxy
-GstHalAudioSrc GstChildProxy
-GstAviMux GstTagSetter
-GstMatroskaMux GstTagSetter
-GstVideoBalance GstImplementsInterface GstColorBalance
-GstIirEqualizer GstChildProxy
-GstIirEqualizerNBands GstChildProxy
-GstIirEqualizer3Bands GstChildProxy
-GstIirEqualizer10Bands GstChildProxy
-GstVideoMixer GstChildProxy
-GstUDPSrc GstURIHandler
-GstV4l2Src GstImplementsInterface GstColorBalance GstTuner GstVideoOrientation GstPropertyProbe
-GstOssSrc GstImplementsInterface GstMixer
-GstPulseSrc GstImplementsInterface GstMixer
+GstAutoVideoSink GstChildProxy
+GstAutoAudioSink GstChildProxy
+GstRgVolume GstChildProxy
+GstRTSPSrc GstChildProxy GstURIHandler
+GstShout2send GstTagSetter
+GstUDPSink GstURIHandler
GstDV1394Src GstURIHandler GstPropertyProbe
GstSoupHTTPSrc GstURIHandler
+GstPulseSrc GstImplementsInterface GstMixer
+GstOssSrc GstImplementsInterface GstMixer
GstCddaBaseSrc GstURIHandler
GstCdioCddaSrc GstURIHandler
-GstUDPSink GstURIHandler
-GstShout2send GstTagSetter
-GstOssMixerElement GstImplementsInterface GstMixer
+GstV4l2Src GstPropertyProbe GstImplementsInterface GstTuner GstColorBalance GstVideoOrientation
+GstUDPSrc GstURIHandler
+GstPulseMixer GstPropertyProbe GstImplementsInterface GstMixer
+GstFlacEnc GstTagSetter
+GstFlacTag GstTagSetter
+GstIirEqualizer GstChildProxy
+GstIirEqualizerNBands GstChildProxy
+GstIirEqualizer3Bands GstChildProxy
+GstIirEqualizer10Bands GstChildProxy
+GstVideoBalance GstImplementsInterface GstColorBalance
GstSpeexEnc GstTagSetter
GstTagLibMux GstTagSetter
GstId3v2Mux GstTagSetter
GstApev2Mux GstTagSetter
-GstFlacEnc GstTagSetter
-GstPulseMixer GstImplementsInterface GstMixer GstPropertyProbe
+GstOssMixerElement GstImplementsInterface GstMixer
+GstAviMux GstTagSetter
+GstVideoMixer GstChildProxy
+GstMatroskaMux GstTagSetter
diff --git a/docs/plugins/gst-plugins-good-plugins.prerequisites b/docs/plugins/gst-plugins-good-plugins.prerequisites
index a33abde0..eb1fa169 100644
--- a/docs/plugins/gst-plugins-good-plugins.prerequisites
+++ b/docs/plugins/gst-plugins-good-plugins.prerequisites
@@ -1,7 +1,7 @@
GstChildProxy GstObject
-GstTagSetter GstObject GstElement
GstImplementsInterface GstObject GstElement
-GstColorBalance GstObject GstImplementsInterface GstElement
+GstMixer GstObject GstImplementsInterface GstElement
+GstTagSetter GstObject GstElement
GstTuner GstObject GstImplementsInterface GstElement
+GstColorBalance GstObject GstImplementsInterface GstElement
GstVideoOrientation GstObject GstImplementsInterface GstElement
-GstMixer GstObject GstImplementsInterface GstElement
diff --git a/docs/plugins/inspect/plugin-flac.xml b/docs/plugins/inspect/plugin-flac.xml
index 616fbb57..ab534c1e 100644
--- a/docs/plugins/inspect/plugin-flac.xml
+++ b/docs/plugins/inspect/plugin-flac.xml
@@ -3,10 +3,10 @@
<description>The FLAC Lossless compressor Codec</description>
<filename>../../ext/flac/.libs/libgstflac.so</filename>
<basename>libgstflac.so</basename>
- <version>0.10.9</version>
+ <version>0.10.9.1</version>
<license>LGPL</license>
<source>gst-plugins-good</source>
- <package>GStreamer Good Plug-ins source release</package>
+ <package>GStreamer Good Plug-ins CVS/prerelease</package>
<origin>Unknown package origin</origin>
<elements>
<element>
@@ -17,16 +17,16 @@
<author>Wim Taymans &lt;wim@fluendo.com&gt;</author>
<pads>
<caps>
- <name>sink</name>
- <direction>sink</direction>
+ <name>src</name>
+ <direction>source</direction>
<presence>always</presence>
- <details>audio/x-flac</details>
+ <details>audio/x-raw-int, endianness=(int)1234, signed=(boolean)true, width=(int){ 8, 16, 32 }, depth=(int)[ 4, 32 ], rate=(int)[ 1, 655350 ], channels=(int)[ 1, 8 ]</details>
</caps>
<caps>
- <name>src</name>
- <direction>source</direction>
+ <name>sink</name>
+ <direction>sink</direction>
<presence>always</presence>
- <details>audio/x-raw-int, endianness=(int)1234, signed=(boolean)true, width=(int){ 8, 16, 32 }, depth=(int){ 8, 12, 16, 20, 24, 32 }, rate=(int)[ 8000, 96000 ], channels=(int)[ 1, 8 ]</details>
+ <details>audio/x-flac</details>
</caps>
</pads>
</element>
@@ -38,6 +38,27 @@
<author>Wim Taymans &lt;wim.taymans@chello.be&gt;</author>
<pads>
<caps>
+ <name>sink</name>
+ <direction>sink</direction>
+ <presence>always</presence>
+ <details>audio/x-raw-int, endianness=(int)1234, signed=(boolean)true, width=(int)8, depth=(int)8, rate=(int)[ 1, 655350 ], channels=(int)[ 1, 8 ]; audio/x-raw-int, endianness=(int)1234, signed=(boolean)true, width=(int)16, depth=(int){ 12, 16 }, rate=(int)[ 1, 655350 ], channels=(int)[ 1, 8 ]; audio/x-raw-int, endianness=(int)1234, signed=(boolean)true, width=(int)32, depth=(int){ 20, 24 }, rate=(int)[ 1, 655350 ], channels=(int)[ 1, 8 ]</details>
+ </caps>
+ <caps>
+ <name>src</name>
+ <direction>source</direction>
+ <presence>always</presence>
+ <details>audio/x-flac</details>
+ </caps>
+ </pads>
+ </element>
+ <element>
+ <name>flactag</name>
+ <longname>FLAC tagger</longname>
+ <class>Formatter/Metadata</class>
+ <description>Rewrite tags in a FLAC file</description>
+ <author>Christophe Fergeau &lt;teuf@gnome.org&gt;</author>
+ <pads>
+ <caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
@@ -47,7 +68,7 @@
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
- <details>audio/x-raw-int, endianness=(int)1234, signed=(boolean)true, width=(int)16, depth=(int)16, rate=(int)[ 8000, 96000 ], channels=(int)[ 1, 2 ]</details>
+ <details>audio/x-flac</details>
</caps>
</pads>
</element>
diff --git a/ext/flac/Makefile.am b/ext/flac/Makefile.am
index 2723680e..0e7d41a2 100644
--- a/ext/flac/Makefile.am
+++ b/ext/flac/Makefile.am
@@ -1,6 +1,6 @@
plugin_LTLIBRARIES = libgstflac.la
-libgstflac_la_SOURCES = gstflac.c gstflacdec.c gstflacenc.c
+libgstflac_la_SOURCES = gstflac.c gstflacdec.c gstflacenc.c gstflactag.c
libgstflac_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
libgstflac_la_LIBADD = \
$(GST_PLUGINS_BASE_LIBS) -lgsttag-$(GST_MAJORMINOR) \
@@ -8,4 +8,4 @@ libgstflac_la_LIBADD = \
$(GST_BASE_LIBS) $(GST_LIBS) $(FLAC_LIBS)
libgstflac_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-noinst_HEADERS = gstflacenc.h gstflacdec.h
+noinst_HEADERS = gstflacenc.h gstflacdec.h gstflactag.h
diff --git a/ext/flac/gstflac.c b/ext/flac/gstflac.c
index d07ec479..7d76a41c 100644
--- a/ext/flac/gstflac.c
+++ b/ext/flac/gstflac.c
@@ -23,7 +23,7 @@
#include "gstflacenc.h"
#include "gstflacdec.h"
-/* #include "gstflactag.h" */
+#include "gstflactag.h"
#include <gst/tag/tag.h>
#include <gst/gst-i18n-plugin.h>
@@ -43,11 +43,9 @@ plugin_init (GstPlugin * plugin)
if (!gst_element_register (plugin, "flacdec", GST_RANK_PRIMARY,
GST_TYPE_FLAC_DEC))
return FALSE;
-#if 0
if (!gst_element_register (plugin, "flactag", GST_RANK_PRIMARY,
gst_flac_tag_get_type ()))
return FALSE;
-#endif
gst_tag_register_musicbrainz_tags ();
diff --git a/ext/flac/gstflacdec.c b/ext/flac/gstflacdec.c
index 7b8e381f..66d6c14c 100644
--- a/ext/flac/gstflacdec.c
+++ b/ext/flac/gstflacdec.c
@@ -105,15 +105,7 @@ GST_DEBUG_CATEGORY_STATIC (flacdec_debug);
static GstPadTemplate *src_template, *sink_template;
-static const GstElementDetails flacdec_details =
-GST_ELEMENT_DETAILS ("FLAC audio decoder",
- "Codec/Decoder/Audio",
- "Decodes FLAC lossless audio streams",
- "Wim Taymans <wim@fluendo.com>");
-
-
static void gst_flac_dec_finalize (GObject * object);
-
static void gst_flac_dec_loop (GstPad * pad);
static GstStateChangeReturn gst_flac_dec_change_state (GstElement * element,
@@ -237,7 +229,9 @@ gst_flac_dec_base_init (gpointer g_class)
GST_PAD_ALWAYS, raw_caps);
gst_element_class_add_pad_template (element_class, sink_template);
gst_element_class_add_pad_template (element_class, src_template);
- gst_element_class_set_details (element_class, &flacdec_details);
+ gst_element_class_set_details_simple (element_class, "FLAC audio decoder",
+ "Codec/Decoder/Audio",
+ "Decodes FLAC lossless audio streams", "Wim Taymans <wim@fluendo.com>");
GST_DEBUG_CATEGORY_INIT (flacdec_debug, "flacdec", 0, "flac decoder");
}
diff --git a/ext/flac/gstflacdec.h b/ext/flac/gstflacdec.h
index b68986d2..100c4e0b 100644
--- a/ext/flac/gstflacdec.h
+++ b/ext/flac/gstflacdec.h
@@ -47,6 +47,8 @@ typedef struct _GstFlacDecClass GstFlacDecClass;
struct _GstFlacDec {
GstElement element;
+ /* < private > */
+
#if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT < 8
FLAC__SeekableStreamDecoder *seekable_decoder; /* for pull-based operation */
#else
diff --git a/ext/flac/gstflacenc.c b/ext/flac/gstflacenc.c
index 1a2a34b6..1e29343c 100644
--- a/ext/flac/gstflacenc.c
+++ b/ext/flac/gstflacenc.c
@@ -77,12 +77,6 @@ static const GstAudioChannelPosition channel_positions[8][8] = {
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}
};
-static const GstElementDetails flacenc_details =
-GST_ELEMENT_DETAILS ("FLAC audio encoder",
- "Codec/Encoder/Audio",
- "Encodes audio with the FLAC lossless audio encoder",
- "Wim Taymans <wim.taymans@chello.be>");
-
#define FLAC_SINK_CAPS \
"audio/x-raw-int, " \
"endianness = (int) BYTE_ORDER, " \
@@ -261,7 +255,10 @@ gst_flac_enc_base_init (gpointer g_class)
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_factory));
- gst_element_class_set_details (element_class, &flacenc_details);
+ gst_element_class_set_details_simple (element_class, "FLAC audio encoder",
+ "Codec/Encoder/Audio",
+ "Encodes audio with the FLAC lossless audio encoder",
+ "Wim Taymans <wim.taymans@chello.be>");
GST_DEBUG_CATEGORY_INIT (flacenc_debug, "flacenc", 0,
"Flac encoding element");
diff --git a/ext/flac/gstflacenc.h b/ext/flac/gstflacenc.h
index 016a56b6..1c6a6c66 100644
--- a/ext/flac/gstflacenc.h
+++ b/ext/flac/gstflacenc.h
@@ -45,6 +45,8 @@ typedef struct _GstFlacEncClass GstFlacEncClass;
struct _GstFlacEnc {
GstElement element;
+ /* < private > */
+
GstPad *sinkpad;
GstPad *srcpad;
diff --git a/ext/flac/gstflactag.c b/ext/flac/gstflactag.c
index 247e1dea..d7ca61cc 100644
--- a/ext/flac/gstflactag.c
+++ b/ext/flac/gstflactag.c
@@ -1,6 +1,7 @@
-
/* GStreamer
* Copyright (C) 2003 Christophe Fergeau <teuf@gnome.org>
+ * Copyright (C) 2008 Jonathan Matthew <jonathan@d14n.org>
+ * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
*
* gstflactag.c: plug-in for reading/modifying vorbis comments in flac files
*
@@ -20,78 +21,58 @@
* Boston, MA 02111-1307, USA.
*/
+/**
+ * SECTION:element-flactag
+ * @see_also: #flacenc, #flacdec, #GstTagSetter
+ *
+ * The flactag element can change the tag contained within a raw
+ * FLAC stream. Specifically, it modifies the comments header packet
+ * of the FLAC stream.
+ *
+ * Applications can set the tags to write using the #GstTagSetter interface.
+ * Tags contained withing the FLAC bitstream will be picked up
+ * automatically (and merged according to the merge mode set via the tag
+ * setter interface).
+ *
+ * <refsect2>
+ * <title>Example pipelines</title>
+ * |[
+ * gst-launch -v filesrc location=foo.flac ! flactag ! filesink location=bar.flac
+ * ]| This element is not useful with gst-launch, because it does not support
+ * setting the tags on a #GstTagSetter interface. Conceptually, the element
+ * will usually be used in this order though.
+ * </refsect2>
+ */
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
+#include <gst/gst.h>
#include <gst/gsttagsetter.h>
+#include <gst/base/gstadapter.h>
#include <gst/tag/tag.h>
#include <string.h>
-#define GST_TYPE_FLAC_TAG (gst_flac_tag_get_type())
-#define GST_FLAC_TAG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FLAC_TAG, GstFlacTag))
-#define GST_FLAC_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FLAC_TAG, GstFlacTag))
-#define GST_IS_FLAC_TAG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FLAC_TAG))
-#define GST_IS_FLAC_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FLAC_TAG))
+#include "gstflactag.h"
-typedef struct _GstFlacTag GstFlacTag;
-typedef struct _GstFlacTagClass GstFlacTagClass;
-
-static inline gint
-min (gint a, gint b)
-{
- if (a < b) {
- return a;
- } else {
- return b;
- }
-}
-
-
-typedef enum
-{
- GST_FLAC_TAG_STATE_INIT,
- GST_FLAC_TAG_STATE_METADATA_BLOCKS,
- GST_FLAC_TAG_STATE_METADATA_NEXT_BLOCK,
- GST_FLAC_TAG_STATE_WRITING_METADATA_BLOCK,
- GST_FLAC_TAG_STATE_VC_METADATA_BLOCK,
- GST_FLAC_TAG_STATE_ADD_VORBIS_COMMENT,
- GST_FLAC_TAG_STATE_AUDIO_DATA
-}
-GstFlacTagState;
-
-
-struct _GstFlacTag
-{
- GstElement element;
-
- /* pads */
- GstPad *sinkpad;
- GstPad *srcpad;
-
- GstFlacTagState state;
-
- GstBuffer *buffer;
- GstBuffer *vorbiscomment;
- GstTagList *tags;
-
- guint metadata_bytes_remaining;
- gboolean metadata_last_block;
-
- gboolean only_output_tags;
-};
-
-struct _GstFlacTagClass
-{
- GstElementClass parent_class;
-};
+GST_DEBUG_CATEGORY_STATIC (flactag_debug);
+#define GST_CAT_DEFAULT flactag_debug
/* elementfactory information */
-static const GstElementDetails gst_flac_tag_details =
-GST_ELEMENT_DETAILS ("FLAC tagger",
- "Tag",
- "Rewrite tags in a FLAC file",
- "Christope Fergeau <teuf@gnome.org>");
+static GstStaticPadTemplate flac_tag_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("audio/x-flac")
+ );
+static GstStaticPadTemplate flac_tag_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("audio/x-flac")
+ );
/* signals and args */
enum
@@ -106,121 +87,42 @@ enum
/* FILL ME */
};
-static GstStaticPadTemplate flac_tag_src_template =
- GST_STATIC_PAD_TEMPLATE ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-flac; application/x-gst-tags")
- );
-
-static GstStaticPadTemplate flac_tag_sink_template =
-GST_STATIC_PAD_TEMPLATE ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-flac")
- );
-
-
-static void gst_flac_tag_base_init (gpointer g_class);
-static void gst_flac_tag_class_init (GstFlacTagClass * klass);
-static void gst_flac_tag_init (GstFlacTag * tag);
+static void gst_flac_tag_dispose (GObject * object);
-static void gst_flac_tag_chain (GstPad * pad, GstData * data);
+static GstFlowReturn gst_flac_tag_chain (GstPad * pad, GstBuffer * buffer);
static GstStateChangeReturn gst_flac_tag_change_state (GstElement * element,
GstStateChange transition);
+static gboolean gst_flac_tag_sink_setcaps (GstPad * pad, GstCaps * caps);
-static GstElementClass *parent_class = NULL;
-
-/* static guint gst_flac_tag_signals[LAST_SIGNAL] = { 0 }; */
-
-GType
-gst_flac_tag_get_type (void)
+static void
+gst_flac_tag_setup_interfaces (GType flac_tag_type)
{
- static GType flac_tag_type = 0;
-
- if (!flac_tag_type) {
- static const GTypeInfo flac_tag_info = {
- sizeof (GstFlacTagClass),
- gst_flac_tag_base_init,
- NULL,
- (GClassInitFunc) gst_flac_tag_class_init,
- NULL,
- NULL,
- sizeof (GstFlacTag),
- 0,
- (GInstanceInitFunc) gst_flac_tag_init,
- };
- static const GInterfaceInfo tag_setter_info = {
- NULL,
- NULL,
- NULL
- };
-
- flac_tag_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstFlacTag", &flac_tag_info,
- 0);
-
- g_type_add_interface_static (flac_tag_type, GST_TYPE_TAG_SETTER,
- &tag_setter_info);
+ static const GInterfaceInfo tag_setter_info = { NULL, NULL, NULL };
- }
- return flac_tag_type;
+ g_type_add_interface_static (flac_tag_type, GST_TYPE_TAG_SETTER,
+ &tag_setter_info);
}
+GST_BOILERPLATE_FULL (GstFlacTag, gst_flac_tag, GstElement, GST_TYPE_ELEMENT,
+ gst_flac_tag_setup_interfaces);
static void
gst_flac_tag_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
- gst_element_class_set_details (element_class, &gst_flac_tag_details);
+ gst_element_class_set_details_simple (element_class, "FLAC tagger",
+ "Formatter/Metadata",
+ "Rewrite tags in a FLAC file", "Christophe Fergeau <teuf@gnome.org>");
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&flac_tag_sink_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&flac_tag_src_template));
-}
-
-static void
-send_eos (GstFlacTag * tag)
-{
- gst_element_set_eos (GST_ELEMENT (tag));
- gst_pad_push (tag->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS)));
- /* Seek to end of sink stream */
- if (gst_pad_send_event (GST_PAD_PEER (tag->sinkpad),
- gst_event_new_seek (GST_FORMAT_BYTES | GST_SEEK_METHOD_END |
- GST_SEEK_FLAG_FLUSH, 0))) {
- } else {
- g_warning ("Couldn't seek to eos on sinkpad\n");
- }
-}
-
-
-static gboolean
-caps_nego (GstFlacTag * tag)
-{
- /* do caps nego */
- GstCaps *caps;
-
- caps = gst_caps_new_simple ("audio/x-flac", NULL);
- if (gst_pad_try_set_caps (tag->srcpad, caps) != GST_PAD_LINK_REFUSED) {
- tag->only_output_tags = FALSE;
- GST_LOG_OBJECT (tag, "normal operation, using audio/x-flac output");
- } else {
- if (gst_pad_try_set_caps (tag->srcpad,
- gst_caps_new_simple ("application/x-gst-tags", NULL))
- != GST_PAD_LINK_REFUSED) {
- tag->only_output_tags = TRUE;
- GST_LOG_OBJECT (tag, "fast operation, just outputting tags");
- printf ("output tags only\n");
- } else {
- return FALSE;
- }
- }
- return TRUE;
+ GST_DEBUG_CATEGORY_INIT (flactag_debug, "flactag", 0, "flac tag rewriter");
}
static void
@@ -234,86 +136,96 @@ gst_flac_tag_class_init (GstFlacTagClass * klass)
parent_class = g_type_class_peek_parent (klass);
+ gobject_class->dispose = gst_flac_tag_dispose;
gstelement_class->change_state = gst_flac_tag_change_state;
}
+static void
+gst_flac_tag_dispose (GObject * object)
+{
+ GstFlacTag *tag = GST_FLAC_TAG (object);
+
+ if (tag->adapter) {
+ gst_object_unref (tag->adapter);
+ tag->adapter = NULL;
+ }
+ if (tag->vorbiscomment) {
+ gst_buffer_unref (tag->vorbiscomment);
+ tag->vorbiscomment = NULL;
+ }
+ if (tag->tags) {
+ gst_tag_list_free (tag->tags);
+ tag->tags = NULL;
+ }
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
static void
-gst_flac_tag_init (GstFlacTag * tag)
+gst_flac_tag_init (GstFlacTag * tag, GstFlacTagClass * klass)
{
/* create the sink and src pads */
tag->sinkpad =
gst_pad_new_from_static_template (&flac_tag_sink_template, "sink");
- gst_element_add_pad (GST_ELEMENT (tag), tag->sinkpad);
gst_pad_set_chain_function (tag->sinkpad,
GST_DEBUG_FUNCPTR (gst_flac_tag_chain));
+ gst_pad_set_setcaps_function (tag->sinkpad,
+ GST_DEBUG_FUNCPTR (gst_flac_tag_sink_setcaps));
+ gst_element_add_pad (GST_ELEMENT (tag), tag->sinkpad);
tag->srcpad =
gst_pad_new_from_static_template (&flac_tag_src_template, "src");
gst_element_add_pad (GST_ELEMENT (tag), tag->srcpad);
- tag->buffer = NULL;
+ tag->adapter = gst_adapter_new ();
+}
+
+static gboolean
+gst_flac_tag_sink_setcaps (GstPad * pad, GstCaps * caps)
+{
+ GstFlacTag *tag = GST_FLAC_TAG (GST_PAD_PARENT (pad));
+
+ return gst_pad_set_caps (tag->srcpad, caps);
}
#define FLAC_MAGIC "fLaC"
#define FLAC_MAGIC_SIZE (sizeof (FLAC_MAGIC) - 1)
-static void
-gst_flac_tag_chain (GstPad * pad, GstData * data)
+static GstFlowReturn
+gst_flac_tag_chain (GstPad * pad, GstBuffer * buffer)
{
- GstBuffer *buffer;
GstFlacTag *tag;
+ GstFlowReturn ret;
- if (GST_IS_EVENT (data)) {
- g_print ("Unhandled event\n");
- return;
- }
-
- buffer = GST_BUFFER (data);
+ ret = GST_FLOW_OK;
tag = GST_FLAC_TAG (gst_pad_get_parent (pad));
- if (tag->buffer) {
- GstBuffer *merge;
-
- merge = gst_buffer_merge (tag->buffer, buffer);
- gst_buffer_unref (buffer);
- gst_buffer_unref (tag->buffer);
- tag->buffer = merge;
- } else {
- tag->buffer = buffer;
- }
-
+ gst_adapter_push (tag->adapter, buffer);
/* Initial state, we don't even know if we are dealing with a flac file */
if (tag->state == GST_FLAC_TAG_STATE_INIT) {
- if (!caps_nego (tag)) {
- goto cleanup;
- }
+ GstBuffer *id_buffer;
- if (GST_BUFFER_SIZE (tag->buffer) < sizeof (FLAC_MAGIC)) {
+ if (gst_adapter_available (tag->adapter) < sizeof (FLAC_MAGIC))
goto cleanup;
- }
- if (strncmp (GST_BUFFER_DATA (tag->buffer), FLAC_MAGIC,
- FLAC_MAGIC_SIZE) == 0) {
- GstBuffer *sub;
+ id_buffer = gst_adapter_take_buffer (tag->adapter, FLAC_MAGIC_SIZE);
+ GST_DEBUG_OBJECT (tag, "looking for " FLAC_MAGIC " identifier");
+ if (memcmp (GST_BUFFER_DATA (id_buffer), FLAC_MAGIC, FLAC_MAGIC_SIZE) == 0) {
+
+ GST_DEBUG_OBJECT (tag, "pushing " FLAC_MAGIC " identifier buffer");
+ gst_buffer_set_caps (id_buffer, GST_PAD_CAPS (tag->srcpad));
+ ret = gst_pad_push (tag->srcpad, id_buffer);
+ if (ret != GST_FLOW_OK)
+ goto cleanup;
tag->state = GST_FLAC_TAG_STATE_METADATA_BLOCKS;
- sub = gst_buffer_create_sub (tag->buffer, 0, FLAC_MAGIC_SIZE);
-
- gst_pad_push (tag->srcpad, GST_DATA (sub));
- sub =
- gst_buffer_create_sub (tag->buffer, FLAC_MAGIC_SIZE,
- GST_BUFFER_SIZE (tag->buffer) - FLAC_MAGIC_SIZE);
- gst_buffer_unref (tag->buffer);
- /* We do a copy because we need a writable buffer, and _create_sub
- * sets the buffer it uses to read-only
- */
- tag->buffer = gst_buffer_copy (sub);
- gst_buffer_unref (sub);
} else {
/* FIXME: does that work well with FLAC files containing ID3v2 tags ? */
+ gst_buffer_unref (id_buffer);
GST_ELEMENT_ERROR (tag, STREAM, WRONG_TYPE, (NULL), (NULL));
+ ret = GST_FLOW_ERROR;
}
}
@@ -325,8 +237,9 @@ gst_flac_tag_chain (GstPad * pad, GstData * data)
guint size;
guint type;
gboolean is_last;
+ const guint8 *block_header;
- g_assert (tag->metadata_bytes_remaining == 0);
+ g_assert (tag->metadata_block_size == 0);
g_assert (tag->metadata_last_block == FALSE);
/* The header of a flac metadata block is 4 bytes long:
@@ -334,26 +247,25 @@ gst_flac_tag_chain (GstPad * pad, GstData * data)
* 7 next bits: 4 if vorbis comment block
* 24 next bits: size of the metadata to follow (big endian)
*/
- if (GST_BUFFER_SIZE (tag->buffer) < 4) {
+ if (gst_adapter_available (tag->adapter) < 4)
goto cleanup;
- }
- is_last = (((GST_BUFFER_DATA (tag->buffer)[0]) & 0x80) == 0x80);
- /* If we have metadata set on the element, the last metadata block
- * will be the vorbis comment block which we will build ourselves
- */
- if (is_last) {
- (GST_BUFFER_DATA (tag->buffer)[0]) &= (~0x80);
- }
- type = (GST_BUFFER_DATA (tag->buffer)[0]) & 0x7F;
- size = ((GST_BUFFER_DATA (tag->buffer)[1]) << 16)
- | ((GST_BUFFER_DATA (tag->buffer)[2]) << 8)
- | (GST_BUFFER_DATA (tag->buffer)[3]);
+ block_header = gst_adapter_peek (tag->adapter, 4);
+
+ is_last = ((block_header[0] & 0x80) == 0x80);
+ type = block_header[0] & 0x7F;
+ size = (block_header[1] << 16)
+ | (block_header[2] << 8)
+ | block_header[3];
/* The 4 bytes long header isn't included in the metadata size */
- tag->metadata_bytes_remaining = size + 4;
+ tag->metadata_block_size = size + 4;
tag->metadata_last_block = is_last;
+ GST_DEBUG_OBJECT (tag,
+ "got metadata block: %d bytes, type %d, is vorbiscomment: %d, is last: %d",
+ size, type, (type == 0x04), is_last);
+
/* Metadata blocks of type 4 are vorbis comment blocks */
if (type == 0x04) {
tag->state = GST_FLAC_TAG_STATE_VC_METADATA_BLOCK;
@@ -366,56 +278,29 @@ gst_flac_tag_chain (GstPad * pad, GstData * data)
/* Reads a metadata block */
if ((tag->state == GST_FLAC_TAG_STATE_WRITING_METADATA_BLOCK) ||
(tag->state == GST_FLAC_TAG_STATE_VC_METADATA_BLOCK)) {
- GstBuffer *sub;
- guint bytes_to_push;
-
- g_assert (tag->metadata_bytes_remaining != 0);
+ GstBuffer *metadata_buffer;
- bytes_to_push = min (tag->metadata_bytes_remaining,
- GST_BUFFER_SIZE (tag->buffer));
+ if (gst_adapter_available (tag->adapter) < tag->metadata_block_size)
+ goto cleanup;
- sub = gst_buffer_create_sub (tag->buffer, 0, bytes_to_push);
+ metadata_buffer = gst_adapter_take_buffer (tag->adapter,
+ tag->metadata_block_size);
+ /* clear the is-last flag, as the last metadata block will
+ * be the vorbis comment block which we will build ourselves.
+ */
+ GST_BUFFER_DATA (metadata_buffer)[0] &= (~0x80);
if (tag->state == GST_FLAC_TAG_STATE_WRITING_METADATA_BLOCK) {
- gst_pad_push (tag->srcpad, GST_DATA (sub));
- } else {
- if (tag->vorbiscomment == NULL) {
- tag->vorbiscomment = sub;
- } else {
- GstBuffer *merge;
-
- merge = gst_buffer_merge (tag->vorbiscomment, sub);
- gst_buffer_unref (tag->vorbiscomment);
- gst_buffer_unref (sub);
- tag->vorbiscomment = merge;
- }
- }
-
- tag->metadata_bytes_remaining -= (bytes_to_push);
-
- if (GST_BUFFER_SIZE (tag->buffer) > bytes_to_push) {
- GstBuffer *sub;
-
- sub = gst_buffer_create_sub (tag->buffer, bytes_to_push,
- GST_BUFFER_SIZE (tag->buffer) - bytes_to_push);
- gst_buffer_unref (tag->buffer);
-
- /* We make a copy because we need a writable buffer, and _create_sub
- * sets the buffer it uses to read-only
- */
- tag->buffer = gst_buffer_copy (sub);
- gst_buffer_unref (sub);
-
- tag->state = GST_FLAC_TAG_STATE_METADATA_NEXT_BLOCK;
- } else if (tag->metadata_bytes_remaining == 0) {
- gst_buffer_unref (tag->buffer);
- tag->buffer = NULL;
- tag->state = GST_FLAC_TAG_STATE_METADATA_NEXT_BLOCK;
- tag->buffer = NULL;
+ GST_DEBUG_OBJECT (tag, "pushing metadata block buffer");
+ gst_buffer_set_caps (metadata_buffer, GST_PAD_CAPS (tag->srcpad));
+ ret = gst_pad_push (tag->srcpad, metadata_buffer);
+ if (ret != GST_FLOW_OK)
+ goto cleanup;
} else {
- tag->state = GST_FLAC_TAG_STATE_WRITING_METADATA_BLOCK;
- tag->buffer = NULL;
+ tag->vorbiscomment = metadata_buffer;
}
+ tag->metadata_block_size = 0;
+ tag->state = GST_FLAC_TAG_STATE_METADATA_NEXT_BLOCK;
}
/* This state is mainly used to be able to stop as soon as we read
@@ -428,36 +313,25 @@ gst_flac_tag_chain (GstPad * pad, GstData * data)
*/
if (tag->vorbiscomment != NULL) {
/* We found some tags, try to parse them and notify the other elements
- * that we encoutered some tags
+ * that we encountered some tags
*/
+ GST_DEBUG_OBJECT (tag, "emitting vorbiscomment tags");
tag->tags = gst_tag_list_from_vorbiscomment_buffer (tag->vorbiscomment,
GST_BUFFER_DATA (tag->vorbiscomment), 4, NULL);
if (tag->tags != NULL) {
- gst_element_found_tags (GST_ELEMENT (tag), tag->tags);
+ gst_element_found_tags (GST_ELEMENT (tag),
+ gst_tag_list_copy (tag->tags));
}
gst_buffer_unref (tag->vorbiscomment);
tag->vorbiscomment = NULL;
-
- if (tag->only_output_tags) {
- send_eos (tag);
- goto cleanup;
- }
}
/* Skip to next state */
if (tag->metadata_last_block == FALSE) {
tag->state = GST_FLAC_TAG_STATE_METADATA_BLOCKS;
} else {
- if (tag->only_output_tags) {
- /* If we finished parsing the metadata blocks, we will never find any
- * metadata, so just stop now
- */
- send_eos (tag);
- goto cleanup;
- } else {
- tag->state = GST_FLAC_TAG_STATE_ADD_VORBIS_COMMENT;
- }
+ tag->state = GST_FLAC_TAG_STATE_ADD_VORBIS_COMMENT;
}
}
@@ -471,18 +345,21 @@ gst_flac_tag_chain (GstPad * pad, GstData * data)
const GstTagList *user_tags;
GstTagList *merged_tags;
- g_assert (tag->only_output_tags == FALSE);
-
+ /* merge the tag lists */
user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (tag));
- merged_tags = gst_tag_list_merge (tag->tags, user_tags,
- gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (tag)));
+ if (user_tags != NULL) {
+ merged_tags = gst_tag_list_merge (user_tags, tag->tags,
+ gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (tag)));
+ } else {
+ merged_tags = gst_tag_list_copy (tag->tags);
+ }
if (merged_tags == NULL) {
/* If we get a NULL list of tags, we must generate a padding block
* which is marked as the last metadata block, otherwise we'll
* end up with a corrupted flac file.
*/
- g_warning ("No tags found\n");
+ GST_WARNING_OBJECT (tag, "No tags found");
buffer = gst_buffer_new_and_alloc (12);
if (buffer == NULL) {
GST_ELEMENT_ERROR (tag, CORE, TOO_LAZY, (NULL),
@@ -501,6 +378,7 @@ gst_flac_tag_chain (GstPad * pad, GstData * data)
*/
buffer = gst_tag_list_to_vorbiscomment_buffer (merged_tags, header,
sizeof (header), NULL);
+ GST_DEBUG_OBJECT (tag, "Writing tags %" GST_PTR_FORMAT, merged_tags);
gst_tag_list_free (merged_tags);
if (buffer == NULL) {
GST_ELEMENT_ERROR (tag, CORE, TAG, (NULL),
@@ -539,18 +417,30 @@ gst_flac_tag_chain (GstPad * pad, GstData * data)
GST_BUFFER_DATA (buffer)[1] = ((size & 0xFF0000) >> 16);
GST_BUFFER_DATA (buffer)[2] = ((size & 0x00FF00) >> 8);
GST_BUFFER_DATA (buffer)[3] = (size & 0x0000FF);
- gst_pad_push (tag->srcpad, GST_DATA (buffer));
+ GST_DEBUG_OBJECT (tag, "pushing %d byte vorbiscomment buffer",
+ GST_BUFFER_SIZE (buffer));
+ gst_buffer_set_caps (buffer, GST_PAD_CAPS (tag->srcpad));
+ ret = gst_pad_push (tag->srcpad, buffer);
+ if (ret != GST_FLOW_OK) {
+ goto cleanup;
+ }
tag->state = GST_FLAC_TAG_STATE_AUDIO_DATA;
}
/* The metadata blocks have been read, now we are reading audio data */
if (tag->state == GST_FLAC_TAG_STATE_AUDIO_DATA) {
- gst_pad_push (tag->srcpad, GST_DATA (tag->buffer));
- tag->buffer = NULL;
+ GstBuffer *buffer;
+ buffer =
+ gst_adapter_take_buffer (tag->adapter,
+ gst_adapter_available (tag->adapter));
+ gst_buffer_set_caps (buffer, GST_PAD_CAPS (tag->srcpad));
+ ret = gst_pad_push (tag->srcpad, buffer);
}
cleanup:
gst_object_unref (tag);
+
+ return ret;
}
@@ -572,17 +462,17 @@ gst_flac_tag_change_state (GstElement * element, GstStateChange transition)
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
- if (tag->buffer) {
- gst_buffer_unref (tag->buffer);
- tag->buffer = NULL;
- }
+ gst_adapter_clear (tag->adapter);
if (tag->vorbiscomment) {
gst_buffer_unref (tag->vorbiscomment);
tag->vorbiscomment = NULL;
}
if (tag->tags) {
gst_tag_list_free (tag->tags);
+ tag->tags = NULL;
}
+ tag->metadata_block_size = 0;
+ tag->metadata_last_block = FALSE;
tag->state = GST_FLAC_TAG_STATE_INIT;
break;
case GST_STATE_CHANGE_READY_TO_NULL:
diff --git a/ext/flac/gstflactag.h b/ext/flac/gstflactag.h
index 5107d1c3..a6f90f5e 100644
--- a/ext/flac/gstflactag.h
+++ b/ext/flac/gstflactag.h
@@ -1,6 +1,78 @@
+/* GStreamer
+ * Copyright (C) 2003 Christophe Fergeau <teuf@gnome.org>
+ * Copyright (C) 2008 Jonathan Matthew <jonathan@d14n.org>
+ * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ *
+ * gstflactag.c: plug-in for reading/modifying vorbis comments in flac files
+ *
+ * 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_FLAC_TAG_H
#define GST_FLAC_TAG_H
+#include <gst/gst.h>
+#include <gst/base/gstadapter.h>
+
+#define GST_TYPE_FLAC_TAG (gst_flac_tag_get_type())
+#define GST_FLAC_TAG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FLAC_TAG, GstFlacTag))
+#define GST_FLAC_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FLAC_TAG, GstFlacTag))
+#define GST_IS_FLAC_TAG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FLAC_TAG))
+#define GST_IS_FLAC_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FLAC_TAG))
+
+typedef struct _GstFlacTag GstFlacTag;
+typedef struct _GstFlacTagClass GstFlacTagClass;
+
+typedef enum
+{
+ GST_FLAC_TAG_STATE_INIT,
+ GST_FLAC_TAG_STATE_METADATA_BLOCKS,
+ GST_FLAC_TAG_STATE_METADATA_NEXT_BLOCK,
+ GST_FLAC_TAG_STATE_WRITING_METADATA_BLOCK,
+ GST_FLAC_TAG_STATE_VC_METADATA_BLOCK,
+ GST_FLAC_TAG_STATE_ADD_VORBIS_COMMENT,
+ GST_FLAC_TAG_STATE_AUDIO_DATA
+}
+GstFlacTagState;
+
+struct _GstFlacTag
+{
+ GstElement element;
+
+ /* < private > */
+
+ /* pads */
+ GstPad *sinkpad;
+ GstPad *srcpad;
+
+ GstFlacTagState state;
+
+ GstAdapter *adapter;
+ GstBuffer *vorbiscomment;
+ GstTagList *tags;
+
+ guint metadata_block_size;
+ gboolean metadata_last_block;
+};
+
+struct _GstFlacTagClass
+{
+ GstElementClass parent_class;
+};
+
GType gst_flac_tag_get_type (void);
#endif /* GST_FLAC_TAG_H */