mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
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.
This commit is contained in:
parent
dfd580b207
commit
8ced1b35ff
16 changed files with 499 additions and 459 deletions
32
ChangeLog
32
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:
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -538,6 +538,34 @@ gst_flac_dec_get_type
|
|||
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>
|
||||
|
|
|
@ -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
|
||||
GstImplementsInterface
|
||||
GstColorBalance
|
||||
GstTuner
|
||||
GstVideoOrientation
|
||||
GstPropertyProbe
|
||||
GstImplementsInterface
|
||||
GstMixer
|
||||
GstTagSetter
|
||||
GstTuner
|
||||
GstColorBalance
|
||||
GstVideoOrientation
|
||||
|
|
|
@ -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
|
||||
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
|
||||
GstV4l2Src GstPropertyProbe GstImplementsInterface GstTuner GstColorBalance GstVideoOrientation
|
||||
GstUDPSrc GstURIHandler
|
||||
GstPulseMixer GstPropertyProbe GstImplementsInterface GstMixer
|
||||
GstFlacEnc GstTagSetter
|
||||
GstFlacTag GstTagSetter
|
||||
GstIirEqualizer GstChildProxy
|
||||
GstIirEqualizerNBands GstChildProxy
|
||||
GstIirEqualizer3Bands GstChildProxy
|
||||
GstIirEqualizer10Bands GstChildProxy
|
||||
GstVideoMixer GstChildProxy
|
||||
GstUDPSrc GstURIHandler
|
||||
GstV4l2Src GstImplementsInterface GstColorBalance GstTuner GstVideoOrientation GstPropertyProbe
|
||||
GstOssSrc GstImplementsInterface GstMixer
|
||||
GstPulseSrc GstImplementsInterface GstMixer
|
||||
GstDV1394Src GstURIHandler GstPropertyProbe
|
||||
GstSoupHTTPSrc GstURIHandler
|
||||
GstCddaBaseSrc GstURIHandler
|
||||
GstCdioCddaSrc GstURIHandler
|
||||
GstUDPSink GstURIHandler
|
||||
GstShout2send GstTagSetter
|
||||
GstOssMixerElement GstImplementsInterface GstMixer
|
||||
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
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
GstChildProxy GstObject
|
||||
GstTagSetter GstObject GstElement
|
||||
GstImplementsInterface GstObject GstElement
|
||||
GstColorBalance GstObject GstImplementsInterface GstElement
|
||||
GstTuner GstObject GstImplementsInterface GstElement
|
||||
GstVideoOrientation GstObject GstImplementsInterface GstElement
|
||||
GstMixer GstObject GstImplementsInterface GstElement
|
||||
GstTagSetter GstObject GstElement
|
||||
GstTuner GstObject GstImplementsInterface GstElement
|
||||
GstColorBalance GstObject GstImplementsInterface GstElement
|
||||
GstVideoOrientation GstObject GstImplementsInterface GstElement
|
||||
|
|
|
@ -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>
|
||||
|
@ -16,18 +16,18 @@
|
|||
<description>Decodes FLAC lossless audio streams</description>
|
||||
<author>Wim Taymans <wim@fluendo.com></author>
|
||||
<pads>
|
||||
<caps>
|
||||
<name>src</name>
|
||||
<direction>source</direction>
|
||||
<presence>always</presence>
|
||||
<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>sink</name>
|
||||
<direction>sink</direction>
|
||||
<presence>always</presence>
|
||||
<details>audio/x-flac</details>
|
||||
</caps>
|
||||
<caps>
|
||||
<name>src</name>
|
||||
<direction>source</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>
|
||||
</caps>
|
||||
</pads>
|
||||
</element>
|
||||
<element>
|
||||
|
@ -36,6 +36,27 @@
|
|||
<class>Codec/Encoder/Audio</class>
|
||||
<description>Encodes audio with the FLAC lossless audio encoder</description>
|
||||
<author>Wim Taymans <wim.taymans@chello.be></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 <teuf@gnome.org></author>
|
||||
<pads>
|
||||
<caps>
|
||||
<name>src</name>
|
||||
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ();
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -45,6 +45,8 @@ typedef struct _GstFlacEncClass GstFlacEncClass;
|
|||
struct _GstFlacEnc {
|
||||
GstElement element;
|
||||
|
||||
/* < private > */
|
||||
|
||||
GstPad *sinkpad;
|
||||
GstPad *srcpad;
|
||||
|
||||
|
|
|
@ -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 void gst_flac_tag_dispose (GObject * object);
|
||||
|
||||
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_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;
|
||||
static const GInterfaceInfo tag_setter_info = { NULL, NULL, NULL };
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
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;
|
||||
GstBuffer *metadata_buffer;
|
||||
|
||||
g_assert (tag->metadata_bytes_remaining != 0);
|
||||
if (gst_adapter_available (tag->adapter) < tag->metadata_block_size)
|
||||
goto cleanup;
|
||||
|
||||
bytes_to_push = min (tag->metadata_bytes_remaining,
|
||||
GST_BUFFER_SIZE (tag->buffer));
|
||||
|
||||
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));
|
||||
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 {
|
||||
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;
|
||||
} 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:
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue