Merge remote-tracking branch 'origin/master' into 0.11

Conflicts:
	docs/plugins/inspect/plugin-esdsink.xml
	docs/plugins/inspect/plugin-gconfelements.xml
	ext/pulse/pulseaudiosink.c
	gst/matroska/matroska-demux.c
	gst/matroska/matroska-mux.c
	gst/multifile/gstmultifilesink.c
This commit is contained in:
Tim-Philipp Müller 2011-12-02 01:58:30 +00:00
commit d895ac645f
89 changed files with 2325 additions and 227 deletions

View file

@ -204,6 +204,7 @@ dnl *** checks for dependency libraries ***
dnl GLib is required
AG_GST_GLIB_CHECK([2.20])
PKG_CHECK_MODULES(GIO, [ gio-2.0 >= 2.20 ], , AC_MSG_ERROR([gio is required]))
dnl Orc
ORC_CHECK([0.4.11])

View file

@ -158,6 +158,7 @@ EXTRA_HFILES = \
$(top_srcdir)/gst/monoscope/gstmonoscope.h \
$(top_srcdir)/gst/multifile/gstmultifilesink.h \
$(top_srcdir)/gst/multifile/gstmultifilesrc.h \
$(top_srcdir)/gst/multifile/gstsplitfilesrc.h \
$(top_srcdir)/gst/multipart/multipartdemux.h \
$(top_srcdir)/gst/multipart/multipartmux.h \
$(top_srcdir)/gst/isomp4/qtdemux.h \

View file

@ -155,6 +155,7 @@
<xi:include href="xml/element-spectrum.xml" />
<xi:include href="xml/element-speexenc.xml" />
<xi:include href="xml/element-speexdec.xml" />
<xi:include href="xml/element-splitfilesrc.xml" />
<xi:include href="xml/element-streaktv.xml" />
<xi:include href="xml/element-taginject.xml" />
<xi:include href="xml/element-udpsrc.xml" />

View file

@ -1911,6 +1911,20 @@ GST_IS_SPEEX_ENC_CLASS
gst_speex_enc_get_type
</SECTION>
<SECTION>
<FILE>element-splitfilesrc</FILE>
<TITLE>splitfilesrc</TITLE>
GstSplitFileSrc
<SUBSECTION Standard>
GstSplitFileSrcClass
GST_SPLIT_FILE_SRC
GST_SPLIT_FILE_SRC_CLASS
GST_IS_SPLIT_FILE_SRC
GST_IS_SPLIT_FILE_SRC_CLASS
GST_TYPE_SPLIT_FILE_SRC
gst_split_file_src_get_type
</SECTION>
<SECTION>
<FILE>element-taginject</FILE>
<TITLE>taginject</TITLE>

View file

@ -178,6 +178,16 @@
<DEFAULT>FALSE</DEFAULT>
</ARG>
<ARG>
<NAME>GstMultiFileSink::max-files</NAME>
<TYPE>guint</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Max files</NICK>
<BLURB>Maximum number of files to keep on disk. Once the maximum is reached,old files start to be deleted to make room for new ones.</BLURB>
<DEFAULT>0</DEFAULT>
</ARG>
<ARG>
<NAME>GstMultiFileSrc::caps</NAME>
<TYPE>GstCaps*</TYPE>
@ -208,6 +218,36 @@
<DEFAULT>"%05d"</DEFAULT>
</ARG>
<ARG>
<NAME>GstMultiFileSrc::loop</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Loop</NICK>
<BLURB>Whether to repeat from the beginning when all files have been read.</BLURB>
<DEFAULT>FALSE</DEFAULT>
</ARG>
<ARG>
<NAME>GstMultiFileSrc::start-index</NAME>
<TYPE>gint</TYPE>
<RANGE>>= 0</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Start Index</NICK>
<BLURB>Start value of index. The initial value of index can be set either by setting index or start-index. When the end of the loop is reached, the index will be set to the value start-index.</BLURB>
<DEFAULT>0</DEFAULT>
</ARG>
<ARG>
<NAME>GstMultiFileSrc::stop-index</NAME>
<TYPE>gint</TYPE>
<RANGE>>= G_MAXULONG</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Start Index</NICK>
<BLURB>Stop value of index. The special value -1 means no stop.</BLURB>
<DEFAULT>0</DEFAULT>
</ARG>
<ARG>
<NAME>GstOssSrc::device</NAME>
<TYPE>gchar*</TYPE>
@ -461,7 +501,7 @@
<ARG>
<NAME>GstUDPSrc::sockfd</NAME>
<TYPE>gint</TYPE>
<RANGE>>= -1</RANGE>
<RANGE>>= G_MAXULONG</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Socket Handle</NICK>
<BLURB>Socket to use for UDP reception. (-1 == allocate).</BLURB>
@ -511,7 +551,7 @@
<ARG>
<NAME>GstUDPSrc::sock</NAME>
<TYPE>gint</TYPE>
<RANGE>>= -1</RANGE>
<RANGE>>= G_MAXULONG</RANGE>
<FLAGS>r</FLAGS>
<NICK>Socket Handle</NICK>
<BLURB>Socket currently in use for UDP reception. (-1 = no socket).</BLURB>
@ -778,6 +818,16 @@
<DEFAULT>524288</DEFAULT>
</ARG>
<ARG>
<NAME>GstRTSPSrc::short-header</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Short Header</NICK>
<BLURB>Only send the basic RTSP headers for broken encoders.</BLURB>
<DEFAULT>FALSE</DEFAULT>
</ARG>
<ARG>
<NAME>GstRTPDec::skip</NAME>
<TYPE>gint</TYPE>
@ -1512,7 +1562,7 @@
<NAME>GstSpeexEnc::abr</NAME>
<TYPE>gint</TYPE>
<RANGE>>= 0</RANGE>
<FLAGS>rw</FLAGS>
<FLAGS>rwx</FLAGS>
<NICK>ABR</NICK>
<BLURB>Enable average bit-rate (0 = disabled).</BLURB>
<DEFAULT>0</DEFAULT>
@ -1522,7 +1572,7 @@
<NAME>GstSpeexEnc::bitrate</NAME>
<TYPE>gint</TYPE>
<RANGE>>= 0</RANGE>
<FLAGS>rw</FLAGS>
<FLAGS>rwx</FLAGS>
<NICK>Encoding Bit-rate</NICK>
<BLURB>Specify an encoding bit-rate (in bps). (0 = automatic).</BLURB>
<DEFAULT>0</DEFAULT>
@ -1532,7 +1582,7 @@
<NAME>GstSpeexEnc::complexity</NAME>
<TYPE>gint</TYPE>
<RANGE>>= 0</RANGE>
<FLAGS>rw</FLAGS>
<FLAGS>rwx</FLAGS>
<NICK>Complexity</NICK>
<BLURB>Set encoding complexity.</BLURB>
<DEFAULT>3</DEFAULT>
@ -1542,7 +1592,7 @@
<NAME>GstSpeexEnc::dtx</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<FLAGS>rwx</FLAGS>
<NICK>DTX</NICK>
<BLURB>Enable discontinuous transmission.</BLURB>
<DEFAULT>FALSE</DEFAULT>
@ -1562,7 +1612,7 @@
<NAME>GstSpeexEnc::nframes</NAME>
<TYPE>gint</TYPE>
<RANGE>>= 0</RANGE>
<FLAGS>rw</FLAGS>
<FLAGS>rwx</FLAGS>
<NICK>NFrames</NICK>
<BLURB>Number of frames per buffer.</BLURB>
<DEFAULT>1</DEFAULT>
@ -1572,7 +1622,7 @@
<NAME>GstSpeexEnc::quality</NAME>
<TYPE>gfloat</TYPE>
<RANGE>[0,10]</RANGE>
<FLAGS>rw</FLAGS>
<FLAGS>rwx</FLAGS>
<NICK>Quality</NICK>
<BLURB>Encoding quality.</BLURB>
<DEFAULT>8</DEFAULT>
@ -1582,7 +1632,7 @@
<NAME>GstSpeexEnc::vad</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<FLAGS>rwx</FLAGS>
<NICK>VAD</NICK>
<BLURB>Enable voice activity detection.</BLURB>
<DEFAULT>FALSE</DEFAULT>
@ -1592,7 +1642,7 @@
<NAME>GstSpeexEnc::vbr</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<FLAGS>rwx</FLAGS>
<NICK>VBR</NICK>
<BLURB>Enable variable bit-rate.</BLURB>
<DEFAULT>FALSE</DEFAULT>
@ -1602,7 +1652,7 @@
<NAME>GstSpeexEnc::mode</NAME>
<TYPE>GstSpeexEncMode</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<FLAGS>rwx</FLAGS>
<NICK>Mode</NICK>
<BLURB>The encoding mode.</BLURB>
<DEFAULT>Auto</DEFAULT>
@ -1651,7 +1701,7 @@
<ARG>
<NAME>GstDV1394Src::port</NAME>
<TYPE>gint</TYPE>
<RANGE>[-1,16]</RANGE>
<RANGE>[G_MAXULONG,16]</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Port</NICK>
<BLURB>Port number (-1 automatic).</BLURB>
@ -1901,7 +1951,7 @@
<ARG>
<NAME>GstTest::allowed-timestamp-deviation</NAME>
<TYPE>gint64</TYPE>
<RANGE>>= -1</RANGE>
<RANGE>>= G_MAXULONG</RANGE>
<FLAGS>rwx</FLAGS>
<NICK>allowed timestamp deviation</NICK>
<BLURB>allowed average difference in usec between timestamp of next buffer and expected timestamp from analyzing last buffer.</BLURB>
@ -1911,7 +1961,7 @@
<ARG>
<NAME>GstTest::buffer-count</NAME>
<TYPE>gint64</TYPE>
<RANGE>>= -1</RANGE>
<RANGE>>= G_MAXULONG</RANGE>
<FLAGS>r</FLAGS>
<NICK>buffer count</NICK>
<BLURB>number of buffers in stream.</BLURB>
@ -1921,7 +1971,7 @@
<ARG>
<NAME>GstTest::expected-buffer-count</NAME>
<TYPE>gint64</TYPE>
<RANGE>>= -1</RANGE>
<RANGE>>= G_MAXULONG</RANGE>
<FLAGS>rwx</FLAGS>
<NICK>expected buffer count</NICK>
<BLURB>expected number of buffers in stream.</BLURB>
@ -1931,7 +1981,7 @@
<ARG>
<NAME>GstTest::expected-length</NAME>
<TYPE>gint64</TYPE>
<RANGE>>= -1</RANGE>
<RANGE>>= G_MAXULONG</RANGE>
<FLAGS>rwx</FLAGS>
<NICK>expected length</NICK>
<BLURB>expected length of stream.</BLURB>
@ -1951,7 +2001,7 @@
<ARG>
<NAME>GstTest::length</NAME>
<TYPE>gint64</TYPE>
<RANGE>>= -1</RANGE>
<RANGE>>= G_MAXULONG</RANGE>
<FLAGS>r</FLAGS>
<NICK>length</NICK>
<BLURB>length of stream.</BLURB>
@ -1971,7 +2021,7 @@
<ARG>
<NAME>GstTest::timestamp-deviation</NAME>
<TYPE>gint64</TYPE>
<RANGE>>= -1</RANGE>
<RANGE>>= G_MAXULONG</RANGE>
<FLAGS>r</FLAGS>
<NICK>timestamp deviation</NICK>
<BLURB>average difference in usec between timestamp of next buffer and expected timestamp from analyzing last buffer.</BLURB>
@ -2051,7 +2101,7 @@
<ARG>
<NAME>GstBreakMyData::set-to</NAME>
<TYPE>gint</TYPE>
<RANGE>[-1,255]</RANGE>
<RANGE>[G_MAXULONG,255]</RANGE>
<FLAGS>rwx</FLAGS>
<NICK>set-to</NICK>
<BLURB>set changed bytes to this value (-1 means random value.</BLURB>
@ -2224,7 +2274,7 @@
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Send Config</NICK>
<BLURB>Send the config parameters in RTP packets as well.</BLURB>
<BLURB>Send the config parameters in RTP packets as well(deprecated see config-interval).</BLURB>
<DEFAULT>FALSE</DEFAULT>
</ARG>
@ -2358,6 +2408,16 @@
<DEFAULT>25</DEFAULT>
</ARG>
<ARG>
<NAME>GstCairoTextOverlay::silent</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>w</FLAGS>
<NICK>silent</NICK>
<BLURB>Whether to render the text string.</BLURB>
<DEFAULT>FALSE</DEFAULT>
</ARG>
<ARG>
<NAME>GstOssMixerElement::device-name</NAME>
<TYPE>gchar*</TYPE>
@ -2391,7 +2451,7 @@
<ARG>
<NAME>GstDynUDPSink::sockfd</NAME>
<TYPE>gint</TYPE>
<RANGE>[-1,32767]</RANGE>
<RANGE>[G_MAXULONG,32767]</RANGE>
<FLAGS>rw</FLAGS>
<NICK>socket handle</NICK>
<BLURB>Socket to use for UDP sending. (-1 == allocate).</BLURB>
@ -2461,7 +2521,7 @@
<ARG>
<NAME>GstMultiUDPSink::sock</NAME>
<TYPE>gint</TYPE>
<RANGE>>= -1</RANGE>
<RANGE>>= G_MAXULONG</RANGE>
<FLAGS>r</FLAGS>
<NICK>Socket Handle</NICK>
<BLURB>Socket currently in use for UDP sending. (-1 == no socket).</BLURB>
@ -2471,7 +2531,7 @@
<ARG>
<NAME>GstMultiUDPSink::sockfd</NAME>
<TYPE>gint</TYPE>
<RANGE>>= -1</RANGE>
<RANGE>>= G_MAXULONG</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Socket Handle</NICK>
<BLURB>Socket to use for UDP sending. (-1 == allocate).</BLURB>
@ -2501,7 +2561,7 @@
<ARG>
<NAME>GstMultiUDPSink::qos-dscp</NAME>
<TYPE>gint</TYPE>
<RANGE>[-1,63]</RANGE>
<RANGE>[G_MAXULONG,63]</RANGE>
<FLAGS>rw</FLAGS>
<NICK>QoS diff srv code point</NICK>
<BLURB>Quality of Service, differentiated services code point (-1 default).</BLURB>
@ -2651,7 +2711,7 @@
<ARG>
<NAME>GstXImageSrc::screen-num</NAME>
<TYPE>guint</TYPE>
<RANGE><= G_MAXLONG</RANGE>
<RANGE><= G_MAXINT</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Screen number</NICK>
<BLURB>X Screen Number.</BLURB>
@ -2671,7 +2731,7 @@
<ARG>
<NAME>GstXImageSrc::endx</NAME>
<TYPE>guint</TYPE>
<RANGE><= G_MAXLONG</RANGE>
<RANGE><= G_MAXINT</RANGE>
<FLAGS>rw</FLAGS>
<NICK>End X</NICK>
<BLURB>X coordinate of bottom right corner of area to be recorded (0 for bottom right of screen).</BLURB>
@ -2681,7 +2741,7 @@
<ARG>
<NAME>GstXImageSrc::endy</NAME>
<TYPE>guint</TYPE>
<RANGE><= G_MAXLONG</RANGE>
<RANGE><= G_MAXINT</RANGE>
<FLAGS>rw</FLAGS>
<NICK>End Y</NICK>
<BLURB>Y coordinate of bottom right corner of area to be recorded (0 for bottom right of screen).</BLURB>
@ -2691,7 +2751,7 @@
<ARG>
<NAME>GstXImageSrc::startx</NAME>
<TYPE>guint</TYPE>
<RANGE><= G_MAXLONG</RANGE>
<RANGE><= G_MAXINT</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Start X co-ordinate</NICK>
<BLURB>X coordinate of top left corner of area to be recorded (0 for top left of screen).</BLURB>
@ -2701,7 +2761,7 @@
<ARG>
<NAME>GstXImageSrc::starty</NAME>
<TYPE>guint</TYPE>
<RANGE><= G_MAXLONG</RANGE>
<RANGE><= G_MAXINT</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Start Y co-ordinate</NICK>
<BLURB>Y coordinate of top left corner of area to be recorded (0 for top left of screen).</BLURB>
@ -2728,6 +2788,26 @@
<DEFAULT>FALSE</DEFAULT>
</ARG>
<ARG>
<NAME>GstXImageSrc::xid</NAME>
<TYPE>guint64</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Window XID</NICK>
<BLURB>Window XID to capture from.</BLURB>
<DEFAULT>0</DEFAULT>
</ARG>
<ARG>
<NAME>GstXImageSrc::xname</NAME>
<TYPE>gchar*</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Window name</NICK>
<BLURB>Window name to capture from.</BLURB>
<DEFAULT>NULL</DEFAULT>
</ARG>
<ARG>
<NAME>GstVideoBalance::brightness</NAME>
<TYPE>gdouble</TYPE>
@ -2788,6 +2868,16 @@
<DEFAULT>NULL</DEFAULT>
</ARG>
<ARG>
<NAME>GstMultipartDemux::single-stream</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Single Stream</NICK>
<BLURB>Assume that there is only one stream whose content-type will not change and emit no-more-pads as soon as the first boundary content is parsed, decoded, and pads are linked.</BLURB>
<DEFAULT>FALSE</DEFAULT>
</ARG>
<ARG>
<NAME>GstAviMux::bigfile</NAME>
<TYPE>gboolean</TYPE>
@ -2811,7 +2901,7 @@
<ARG>
<NAME>GstJpegDec::max-errors</NAME>
<TYPE>gint</TYPE>
<RANGE>>= -1</RANGE>
<RANGE>>= G_MAXULONG</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Maximum Consecutive Decoding Errors</NICK>
<BLURB>Error out after receiving N consecutive decoding errors (-1 = never fail, 0 = automatic, 1 = fail on first error).</BLURB>
@ -3121,7 +3211,7 @@
<ARG>
<NAME>GstV4l2Src::device-fd</NAME>
<TYPE>gint</TYPE>
<RANGE>>= -1</RANGE>
<RANGE>>= G_MAXULONG</RANGE>
<FLAGS>r</FLAGS>
<NICK>File descriptor</NICK>
<BLURB>File descriptor of the device.</BLURB>
@ -3178,6 +3268,16 @@
<DEFAULT>0</DEFAULT>
</ARG>
<ARG>
<NAME>GstV4l2Src::norm</NAME>
<TYPE>V4L2_TV_norms</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>TV norm</NICK>
<BLURB>video standard.</BLURB>
<DEFAULT>none</DEFAULT>
</ARG>
<ARG>
<NAME>GstAudioChebBand::lower-frequency</NAME>
<TYPE>gfloat</TYPE>
@ -3391,7 +3491,7 @@
<ARG>
<NAME>GstRndBufferSize::max</NAME>
<TYPE>glong</TYPE>
<RANGE>>= 1</RANGE>
<RANGE>[1,G_MAXINT]</RANGE>
<FLAGS>rwx</FLAGS>
<NICK>maximum</NICK>
<BLURB>maximum buffer size.</BLURB>
@ -3401,7 +3501,7 @@
<ARG>
<NAME>GstRndBufferSize::min</NAME>
<TYPE>glong</TYPE>
<RANGE>>= 0</RANGE>
<RANGE>[0,G_MAXINT]</RANGE>
<FLAGS>rwx</FLAGS>
<NICK>mininum</NICK>
<BLURB>mininum buffer size.</BLURB>
@ -3411,7 +3511,7 @@
<ARG>
<NAME>GstRndBufferSize::seed</NAME>
<TYPE>gulong</TYPE>
<RANGE></RANGE>
<RANGE><= G_MAXUINT</RANGE>
<FLAGS>rwx</FLAGS>
<NICK>random number seed</NICK>
<BLURB>seed for randomness (initialized when going from READY to PAUSED).</BLURB>
@ -19898,6 +19998,36 @@
<DEFAULT>"<unknown>"</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseSrc::mute</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Mute</NICK>
<BLURB>Mute state of this stream.</BLURB>
<DEFAULT>FALSE</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseSrc::source-output-index</NAME>
<TYPE>guint</TYPE>
<RANGE></RANGE>
<FLAGS>r</FLAGS>
<NICK>source output index</NICK>
<BLURB>The index of the PulseAudio source output corresponding to this record stream.</BLURB>
<DEFAULT>4294967295</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseSrc::volume</NAME>
<TYPE>gdouble</TYPE>
<RANGE>[0,10]</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Volume</NICK>
<BLURB>Linear volume of this stream, 1.0=100%.</BLURB>
<DEFAULT>1</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseMixer::device</NAME>
<TYPE>gchar*</TYPE>
@ -20111,7 +20241,7 @@
<ARG>
<NAME>GstHDV1394Src::port</NAME>
<TYPE>gint</TYPE>
<RANGE>[-1,16]</RANGE>
<RANGE>[G_MAXULONG,16]</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Port</NICK>
<BLURB>Port number (-1 automatic).</BLURB>
@ -20491,7 +20621,7 @@
<ARG>
<NAME>GstOpTV::threshold</NAME>
<TYPE>guint</TYPE>
<RANGE><= G_MAXLONG</RANGE>
<RANGE><= G_MAXINT</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Threshold</NICK>
<BLURB>Luma threshold.</BLURB>
@ -20511,7 +20641,7 @@
<ARG>
<NAME>GstRadioacTV::interval</NAME>
<TYPE>guint</TYPE>
<RANGE><= G_MAXLONG</RANGE>
<RANGE><= G_MAXINT</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Interval</NICK>
<BLURB>Snapshot interval (in strobe mode).</BLURB>
@ -20648,6 +20778,26 @@
<DEFAULT>FALSE</DEFAULT>
</ARG>
<ARG>
<NAME>GstRtpBin::rtcp-sync</NAME>
<TYPE>GstRTCPSync</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>RTCP Sync</NICK>
<BLURB>Use of RTCP SR in synchronization.</BLURB>
<DEFAULT>always</DEFAULT>
</ARG>
<ARG>
<NAME>GstRtpBin::rtcp-sync-interval</NAME>
<TYPE>guint</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>RTCP Sync Interval</NICK>
<BLURB>RTCP SR interval synchronization (ms) (0 = always).</BLURB>
<DEFAULT>0</DEFAULT>
</ARG>
<ARG>
<NAME>GstRtpJitterBuffer::do-lost</NAME>
<TYPE>gboolean</TYPE>
@ -20781,7 +20931,7 @@
<ARG>
<NAME>GstRtpSession::rtcp-rr-bandwidth</NAME>
<TYPE>gint</TYPE>
<RANGE>>= -1</RANGE>
<RANGE>>= G_MAXULONG</RANGE>
<FLAGS>rw</FLAGS>
<NICK>RTCP RR bandwidth</NICK>
<BLURB>The RTCP bandwidth used for receivers in bytes per second (-1 = default).</BLURB>
@ -20791,7 +20941,7 @@
<ARG>
<NAME>GstRtpSession::rtcp-rs-bandwidth</NAME>
<TYPE>gint</TYPE>
<RANGE>>= -1</RANGE>
<RANGE>>= G_MAXULONG</RANGE>
<FLAGS>rw</FLAGS>
<NICK>RTCP RS bandwidth</NICK>
<BLURB>The RTCP bandwidth used for senders in bytes per second (-1 = default).</BLURB>
@ -21858,3 +22008,383 @@
<DEFAULT>0</DEFAULT>
</ARG>
<ARG>
<NAME>GstSplitFileSrc::location</NAME>
<TYPE>gchar*</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>File Location</NICK>
<BLURB>Wildcard pattern to match file names of the input files. If the location is an absolute path or contains directory components, only the base file name part will be considered for pattern matching. The results will be sorted.</BLURB>
<DEFAULT>NULL</DEFAULT>
</ARG>
<ARG>
<NAME>GstMatroskaDemux::max-gap-time</NAME>
<TYPE>guint64</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Maximum gap time</NICK>
<BLURB>The demuxer sends out newsegment events for skipping gaps longer than this (0 = disabled).</BLURB>
<DEFAULT>2000000000</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::alignment-threshold</NAME>
<TYPE>guint64</TYPE>
<RANGE>[1,18446744073709551614]</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Alignment Threshold</NICK>
<BLURB>Timestamp alignment threshold in nanoseconds.</BLURB>
<DEFAULT>40000000</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::async</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Async</NICK>
<BLURB>Go asynchronously to PAUSED.</BLURB>
<DEFAULT>TRUE</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::blocksize</NAME>
<TYPE>guint</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Block size</NICK>
<BLURB>Size in bytes to pull per buffer (0 = default).</BLURB>
<DEFAULT>4096</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::buffer-time</NAME>
<TYPE>gint64</TYPE>
<RANGE>>= 1</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Buffer Time</NICK>
<BLURB>Size of audio buffer in microseconds.</BLURB>
<DEFAULT>200000</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::can-activate-pull</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Allow Pull Scheduling</NICK>
<BLURB>Allow pull-based scheduling.</BLURB>
<DEFAULT>FALSE</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::client</NAME>
<TYPE>gchar*</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Client</NICK>
<BLURB>The PulseAudio client name to use.</BLURB>
<DEFAULT>"<unknown>"</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::device</NAME>
<TYPE>gchar*</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Device</NICK>
<BLURB>The PulseAudio sink device to connect to.</BLURB>
<DEFAULT>NULL</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::device-name</NAME>
<TYPE>gchar*</TYPE>
<RANGE></RANGE>
<FLAGS>r</FLAGS>
<NICK>Device name</NICK>
<BLURB>Human-readable name of the sound device.</BLURB>
<DEFAULT>NULL</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::discont-wait</NAME>
<TYPE>guint64</TYPE>
<RANGE><= 18446744073709551614</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Discont Wait</NICK>
<BLURB>Window of time in nanoseconds to wait before creating a discontinuity.</BLURB>
<DEFAULT>1000000000</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::drift-tolerance</NAME>
<TYPE>gint64</TYPE>
<RANGE>>= 1</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Drift Tolerance</NICK>
<BLURB>Tolerance for clock drift in microseconds.</BLURB>
<DEFAULT>40000</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::enable-last-buffer</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Enable Last Buffer</NICK>
<BLURB>Enable the last-buffer property.</BLURB>
<DEFAULT>TRUE</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::last-buffer</NAME>
<TYPE>GstBuffer*</TYPE>
<RANGE></RANGE>
<FLAGS>r</FLAGS>
<NICK>Last Buffer</NICK>
<BLURB>The last buffer received in the sink.</BLURB>
<DEFAULT></DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::latency-time</NAME>
<TYPE>gint64</TYPE>
<RANGE>>= 1</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Latency Time</NICK>
<BLURB>Audio latency in microseconds.</BLURB>
<DEFAULT>10000</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::max-lateness</NAME>
<TYPE>gint64</TYPE>
<RANGE>>= G_MAXULONG</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Max Lateness</NICK>
<BLURB>Maximum number of nanoseconds that a buffer can be late before it is dropped (-1 unlimited).</BLURB>
<DEFAULT>-1</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::mute</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Mute</NICK>
<BLURB>Mute state of this stream.</BLURB>
<DEFAULT>FALSE</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::preroll-queue-len</NAME>
<TYPE>guint</TYPE>
<RANGE></RANGE>
<FLAGS>rwx</FLAGS>
<NICK>Preroll queue length</NICK>
<BLURB>Number of buffers to queue during preroll.</BLURB>
<DEFAULT>0</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::provide-clock</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Provide Clock</NICK>
<BLURB>Provide a clock to be used as the global pipeline clock.</BLURB>
<DEFAULT>TRUE</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::qos</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Qos</NICK>
<BLURB>Generate Quality-of-Service events upstream.</BLURB>
<DEFAULT>FALSE</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::render-delay</NAME>
<TYPE>guint64</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Render Delay</NICK>
<BLURB>Additional render delay of the sink in nanoseconds.</BLURB>
<DEFAULT>0</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::server</NAME>
<TYPE>gchar*</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Server</NICK>
<BLURB>The PulseAudio server to connect to.</BLURB>
<DEFAULT>NULL</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::slave-method</NAME>
<TYPE>GstBaseAudioSinkSlaveMethod</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Slave Method</NICK>
<BLURB>Algorithm to use to match the rate of the masterclock.</BLURB>
<DEFAULT>GST_BASE_AUDIO_SINK_SLAVE_SKEW</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::stream-properties</NAME>
<TYPE>GstStructure*</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>stream properties</NICK>
<BLURB>list of pulseaudio stream properties.</BLURB>
<DEFAULT></DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::sync</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Sync</NICK>
<BLURB>Sync on the clock.</BLURB>
<DEFAULT>TRUE</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::throttle-time</NAME>
<TYPE>guint64</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Throttle time</NICK>
<BLURB>The time to keep between rendered buffers (unused).</BLURB>
<DEFAULT>0</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::ts-offset</NAME>
<TYPE>gint64</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>TS Offset</NICK>
<BLURB>Timestamp offset in nanoseconds.</BLURB>
<DEFAULT>0</DEFAULT>
</ARG>
<ARG>
<NAME>GstPulseAudioSink::volume</NAME>
<TYPE>gdouble</TYPE>
<RANGE>[0,10]</RANGE>
<FLAGS>rw</FLAGS>
<NICK>Volume</NICK>
<BLURB>Linear volume of this stream, 1.0=100%.</BLURB>
<DEFAULT>1</DEFAULT>
</ARG>
<ARG>
<NAME>GstSoupHttpClientSink::automatic-redirect</NAME>
<TYPE>gboolean</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>automatic-redirect</NICK>
<BLURB>Automatically follow HTTP redirects (HTTP Status Code 3xx).</BLURB>
<DEFAULT>TRUE</DEFAULT>
</ARG>
<ARG>
<NAME>GstSoupHttpClientSink::cookies</NAME>
<TYPE>GStrv</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Cookies</NICK>
<BLURB>HTTP request cookies.</BLURB>
<DEFAULT></DEFAULT>
</ARG>
<ARG>
<NAME>GstSoupHttpClientSink::location</NAME>
<TYPE>gchar*</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Location</NICK>
<BLURB>URI to send to.</BLURB>
<DEFAULT>""</DEFAULT>
</ARG>
<ARG>
<NAME>GstSoupHttpClientSink::proxy</NAME>
<TYPE>gchar*</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>Proxy</NICK>
<BLURB>HTTP proxy server URI.</BLURB>
<DEFAULT>""</DEFAULT>
</ARG>
<ARG>
<NAME>GstSoupHttpClientSink::proxy-id</NAME>
<TYPE>gchar*</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>proxy-id</NICK>
<BLURB>user id for proxy authentication.</BLURB>
<DEFAULT>""</DEFAULT>
</ARG>
<ARG>
<NAME>GstSoupHttpClientSink::proxy-pw</NAME>
<TYPE>gchar*</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>proxy-pw</NICK>
<BLURB>user password for proxy authentication.</BLURB>
<DEFAULT>""</DEFAULT>
</ARG>
<ARG>
<NAME>GstSoupHttpClientSink::session</NAME>
<TYPE>SoupSession*</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>session</NICK>
<BLURB>SoupSession object to use for communication.</BLURB>
<DEFAULT></DEFAULT>
</ARG>
<ARG>
<NAME>GstSoupHttpClientSink::user-agent</NAME>
<TYPE>gchar*</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>User-Agent</NICK>
<BLURB>Value of the User-Agent HTTP request header field.</BLURB>
<DEFAULT>"GStreamer souphttpclientsink "</DEFAULT>
</ARG>
<ARG>
<NAME>GstSoupHttpClientSink::user-id</NAME>
<TYPE>gchar*</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>user-id</NICK>
<BLURB>user id for authentication.</BLURB>
<DEFAULT>""</DEFAULT>
</ARG>
<ARG>
<NAME>GstSoupHttpClientSink::user-pw</NAME>
<TYPE>gchar*</TYPE>
<RANGE></RANGE>
<FLAGS>rw</FLAGS>
<NICK>user-pw</NICK>
<BLURB>user password for authentication.</BLURB>
<DEFAULT>""</DEFAULT>
</ARG>

View file

@ -15,6 +15,11 @@ GObject
GstALawEnc
GstAsteriskh263
GstAuParse
GstAudioDecoder
GstSpeexDec
GstAudioEncoder
GstFlacEnc
GstSpeexEnc
GstAviDemux
GstAviMux
GstAviSubtitle
@ -111,10 +116,10 @@ GObject
GstMultiUDPSink
GstUDPSink
GstShout2send
GstSoupHttpClientSink
GstTest
GstVideoSink
GstGdkPixbufSink
GstV4l2Sink
GstBaseSrc
GstPushSrc
GstBaseAudioSrc
@ -130,6 +135,7 @@ GObject
GstUDPSrc
GstV4l2Src
GstXImageSrc
GstSplitFileSrc
GstBaseTransform
GstAudioFilter
GstAudioAmplify
@ -195,6 +201,7 @@ GObject
GstHalAudioSrc
GstPipeline
GstQTMoovRecover
GstPulseAudioSink
GstPushFileSrc
GstRTSPSrc
GstRgVolume
@ -217,7 +224,6 @@ GObject
GstDeinterleave
GstEFence
GstFlacDec
GstFlacEnc
GstFlacTag
GstFlvDemux
GstFlvMux
@ -261,8 +267,6 @@ GObject
GstShapeWipe
GstSmokeDec
GstSmokeEnc
GstSpeexDec
GstSpeexEnc
GstTagDemux
GstApeDemux
GstID3Demux
@ -300,6 +304,7 @@ GObject
GstTunerChannel
GstTunerNorm
RTPSession
SoupSession
GInterface
GIcon
GTypePlugin
@ -307,7 +312,6 @@ GInterface
GstColorBalance
GstImplementsInterface
GstMixer
GstNavigation
GstPreset
GstPropertyProbe
GstStreamVolume
@ -316,4 +320,3 @@ GInterface
GstTuner
GstURIHandler
GstVideoOrientation
GstXOverlay

View file

@ -2,6 +2,7 @@ GdkPixbuf GIcon
Gst3GPPMux GstTagSetter GstTagXmpWriter
GstApev2Mux GstTagSetter
GstAspectRatioCrop GstChildProxy
GstAudioEncoder GstPreset
GstAutoAudioSink GstChildProxy
GstAutoAudioSrc GstChildProxy
GstAutoVideoSink GstChildProxy
@ -10,6 +11,7 @@ GstAviMux GstTagSetter
GstBin GstChildProxy
GstDV1394Src GstURIHandler GstPropertyProbe
GstDeinterlace GstChildProxy
GstFlacEnc GstPreset GstTagSetter
GstFlacEnc GstTagSetter GstPreset
GstFlacTag GstTagSetter
GstFlvMux GstTagSetter
@ -36,9 +38,11 @@ GstOss4Source GstImplementsInterface GstMixer GstPropertyProbe
GstOssMixerElement GstImplementsInterface GstMixer
GstOssSrc GstImplementsInterface GstMixer
GstPipeline GstChildProxy
GstPulseAudioSink GstChildProxy
GstPulseMixer GstImplementsInterface GstMixer GstPropertyProbe
GstPulseSink GstStreamVolume GstImplementsInterface GstPropertyProbe
GstPulseSrc GstImplementsInterface GstMixer GstPropertyProbe
GstPulseSrc GstStreamVolume GstImplementsInterface GstMixer GstPropertyProbe
GstPushFileSrc GstChildProxy GstURIHandler
GstQTMoovRecover GstChildProxy
GstQTMux GstTagSetter GstTagXmpWriter
@ -47,6 +51,7 @@ GstRgVolume GstChildProxy
GstRtpBin GstChildProxy
GstShout2send GstTagSetter
GstSoupHTTPSrc GstURIHandler
GstSpeexEnc GstPreset GstTagSetter
GstSpeexEnc GstTagSetter GstPreset
GstSwitchSink GstChildProxy
GstSwitchSrc GstChildProxy

View file

@ -14,7 +14,7 @@ GstGSMEnc *gstgsmenc
<SIGNAL>
<NAME>GstMultiUDPSink::add</NAME>
<RETURNS>void</RETURNS>
<FLAGS>l</FLAGS>
<FLAGS>la</FLAGS>
GstMultiUDPSink *gstmultiudpsink
gchar *arg1
gint arg2
@ -23,7 +23,7 @@ gint arg2
<SIGNAL>
<NAME>GstMultiUDPSink::clear</NAME>
<RETURNS>void</RETURNS>
<FLAGS>l</FLAGS>
<FLAGS>la</FLAGS>
GstMultiUDPSink *gstmultiudpsink
</SIGNAL>
@ -48,7 +48,7 @@ gint arg2
<SIGNAL>
<NAME>GstMultiUDPSink::get-stats</NAME>
<RETURNS>GValueArray*</RETURNS>
<FLAGS>l</FLAGS>
<FLAGS>la</FLAGS>
GstMultiUDPSink *gstmultiudpsink
gchar *arg1
gint arg2
@ -57,7 +57,7 @@ gint arg2
<SIGNAL>
<NAME>GstMultiUDPSink::remove</NAME>
<RETURNS>void</RETURNS>
<FLAGS>l</FLAGS>
<FLAGS>la</FLAGS>
GstMultiUDPSink *gstmultiudpsink
gchar *arg1
gint arg2

View file

@ -40,4 +40,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -25,4 +25,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -52,4 +52,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -33,4 +33,4 @@ Jan Schmidt &lt;thaytan@noraisin.net&gt;</author>
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -52,4 +52,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -262,4 +262,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -20,7 +20,7 @@
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>audio/mpeg, framed=(boolean)false, mpegversion=(int){ 2, 4 }</details>
<details>audio/mpeg, mpegversion=(int){ 2, 4 }</details>
</caps>
<caps>
<name>src</name>
@ -33,7 +33,7 @@
<element>
<name>ac3parse</name>
<longname>AC3 audio stream parser</longname>
<class>Codec/Parser/Audio</class>
<class>Codec/Parser/Converter/Audio</class>
<description>AC3 parser</description>
<author>Tim-Philipp Müller &lt;tim centricular net&gt;</author>
<pads>
@ -41,13 +41,13 @@
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>audio/x-ac3, framed=(boolean)false; audio/x-eac3, framed=(boolean)false; audio/ac3, framed=(boolean)false</details>
<details>audio/x-ac3; audio/x-eac3; audio/ac3</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>audio/x-ac3, framed=(boolean)true, channels=(int)[ 1, 6 ], rate=(int)[ 32000, 48000 ]; audio/x-eac3, framed=(boolean)true, channels=(int)[ 1, 6 ], rate=(int)[ 32000, 48000 ]</details>
<details>audio/x-ac3, framed=(boolean)true, channels=(int)[ 1, 6 ], rate=(int)[ 8000, 48000 ], alignment=(string){ iec61937, frame }; audio/x-eac3, framed=(boolean)true, channels=(int)[ 1, 6 ], rate=(int)[ 8000, 48000 ], alignment=(string){ iec61937, frame }</details>
</caps>
</pads>
</element>
@ -83,13 +83,13 @@
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>audio/x-dts, framed=(boolean)false</details>
<details>audio/x-dts</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>audio/x-dts, framed=(boolean)true, channels=(int)[ 1, 8 ], rate=(int)[ 8000, 192000 ], depth=(int){ 14, 16 }, endianness=(int){ 1234, 4321 }</details>
<details>audio/x-dts, framed=(boolean)true, channels=(int)[ 1, 8 ], rate=(int)[ 8000, 192000 ], depth=(int){ 14, 16 }, endianness=(int){ 1234, 4321 }, block-size=(int)[ 1, 2147483647 ], frame-size=(int)[ 1, 2147483647 ]</details>
</caps>
</pads>
</element>
@ -104,7 +104,7 @@
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>audio/x-flac, framed=(boolean)false</details>
<details>audio/x-flac</details>
</caps>
<caps>
<name>src</name>
@ -125,15 +125,15 @@
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>audio/mpeg, mpegversion=(int)1, parsed=(boolean)false</details>
<details>audio/mpeg, mpegversion=(int)1</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>audio/mpeg, mpegversion=(int)1, layer=(int)[ 1, 3 ], rate=(int)[ 8000, 48000 ], channels=(int)[ 1, 2 ], parsed=(boolean)true</details>
<details>audio/mpeg, mpegversion=(int)1, layer=(int)[ 1, 3 ], mpegaudioversion=(int)[ 1, 3 ], rate=(int)[ 8000, 48000 ], channels=(int)[ 1, 2 ], parsed=(boolean)true</details>
</caps>
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -70,4 +70,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -59,7 +59,7 @@
<name>video_%d</name>
<direction>sink</direction>
<presence>request</presence>
<details>video/x-raw-yuv, format=(fourcc){ YUY2, I420 }, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; image/jpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-divx, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ], divxversion=(int)[ 3, 5 ]; video/x-xvid, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-3ivx, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-msmpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ], msmpegversion=(int)[ 41, 43 ]; video/mpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ], mpegversion=(int){ 1, 2, 4 }, systemstream=(boolean)false; video/x-h263, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-dv, width=(int)720, height=(int){ 576, 480 }, framerate=(fraction)[ 0/1, 2147483647/1 ], systemstream=(boolean)false; video/x-huffyuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-dirac, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-wmv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ], wmvversion=(int)[ 1, 3 ]; image/x-jpc, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-vp8, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
<details>video/x-raw-yuv, format=(fourcc){ YUY2, I420 }, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; image/jpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-divx, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ], divxversion=(int)[ 3, 5 ]; video/x-xvid, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-3ivx, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-msmpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ], msmpegversion=(int)[ 41, 43 ]; video/mpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ], mpegversion=(int){ 1, 2, 4 }, systemstream=(boolean)false; video/x-h263, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-dv, width=(int)720, height=(int){ 576, 480 }, framerate=(fraction)[ 0/1, 2147483647/1 ], systemstream=(boolean)false; video/x-huffyuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-wmv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ], wmvversion=(int)[ 1, 3 ]; image/x-jpc, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-vp8, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
</caps>
<caps>
<name>src</name>
@ -91,4 +91,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -25,4 +25,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -100,4 +100,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -155,7 +155,7 @@
<longname>Random buffer size</longname>
<class>Testing</class>
<description>pull random sized buffers</description>
<author>Stefan Kost &lt;stefan.kost@nokia.com&gt;)</author>
<author>Stefan Kost &lt;stefan.kost@nokia.com&gt;</author>
<pads>
<caps>
<name>sink</name>
@ -208,4 +208,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -58,4 +58,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -125,13 +125,13 @@
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
<details>video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
<details>video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
</caps>
</pads>
</element>
@ -262,4 +262,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -73,4 +73,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -73,4 +73,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -47,7 +47,7 @@
<name>audio</name>
<direction>sink</direction>
<presence>request</presence>
<details>audio/x-adpcm, layout=(string)swf, channels=(int){ 1, 2 }, rate=(int){ 5512, 11025, 22050, 44100 }; audio/mpeg, mpegversion=(int)1, layer=(int)3, channels=(int){ 1, 2 }, rate=(int){ 5512, 8000, 11025, 22050, 44100 }, parsed=(boolean)true; audio/mpeg, mpegversion=(int)4, framed=(boolean)true; audio/x-nellymoser, channels=(int){ 1, 2 }, rate=(int){ 5512, 8000, 11025, 16000, 22050, 44100 }; audio/x-raw-int, endianness=(int)1234, channels=(int){ 1, 2 }, width=(int)8, depth=(int)8, rate=(int){ 5512, 11025, 22050, 44100 }, signed=(boolean)false; audio/x-raw-int, endianness=(int)1234, channels=(int){ 1, 2 }, width=(int)16, depth=(int)16, rate=(int){ 5512, 11025, 22050, 44100 }, signed=(boolean)true; audio/x-alaw, channels=(int){ 1, 2 }, rate=(int){ 5512, 11025, 22050, 44100 }; audio/x-mulaw, channels=(int){ 1, 2 }, rate=(int){ 5512, 11025, 22050, 44100 }; audio/x-speex, channels=(int){ 1, 2 }, rate=(int){ 5512, 11025, 22050, 44100 }</details>
<details>audio/x-adpcm, layout=(string)swf, channels=(int){ 1, 2 }, rate=(int){ 5512, 11025, 22050, 44100 }; audio/mpeg, mpegversion=(int)1, layer=(int)3, channels=(int){ 1, 2 }, rate=(int){ 5512, 8000, 11025, 22050, 44100 }, parsed=(boolean)true; audio/mpeg, mpegversion=(int){ 2, 4 }, framed=(boolean)true; audio/x-nellymoser, channels=(int){ 1, 2 }, rate=(int){ 5512, 8000, 11025, 16000, 22050, 44100 }; audio/x-raw-int, endianness=(int)1234, channels=(int){ 1, 2 }, width=(int)8, depth=(int)8, rate=(int){ 5512, 11025, 22050, 44100 }, signed=(boolean)false; audio/x-raw-int, endianness=(int)1234, channels=(int){ 1, 2 }, width=(int)16, depth=(int)16, rate=(int){ 5512, 11025, 22050, 44100 }, signed=(boolean)true; audio/x-alaw, channels=(int){ 1, 2 }, rate=(int){ 5512, 11025, 22050, 44100 }; audio/x-mulaw, channels=(int){ 1, 2 }, rate=(int){ 5512, 11025, 22050, 44100 }; audio/x-speex, channels=(int){ 1, 2 }, rate=(int){ 5512, 11025, 22050, 44100 }</details>
</caps>
<caps>
<name>video</name>
@ -64,4 +64,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -67,4 +67,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -40,4 +40,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -52,4 +52,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -86,7 +86,7 @@
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>video/quicktime, variant=(string)iso</details>
<details>video/quicktime, variant=(string)iso-fragmented</details>
</caps>
</pads>
</element>
@ -203,7 +203,7 @@
<name>video_%d</name>
<direction>sink</direction>
<presence>request</presence>
<details>video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-yuv, format=(fourcc)UYVY, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/mpeg, mpegversion=(int)4, systemstream=(boolean)false, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-divx, divxversion=(int)5, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-h263, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-h264, stream-format=(string)avc, alignment=(string)au, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-svq, svqversion=(int)3, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-dv, systemstream=(boolean)false, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; image/jpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-vp8, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-qt-part, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
<details>video/x-raw-rgb, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-yuv, format=(fourcc)UYVY, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/mpeg, mpegversion=(int)4, systemstream=(boolean)false, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-divx, divxversion=(int)5, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-h263, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-h264, stream-format=(string)avc, alignment=(string)au, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-svq, svqversion=(int)3, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-dv, systemstream=(boolean)false, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; image/jpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-vp8, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-dirac, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-qt-part, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
</caps>
<caps>
<name>src</name>
@ -235,4 +235,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -40,4 +40,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -20,7 +20,7 @@
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>image/jpeg, width=(int)[ 1, 65535 ], height=(int)[ 1, 65535 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
<details>image/jpeg, width=(int)[ 1, 65535 ], height=(int)[ 1, 65535 ], framerate=(fraction)[ 0/1, 2147483647/1 ], sof-marker=(int){ 0, 1, 2, 5, 6, 7, 9, 10, 13, 14 }</details>
</caps>
<caps>
<name>src</name>
@ -94,4 +94,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -32,7 +32,7 @@
<name>subtitle_%02d</name>
<direction>source</direction>
<presence>sometimes</presence>
<details>text/plain; application/x-ssa; application/x-ass; application/x-usf; video/x-dvd-subpicture; subpicture/x-pgs; subtitle/x-kate; application/x-subtitle-unknown</details>
<details>text/x-pango-markup; application/x-ssa; application/x-ass; application/x-usf; video/x-dvd-subpicture; subpicture/x-pgs; subtitle/x-kate; application/x-subtitle-unknown</details>
</caps>
<caps>
<name>video_%02d</name>
@ -124,4 +124,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -3,10 +3,10 @@
<description>Monoscope visualization</description>
<filename>../../gst/monoscope/.libs/libgstmonoscope.so</filename>
<basename>libgstmonoscope.so</basename>
<version>0.10.28.4</version>
<version>0.10.30.1</version>
<license>LGPL</license>
<source>gst-plugins-good</source>
<package>GStreamer Good Plug-ins prerelease</package>
<package>GStreamer Good Plug-ins git</package>
<origin>Unknown package origin</origin>
<elements>
<element>

View file

@ -52,4 +52,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -39,5 +39,20 @@
</caps>
</pads>
</element>
<element>
<name>splitfilesrc</name>
<longname>Split-File Source</longname>
<class>Source/File</class>
<description>Read a sequentially named set of files as if it was one large file</description>
<author>Tim-Philipp Müller &lt;tim.muller@collabora.co.uk&gt;</author>
<pads>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>ANY</details>
</caps>
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -52,4 +52,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -49,4 +49,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -49,4 +49,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -47,9 +47,9 @@
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>image/png, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
<details>image/png, width=(int)[ 16, 1000000 ], height=(int)[ 16, 1000000 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
</caps>
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -9,6 +9,21 @@
<package>GStreamer Good Plug-ins git</package>
<origin>Unknown package origin</origin>
<elements>
<element>
<name>pulseaudiosink</name>
<longname>Bin wrapping pulsesink</longname>
<class>Sink/Audio/Bin</class>
<description>Correctly handles sink changes when streaming compressed formats to pulsesink</description>
<author>Arun Raghavan &lt;arun.raghavan@collabora.co.uk&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean)true, width=(int)16, depth=(int)16, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-raw-float, endianness=(int){ 1234, 4321 }, width=(int)32, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean)true, width=(int)32, depth=(int)32, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-raw-int, signed=(boolean)false, width=(int)8, depth=(int)8, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-alaw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-mulaw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean)true, width=(int)24, depth=(int)24, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean)true, width=(int)32, depth=(int)24, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-ac3, framed=(boolean)true; audio/x-eac3, framed=(boolean)true; audio/x-dts, framed=(boolean)true, block-size=(int){ 512, 1024, 2048 }; audio/mpeg, mpegversion=(int)1, mpegaudioversion=(int)[ 1, 2 ], parsed=(boolean)true</details>
</caps>
</pads>
</element>
<element>
<name>pulsemixer</name>
<longname>PulseAudio Mixer</longname>
@ -29,7 +44,7 @@
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean)true, width=(int)16, depth=(int)16, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-raw-float, endianness=(int){ 1234, 4321 }, width=(int)32, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean)true, width=(int)32, depth=(int)32, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean)true, width=(int)24, depth=(int)24, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean)true, width=(int)32, depth=(int)24, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-raw-int, signed=(boolean)false, width=(int)8, depth=(int)8, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-alaw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-mulaw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]</details>
<details>audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean)true, width=(int)16, depth=(int)16, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-raw-float, endianness=(int){ 1234, 4321 }, width=(int)32, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean)true, width=(int)32, depth=(int)32, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-raw-int, signed=(boolean)false, width=(int)8, depth=(int)8, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-alaw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-mulaw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean)true, width=(int)24, depth=(int)24, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-raw-int, endianness=(int){ 1234, 4321 }, signed=(boolean)true, width=(int)32, depth=(int)24, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 32 ]; audio/x-ac3, framed=(boolean)true; audio/x-eac3, framed=(boolean)true; audio/x-dts, framed=(boolean)true, block-size=(int){ 512, 1024, 2048 }; audio/mpeg, mpegversion=(int)1, mpegaudioversion=(int)[ 1, 2 ], parsed=(boolean)true</details>
</caps>
</pads>
</element>
@ -49,4 +64,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -73,4 +73,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -1124,13 +1124,13 @@
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>application/x-rtp, media=(string)audio, payload=(int)[ 96, 127 ], clock-rate=(int)8000, encoding-name=(string)PCMA; application/x-rtp, media=(string)audio, payload=(int)8, clock-rate=(int)8000</details>
<details>application/x-rtp, media=(string)audio, payload=(int)8, clock-rate=(int)8000, encoding-name=(string)PCMA; application/x-rtp, media=(string)audio, payload=(int)[ 96, 127 ], clock-rate=(int)[ 1, 2147483647 ], encoding-name=(string)PCMA</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>audio/x-alaw, channels=(int)1, rate=(int)8000</details>
<details>audio/x-alaw, channels=(int)1, rate=(int)[ 1, 2147483647 ]</details>
</caps>
</pads>
</element>
@ -1151,7 +1151,7 @@
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>application/x-rtp, media=(string)audio, payload=(int)8, clock-rate=(int)8000, encoding-name=(string)PCMA; application/x-rtp, media=(string)audio, payload=(int)[ 96, 127 ], clock-rate=(int)8000, encoding-name=(string)PCMA</details>
<details>application/x-rtp, media=(string)audio, payload=(int)8, clock-rate=(int)8000, encoding-name=(string)PCMA; application/x-rtp, media=(string)audio, payload=(int)[ 96, 127 ], clock-rate=(int)[ 1, 2147483647 ], encoding-name=(string)PCMA</details>
</caps>
</pads>
</element>
@ -1166,13 +1166,13 @@
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>application/x-rtp, media=(string)audio, payload=(int)[ 96, 127 ], clock-rate=(int)8000, encoding-name=(string)PCMU; application/x-rtp, media=(string)audio, payload=(int)0, clock-rate=(int)8000</details>
<details>application/x-rtp, media=(string)audio, payload=(int)0, encoding-name=(string)PCMU, clock-rate=(int)8000; application/x-rtp, media=(string)audio, payload=(int)[ 96, 127 ], encoding-name=(string)PCMU, clock-rate=(int)[ 1, 2147483647 ]</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>audio/x-mulaw, channels=(int)1, rate=(int)8000</details>
<details>audio/x-mulaw, channels=(int)1, rate=(int)[ 1, 2147483647 ]</details>
</caps>
</pads>
</element>
@ -1193,7 +1193,7 @@
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>application/x-rtp, media=(string)audio, payload=(int)0, clock-rate=(int)8000, encoding-name=(string)PCMU; application/x-rtp, media=(string)audio, payload=(int)[ 96, 127 ], clock-rate=(int)8000, encoding-name=(string)PCMU</details>
<details>application/x-rtp, media=(string)audio, payload=(int)0, clock-rate=(int)8000, encoding-name=(string)PCMU; application/x-rtp, media=(string)audio, payload=(int)[ 96, 127 ], clock-rate=(int)[ 1, 2147483647 ], encoding-name=(string)PCMU</details>
</caps>
</pads>
</element>
@ -1460,7 +1460,7 @@
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)32, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, alpha_mask=(int)255, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)32, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, alpha_mask=(int)255, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ]; video/x-raw-yuv, format=(fourcc){ AYUV, UYVY, I420, Y41B, UYVP }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ]</details>
<details>video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)16711680, green_mask=(int)65280, blue_mask=(int)255, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)32, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, alpha_mask=(int)255, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ]; video/x-raw-rgb, bpp=(int)24, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)32, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, alpha_mask=(int)255, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ]; video/x-raw-yuv, format=(fourcc){ AYUV, UYVY, I420, Y41B, UYVP }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ]</details>
</caps>
<caps>
<name>src</name>
@ -1471,4 +1471,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -58,4 +58,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -37,4 +37,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -25,4 +25,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -58,4 +58,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -1,6 +1,6 @@
<plugin>
<name>soup</name>
<description>libsoup HTTP client src</description>
<description>libsoup HTTP client src/sink</description>
<filename>../../ext/soup/.libs/libgstsouphttpsrc.so</filename>
<basename>libgstsouphttpsrc.so</basename>
<version>0.10.30.1</version>
@ -9,6 +9,21 @@
<package>GStreamer Good Plug-ins git</package>
<origin>Unknown package origin</origin>
<elements>
<element>
<name>souphttpclientsink</name>
<longname>HTTP client sink</longname>
<class>Generic</class>
<description>Sends streams to HTTP server via PUT</description>
<author>David Schleef &lt;ds@entropywave.com&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>ANY</details>
</caps>
</pads>
</element>
<element>
<name>souphttpsrc</name>
<longname>HTTP client source</longname>
@ -25,4 +40,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -52,4 +52,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -52,4 +52,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -70,4 +70,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -34,4 +34,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -52,4 +52,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -14,7 +14,7 @@
<longname>Video gamma correction</longname>
<class>Filter/Effect/Video</class>
<description>Adjusts gamma on a video stream</description>
<author>Arwed v. Merkatz &lt;v.merkatz@gmx.net</author>
<author>Arwed v. Merkatz &lt;v.merkatz@gmx.net&gt;</author>
<pads>
<caps>
<name>sink</name>
@ -73,4 +73,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -52,4 +52,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -85,4 +85,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -25,4 +25,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -31,4 +31,4 @@
</pads>
</element>
</elements>
</plugin>
</plugin>

View file

@ -418,18 +418,18 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in,
v = (gint) vp[1];
dx = x + h;
dy = y + v;
dx = CLAMP (dx, 0, (v_w - 1));
dy = CLAMP (dy, 0, (v_h - 1));
dx = CLAMP (dx, 0, (v_w - 2));
dy = CLAMP (dy, 0, (v_h - 2));
dest[0] = src[dy * v_w + dx];
o_dx = dx;
dx = x + 1 + (h + (gint) vp[2]) / 2;
dx = CLAMP (dx, 0, (v_w - 1));
dx = CLAMP (dx, 0, (v_w - 2));
dest[1] = src[dy * v_w + dx];
dy = y + 1 + (v + (gint) vp[m_w * 2 + 1]) / 2;
dy = CLAMP (dy, 0, (v_h - 1));
dy = CLAMP (dy, 0, (v_h - 2));
dest[v_w] = src[dy * v_w + o_dx];
dest[v_w + 1] = src[dy * v_w + dx];

View file

@ -2935,29 +2935,34 @@ gst_matroska_demux_check_subtitle_buffer (GstElement * element,
newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
gst_buffer_copy_into (newbuf, *buf,
GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_META,
0, -1);
gst_buffer_unmap (*buf, data, size);
gst_buffer_unref (*buf);
*buf = newbuf;
data = gst_buffer_map (*buf, &size, NULL, GST_MAP_READ);
next:
/* caps claim markup text, so we need to escape text,
* except if text is already markup and then needs no further escaping */
sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
gst_matroska_demux_subtitle_chunk_has_tag (element, data);
if (sub_stream->check_markup) {
/* caps claim markup text, so we need to escape text,
* except if text is already markup and then needs no further escaping */
sub_stream->seen_markup_tag = sub_stream->seen_markup_tag ||
gst_matroska_demux_subtitle_chunk_has_tag (element, data);
if (!sub_stream->seen_markup_tag) {
utf8 = g_markup_escape_text (data, size);
if (!sub_stream->seen_markup_tag) {
utf8 = g_markup_escape_text (data, size);
newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
gst_buffer_copy_into (newbuf, *buf,
GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
gst_buffer_unmap (*buf, data, size);
gst_buffer_unref (*buf);
newbuf = gst_buffer_new_wrapped (utf8, strlen (utf8));
gst_buffer_copy_into (newbuf, *buf,
GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS |
GST_BUFFER_COPY_META, 0, -1);
gst_buffer_unmap (*buf, data, size);
gst_buffer_unref (*buf);
*buf = newbuf;
*buf = newbuf;
}
}
return GST_FLOW_OK;
@ -5448,15 +5453,19 @@ gst_matroska_demux_subtitle_caps (GstMatroskaTrackSubtitleContext *
/* well, plain text simply does not have a lot of markup ... */
caps = gst_caps_new_empty_simple ("text/x-pango-markup");
context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
subtitlecontext->check_markup = TRUE;
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_SSA)) {
caps = gst_caps_new_empty_simple ("application/x-ssa");
context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
subtitlecontext->check_markup = FALSE;
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_ASS)) {
caps = gst_caps_new_empty_simple ("application/x-ass");
context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
subtitlecontext->check_markup = FALSE;
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_USF)) {
caps = gst_caps_new_empty_simple ("application/x-usf");
context->postprocess_frame = gst_matroska_demux_check_subtitle_buffer;
subtitlecontext->check_markup = FALSE;
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_SUBTITLE_VOBSUB)) {
caps = gst_caps_new_empty_simple ("video/x-dvd-subpicture");
((GstMatroskaTrackContext *) subtitlecontext)->send_dvd_event = TRUE;

View file

@ -569,6 +569,8 @@ typedef struct _GstMatroskaTrackSubtitleContext {
GstMatroskaTrackContext parent;
gboolean check_utf8; /* buffers should be valid UTF-8 */
gboolean check_markup; /* check if buffers contain markup
* or plaintext and escape characters */
gboolean invalid_utf8; /* work around broken files */
gboolean seen_markup_tag; /* markup found in text */
} GstMatroskaTrackSubtitleContext;

View file

@ -297,6 +297,103 @@ gst_matroska_mux_class_init (GstMatroskaMuxClass * klass)
GST_DEBUG_FUNCPTR (gst_matroska_mux_release_pad);
}
/**
* Start of pad option handler code
*/
#define DEFAULT_PAD_FRAME_DURATION TRUE
#define DEFAULT_PAD_FRAME_DURATION_VP8 FALSE
enum
{
PROP_PAD_0,
PROP_PAD_FRAME_DURATION
};
typedef struct
{
GstPad parent;
gboolean frame_duration;
gboolean frame_duration_user;
} GstMatroskamuxPad;
static void gst_matroskamux_pad_class_init (GstPadClass * klass);
static GType
gst_matroskamux_pad_get_type (void)
{
static GType type = 0;
if (G_UNLIKELY (type == 0)) {
type = g_type_register_static_simple (GST_TYPE_PAD,
g_intern_static_string ("GstMatroskamuxPad"), sizeof (GstPadClass),
(GClassInitFunc) gst_matroskamux_pad_class_init,
sizeof (GstMatroskamuxPad), NULL, 0);
}
return type;
}
#define GST_TYPE_MATROSKAMUX_PAD (gst_matroskamux_pad_get_type())
#define GST_MATROSKAMUX_PAD(pad) (G_TYPE_CHECK_INSTANCE_CAST((pad),GST_TYPE_MATROSKAMUX_PAD,GstMatroskamuxPad))
#define GST_MATROSKAMUX_PAD_CAST(pad) ((GstMatroskamuxPad *) pad)
#define GST_IS_MATROSKAMUX_PAD(pad) (G_TYPE_CHECK_INSTANCE_TYPE((pad),GST_TYPE_MATROSKAMUX_PAD))
static void
gst_matroskamux_pad_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstMatroskamuxPad *pad = GST_MATROSKAMUX_PAD (object);
switch (prop_id) {
case PROP_PAD_FRAME_DURATION:
g_value_set_boolean (value, pad->frame_duration);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_matroskamux_pad_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstMatroskamuxPad *pad = GST_MATROSKAMUX_PAD (object);
switch (prop_id) {
case PROP_PAD_FRAME_DURATION:
pad->frame_duration = g_value_get_boolean (value);
pad->frame_duration_user = TRUE;
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_matroskamux_pad_class_init (GstPadClass * klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
gobject_class->set_property = gst_matroskamux_pad_set_property;
gobject_class->get_property = gst_matroskamux_pad_get_property;
g_object_class_install_property (gobject_class, PROP_PAD_FRAME_DURATION,
g_param_spec_boolean ("frame-duration", "Frame duration",
"Default frame duration", DEFAULT_PAD_FRAME_DURATION,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
}
static void
gst_matroskamux_pad_init (GstMatroskamuxPad * pad)
{
pad->frame_duration = DEFAULT_PAD_FRAME_DURATION;
pad->frame_duration_user = FALSE;
}
/*
* End of pad option handler code
**/
/**
* gst_matroska_mux_init:
@ -484,9 +581,9 @@ gst_matroska_pad_reset (GstMatroskaPad * collect_pad, gboolean full)
* Release resources of a matroska collect pad.
*/
static void
gst_matroska_pad_free (GstMatroskaPad * collect_pad)
gst_matroska_pad_free (GstPad * collect_pad)
{
gst_matroska_pad_reset (collect_pad, TRUE);
gst_matroska_pad_reset ((GstMatroskaPad *) collect_pad, TRUE);
}
@ -722,7 +819,15 @@ gst_matroska_mux_video_pad_setcaps (GstPad * pad, GstCaps * caps)
videocontext->pixel_width = width;
videocontext->pixel_height = height;
if (gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d)
/* set vp8 defaults or let user override it */
if (GST_MATROSKAMUX_PAD_CAST (pad)->frame_duration_user == FALSE
&& (!strcmp (mimetype, "video/x-vp8")))
GST_MATROSKAMUX_PAD_CAST (pad)->frame_duration =
DEFAULT_PAD_FRAME_DURATION_VP8;
if (GST_MATROSKAMUX_PAD_CAST (pad)->frame_duration
&& gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d)
&& fps_n > 0) {
context->default_duration =
gst_util_uint64_scale_int (GST_SECOND, fps_d, fps_n);
@ -1816,7 +1921,7 @@ gst_matroska_mux_request_new_pad (GstElement * element,
GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
GstMatroskaMux *mux = GST_MATROSKA_MUX (element);
GstMatroskaPad *collect_pad;
GstPad *newpad = NULL;
GstMatroskamuxPad *newpad;
gchar *name = NULL;
const gchar *pad_name = NULL;
GstMatroskaCapsFunc capsfunc = NULL;
@ -1870,10 +1975,13 @@ gst_matroska_mux_request_new_pad (GstElement * element,
return NULL;
}
newpad = gst_pad_new_from_template (templ, pad_name);
newpad = g_object_new (GST_TYPE_MATROSKAMUX_PAD,
"name", pad_name, "direction", templ->direction, "template", templ, NULL);
g_free (name);
gst_matroskamux_pad_init (newpad);
collect_pad = (GstMatroskaPad *)
gst_collect_pads_add_pad (mux->collect, newpad,
gst_collect_pads_add_pad (mux->collect, GST_PAD (newpad),
sizeof (GstMatroskaPad),
(GstCollectDataDestroyNotify) gst_matroska_pad_free);
@ -1889,19 +1997,19 @@ gst_matroska_mux_request_new_pad (GstElement * element,
* This would allow (clean) transcoding of info from demuxer/streams
* to another muxer */
mux->collect_event = (GstPadEventFunction) GST_PAD_EVENTFUNC (newpad);
gst_pad_set_event_function (newpad,
gst_pad_set_event_function (GST_PAD (newpad),
GST_DEBUG_FUNCPTR (gst_matroska_mux_handle_sink_event));
collect_pad->capsfunc = capsfunc;
gst_pad_set_active (newpad, TRUE);
if (!gst_element_add_pad (element, newpad))
gst_pad_set_active (GST_PAD (newpad), TRUE);
if (!gst_element_add_pad (element, GST_PAD (newpad)))
goto pad_add_failed;
mux->num_streams++;
GST_DEBUG_OBJECT (newpad, "Added new request pad");
return newpad;
return GST_PAD (newpad);
/* ERROR cases */
pad_add_failed:
@ -2650,10 +2758,12 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad)
gint64 relative_timestamp64;
guint64 block_duration;
gboolean is_video_keyframe = FALSE;
GstMatroskamuxPad *pad;
/* write data */
buf = collect_pad->buffer;
collect_pad->buffer = NULL;
pad = GST_MATROSKAMUX_PAD_CAST (collect_pad->collect.pad);
/* vorbis/theora headers are retrieved from caps and put in CodecPrivate */
if (collect_pad->track->xiph_headers_to_skip > 0) {
@ -2781,7 +2891,7 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad)
/* Check if the duration differs from the default duration. */
write_duration = FALSE;
block_duration = 0;
if (GST_BUFFER_DURATION_IS_VALID (buf)) {
if (pad->frame_duration && GST_BUFFER_DURATION_IS_VALID (buf)) {
block_duration = gst_util_uint64_scale (GST_BUFFER_DURATION (buf),
1, mux->time_scale);

View file

@ -1,13 +1,18 @@
plugin_LTLIBRARIES = libgstmultifile.la
libgstmultifile_la_SOURCES = gstmultifilesink.c gstmultifilesrc.c gstmultifile.c
libgstmultifile_la_CFLAGS = $(GST_BASE_CFLAGS) $(GST_CFLAGS)
libgstmultifile_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS)
libgstmultifile_la_SOURCES = \
gstmultifilesink.c \
gstmultifilesrc.c \
gstmultifile.c \
gstsplitfilesrc.c \
patternspec.c
libgstmultifile_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(GIO_CFLAGS)
libgstmultifile_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstvideo-@GST_MAJORMINOR@ $(GST_BASE_LIBS) $(GST_LIBS) $(GIO_LIBS)
libgstmultifile_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstmultifile_la_LIBTOOLFLAGS = --tag=disable-static
noinst_HEADERS = gstmultifilesrc.h gstmultifilesink.h
noinst_HEADERS = gstmultifilesrc.h gstmultifilesink.h gstsplitfilesrc.h patternspec.h
Android.mk: Makefile.am $(BUILT_SOURCES)

View file

@ -30,6 +30,7 @@
#include "gstmultifilesink.h"
#include "gstmultifilesrc.h"
#include "gstsplitfilesrc.h"
static gboolean
plugin_init (GstPlugin * plugin)
@ -38,6 +39,8 @@ plugin_init (GstPlugin * plugin)
gst_multi_file_src_get_type ());
gst_element_register (plugin, "multifilesink", GST_RANK_NONE,
gst_multi_file_sink_get_type ());
gst_element_register (plugin, "splitfilesrc", GST_RANK_NONE,
gst_split_file_src_get_type ());
return TRUE;
}

View file

@ -3,6 +3,7 @@
* 2000 Wim Taymans <wtay@chello.be>
* 2006 Wim Taymans <wim@fluendo.com>
* 2006 David A. Schleef <ds@schleef.org>
* 2011 Collabora Ltd. <tim.muller@collabora.co.uk>
*
* gstmultifilesink.c:
*
@ -110,6 +111,7 @@
# include "config.h"
#endif
#include <gst/base/gstbasetransform.h>
#include <gst/video/video.h>
#include <glib/gstdio.h>
#include "gstmultifilesink.h"
@ -126,6 +128,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_multi_file_sink_debug);
#define DEFAULT_POST_MESSAGES FALSE
#define DEFAULT_NEXT_FILE GST_MULTI_FILE_SINK_NEXT_BUFFER
#define DEFAULT_MAX_FILES 0
#define DEFAULT_MAX_FILE_SIZE G_GUINT64_CONSTANT(2*1024*1024*1024)
enum
{
@ -135,6 +138,7 @@ enum
PROP_POST_MESSAGES,
PROP_NEXT_FILE,
PROP_MAX_FILES,
PROP_MAX_FILE_SIZE,
PROP_LAST
};
@ -148,6 +152,8 @@ static void gst_multi_file_sink_get_property (GObject * object, guint prop_id,
static gboolean gst_multi_file_sink_stop (GstBaseSink * sink);
static GstFlowReturn gst_multi_file_sink_render (GstBaseSink * sink,
GstBuffer * buffer);
static GstFlowReturn gst_multi_file_sink_render_list (GstBaseSink * sink,
GstBufferList * buffer_list);
static gboolean gst_multi_file_sink_set_caps (GstBaseSink * sink,
GstCaps * caps);
static gboolean gst_multi_file_sink_open_next_file (GstMultiFileSink *
@ -156,6 +162,8 @@ static void gst_multi_file_sink_close_file (GstMultiFileSink * multifilesink,
GstBuffer * buffer);
static void gst_multi_file_sink_ensure_max_files (GstMultiFileSink *
multifilesink);
static gboolean gst_multi_file_sink_event (GstBaseSink * sink,
GstEvent * event);
#define GST_TYPE_MULTI_FILE_SINK_NEXT (gst_multi_file_sink_next_get_type ())
static GType
@ -168,6 +176,11 @@ gst_multi_file_sink_next_get_type (void)
"discont"},
{GST_MULTI_FILE_SINK_NEXT_KEY_FRAME, "New file at each key frame "
"(Useful for MPEG-TS segmenting)", "key-frame"},
{GST_MULTI_FILE_SINK_NEXT_KEY_UNIT_EVENT,
"New file after a force key unit event", "key-unit-event"},
{GST_MULTI_FILE_SINK_NEXT_MAX_SIZE, "New file when the configured maximum "
"file size would be exceeded with the next buffer or buffer list",
"max-size"},
{0, NULL, NULL}
};
@ -243,13 +256,29 @@ gst_multi_file_sink_class_init (GstMultiFileSinkClass * klass)
0, G_MAXUINT, DEFAULT_MAX_FILES,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstMultiFileSink:max-file-size
*
* Maximum file size before starting a new file in max-size mode.
*
* Since: 0.10.31
*/
g_object_class_install_property (gobject_class, PROP_MAX_FILE_SIZE,
g_param_spec_uint64 ("max-file-size", "Maximum File Size",
"Maximum file size before starting a new file in max-size mode",
0, G_MAXUINT64, DEFAULT_MAX_FILE_SIZE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gobject_class->finalize = gst_multi_file_sink_finalize;
gstbasesink_class->get_times = NULL;
gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_multi_file_sink_stop);
gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_multi_file_sink_render);
gstbasesink_class->render_list =
GST_DEBUG_FUNCPTR (gst_multi_file_sink_render_list);
gstbasesink_class->set_caps =
GST_DEBUG_FUNCPTR (gst_multi_file_sink_set_caps);
gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_multi_file_sink_event);
GST_DEBUG_CATEGORY_INIT (gst_multi_file_sink_debug, "multifilesink", 0,
"multifilesink element");
@ -269,12 +298,14 @@ gst_multi_file_sink_init (GstMultiFileSink * multifilesink)
multifilesink->index = DEFAULT_INDEX;
multifilesink->post_messages = DEFAULT_POST_MESSAGES;
multifilesink->max_files = DEFAULT_MAX_FILES;
multifilesink->max_file_size = DEFAULT_MAX_FILE_SIZE;
multifilesink->files = NULL;
multifilesink->n_files = 0;
gst_base_sink_set_sync (GST_BASE_SINK (multifilesink), FALSE);
multifilesink->next_segment = GST_CLOCK_TIME_NONE;
multifilesink->force_key_unit_count = -1;
}
static void
@ -322,6 +353,9 @@ gst_multi_file_sink_set_property (GObject * object, guint prop_id,
case PROP_MAX_FILES:
sink->max_files = g_value_get_uint (value);
break;
case PROP_MAX_FILE_SIZE:
sink->max_file_size = g_value_get_uint64 (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -350,6 +384,9 @@ gst_multi_file_sink_get_property (GObject * object, guint prop_id,
case PROP_MAX_FILES:
g_value_set_uint (value, sink->max_files);
break;
case PROP_MAX_FILE_SIZE:
g_value_set_uint64 (value, sink->max_file_size);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -377,46 +414,95 @@ gst_multi_file_sink_stop (GstBaseSink * sink)
multifilesink->streamheaders = NULL;
}
multifilesink->force_key_unit_count = -1;
return TRUE;
}
static void
gst_multi_file_sink_post_message_full (GstMultiFileSink * multifilesink,
GstClockTime timestamp, GstClockTime duration, GstClockTime offset,
GstClockTime offset_end, GstClockTime running_time,
GstClockTime stream_time, const char *filename)
{
GstStructure *s;
if (!multifilesink->post_messages)
return;
s = gst_structure_new ("GstMultiFileSink",
"filename", G_TYPE_STRING, filename,
"index", G_TYPE_INT, multifilesink->index,
"timestamp", G_TYPE_UINT64, timestamp,
"stream-time", G_TYPE_UINT64, stream_time,
"running-time", G_TYPE_UINT64, running_time,
"duration", G_TYPE_UINT64, duration,
"offset", G_TYPE_UINT64, offset,
"offset-end", G_TYPE_UINT64, offset_end, NULL);
gst_element_post_message (GST_ELEMENT_CAST (multifilesink),
gst_message_new_element (GST_OBJECT_CAST (multifilesink), s));
}
static void
gst_multi_file_sink_post_message (GstMultiFileSink * multifilesink,
GstBuffer * buffer, const char *filename)
{
if (multifilesink->post_messages) {
GstClockTime duration, timestamp;
GstClockTime running_time, stream_time;
guint64 offset, offset_end;
GstStructure *s;
GstSegment *segment;
GstFormat format;
GstClockTime duration, timestamp;
GstClockTime running_time, stream_time;
guint64 offset, offset_end;
GstSegment *segment;
GstFormat format;
segment = &GST_BASE_SINK (multifilesink)->segment;
format = segment->format;
if (!multifilesink->post_messages)
return;
timestamp = GST_BUFFER_TIMESTAMP (buffer);
duration = GST_BUFFER_DURATION (buffer);
offset = GST_BUFFER_OFFSET (buffer);
offset_end = GST_BUFFER_OFFSET_END (buffer);
segment = &GST_BASE_SINK (multifilesink)->segment;
format = segment->format;
running_time = gst_segment_to_running_time (segment, format, timestamp);
stream_time = gst_segment_to_stream_time (segment, format, timestamp);
timestamp = GST_BUFFER_TIMESTAMP (buffer);
duration = GST_BUFFER_DURATION (buffer);
offset = GST_BUFFER_OFFSET (buffer);
offset_end = GST_BUFFER_OFFSET_END (buffer);
s = gst_structure_new ("GstMultiFileSink",
"filename", G_TYPE_STRING, filename,
"index", G_TYPE_INT, multifilesink->index,
"timestamp", G_TYPE_UINT64, timestamp,
"stream-time", G_TYPE_UINT64, stream_time,
"running-time", G_TYPE_UINT64, running_time,
"duration", G_TYPE_UINT64, duration,
"offset", G_TYPE_UINT64, offset,
"offset-end", G_TYPE_UINT64, offset_end, NULL);
running_time = gst_segment_to_running_time (segment, format, timestamp);
stream_time = gst_segment_to_stream_time (segment, format, timestamp);
gst_element_post_message (GST_ELEMENT_CAST (multifilesink),
gst_message_new_element (GST_OBJECT_CAST (multifilesink), s));
gst_multi_file_sink_post_message_full (multifilesink, timestamp, duration,
offset, offset_end, running_time, stream_time, filename);
}
static gboolean
gst_multi_file_sink_write_stream_headers (GstMultiFileSink * sink)
{
int i;
if (sink->streamheaders == NULL)
return TRUE;
/* we want to write these at the beginning */
g_assert (sink->cur_file_size == 0);
for (i = 0; i < sink->n_streamheaders; i++) {
GstBuffer *hdr;
guint8 *sdata;
gsize ssize;
int ret;
hdr = sink->streamheaders[i];
sdata = gst_buffer_map (hdr, &ssize, NULL, GST_MAP_READ);
ret = fwrite (sdata, ssize, 1, sink->file);
gst_buffer_unmap (hdr, sdata, ssize);
if (ret != 1)
return FALSE;
sink->cur_file_size += ssize;
}
return TRUE;
}
static GstFlowReturn
@ -484,24 +570,10 @@ gst_multi_file_sink_render (GstBaseSink * sink, GstBuffer * buffer)
}
if (multifilesink->file == NULL) {
int i;
if (!gst_multi_file_sink_open_next_file (multifilesink))
goto stdio_write_error;
if (multifilesink->streamheaders) {
for (i = 0; i < multifilesink->n_streamheaders; i++) {
guint8 *sdata;
gsize ssize;
sdata = gst_buffer_map (multifilesink->streamheaders[i], &ssize,
NULL, GST_MAP_READ);
ret = fwrite (data, ssize, 1, multifilesink->file);
gst_buffer_unmap (multifilesink->streamheaders[i], sdata, ssize);
if (ret != 1)
goto stdio_write_error;
}
}
gst_multi_file_sink_write_stream_headers (multifilesink);
}
ret = fwrite (data, size, 1, multifilesink->file);
@ -509,6 +581,51 @@ gst_multi_file_sink_render (GstBaseSink * sink, GstBuffer * buffer)
goto stdio_write_error;
break;
case GST_MULTI_FILE_SINK_NEXT_KEY_UNIT_EVENT:
if (multifilesink->file == NULL) {
if (!gst_multi_file_sink_open_next_file (multifilesink))
goto stdio_write_error;
}
if (!gst_multi_file_sink_write_stream_headers (multifilesink))
goto stdio_write_error;
ret = fwrite (data, size, 1, multifilesink->file);
if (ret != 1)
goto stdio_write_error;
break;
case GST_MULTI_FILE_SINK_NEXT_MAX_SIZE:{
guint64 new_size;
new_size = multifilesink->cur_file_size + size;
if (new_size > multifilesink->max_file_size) {
GST_INFO_OBJECT (multifilesink, "current size: %" G_GUINT64_FORMAT
", new_size: %" G_GUINT64_FORMAT ", max. size %" G_GUINT64_FORMAT,
multifilesink->cur_file_size, new_size,
multifilesink->max_file_size);
if (multifilesink->file != NULL)
gst_multi_file_sink_close_file (multifilesink, NULL);
}
if (multifilesink->file == NULL) {
if (!gst_multi_file_sink_open_next_file (multifilesink))
goto stdio_write_error;
gst_multi_file_sink_write_stream_headers (multifilesink);
}
ret = fwrite (data, size, 1, multifilesink->file);
if (ret != 1)
goto stdio_write_error;
multifilesink->cur_file_size += size;
break;
}
default:
g_assert_not_reached ();
}
@ -546,6 +663,63 @@ stdio_write_error:
}
}
static gboolean
buffer_list_calc_size (GstBuffer ** buf, guint idx, gpointer data)
{
guint *p_size = data;
guint buf_size;
buf_size = gst_buffer_get_size (*buf);
GST_TRACE ("buffer %u has size %" G_GSIZE_FORMAT, idx, buf_size);
*p_size += buf_size;
return TRUE;
}
static gboolean
buffer_list_copy_data (GstBuffer ** buf, guint idx, gpointer data)
{
GstBuffer *dest = data;
guint num, i;
if (idx == 0)
gst_buffer_copy_into (dest, *buf, GST_BUFFER_COPY_METADATA, 0, -1);
num = gst_buffer_n_memory (*buf);
for (i = 0; i < num; ++i) {
GstMemory *mem;
mem = gst_buffer_peek_memory (*buf, i, GST_MAP_READ);
gst_buffer_take_memory (dest, -1, gst_memory_ref (mem));
}
return TRUE;
}
/* Our assumption for now is that the buffers in a buffer list should always
* end up in the same file. If someone wants different behaviour, they'll just
* have to add a property for that. */
static GstFlowReturn
gst_multi_file_sink_render_list (GstBaseSink * sink, GstBufferList * list)
{
GstBuffer *buf;
guint size;
gst_buffer_list_foreach (list, buffer_list_calc_size, &size);
GST_LOG_OBJECT (sink, "total size of buffer list %p: %u", list, size);
/* copy all buffers in the list into one single buffer, so we can use
* the normal render function (FIXME: optimise to avoid the memcpy) */
buf = gst_buffer_new ();
gst_buffer_list_foreach (list, buffer_list_copy_data, buf);
g_assert (gst_buffer_get_size (buf) == size);
gst_multi_file_sink_render (sink, buf);
gst_buffer_unref (buf);
return GST_FLOW_OK;
}
static gboolean
gst_multi_file_sink_set_caps (GstBaseSink * sink, GstCaps * caps)
{
@ -601,6 +775,71 @@ gst_multi_file_sink_ensure_max_files (GstMultiFileSink * multifilesink)
}
}
static gboolean
gst_multi_file_sink_event (GstBaseSink * sink, GstEvent * event)
{
GstMultiFileSink *multifilesink;
gchar *filename;
gboolean res = TRUE;
multifilesink = GST_MULTI_FILE_SINK (sink);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CUSTOM_DOWNSTREAM:
{
GstClockTime timestamp, duration;
GstClockTime running_time, stream_time;
guint64 offset, offset_end;
gboolean all_headers;
guint count;
if (multifilesink->next_file != GST_MULTI_FILE_SINK_NEXT_KEY_UNIT_EVENT ||
!gst_video_event_is_force_key_unit (event))
goto out;
gst_video_event_parse_downstream_force_key_unit (event, &timestamp,
&stream_time, &running_time, &all_headers, &count);
if (multifilesink->force_key_unit_count != -1 &&
multifilesink->force_key_unit_count == count)
goto out;
multifilesink->force_key_unit_count = count;
if (multifilesink->file) {
duration = GST_CLOCK_TIME_NONE;
offset = offset_end = -1;
filename = g_strdup_printf (multifilesink->filename,
multifilesink->index);
gst_multi_file_sink_post_message_full (multifilesink, timestamp,
duration, offset, offset_end, running_time, stream_time, filename);
g_free (filename);
gst_multi_file_sink_close_file (multifilesink, NULL);
}
if (multifilesink->file == NULL) {
if (!gst_multi_file_sink_open_next_file (multifilesink))
goto stdio_write_error;
}
break;
}
default:
break;
}
out:
return res;
stdio_write_error:
GST_ELEMENT_ERROR (multifilesink, RESOURCE, WRITE,
("Error while writing to file."), (NULL));
return FALSE;
}
static gboolean
gst_multi_file_sink_open_next_file (GstMultiFileSink * multifilesink)
{
@ -616,9 +855,11 @@ gst_multi_file_sink_open_next_file (GstMultiFileSink * multifilesink)
return FALSE;
}
GST_INFO_OBJECT (multifilesink, "opening file %s", filename);
multifilesink->files = g_slist_append (multifilesink->files, filename);
multifilesink->n_files += 1;
multifilesink->cur_file_size = 0;
return TRUE;
}

View file

@ -55,7 +55,9 @@ typedef struct _GstMultiFileSinkClass GstMultiFileSinkClass;
typedef enum {
GST_MULTI_FILE_SINK_NEXT_BUFFER,
GST_MULTI_FILE_SINK_NEXT_DISCONT,
GST_MULTI_FILE_SINK_NEXT_KEY_FRAME
GST_MULTI_FILE_SINK_NEXT_KEY_FRAME,
GST_MULTI_FILE_SINK_NEXT_KEY_UNIT_EVENT,
GST_MULTI_FILE_SINK_NEXT_MAX_SIZE
} GstMultiFileSinkNext;
struct _GstMultiFileSink
@ -75,6 +77,10 @@ struct _GstMultiFileSink
int n_streamheaders;
GstBuffer **streamheaders;
guint force_key_unit_count;
guint64 cur_file_size;
guint64 max_file_size;
};
struct _GstMultiFileSinkClass

View file

@ -0,0 +1,603 @@
/* GStreamer Split File Source
* Copyright (C) 2011 Collabora Ltd. <tim.muller@collabora.co.uk>
*
* 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:element-splitfilesrc
* @see_also: #GstFileSrc, #GstMultiFileSrc
*
* Reads data from multiple files, presenting those files as one continuous
* file to downstream elements. This is useful for reading a large file that
* had to be split into multiple parts due to filesystem file size limitations,
* for example.
*
* The files to select are chosen via the location property, which supports
* (and expects) shell-style wildcards (but only for the filename, not for
* directories). The results will be sorted.
*
* <refsect2>
* <title>Example launch line</title>
* |[
* gst-launch splitfilesrc location="/path/to/part-*.mpg" ! decodebin ! ... \
* ]| Plays the different parts as if they were one single MPEG file.
* </refsect2>
*
* Since: 0.10.31
*/
/* TODO:
* - implement splitfile:// URI handler?
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "gstsplitfilesrc.h"
#include "patternspec.h"
#include <string.h>
#ifdef G_OS_WIN32
#define DEFAULT_PATTERN_MATCH_MODE MATCH_MODE_UTF8
#else
#define DEFAULT_PATTERN_MATCH_MODE MATCH_MODE_AUTO
#endif
enum
{
PROP_LOCATION = 1
};
#define DEFAULT_LOCATION NULL
static void gst_split_file_src_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_split_file_src_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_split_file_src_finalize (GObject * obj);
static gboolean gst_split_file_src_start (GstBaseSrc * basesrc);
static gboolean gst_split_file_src_stop (GstBaseSrc * basesrc);
static gboolean gst_split_file_src_can_seek (GstBaseSrc * basesrc);
static gboolean gst_split_file_src_get_size (GstBaseSrc * basesrc, guint64 * s);
static gboolean gst_split_file_src_unlock (GstBaseSrc * basesrc);
static GstFlowReturn gst_split_file_src_create (GstBaseSrc * basesrc,
guint64 offset, guint size, GstBuffer ** buffer);
static GstStaticPadTemplate gst_split_file_src_pad_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS_ANY);
GST_DEBUG_CATEGORY_STATIC (splitfilesrc_debug);
#define GST_CAT_DEFAULT splitfilesrc_debug
G_DEFINE_TYPE (GstSplitFileSrc, gst_split_file_src, GST_TYPE_BASE_SRC);
#ifdef G_OS_WIN32
#define WIN32_BLURB " Location string must be in UTF-8 encoding (on Windows)."
#else
#define WIN32_BLURB /* nothing */
#endif
static void
gst_split_file_src_class_init (GstSplitFileSrcClass * klass)
{
GstBaseSrcClass *gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->set_property = gst_split_file_src_set_property;
gobject_class->get_property = gst_split_file_src_get_property;
gobject_class->finalize = gst_split_file_src_finalize;
g_object_class_install_property (gobject_class, PROP_LOCATION,
g_param_spec_string ("location", "File Location",
"Wildcard pattern to match file names of the input files. If "
"the location is an absolute path or contains directory components, "
"only the base file name part will be considered for pattern "
"matching. The results will be sorted." WIN32_BLURB,
DEFAULT_LOCATION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_split_file_src_start);
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_split_file_src_stop);
gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_split_file_src_create);
gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_split_file_src_get_size);
gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_split_file_src_unlock);
gstbasesrc_class->is_seekable =
GST_DEBUG_FUNCPTR (gst_split_file_src_can_seek);
GST_DEBUG_CATEGORY_INIT (splitfilesrc_debug, "splitfilesrc", 0,
"splitfilesrc element");
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&gst_split_file_src_pad_template));
gst_element_class_set_details_simple (gstelement_class, "Split-File Source",
"Source/File",
"Read a sequentially named set of files as if it was one large file",
"Tim-Philipp Müller <tim.muller@collabora.co.uk>");
}
static void
gst_split_file_src_init (GstSplitFileSrc * splitfilesrc)
{
}
static void
gst_split_file_src_finalize (GObject * obj)
{
GstSplitFileSrc *src = GST_SPLIT_FILE_SRC (obj);
g_free (src->location);
src->location = NULL;
G_OBJECT_CLASS (gst_split_file_src_parent_class)->finalize (obj);
}
static gboolean
gst_split_file_src_can_seek (GstBaseSrc * basesrc)
{
return TRUE;
}
static gboolean
gst_split_file_src_unlock (GstBaseSrc * basesrc)
{
/* This is not actually that useful, since all normal file
* operations are fully blocking anyway */
#if 0
GstSplitFileSrc *src = GST_SPLIT_FILE_SRC (basesrc);
GST_DEBUG_OBJECT (src, "cancelling pending I/O operation if there is one");
/* g_cancellable_cancel (src->cancellable); */
GST_DEBUG_OBJECT (src, "done");
#endif
return TRUE;
}
static gboolean
gst_split_file_src_get_size (GstBaseSrc * basesrc, guint64 * size)
{
GstSplitFileSrc *src = GST_SPLIT_FILE_SRC (basesrc);
*size = src->parts[src->num_parts - 1].stop + 1;
return TRUE;
}
static void
gst_split_file_src_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstSplitFileSrc *src = GST_SPLIT_FILE_SRC (object);
switch (prop_id) {
case PROP_LOCATION:
GST_OBJECT_LOCK (src);
g_free (src->location);
src->location = g_value_dup_string (value);
#ifdef G_OS_WIN32
if (!g_utf8_validate (src->location, -1, NULL)) {
g_warning ("splitfilesrc 'location' property must be in UTF-8 "
"encoding on Windows");
}
#endif
GST_OBJECT_UNLOCK (src);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_split_file_src_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstSplitFileSrc *src = GST_SPLIT_FILE_SRC (object);
switch (prop_id) {
case PROP_LOCATION:
GST_OBJECT_LOCK (src);
g_value_set_string (value, src->location);
GST_OBJECT_UNLOCK (src);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static int
gst_split_file_src_array_sortfunc (gchar ** a, gchar ** b)
{
return strcmp (*a, *b);
}
static gchar **
gst_split_file_src_find_files (GstSplitFileSrc * src, const gchar * dirname,
const gchar * basename, GError ** err)
{
PatternSpec *pspec;
GPtrArray *files;
const gchar *name;
GDir *dir;
if (dirname == NULL || basename == NULL)
goto invalid_location;
GST_INFO_OBJECT (src, "checking in directory '%s' for pattern '%s'",
dirname, basename);
dir = g_dir_open (dirname, 0, err);
if (dir == NULL)
return NULL;
if (DEFAULT_PATTERN_MATCH_MODE == MATCH_MODE_UTF8 &&
!g_utf8_validate (basename, -1, NULL)) {
goto not_utf8;
}
/* mode will be AUTO on linux/unix and UTF8 on win32 */
pspec = pattern_spec_new (basename, DEFAULT_PATTERN_MATCH_MODE);
files = g_ptr_array_new ();
while ((name = g_dir_read_name (dir))) {
GST_TRACE_OBJECT (src, "check: %s", name);
if (pattern_match_string (pspec, name)) {
GST_DEBUG_OBJECT (src, "match: %s", name);
g_ptr_array_add (files, g_build_filename (dirname, name, NULL));
}
}
if (files->len == 0)
goto no_matches;
g_ptr_array_sort (files, (GCompareFunc) gst_split_file_src_array_sortfunc);
g_ptr_array_add (files, NULL);
pattern_spec_free (pspec);
g_dir_close (dir);
return (gchar **) g_ptr_array_free (files, FALSE);
/* ERRORS */
invalid_location:
{
g_set_error_literal (err, G_FILE_ERROR, G_FILE_ERROR_INVAL,
"No filename specified.");
return NULL;
}
not_utf8:
{
g_dir_close (dir);
g_set_error_literal (err, G_FILE_ERROR, G_FILE_ERROR_INVAL,
"Filename pattern must be UTF-8 on Windows.");
return NULL;
}
no_matches:
{
pattern_spec_free (pspec);
g_dir_close (dir);
g_set_error_literal (err, G_FILE_ERROR, G_FILE_ERROR_NOENT,
"Found no files matching the pattern.");
return NULL;
}
}
static gboolean
gst_split_file_src_start (GstBaseSrc * basesrc)
{
GstSplitFileSrc *src = GST_SPLIT_FILE_SRC (basesrc);
GCancellable *cancel;
gboolean ret = FALSE;
guint64 offset;
GError *err = NULL;
gchar *basename = NULL;
gchar *dirname = NULL;
gchar **files;
guint i;
GST_OBJECT_LOCK (src);
if (src->location != NULL && src->location[0] != '\0') {
basename = g_path_get_basename (src->location);
dirname = g_path_get_dirname (src->location);
}
GST_OBJECT_UNLOCK (src);
files = gst_split_file_src_find_files (src, dirname, basename, &err);
if (files == NULL || *files == NULL)
goto no_files;
src->num_parts = g_strv_length (files);
src->parts = g_new0 (GstFilePart, src->num_parts);
cancel = src->cancellable;
offset = 0;
for (i = 0; i < src->num_parts; ++i) {
GFileInputStream *stream;
GFileInfo *info;
goffset size;
GFile *file;
file = g_file_new_for_path (files[i]);
stream = g_file_read (file, cancel, &err);
g_object_unref (file);
if (err != NULL)
goto open_read_error;
info = g_file_input_stream_query_info (stream, "standard::*", NULL, &err);
if (err != NULL) {
g_object_unref (stream);
goto query_info_error;
}
size = g_file_info_get_size (info);
g_object_unref (info);
src->parts[i].stream = stream;
src->parts[i].path = g_strdup (files[i]);
src->parts[i].start = offset;
src->parts[i].stop = offset + size - 1;
GST_DEBUG ("[%010" G_GUINT64_FORMAT "-%010" G_GUINT64_FORMAT "] %s",
src->parts[i].start, src->parts[i].stop, src->parts[i].path);
offset += size;
}
GST_INFO ("Successfully opened %u file parts for reading", src->num_parts);
src->cur_part = 0;
src->cancellable = g_cancellable_new ();
ret = TRUE;
done:
if (err != NULL)
g_error_free (err);
g_strfreev (files);
g_free (basename);
g_free (dirname);
return ret;
/* ERRORS */
no_files:
{
if (err->code == G_IO_ERROR_CANCELLED)
goto cancelled;
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("%s", err->message),
("Failed to find files in '%s' for pattern '%s'",
GST_STR_NULL (dirname), GST_STR_NULL (basename)));
goto done;
}
open_read_error:
{
if (err->code == G_IO_ERROR_CANCELLED)
goto cancelled;
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("%s", err->message),
("Failed to open file '%s' for reading", files[i]));
goto done;
}
query_info_error:
{
if (err->code == G_IO_ERROR_CANCELLED)
goto cancelled;
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("%s", err->message),
("Failed to query info for file '%s'", files[i]));
goto done;
}
cancelled:
{
GST_DEBUG_OBJECT (src, "I/O operation cancelled from another thread");
goto done;
}
}
static gboolean
gst_split_file_src_stop (GstBaseSrc * basesrc)
{
GstSplitFileSrc *src = GST_SPLIT_FILE_SRC (basesrc);
guint i;
for (i = 0; i < src->num_parts; ++i) {
if (src->parts[i].stream != NULL)
g_object_unref (src->parts[i].stream);
g_free (src->parts[i].path);
}
g_free (src->parts);
src->parts = NULL;
src->num_parts = 0;
g_object_unref (src->cancellable);
src->cancellable = NULL;
return TRUE;
}
static gboolean
gst_split_file_src_find_part_for_offset (GstSplitFileSrc * src, guint64 offset,
guint * part_number)
{
GstFilePart *part;
guint i;
/* TODO: could use gst_util_array_binary_search() here */
part = src->parts;
for (i = 0; i < src->num_parts; ++i) {
if (offset >= part->start && offset <= part->stop) {
*part_number = i;
return TRUE;
}
++part;
}
return FALSE;
}
static GstFlowReturn
gst_split_file_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
GstBuffer ** buffer)
{
GstSplitFileSrc *src = GST_SPLIT_FILE_SRC (basesrc);
GstFilePart cur_part;
GInputStream *stream;
GCancellable *cancel;
GSeekable *seekable;
GstBuffer *buf;
GError *err = NULL;
guint64 read_offset;
guint8 *data;
guint to_read;
cur_part = src->parts[src->cur_part];
if (offset < cur_part.start || offset > cur_part.stop) {
if (!gst_split_file_src_find_part_for_offset (src, offset, &src->cur_part))
return GST_FLOW_UNEXPECTED;
cur_part = src->parts[src->cur_part];
}
GST_LOG_OBJECT (src, "current part: %u (%" G_GUINT64_FORMAT " - "
"%" G_GUINT64_FORMAT ", %s)", src->cur_part, cur_part.start,
cur_part.stop, cur_part.path);
buf = gst_buffer_new_allocate (NULL, size, 0);
GST_BUFFER_OFFSET (buf) = offset;
data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
cancel = src->cancellable;
while (size > 0) {
guint64 bytes_to_end_of_part;
gsize read = 0;
/* we want the offset into the file part */
read_offset = offset - cur_part.start;
GST_LOG ("Reading part %03u from offset %" G_GUINT64_FORMAT " (%s)",
src->cur_part, read_offset, cur_part.path);
/* FIXME: only seek when needed (hopefully gio is smart) */
seekable = G_SEEKABLE (cur_part.stream);
if (!g_seekable_seek (seekable, read_offset, G_SEEK_SET, cancel, &err))
goto seek_failed;
GST_LOG_OBJECT (src, "now: %" G_GUINT64_FORMAT, g_seekable_tell (seekable));
bytes_to_end_of_part = (cur_part.stop - cur_part.start) + 1 - read_offset;
to_read = MIN (size, bytes_to_end_of_part);
GST_LOG_OBJECT (src, "reading %u bytes from part %u (bytes to end of "
"part: %u)", to_read, src->cur_part, (guint) bytes_to_end_of_part);
stream = G_INPUT_STREAM (cur_part.stream);
/* NB: we won't try to read beyond EOF */
if (!g_input_stream_read_all (stream, data, to_read, &read, cancel, &err))
goto read_failed;
GST_LOG_OBJECT (src, "read %u bytes", (guint) read);
data += read;
size -= read;
offset += read;
/* are we done? */
if (size == 0)
break;
GST_LOG_OBJECT (src, "%u bytes left to read for this chunk", size);
/* corner case, this should never really happen (assuming basesrc clips
* requests beyond the file size) */
if (read < to_read) {
if (src->cur_part == src->num_parts - 1) {
/* last file part, stop reading and truncate buffer */
gst_buffer_set_size (buf, offset - GST_BUFFER_OFFSET (buf));
break;
} else {
goto file_part_changed;
}
}
++src->cur_part;
cur_part = src->parts[src->cur_part];
}
GST_BUFFER_OFFSET_END (buf) = offset;
gst_buffer_unmap (buf, data, size);
*buffer = buf;
GST_LOG_OBJECT (src, "read %" G_GSIZE_FORMAT " bytes into buf %p",
gst_buffer_get_size (buf), buf);
return GST_FLOW_OK;
/* ERRORS */
seek_failed:
{
if (err->code == G_IO_ERROR_CANCELLED)
goto cancelled;
GST_ELEMENT_ERROR (src, RESOURCE, SEEK, (NULL),
("Seek to %" G_GUINT64_FORMAT " in %s failed", read_offset,
cur_part.path));
g_error_free (err);
gst_buffer_unref (buf);
return GST_FLOW_ERROR;
}
read_failed:
{
if (err->code == G_IO_ERROR_CANCELLED)
goto cancelled;
GST_ELEMENT_ERROR (src, RESOURCE, READ, ("%s", err->message),
("Read from %" G_GUINT64_FORMAT " in %s failed", read_offset,
cur_part.path));
g_error_free (err);
gst_buffer_unref (buf);
return GST_FLOW_ERROR;
}
file_part_changed:
{
GST_ELEMENT_ERROR (src, RESOURCE, READ,
("Read error while reading file part %s", cur_part.path),
("Short read in file part, file may have been modified since start"));
gst_buffer_unref (buf);
return GST_FLOW_ERROR;
}
cancelled:
{
GST_DEBUG_OBJECT (src, "I/O operation cancelled from another thread");
g_error_free (err);
gst_buffer_unref (buf);
return GST_FLOW_WRONG_STATE;
}
}

View file

@ -0,0 +1,74 @@
/* GStreamer Split File Source
* Copyright (C) 2011 Collabora Ltd. <tim.muller@collabora.co.uk>
*
* 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_SPLIT_FILE_SRC_H__
#define __GST_SPLIT_FILE_SRC_H__
#include <gst/gst.h>
#include <gst/base/gstbasesrc.h>
#include <gio/gio.h>
G_BEGIN_DECLS
#define GST_TYPE_SPLIT_FILE_SRC \
(gst_split_file_src_get_type())
#define GST_SPLIT_FILE_SRC(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SPLIT_FILE_SRC,GstSplitFileSrc))
#define GST_SPLIT_FILE_SRC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SPLIT_FILE_SRC,GstSplitFileSrcClass))
#define GST_IS_SPLIT_FILE_SRC(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SPLIT_FILE_SRC))
#define GST_IS_SPLIT_FILE_SRC_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SPLIT_FILE_SRC))
typedef struct _GstFilePart GstFilePart;
typedef struct _GstSplitFileSrc GstSplitFileSrc;
typedef struct _GstSplitFileSrcClass GstSplitFileSrcClass;
struct _GstFilePart
{
GFileInputStream *stream;
gchar *path;
guint64 start; /* inclusive */
guint64 stop; /* inclusive */
};
struct _GstSplitFileSrc
{
GstBaseSrc parent;
gchar *location; /* OBJECT_LOCK */
GstFilePart *parts;
guint num_parts;
guint cur_part; /* part used last (likely also to be used next) */
GCancellable *cancellable; /* so we can interrupt blocking operations */
};
struct _GstSplitFileSrcClass
{
GstBaseSrcClass parent_class;
};
GType gst_split_file_src_get_type (void);
G_END_DECLS
#endif /* __GST_SPLIT_FILE_SRC_H__ */

334
gst/multifile/patternspec.c Normal file
View file

@ -0,0 +1,334 @@
/* GPattern copy that supports raw (non-utf8) matching
* based on: GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997, 1999 Peter Mattis, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "patternspec.h"
#include <string.h>
typedef enum
{
MATCH_ALL, /* "*A?A*" */
MATCH_ALL_TAIL, /* "*A?AA" */
MATCH_HEAD, /* "AAAA*" */
MATCH_TAIL, /* "*AAAA" */
MATCH_EXACT, /* "AAAAA" */
MATCH_LAST
} MatchType;
struct _PatternSpec
{
MatchMode match_mode;
MatchType match_type;
guint pattern_length;
guint min_length;
guint max_length;
gchar *pattern;
};
static inline gchar *
raw_strreverse (const gchar * str, gssize size)
{
g_assert (size > 0);
return g_strreverse (g_strndup (str, size));
}
static inline gboolean
pattern_ph_match (const gchar * match_pattern, MatchMode match_mode,
const gchar * match_string, gboolean * wildcard_reached_p)
{
register const gchar *pattern, *string;
register gchar ch;
pattern = match_pattern;
string = match_string;
ch = *pattern;
pattern++;
while (ch) {
switch (ch) {
case '?':
if (!*string)
return FALSE;
if (match_mode == MATCH_MODE_UTF8)
string = g_utf8_next_char (string);
else
++string;
break;
case '*':
*wildcard_reached_p = TRUE;
do {
ch = *pattern;
pattern++;
if (ch == '?') {
if (!*string)
return FALSE;
if (match_mode == MATCH_MODE_UTF8)
string = g_utf8_next_char (string);
else
++string;
}
}
while (ch == '*' || ch == '?');
if (!ch)
return TRUE;
do {
gboolean next_wildcard_reached = FALSE;
while (ch != *string) {
if (!*string)
return FALSE;
if (match_mode == MATCH_MODE_UTF8)
string = g_utf8_next_char (string);
else
++string;
}
string++;
if (pattern_ph_match (pattern, match_mode, string,
&next_wildcard_reached))
return TRUE;
if (next_wildcard_reached)
/* the forthcoming pattern substring up to the next wildcard has
* been matched, but a mismatch occoured for the rest of the
* pattern, following the next wildcard.
* there's no need to advance the current match position any
* further if the rest pattern will not match.
*/
return FALSE;
}
while (*string);
break;
default:
if (ch == *string)
string++;
else
return FALSE;
break;
}
ch = *pattern;
pattern++;
}
return *string == 0;
}
static gboolean
pattern_match (PatternSpec * pspec, guint string_length,
const gchar * string, const gchar * string_reversed)
{
MatchMode match_mode;
g_assert (pspec != NULL);
g_assert (string != NULL);
if (string_length < pspec->min_length || string_length > pspec->max_length)
return FALSE;
match_mode = pspec->match_mode;
if (match_mode == MATCH_MODE_AUTO) {
if (!g_utf8_validate (string, string_length, NULL))
match_mode = MATCH_MODE_RAW;
else
match_mode = MATCH_MODE_UTF8;
}
switch (pspec->match_type) {
gboolean dummy;
case MATCH_ALL:
return pattern_ph_match (pspec->pattern, match_mode, string, &dummy);
case MATCH_ALL_TAIL:
if (string_reversed)
return pattern_ph_match (pspec->pattern, match_mode, string_reversed,
&dummy);
else {
gboolean result;
gchar *tmp;
if (match_mode == MATCH_MODE_UTF8) {
tmp = g_utf8_strreverse (string, string_length);
} else {
tmp = raw_strreverse (string, string_length);
}
result = pattern_ph_match (pspec->pattern, match_mode, tmp, &dummy);
g_free (tmp);
return result;
}
case MATCH_HEAD:
if (pspec->pattern_length == string_length)
return memcmp (pspec->pattern, string, string_length) == 0;
else if (pspec->pattern_length)
return memcmp (pspec->pattern, string, pspec->pattern_length) == 0;
else
return TRUE;
case MATCH_TAIL:
if (pspec->pattern_length)
/* compare incl. NUL terminator */
return memcmp (pspec->pattern,
string + (string_length - pspec->pattern_length),
pspec->pattern_length + 1) == 0;
else
return TRUE;
case MATCH_EXACT:
if (pspec->pattern_length != string_length)
return FALSE;
else
return memcmp (pspec->pattern, string, string_length) == 0;
default:
g_return_val_if_fail (pspec->match_type < MATCH_LAST, FALSE);
return FALSE;
}
}
PatternSpec *
pattern_spec_new (const gchar * pattern, MatchMode match_mode)
{
PatternSpec *pspec;
gboolean seen_joker = FALSE, seen_wildcard = FALSE, more_wildcards = FALSE;
gint hw_pos = -1, tw_pos = -1, hj_pos = -1, tj_pos = -1;
gboolean follows_wildcard = FALSE;
guint pending_jokers = 0;
const gchar *s;
gchar *d;
guint i;
g_assert (pattern != NULL);
g_assert (match_mode != MATCH_MODE_UTF8
|| g_utf8_validate (pattern, -1, NULL));
/* canonicalize pattern and collect necessary stats */
pspec = g_new (PatternSpec, 1);
pspec->match_mode = match_mode;
pspec->pattern_length = strlen (pattern);
pspec->min_length = 0;
pspec->max_length = 0;
pspec->pattern = g_new (gchar, pspec->pattern_length + 1);
if (pspec->match_mode == MATCH_MODE_AUTO) {
if (!g_utf8_validate (pattern, -1, NULL))
pspec->match_mode = MATCH_MODE_RAW;
}
d = pspec->pattern;
for (i = 0, s = pattern; *s != 0; s++) {
switch (*s) {
case '*':
if (follows_wildcard) { /* compress multiple wildcards */
pspec->pattern_length--;
continue;
}
follows_wildcard = TRUE;
if (hw_pos < 0)
hw_pos = i;
tw_pos = i;
break;
case '?':
pending_jokers++;
pspec->min_length++;
if (pspec->match_mode == MATCH_MODE_RAW) {
pspec->max_length += 1;
} else {
pspec->max_length += 4; /* maximum UTF-8 character length */
}
continue;
default:
for (; pending_jokers; pending_jokers--, i++) {
*d++ = '?';
if (hj_pos < 0)
hj_pos = i;
tj_pos = i;
}
follows_wildcard = FALSE;
pspec->min_length++;
pspec->max_length++;
break;
}
*d++ = *s;
i++;
}
for (; pending_jokers; pending_jokers--) {
*d++ = '?';
if (hj_pos < 0)
hj_pos = i;
tj_pos = i;
}
*d++ = 0;
seen_joker = hj_pos >= 0;
seen_wildcard = hw_pos >= 0;
more_wildcards = seen_wildcard && hw_pos != tw_pos;
if (seen_wildcard)
pspec->max_length = G_MAXUINT;
/* special case sole head/tail wildcard or exact matches */
if (!seen_joker && !more_wildcards) {
if (pspec->pattern[0] == '*') {
pspec->match_type = MATCH_TAIL;
memmove (pspec->pattern, pspec->pattern + 1, --pspec->pattern_length);
pspec->pattern[pspec->pattern_length] = 0;
return pspec;
}
if (pspec->pattern_length > 0 &&
pspec->pattern[pspec->pattern_length - 1] == '*') {
pspec->match_type = MATCH_HEAD;
pspec->pattern[--pspec->pattern_length] = 0;
return pspec;
}
if (!seen_wildcard) {
pspec->match_type = MATCH_EXACT;
return pspec;
}
}
/* now just need to distinguish between head or tail match start */
tw_pos = pspec->pattern_length - 1 - tw_pos; /* last pos to tail distance */
tj_pos = pspec->pattern_length - 1 - tj_pos; /* last pos to tail distance */
if (seen_wildcard)
pspec->match_type = tw_pos > hw_pos ? MATCH_ALL_TAIL : MATCH_ALL;
else /* seen_joker */
pspec->match_type = tj_pos > hj_pos ? MATCH_ALL_TAIL : MATCH_ALL;
if (pspec->match_type == MATCH_ALL_TAIL) {
gchar *tmp = pspec->pattern;
if (pspec->match_mode == MATCH_MODE_RAW) {
pspec->pattern = raw_strreverse (pspec->pattern, pspec->pattern_length);
} else {
pspec->pattern =
g_utf8_strreverse (pspec->pattern, pspec->pattern_length);
}
g_free (tmp);
}
return pspec;
}
void
pattern_spec_free (PatternSpec * pspec)
{
g_assert (pspec != NULL);
g_free (pspec->pattern);
g_free (pspec);
}
gboolean
pattern_match_string (PatternSpec * pspec, const gchar * string)
{
return pattern_match (pspec, strlen (string), string, NULL);
}

View file

@ -0,0 +1,47 @@
/* GPattern copy that supports raw (non-utf8) matching
* based on: GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997, 1999 Peter Mattis, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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 __PATTERN_SPEC_H__
#define __PATTERN_SPEC_H__
#include <glib.h>
G_BEGIN_DECLS
typedef enum
{
MATCH_MODE_AUTO = 0,
MATCH_MODE_UTF8,
MATCH_MODE_RAW
} MatchMode;
typedef struct _PatternSpec PatternSpec;
PatternSpec * pattern_spec_new (const gchar * pattern,
MatchMode match_mode);
void pattern_spec_free (PatternSpec * pspec);
gboolean pattern_match_string (PatternSpec * pspec,
const gchar * string);
G_END_DECLS
#endif /* __PATTERN_SPEC_H__ */

View file

@ -239,15 +239,18 @@ elements_interleave_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS)
elements_interleave_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_MAJORMINOR) $(LDADD)
elements_imagefreeze_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(AM_CFLAGS)
elements_imagefreeze_LDADD = $(GST_BASE_LIBS) $(LDADD) -lgstvideo-$(GST_MAJORMINOR)
elements_imagefreeze_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_MAJORMINOR) $(GST_BASE_LIBS) $(LDADD)
elements_jpegenc_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(AM_CFLAGS)
elements_jpegenc_LDADD = $(GST_BASE_LIBS) $(LDADD) -lgstapp-0.10
elements_jpegenc_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstapp-0.10 $(GST_BASE_LIBS) $(LDADD)
elements_level_LDADD = $(LDADD) $(LIBM)
elements_matroskamux_LDADD = $(GST_BASE_LIBS) $(LDADD) $(LIBM)
elements_multifile_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(AM_CFLAGS)
elements_multifile_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_MAJORMINOR) $(GST_LIBS) $(LDADD) $(LIBM)
elements_qtmux_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(AM_CFLAGS)
elements_qtmux_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgstpbutils-@GST_MAJORMINOR@ \
$(GST_BASE_LIBS) $(GST_LIBS) $(GST_CHECK_LIBS)

View file

@ -26,6 +26,7 @@
#include <unistd.h>
#include <gst/check/gstcheck.h>
#include <gst/video/video.h>
#include <stdlib.h>
#include <unistd.h>
@ -40,7 +41,7 @@ run_pipeline (GstElement * pipeline)
gst_element_set_state (pipeline, GST_STATE_NULL);
}
#if !GLIB_CHECK_VERSION(2,26,0)
#if !GLIB_CHECK_VERSION(2,30,0)
static gchar *
g_mkdtemp (gchar * template)
{
@ -71,10 +72,10 @@ GST_START_TEST (test_multifilesink_key_frame)
pipeline =
gst_parse_launch
("videotestsrc num-buffers=10 ! video/x-raw-yuv,format=(fourcc)I420,width=320,height=240 ! multifilesink",
("videotestsrc num-buffers=10 ! video/x-raw-yuv,format=(fourcc)I420,width=320,height=240 ! multifilesink name=mfs",
NULL);
fail_if (pipeline == NULL);
mfs = gst_bin_get_by_name (GST_BIN (pipeline), "multifilesink0");
mfs = gst_bin_get_by_name (GST_BIN (pipeline), "mfs");
fail_if (mfs == NULL);
mfs_pattern = g_build_filename (my_tmpdir, "%05d", NULL);
g_object_set (G_OBJECT (mfs), "location", mfs_pattern, NULL);
@ -147,6 +148,65 @@ GST_START_TEST (test_multifilesink_max_files)
GST_END_TEST;
GST_START_TEST (test_multifilesink_key_unit)
{
GstElement *mfs;
int i;
const gchar *tmpdir;
gchar *my_tmpdir;
gchar *template;
gchar *mfs_pattern;
GstBuffer *buf;
GstPad *sink;
tmpdir = g_get_tmp_dir ();
template = g_build_filename (tmpdir, "multifile-test-XXXXXX", NULL);
my_tmpdir = g_mkdtemp (template);
fail_if (my_tmpdir == NULL);
mfs = gst_element_factory_make ("multifilesink", NULL);
fail_if (mfs == NULL);
mfs_pattern = g_build_filename (my_tmpdir, "%05d", NULL);
g_object_set (G_OBJECT (mfs), "location", mfs_pattern, "next-file", 3, NULL);
fail_if (gst_element_set_state (mfs,
GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
sink = gst_element_get_static_pad (mfs, "sink");
buf = gst_buffer_new_and_alloc (4);
memcpy (GST_BUFFER_DATA (buf), "foo", 4);
fail_if (gst_pad_chain (sink, gst_buffer_ref (buf)) != GST_FLOW_OK);
memcpy (GST_BUFFER_DATA (buf), "bar", 4);
fail_if (gst_pad_chain (sink, gst_buffer_ref (buf)) != GST_FLOW_OK);
fail_unless (gst_pad_send_event (sink,
gst_video_event_new_downstream_force_key_unit (GST_CLOCK_TIME_NONE,
GST_CLOCK_TIME_NONE, GST_CLOCK_TIME_NONE, TRUE, 1)));
memcpy (GST_BUFFER_DATA (buf), "baz", 4);
fail_if (gst_pad_chain (sink, buf) != GST_FLOW_OK);
fail_if (gst_element_set_state (mfs,
GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE);
for (i = 0; i < 2; i++) {
char *s;
s = g_strdup_printf (mfs_pattern, i);
fail_if (g_remove (s) != 0);
g_free (s);
}
fail_if (g_remove (my_tmpdir) != 0);
g_free (mfs_pattern);
g_free (my_tmpdir);
gst_object_unref (sink);
gst_object_unref (mfs);
}
GST_END_TEST;
GST_START_TEST (test_multifilesrc)
{
GstElement *pipeline;
@ -164,10 +224,10 @@ GST_START_TEST (test_multifilesrc)
pipeline =
gst_parse_launch
("videotestsrc num-buffers=10 ! video/x-raw-yuv,format=(fourcc)I420,width=320,height=240 ! multifilesink",
("videotestsrc num-buffers=10 ! video/x-raw-yuv,format=(fourcc)I420,width=320,height=240 ! multifilesink name=mfs",
NULL);
fail_if (pipeline == NULL);
mfs = gst_bin_get_by_name (GST_BIN (pipeline), "multifilesink0");
mfs = gst_bin_get_by_name (GST_BIN (pipeline), "mfs");
fail_if (mfs == NULL);
mfs_pattern = g_build_filename (my_tmpdir, "%05d", NULL);
g_object_set (G_OBJECT (mfs), "location", mfs_pattern, NULL);
@ -214,6 +274,7 @@ libvisual_suite (void)
tcase_add_test (tc_chain, test_multifilesink_key_frame);
tcase_add_test (tc_chain, test_multifilesink_max_files);
tcase_add_test (tc_chain, test_multifilesink_key_unit);
tcase_add_test (tc_chain, test_multifilesrc);
return s;