diff --git a/configure.ac b/configure.ac
index 45d9537974..d7777b6dcc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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])
diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am
index 38d9fb298d..683475bdc0 100644
--- a/docs/plugins/Makefile.am
+++ b/docs/plugins/Makefile.am
@@ -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 \
diff --git a/docs/plugins/gst-plugins-good-plugins-docs.sgml b/docs/plugins/gst-plugins-good-plugins-docs.sgml
index 9a7e8542a3..7d93c2a7aa 100644
--- a/docs/plugins/gst-plugins-good-plugins-docs.sgml
+++ b/docs/plugins/gst-plugins-good-plugins-docs.sgml
@@ -155,6 +155,7 @@
+
diff --git a/docs/plugins/gst-plugins-good-plugins-sections.txt b/docs/plugins/gst-plugins-good-plugins-sections.txt
index c92a5717e0..5a8e692b2c 100644
--- a/docs/plugins/gst-plugins-good-plugins-sections.txt
+++ b/docs/plugins/gst-plugins-good-plugins-sections.txt
@@ -1911,6 +1911,20 @@ GST_IS_SPEEX_ENC_CLASS
gst_speex_enc_get_type
+
+element-splitfilesrc
+splitfilesrc
+GstSplitFileSrc
+
+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
+
+
element-taginject
taginject
diff --git a/docs/plugins/gst-plugins-good-plugins.args b/docs/plugins/gst-plugins-good-plugins.args
index 0c96249e11..95f2db51b5 100644
--- a/docs/plugins/gst-plugins-good-plugins.args
+++ b/docs/plugins/gst-plugins-good-plugins.args
@@ -178,6 +178,16 @@
FALSE
+
+GstMultiFileSink::max-files
+guint
+
+rw
+Max files
+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.
+0
+
+
GstMultiFileSrc::caps
GstCaps*
@@ -208,6 +218,36 @@
"%05d"
+
+GstMultiFileSrc::loop
+gboolean
+
+rw
+Loop
+Whether to repeat from the beginning when all files have been read.
+FALSE
+
+
+
+GstMultiFileSrc::start-index
+gint
+>= 0
+rw
+Start Index
+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.
+0
+
+
+
+GstMultiFileSrc::stop-index
+gint
+>= G_MAXULONG
+rw
+Start Index
+Stop value of index. The special value -1 means no stop.
+0
+
+
GstOssSrc::device
gchar*
@@ -461,7 +501,7 @@
GstUDPSrc::sockfd
gint
->= -1
+>= G_MAXULONG
rw
Socket Handle
Socket to use for UDP reception. (-1 == allocate).
@@ -511,7 +551,7 @@
GstUDPSrc::sock
gint
->= -1
+>= G_MAXULONG
r
Socket Handle
Socket currently in use for UDP reception. (-1 = no socket).
@@ -778,6 +818,16 @@
524288
+
+GstRTSPSrc::short-header
+gboolean
+
+rw
+Short Header
+Only send the basic RTSP headers for broken encoders.
+FALSE
+
+
GstRTPDec::skip
gint
@@ -1512,7 +1562,7 @@
GstSpeexEnc::abr
gint
>= 0
-rw
+rwx
ABR
Enable average bit-rate (0 = disabled).
0
@@ -1522,7 +1572,7 @@
GstSpeexEnc::bitrate
gint
>= 0
-rw
+rwx
Encoding Bit-rate
Specify an encoding bit-rate (in bps). (0 = automatic).
0
@@ -1532,7 +1582,7 @@
GstSpeexEnc::complexity
gint
>= 0
-rw
+rwx
Complexity
Set encoding complexity.
3
@@ -1542,7 +1592,7 @@
GstSpeexEnc::dtx
gboolean
-rw
+rwx
DTX
Enable discontinuous transmission.
FALSE
@@ -1562,7 +1612,7 @@
GstSpeexEnc::nframes
gint
>= 0
-rw
+rwx
NFrames
Number of frames per buffer.
1
@@ -1572,7 +1622,7 @@
GstSpeexEnc::quality
gfloat
[0,10]
-rw
+rwx
Quality
Encoding quality.
8
@@ -1582,7 +1632,7 @@
GstSpeexEnc::vad
gboolean
-rw
+rwx
VAD
Enable voice activity detection.
FALSE
@@ -1592,7 +1642,7 @@
GstSpeexEnc::vbr
gboolean
-rw
+rwx
VBR
Enable variable bit-rate.
FALSE
@@ -1602,7 +1652,7 @@
GstSpeexEnc::mode
GstSpeexEncMode
-rw
+rwx
Mode
The encoding mode.
Auto
@@ -1651,7 +1701,7 @@
GstDV1394Src::port
gint
-[-1,16]
+[G_MAXULONG,16]
rw
Port
Port number (-1 automatic).
@@ -1901,7 +1951,7 @@
GstTest::allowed-timestamp-deviation
gint64
->= -1
+>= G_MAXULONG
rwx
allowed timestamp deviation
allowed average difference in usec between timestamp of next buffer and expected timestamp from analyzing last buffer.
@@ -1911,7 +1961,7 @@
GstTest::buffer-count
gint64
->= -1
+>= G_MAXULONG
r
buffer count
number of buffers in stream.
@@ -1921,7 +1971,7 @@
GstTest::expected-buffer-count
gint64
->= -1
+>= G_MAXULONG
rwx
expected buffer count
expected number of buffers in stream.
@@ -1931,7 +1981,7 @@
GstTest::expected-length
gint64
->= -1
+>= G_MAXULONG
rwx
expected length
expected length of stream.
@@ -1951,7 +2001,7 @@
GstTest::length
gint64
->= -1
+>= G_MAXULONG
r
length
length of stream.
@@ -1971,7 +2021,7 @@
GstTest::timestamp-deviation
gint64
->= -1
+>= G_MAXULONG
r
timestamp deviation
average difference in usec between timestamp of next buffer and expected timestamp from analyzing last buffer.
@@ -2051,7 +2101,7 @@
GstBreakMyData::set-to
gint
-[-1,255]
+[G_MAXULONG,255]
rwx
set-to
set changed bytes to this value (-1 means random value.
@@ -2224,7 +2274,7 @@
rw
Send Config
-Send the config parameters in RTP packets as well.
+Send the config parameters in RTP packets as well(deprecated see config-interval).
FALSE
@@ -2358,6 +2408,16 @@
25
+
+GstCairoTextOverlay::silent
+gboolean
+
+w
+silent
+Whether to render the text string.
+FALSE
+
+
GstOssMixerElement::device-name
gchar*
@@ -2391,7 +2451,7 @@
GstDynUDPSink::sockfd
gint
-[-1,32767]
+[G_MAXULONG,32767]
rw
socket handle
Socket to use for UDP sending. (-1 == allocate).
@@ -2461,7 +2521,7 @@
GstMultiUDPSink::sock
gint
->= -1
+>= G_MAXULONG
r
Socket Handle
Socket currently in use for UDP sending. (-1 == no socket).
@@ -2471,7 +2531,7 @@
GstMultiUDPSink::sockfd
gint
->= -1
+>= G_MAXULONG
rw
Socket Handle
Socket to use for UDP sending. (-1 == allocate).
@@ -2501,7 +2561,7 @@
GstMultiUDPSink::qos-dscp
gint
-[-1,63]
+[G_MAXULONG,63]
rw
QoS diff srv code point
Quality of Service, differentiated services code point (-1 default).
@@ -2651,7 +2711,7 @@
GstXImageSrc::screen-num
guint
-<= G_MAXLONG
+<= G_MAXINT
rw
Screen number
X Screen Number.
@@ -2671,7 +2731,7 @@
GstXImageSrc::endx
guint
-<= G_MAXLONG
+<= G_MAXINT
rw
End X
X coordinate of bottom right corner of area to be recorded (0 for bottom right of screen).
@@ -2681,7 +2741,7 @@
GstXImageSrc::endy
guint
-<= G_MAXLONG
+<= G_MAXINT
rw
End Y
Y coordinate of bottom right corner of area to be recorded (0 for bottom right of screen).
@@ -2691,7 +2751,7 @@
GstXImageSrc::startx
guint
-<= G_MAXLONG
+<= G_MAXINT
rw
Start X co-ordinate
X coordinate of top left corner of area to be recorded (0 for top left of screen).
@@ -2701,7 +2761,7 @@
GstXImageSrc::starty
guint
-<= G_MAXLONG
+<= G_MAXINT
rw
Start Y co-ordinate
Y coordinate of top left corner of area to be recorded (0 for top left of screen).
@@ -2728,6 +2788,26 @@
FALSE
+
+GstXImageSrc::xid
+guint64
+
+rw
+Window XID
+Window XID to capture from.
+0
+
+
+
+GstXImageSrc::xname
+gchar*
+
+rw
+Window name
+Window name to capture from.
+NULL
+
+
GstVideoBalance::brightness
gdouble
@@ -2788,6 +2868,16 @@
NULL
+
+GstMultipartDemux::single-stream
+gboolean
+
+rw
+Single Stream
+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.
+FALSE
+
+
GstAviMux::bigfile
gboolean
@@ -2811,7 +2901,7 @@
GstJpegDec::max-errors
gint
->= -1
+>= G_MAXULONG
rw
Maximum Consecutive Decoding Errors
Error out after receiving N consecutive decoding errors (-1 = never fail, 0 = automatic, 1 = fail on first error).
@@ -3121,7 +3211,7 @@
GstV4l2Src::device-fd
gint
->= -1
+>= G_MAXULONG
r
File descriptor
File descriptor of the device.
@@ -3178,6 +3268,16 @@
0
+
+GstV4l2Src::norm
+V4L2_TV_norms
+
+rw
+TV norm
+video standard.
+none
+
+
GstAudioChebBand::lower-frequency
gfloat
@@ -3391,7 +3491,7 @@
GstRndBufferSize::max
glong
->= 1
+[1,G_MAXINT]
rwx
maximum
maximum buffer size.
@@ -3401,7 +3501,7 @@
GstRndBufferSize::min
glong
->= 0
+[0,G_MAXINT]
rwx
mininum
mininum buffer size.
@@ -3411,7 +3511,7 @@
GstRndBufferSize::seed
gulong
-
+<= G_MAXUINT
rwx
random number seed
seed for randomness (initialized when going from READY to PAUSED).
@@ -19898,6 +19998,36 @@
""
+
+GstPulseSrc::mute
+gboolean
+
+rw
+Mute
+Mute state of this stream.
+FALSE
+
+
+
+GstPulseSrc::source-output-index
+guint
+
+r
+source output index
+The index of the PulseAudio source output corresponding to this record stream.
+4294967295
+
+
+
+GstPulseSrc::volume
+gdouble
+[0,10]
+rw
+Volume
+Linear volume of this stream, 1.0=100%.
+1
+
+
GstPulseMixer::device
gchar*
@@ -20111,7 +20241,7 @@
GstHDV1394Src::port
gint
-[-1,16]
+[G_MAXULONG,16]
rw
Port
Port number (-1 automatic).
@@ -20491,7 +20621,7 @@
GstOpTV::threshold
guint
-<= G_MAXLONG
+<= G_MAXINT
rw
Threshold
Luma threshold.
@@ -20511,7 +20641,7 @@
GstRadioacTV::interval
guint
-<= G_MAXLONG
+<= G_MAXINT
rw
Interval
Snapshot interval (in strobe mode).
@@ -20648,6 +20778,26 @@
FALSE
+
+GstRtpBin::rtcp-sync
+GstRTCPSync
+
+rw
+RTCP Sync
+Use of RTCP SR in synchronization.
+always
+
+
+
+GstRtpBin::rtcp-sync-interval
+guint
+
+rw
+RTCP Sync Interval
+RTCP SR interval synchronization (ms) (0 = always).
+0
+
+
GstRtpJitterBuffer::do-lost
gboolean
@@ -20781,7 +20931,7 @@
GstRtpSession::rtcp-rr-bandwidth
gint
->= -1
+>= G_MAXULONG
rw
RTCP RR bandwidth
The RTCP bandwidth used for receivers in bytes per second (-1 = default).
@@ -20791,7 +20941,7 @@
GstRtpSession::rtcp-rs-bandwidth
gint
->= -1
+>= G_MAXULONG
rw
RTCP RS bandwidth
The RTCP bandwidth used for senders in bytes per second (-1 = default).
@@ -21858,3 +22008,383 @@
0
+
+GstSplitFileSrc::location
+gchar*
+
+rw
+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.
+NULL
+
+
+
+GstMatroskaDemux::max-gap-time
+guint64
+
+rw
+Maximum gap time
+The demuxer sends out newsegment events for skipping gaps longer than this (0 = disabled).
+2000000000
+
+
+
+GstPulseAudioSink::alignment-threshold
+guint64
+[1,18446744073709551614]
+rw
+Alignment Threshold
+Timestamp alignment threshold in nanoseconds.
+40000000
+
+
+
+GstPulseAudioSink::async
+gboolean
+
+rw
+Async
+Go asynchronously to PAUSED.
+TRUE
+
+
+
+GstPulseAudioSink::blocksize
+guint
+
+rw
+Block size
+Size in bytes to pull per buffer (0 = default).
+4096
+
+
+
+GstPulseAudioSink::buffer-time
+gint64
+>= 1
+rw
+Buffer Time
+Size of audio buffer in microseconds.
+200000
+
+
+
+GstPulseAudioSink::can-activate-pull
+gboolean
+
+rw
+Allow Pull Scheduling
+Allow pull-based scheduling.
+FALSE
+
+
+
+GstPulseAudioSink::client
+gchar*
+
+rw
+Client
+The PulseAudio client name to use.
+""
+
+
+
+GstPulseAudioSink::device
+gchar*
+
+rw
+Device
+The PulseAudio sink device to connect to.
+NULL
+
+
+
+GstPulseAudioSink::device-name
+gchar*
+
+r
+Device name
+Human-readable name of the sound device.
+NULL
+
+
+
+GstPulseAudioSink::discont-wait
+guint64
+<= 18446744073709551614
+rw
+Discont Wait
+Window of time in nanoseconds to wait before creating a discontinuity.
+1000000000
+
+
+
+GstPulseAudioSink::drift-tolerance
+gint64
+>= 1
+rw
+Drift Tolerance
+Tolerance for clock drift in microseconds.
+40000
+
+
+
+GstPulseAudioSink::enable-last-buffer
+gboolean
+
+rw
+Enable Last Buffer
+Enable the last-buffer property.
+TRUE
+
+
+
+GstPulseAudioSink::last-buffer
+GstBuffer*
+
+r
+Last Buffer
+The last buffer received in the sink.
+
+
+
+
+GstPulseAudioSink::latency-time
+gint64
+>= 1
+rw
+Latency Time
+Audio latency in microseconds.
+10000
+
+
+
+GstPulseAudioSink::max-lateness
+gint64
+>= G_MAXULONG
+rw
+Max Lateness
+Maximum number of nanoseconds that a buffer can be late before it is dropped (-1 unlimited).
+-1
+
+
+
+GstPulseAudioSink::mute
+gboolean
+
+rw
+Mute
+Mute state of this stream.
+FALSE
+
+
+
+GstPulseAudioSink::preroll-queue-len
+guint
+
+rwx
+Preroll queue length
+Number of buffers to queue during preroll.
+0
+
+
+
+GstPulseAudioSink::provide-clock
+gboolean
+
+rw
+Provide Clock
+Provide a clock to be used as the global pipeline clock.
+TRUE
+
+
+
+GstPulseAudioSink::qos
+gboolean
+
+rw
+Qos
+Generate Quality-of-Service events upstream.
+FALSE
+
+
+
+GstPulseAudioSink::render-delay
+guint64
+
+rw
+Render Delay
+Additional render delay of the sink in nanoseconds.
+0
+
+
+
+GstPulseAudioSink::server
+gchar*
+
+rw
+Server
+The PulseAudio server to connect to.
+NULL
+
+
+
+GstPulseAudioSink::slave-method
+GstBaseAudioSinkSlaveMethod
+
+rw
+Slave Method
+Algorithm to use to match the rate of the masterclock.
+GST_BASE_AUDIO_SINK_SLAVE_SKEW
+
+
+
+GstPulseAudioSink::stream-properties
+GstStructure*
+
+rw
+stream properties
+list of pulseaudio stream properties.
+
+
+
+
+GstPulseAudioSink::sync
+gboolean
+
+rw
+Sync
+Sync on the clock.
+TRUE
+
+
+
+GstPulseAudioSink::throttle-time
+guint64
+
+rw
+Throttle time
+The time to keep between rendered buffers (unused).
+0
+
+
+
+GstPulseAudioSink::ts-offset
+gint64
+
+rw
+TS Offset
+Timestamp offset in nanoseconds.
+0
+
+
+
+GstPulseAudioSink::volume
+gdouble
+[0,10]
+rw
+Volume
+Linear volume of this stream, 1.0=100%.
+1
+
+
+
+GstSoupHttpClientSink::automatic-redirect
+gboolean
+
+rw
+automatic-redirect
+Automatically follow HTTP redirects (HTTP Status Code 3xx).
+TRUE
+
+
+
+GstSoupHttpClientSink::cookies
+GStrv
+
+rw
+Cookies
+HTTP request cookies.
+
+
+
+
+GstSoupHttpClientSink::location
+gchar*
+
+rw
+Location
+URI to send to.
+""
+
+
+
+GstSoupHttpClientSink::proxy
+gchar*
+
+rw
+Proxy
+HTTP proxy server URI.
+""
+
+
+
+GstSoupHttpClientSink::proxy-id
+gchar*
+
+rw
+proxy-id
+user id for proxy authentication.
+""
+
+
+
+GstSoupHttpClientSink::proxy-pw
+gchar*
+
+rw
+proxy-pw
+user password for proxy authentication.
+""
+
+
+
+GstSoupHttpClientSink::session
+SoupSession*
+
+rw
+session
+SoupSession object to use for communication.
+
+
+
+
+GstSoupHttpClientSink::user-agent
+gchar*
+
+rw
+User-Agent
+Value of the User-Agent HTTP request header field.
+"GStreamer souphttpclientsink "
+
+
+
+GstSoupHttpClientSink::user-id
+gchar*
+
+rw
+user-id
+user id for authentication.
+""
+
+
+
+GstSoupHttpClientSink::user-pw
+gchar*
+
+rw
+user-pw
+user password for authentication.
+""
+
+
diff --git a/docs/plugins/gst-plugins-good-plugins.hierarchy b/docs/plugins/gst-plugins-good-plugins.hierarchy
index 5e1dff3865..9f4fabee7d 100644
--- a/docs/plugins/gst-plugins-good-plugins.hierarchy
+++ b/docs/plugins/gst-plugins-good-plugins.hierarchy
@@ -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
diff --git a/docs/plugins/gst-plugins-good-plugins.interfaces b/docs/plugins/gst-plugins-good-plugins.interfaces
index 518366a8ab..b356c99aa9 100644
--- a/docs/plugins/gst-plugins-good-plugins.interfaces
+++ b/docs/plugins/gst-plugins-good-plugins.interfaces
@@ -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
diff --git a/docs/plugins/gst-plugins-good-plugins.signals b/docs/plugins/gst-plugins-good-plugins.signals
index 37613c7350..a68d13ba2b 100644
--- a/docs/plugins/gst-plugins-good-plugins.signals
+++ b/docs/plugins/gst-plugins-good-plugins.signals
@@ -14,7 +14,7 @@ GstGSMEnc *gstgsmenc
GstMultiUDPSink::add
void
-l
+la
GstMultiUDPSink *gstmultiudpsink
gchar *arg1
gint arg2
@@ -23,7 +23,7 @@ gint arg2
GstMultiUDPSink::clear
void
-l
+la
GstMultiUDPSink *gstmultiudpsink
@@ -48,7 +48,7 @@ gint arg2
GstMultiUDPSink::get-stats
GValueArray*
-l
+la
GstMultiUDPSink *gstmultiudpsink
gchar *arg1
gint arg2
@@ -57,7 +57,7 @@ gint arg2
GstMultiUDPSink::remove
void
-l
+la
GstMultiUDPSink *gstmultiudpsink
gchar *arg1
gint arg2
diff --git a/docs/plugins/inspect/plugin-1394.xml b/docs/plugins/inspect/plugin-1394.xml
index fdb4bc6eb7..56e1fec639 100644
--- a/docs/plugins/inspect/plugin-1394.xml
+++ b/docs/plugins/inspect/plugin-1394.xml
@@ -40,4 +40,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-aasink.xml b/docs/plugins/inspect/plugin-aasink.xml
index 7feec451fb..a8a18e2388 100644
--- a/docs/plugins/inspect/plugin-aasink.xml
+++ b/docs/plugins/inspect/plugin-aasink.xml
@@ -25,4 +25,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-alaw.xml b/docs/plugins/inspect/plugin-alaw.xml
index f62e9fa9ef..4f13d5bed4 100644
--- a/docs/plugins/inspect/plugin-alaw.xml
+++ b/docs/plugins/inspect/plugin-alaw.xml
@@ -52,4 +52,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-alpha.xml b/docs/plugins/inspect/plugin-alpha.xml
index d12896daec..b935b0fd46 100644
--- a/docs/plugins/inspect/plugin-alpha.xml
+++ b/docs/plugins/inspect/plugin-alpha.xml
@@ -33,4 +33,4 @@ Jan Schmidt <thaytan@noraisin.net>
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-alphacolor.xml b/docs/plugins/inspect/plugin-alphacolor.xml
index 2947138d0d..84de6c7756 100644
--- a/docs/plugins/inspect/plugin-alphacolor.xml
+++ b/docs/plugins/inspect/plugin-alphacolor.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-annodex.xml b/docs/plugins/inspect/plugin-annodex.xml
index 1dde4b0634..9c086dbd0a 100644
--- a/docs/plugins/inspect/plugin-annodex.xml
+++ b/docs/plugins/inspect/plugin-annodex.xml
@@ -52,4 +52,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-apetag.xml b/docs/plugins/inspect/plugin-apetag.xml
index 339aa122ed..1be46d47bb 100644
--- a/docs/plugins/inspect/plugin-apetag.xml
+++ b/docs/plugins/inspect/plugin-apetag.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-audiofx.xml b/docs/plugins/inspect/plugin-audiofx.xml
index 05e7ed73fd..577ae54a49 100644
--- a/docs/plugins/inspect/plugin-audiofx.xml
+++ b/docs/plugins/inspect/plugin-audiofx.xml
@@ -262,4 +262,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-audioparsers.xml b/docs/plugins/inspect/plugin-audioparsers.xml
index b129a6923d..09406505e2 100644
--- a/docs/plugins/inspect/plugin-audioparsers.xml
+++ b/docs/plugins/inspect/plugin-audioparsers.xml
@@ -20,7 +20,7 @@
sink
sink
always
- audio/mpeg, framed=(boolean)false, mpegversion=(int){ 2, 4 }
+ audio/mpeg, mpegversion=(int){ 2, 4 }
src
@@ -33,7 +33,7 @@
ac3parse
AC3 audio stream parser
- Codec/Parser/Audio
+ Codec/Parser/Converter/Audio
AC3 parser
Tim-Philipp Müller <tim centricular net>
@@ -41,13 +41,13 @@
sink
sink
always
- audio/x-ac3, framed=(boolean)false; audio/x-eac3, framed=(boolean)false; audio/ac3, framed=(boolean)false
+ audio/x-ac3; audio/x-eac3; audio/ac3
src
source
always
- 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 ]
+ 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 }
@@ -83,13 +83,13 @@
sink
sink
always
- audio/x-dts, framed=(boolean)false
+ audio/x-dts
src
source
always
- audio/x-dts, framed=(boolean)true, channels=(int)[ 1, 8 ], rate=(int)[ 8000, 192000 ], depth=(int){ 14, 16 }, endianness=(int){ 1234, 4321 }
+ 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 ]
@@ -104,7 +104,7 @@
sink
sink
always
- audio/x-flac, framed=(boolean)false
+ audio/x-flac
src
@@ -125,15 +125,15 @@
sink
sink
always
- audio/mpeg, mpegversion=(int)1, parsed=(boolean)false
+ audio/mpeg, mpegversion=(int)1
src
source
always
- audio/mpeg, mpegversion=(int)1, layer=(int)[ 1, 3 ], rate=(int)[ 8000, 48000 ], channels=(int)[ 1, 2 ], parsed=(boolean)true
+ audio/mpeg, mpegversion=(int)1, layer=(int)[ 1, 3 ], mpegaudioversion=(int)[ 1, 3 ], rate=(int)[ 8000, 48000 ], channels=(int)[ 1, 2 ], parsed=(boolean)true
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-auparse.xml b/docs/plugins/inspect/plugin-auparse.xml
index 1f20361e17..52797c70bf 100644
--- a/docs/plugins/inspect/plugin-auparse.xml
+++ b/docs/plugins/inspect/plugin-auparse.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-autodetect.xml b/docs/plugins/inspect/plugin-autodetect.xml
index 84c9ad91ad..c91b864c2f 100644
--- a/docs/plugins/inspect/plugin-autodetect.xml
+++ b/docs/plugins/inspect/plugin-autodetect.xml
@@ -70,4 +70,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-avi.xml b/docs/plugins/inspect/plugin-avi.xml
index 5e351df3c2..0ec9e2e658 100644
--- a/docs/plugins/inspect/plugin-avi.xml
+++ b/docs/plugins/inspect/plugin-avi.xml
@@ -59,7 +59,7 @@
video_%d
sink
request
- 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 ]
+ 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 ]
src
@@ -91,4 +91,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-cacasink.xml b/docs/plugins/inspect/plugin-cacasink.xml
index 9791809cb5..4205723bf7 100644
--- a/docs/plugins/inspect/plugin-cacasink.xml
+++ b/docs/plugins/inspect/plugin-cacasink.xml
@@ -25,4 +25,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-cairo.xml b/docs/plugins/inspect/plugin-cairo.xml
index bcff09cee7..1691a118ee 100644
--- a/docs/plugins/inspect/plugin-cairo.xml
+++ b/docs/plugins/inspect/plugin-cairo.xml
@@ -100,4 +100,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-cutter.xml b/docs/plugins/inspect/plugin-cutter.xml
index 41b91c7a75..9168291bd1 100644
--- a/docs/plugins/inspect/plugin-cutter.xml
+++ b/docs/plugins/inspect/plugin-cutter.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-debug.xml b/docs/plugins/inspect/plugin-debug.xml
index 96fe0a45dd..f8021cae5a 100644
--- a/docs/plugins/inspect/plugin-debug.xml
+++ b/docs/plugins/inspect/plugin-debug.xml
@@ -155,7 +155,7 @@
Random buffer size
Testing
pull random sized buffers
- Stefan Kost <stefan.kost@nokia.com>)
+ Stefan Kost <stefan.kost@nokia.com>
sink
@@ -208,4 +208,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-deinterlace.xml b/docs/plugins/inspect/plugin-deinterlace.xml
index 6bc3dcc069..448356da98 100644
--- a/docs/plugins/inspect/plugin-deinterlace.xml
+++ b/docs/plugins/inspect/plugin-deinterlace.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-dv.xml b/docs/plugins/inspect/plugin-dv.xml
index 2b0abb9095..fc450764e8 100644
--- a/docs/plugins/inspect/plugin-dv.xml
+++ b/docs/plugins/inspect/plugin-dv.xml
@@ -58,4 +58,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-efence.xml b/docs/plugins/inspect/plugin-efence.xml
index d6d5efb4bd..c6cef5238b 100644
--- a/docs/plugins/inspect/plugin-efence.xml
+++ b/docs/plugins/inspect/plugin-efence.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-effectv.xml b/docs/plugins/inspect/plugin-effectv.xml
index 164926e35e..f6e05ab241 100644
--- a/docs/plugins/inspect/plugin-effectv.xml
+++ b/docs/plugins/inspect/plugin-effectv.xml
@@ -125,13 +125,13 @@
sink
sink
always
- 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)-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 ]
src
source
always
- 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)-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 ]
@@ -262,4 +262,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-equalizer.xml b/docs/plugins/inspect/plugin-equalizer.xml
index 9a434ca3fd..dea4fb069c 100644
--- a/docs/plugins/inspect/plugin-equalizer.xml
+++ b/docs/plugins/inspect/plugin-equalizer.xml
@@ -73,4 +73,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-flac.xml b/docs/plugins/inspect/plugin-flac.xml
index 0f8c296f43..26c69196c2 100644
--- a/docs/plugins/inspect/plugin-flac.xml
+++ b/docs/plugins/inspect/plugin-flac.xml
@@ -73,4 +73,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-flv.xml b/docs/plugins/inspect/plugin-flv.xml
index b5b5370609..487ef8fc1f 100644
--- a/docs/plugins/inspect/plugin-flv.xml
+++ b/docs/plugins/inspect/plugin-flv.xml
@@ -47,7 +47,7 @@
audio
sink
request
- 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 }
+ 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 }
video
@@ -64,4 +64,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-flxdec.xml b/docs/plugins/inspect/plugin-flxdec.xml
index 48ac3b0036..e035f3dc85 100644
--- a/docs/plugins/inspect/plugin-flxdec.xml
+++ b/docs/plugins/inspect/plugin-flxdec.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-gdkpixbuf.xml b/docs/plugins/inspect/plugin-gdkpixbuf.xml
index fe9e907467..8b27462bf3 100644
--- a/docs/plugins/inspect/plugin-gdkpixbuf.xml
+++ b/docs/plugins/inspect/plugin-gdkpixbuf.xml
@@ -67,4 +67,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-goom.xml b/docs/plugins/inspect/plugin-goom.xml
index 0d8184ecbb..4cdc7c29d2 100644
--- a/docs/plugins/inspect/plugin-goom.xml
+++ b/docs/plugins/inspect/plugin-goom.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-goom2k1.xml b/docs/plugins/inspect/plugin-goom2k1.xml
index 7ab72f73a6..f2500bab23 100644
--- a/docs/plugins/inspect/plugin-goom2k1.xml
+++ b/docs/plugins/inspect/plugin-goom2k1.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-halelements.xml b/docs/plugins/inspect/plugin-halelements.xml
index 152cda2928..689988a8d8 100644
--- a/docs/plugins/inspect/plugin-halelements.xml
+++ b/docs/plugins/inspect/plugin-halelements.xml
@@ -40,4 +40,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-icydemux.xml b/docs/plugins/inspect/plugin-icydemux.xml
index d45aa48d73..1a2f808b35 100644
--- a/docs/plugins/inspect/plugin-icydemux.xml
+++ b/docs/plugins/inspect/plugin-icydemux.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-id3demux.xml b/docs/plugins/inspect/plugin-id3demux.xml
index 77ad31c6fc..ceafebd36d 100644
--- a/docs/plugins/inspect/plugin-id3demux.xml
+++ b/docs/plugins/inspect/plugin-id3demux.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-imagefreeze.xml b/docs/plugins/inspect/plugin-imagefreeze.xml
index 0c9fd7b965..887076310c 100644
--- a/docs/plugins/inspect/plugin-imagefreeze.xml
+++ b/docs/plugins/inspect/plugin-imagefreeze.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-interleave.xml b/docs/plugins/inspect/plugin-interleave.xml
index 45f4bd575a..9dd3d189c3 100644
--- a/docs/plugins/inspect/plugin-interleave.xml
+++ b/docs/plugins/inspect/plugin-interleave.xml
@@ -52,4 +52,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-isomp4.xml b/docs/plugins/inspect/plugin-isomp4.xml
index 577cacaf91..8df339885c 100644
--- a/docs/plugins/inspect/plugin-isomp4.xml
+++ b/docs/plugins/inspect/plugin-isomp4.xml
@@ -86,7 +86,7 @@
src
source
always
- video/quicktime, variant=(string)iso
+ video/quicktime, variant=(string)iso-fragmented
@@ -203,7 +203,7 @@
video_%d
sink
request
- 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 ]
+ 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 ]
src
@@ -235,4 +235,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-jack.xml b/docs/plugins/inspect/plugin-jack.xml
index 24f46454a0..b31bc2584c 100644
--- a/docs/plugins/inspect/plugin-jack.xml
+++ b/docs/plugins/inspect/plugin-jack.xml
@@ -40,4 +40,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-jpeg.xml b/docs/plugins/inspect/plugin-jpeg.xml
index 49d9efe755..bc579c0c6c 100644
--- a/docs/plugins/inspect/plugin-jpeg.xml
+++ b/docs/plugins/inspect/plugin-jpeg.xml
@@ -20,7 +20,7 @@
sink
sink
always
- image/jpeg, width=(int)[ 1, 65535 ], height=(int)[ 1, 65535 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+ 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 }
src
@@ -94,4 +94,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-level.xml b/docs/plugins/inspect/plugin-level.xml
index c4a4955906..7c7cb22596 100644
--- a/docs/plugins/inspect/plugin-level.xml
+++ b/docs/plugins/inspect/plugin-level.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-matroska.xml b/docs/plugins/inspect/plugin-matroska.xml
index 1a530f8006..c5180bbe0f 100644
--- a/docs/plugins/inspect/plugin-matroska.xml
+++ b/docs/plugins/inspect/plugin-matroska.xml
@@ -32,7 +32,7 @@
subtitle_%02d
source
sometimes
- 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
+ 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
video_%02d
@@ -124,4 +124,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-monoscope.xml b/docs/plugins/inspect/plugin-monoscope.xml
index a2aa4e7db4..02762d3f5a 100644
--- a/docs/plugins/inspect/plugin-monoscope.xml
+++ b/docs/plugins/inspect/plugin-monoscope.xml
@@ -3,10 +3,10 @@
Monoscope visualization
../../gst/monoscope/.libs/libgstmonoscope.so
libgstmonoscope.so
- 0.10.28.4
+ 0.10.30.1
LGPL
- GStreamer Good Plug-ins prerelease
+ GStreamer Good Plug-ins git
Unknown package origin
diff --git a/docs/plugins/inspect/plugin-mulaw.xml b/docs/plugins/inspect/plugin-mulaw.xml
index 0ddde6ed35..e805bdf63c 100644
--- a/docs/plugins/inspect/plugin-mulaw.xml
+++ b/docs/plugins/inspect/plugin-mulaw.xml
@@ -52,4 +52,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-multifile.xml b/docs/plugins/inspect/plugin-multifile.xml
index b42bff3d33..f14ec4bd7c 100644
--- a/docs/plugins/inspect/plugin-multifile.xml
+++ b/docs/plugins/inspect/plugin-multifile.xml
@@ -39,5 +39,20 @@
+
+ splitfilesrc
+ 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>
+
+
+ src
+ source
+ always
+ ANY
+
+
+
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-multipart.xml b/docs/plugins/inspect/plugin-multipart.xml
index 48d1ede530..0b9538a41c 100644
--- a/docs/plugins/inspect/plugin-multipart.xml
+++ b/docs/plugins/inspect/plugin-multipart.xml
@@ -52,4 +52,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-navigationtest.xml b/docs/plugins/inspect/plugin-navigationtest.xml
index 4fd34b8257..640982c9bf 100644
--- a/docs/plugins/inspect/plugin-navigationtest.xml
+++ b/docs/plugins/inspect/plugin-navigationtest.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-oss4.xml b/docs/plugins/inspect/plugin-oss4.xml
index ecb0ee9c5c..533de3dbef 100644
--- a/docs/plugins/inspect/plugin-oss4.xml
+++ b/docs/plugins/inspect/plugin-oss4.xml
@@ -49,4 +49,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-ossaudio.xml b/docs/plugins/inspect/plugin-ossaudio.xml
index a249f86707..564ed53a17 100644
--- a/docs/plugins/inspect/plugin-ossaudio.xml
+++ b/docs/plugins/inspect/plugin-ossaudio.xml
@@ -49,4 +49,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-png.xml b/docs/plugins/inspect/plugin-png.xml
index 2c93ec89e9..ec1e9d13f6 100644
--- a/docs/plugins/inspect/plugin-png.xml
+++ b/docs/plugins/inspect/plugin-png.xml
@@ -47,9 +47,9 @@
src
source
always
- image/png, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
+ image/png, width=(int)[ 16, 1000000 ], height=(int)[ 16, 1000000 ], framerate=(fraction)[ 0/1, 2147483647/1 ]
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-pulseaudio.xml b/docs/plugins/inspect/plugin-pulseaudio.xml
index 6dfef36cb6..7426de9275 100644
--- a/docs/plugins/inspect/plugin-pulseaudio.xml
+++ b/docs/plugins/inspect/plugin-pulseaudio.xml
@@ -9,6 +9,21 @@
GStreamer Good Plug-ins git
Unknown package origin
+
+ pulseaudiosink
+ Bin wrapping pulsesink
+ Sink/Audio/Bin
+ Correctly handles sink changes when streaming compressed formats to pulsesink
+ Arun Raghavan <arun.raghavan@collabora.co.uk>
+
+
+ sink
+ sink
+ always
+ 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
+
+
+
pulsemixer
PulseAudio Mixer
@@ -29,7 +44,7 @@
sink
sink
always
- 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 ]
+ 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
@@ -49,4 +64,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-replaygain.xml b/docs/plugins/inspect/plugin-replaygain.xml
index 266e49879b..419354bc99 100644
--- a/docs/plugins/inspect/plugin-replaygain.xml
+++ b/docs/plugins/inspect/plugin-replaygain.xml
@@ -73,4 +73,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-rtp.xml b/docs/plugins/inspect/plugin-rtp.xml
index b6d44d920c..bd6d7a9ba9 100644
--- a/docs/plugins/inspect/plugin-rtp.xml
+++ b/docs/plugins/inspect/plugin-rtp.xml
@@ -1124,13 +1124,13 @@
sink
sink
always
- 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
+ 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
src
source
always
- audio/x-alaw, channels=(int)1, rate=(int)8000
+ audio/x-alaw, channels=(int)1, rate=(int)[ 1, 2147483647 ]
@@ -1151,7 +1151,7 @@
src
source
always
- 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
+ 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
@@ -1166,13 +1166,13 @@
sink
sink
always
- 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
+ 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 ]
src
source
always
- audio/x-mulaw, channels=(int)1, rate=(int)8000
+ audio/x-mulaw, channels=(int)1, rate=(int)[ 1, 2147483647 ]
@@ -1193,7 +1193,7 @@
src
source
always
- 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
+ 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
@@ -1460,7 +1460,7 @@
sink
sink
always
- 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 ]
+ 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 ]
src
@@ -1471,4 +1471,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-rtsp.xml b/docs/plugins/inspect/plugin-rtsp.xml
index a63773598b..ebe286380f 100644
--- a/docs/plugins/inspect/plugin-rtsp.xml
+++ b/docs/plugins/inspect/plugin-rtsp.xml
@@ -58,4 +58,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-shapewipe.xml b/docs/plugins/inspect/plugin-shapewipe.xml
index 75141885cd..4631cbcdab 100644
--- a/docs/plugins/inspect/plugin-shapewipe.xml
+++ b/docs/plugins/inspect/plugin-shapewipe.xml
@@ -37,4 +37,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-shout2send.xml b/docs/plugins/inspect/plugin-shout2send.xml
index 731a54765d..2f9d8f1dc6 100644
--- a/docs/plugins/inspect/plugin-shout2send.xml
+++ b/docs/plugins/inspect/plugin-shout2send.xml
@@ -25,4 +25,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-smpte.xml b/docs/plugins/inspect/plugin-smpte.xml
index 41d5d5ba66..514147e611 100644
--- a/docs/plugins/inspect/plugin-smpte.xml
+++ b/docs/plugins/inspect/plugin-smpte.xml
@@ -58,4 +58,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-soup.xml b/docs/plugins/inspect/plugin-soup.xml
index 0851d07ee6..da3d787dc8 100644
--- a/docs/plugins/inspect/plugin-soup.xml
+++ b/docs/plugins/inspect/plugin-soup.xml
@@ -1,6 +1,6 @@
soup
- libsoup HTTP client src
+ libsoup HTTP client src/sink
../../ext/soup/.libs/libgstsouphttpsrc.so
libgstsouphttpsrc.so
0.10.30.1
@@ -9,6 +9,21 @@
GStreamer Good Plug-ins git
Unknown package origin
+
+ souphttpclientsink
+ HTTP client sink
+ Generic
+ Sends streams to HTTP server via PUT
+ David Schleef <ds@entropywave.com>
+
+
+ sink
+ sink
+ always
+ ANY
+
+
+
souphttpsrc
HTTP client source
@@ -25,4 +40,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-spectrum.xml b/docs/plugins/inspect/plugin-spectrum.xml
index fd1deea86f..5d98644b4f 100644
--- a/docs/plugins/inspect/plugin-spectrum.xml
+++ b/docs/plugins/inspect/plugin-spectrum.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-speex.xml b/docs/plugins/inspect/plugin-speex.xml
index 906f61a90e..aee0ba804c 100644
--- a/docs/plugins/inspect/plugin-speex.xml
+++ b/docs/plugins/inspect/plugin-speex.xml
@@ -52,4 +52,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-taglib.xml b/docs/plugins/inspect/plugin-taglib.xml
index 7b78f53850..f635b757da 100644
--- a/docs/plugins/inspect/plugin-taglib.xml
+++ b/docs/plugins/inspect/plugin-taglib.xml
@@ -52,4 +52,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-udp.xml b/docs/plugins/inspect/plugin-udp.xml
index be6799be6b..e58e3c5cad 100644
--- a/docs/plugins/inspect/plugin-udp.xml
+++ b/docs/plugins/inspect/plugin-udp.xml
@@ -70,4 +70,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-video4linux2.xml b/docs/plugins/inspect/plugin-video4linux2.xml
index 2555d49db4..004de03a17 100644
--- a/docs/plugins/inspect/plugin-video4linux2.xml
+++ b/docs/plugins/inspect/plugin-video4linux2.xml
@@ -34,4 +34,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-videobox.xml b/docs/plugins/inspect/plugin-videobox.xml
index f10df56367..3a932372ae 100644
--- a/docs/plugins/inspect/plugin-videobox.xml
+++ b/docs/plugins/inspect/plugin-videobox.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-videocrop.xml b/docs/plugins/inspect/plugin-videocrop.xml
index 039b97cd9a..dd71aa646d 100644
--- a/docs/plugins/inspect/plugin-videocrop.xml
+++ b/docs/plugins/inspect/plugin-videocrop.xml
@@ -52,4 +52,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-videofilter.xml b/docs/plugins/inspect/plugin-videofilter.xml
index 3a08eb3597..9ab132a71d 100644
--- a/docs/plugins/inspect/plugin-videofilter.xml
+++ b/docs/plugins/inspect/plugin-videofilter.xml
@@ -14,7 +14,7 @@
Video gamma correction
Filter/Effect/Video
Adjusts gamma on a video stream
- Arwed v. Merkatz <v.merkatz@gmx.net
+ Arwed v. Merkatz <v.merkatz@gmx.net>
sink
@@ -73,4 +73,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-videomixer.xml b/docs/plugins/inspect/plugin-videomixer.xml
index 6bb87daf9e..aab551138f 100644
--- a/docs/plugins/inspect/plugin-videomixer.xml
+++ b/docs/plugins/inspect/plugin-videomixer.xml
@@ -52,4 +52,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-wavenc.xml b/docs/plugins/inspect/plugin-wavenc.xml
index 549396a475..890bbe16aa 100644
--- a/docs/plugins/inspect/plugin-wavenc.xml
+++ b/docs/plugins/inspect/plugin-wavenc.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-wavpack.xml b/docs/plugins/inspect/plugin-wavpack.xml
index c14aa01e24..d5b7cbddb6 100644
--- a/docs/plugins/inspect/plugin-wavpack.xml
+++ b/docs/plugins/inspect/plugin-wavpack.xml
@@ -85,4 +85,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-wavparse.xml b/docs/plugins/inspect/plugin-wavparse.xml
index 1d7f80beed..90b4780ed0 100644
--- a/docs/plugins/inspect/plugin-wavparse.xml
+++ b/docs/plugins/inspect/plugin-wavparse.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-ximagesrc.xml b/docs/plugins/inspect/plugin-ximagesrc.xml
index cafcad8980..41747a25d6 100644
--- a/docs/plugins/inspect/plugin-ximagesrc.xml
+++ b/docs/plugins/inspect/plugin-ximagesrc.xml
@@ -25,4 +25,4 @@
-
+
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-y4menc.xml b/docs/plugins/inspect/plugin-y4menc.xml
index df65224402..5f04cd0547 100644
--- a/docs/plugins/inspect/plugin-y4menc.xml
+++ b/docs/plugins/inspect/plugin-y4menc.xml
@@ -31,4 +31,4 @@
-
+
\ No newline at end of file
diff --git a/gst/effectv/gstripple.c b/gst/effectv/gstripple.c
index 285b92ad63..170fd3a65b 100644
--- a/gst/effectv/gstripple.c
+++ b/gst/effectv/gstripple.c
@@ -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];
diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
index 414c02fec3..be9456807d 100644
--- a/gst/matroska/matroska-demux.c
+++ b/gst/matroska/matroska-demux.c
@@ -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;
diff --git a/gst/matroska/matroska-ids.h b/gst/matroska/matroska-ids.h
index ec56bb1032..df93d88856 100644
--- a/gst/matroska/matroska-ids.h
+++ b/gst/matroska/matroska-ids.h
@@ -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;
diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c
index bc87b80a12..55fd051aaa 100644
--- a/gst/matroska/matroska-mux.c
+++ b/gst/matroska/matroska-mux.c
@@ -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);
diff --git a/gst/multifile/Makefile.am b/gst/multifile/Makefile.am
index 52e33bc09a..3c9e31650e 100644
--- a/gst/multifile/Makefile.am
+++ b/gst/multifile/Makefile.am
@@ -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)
diff --git a/gst/multifile/gstmultifile.c b/gst/multifile/gstmultifile.c
index d2ba57b4e6..744110370b 100644
--- a/gst/multifile/gstmultifile.c
+++ b/gst/multifile/gstmultifile.c
@@ -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;
}
diff --git a/gst/multifile/gstmultifilesink.c b/gst/multifile/gstmultifilesink.c
index d2d5603816..1b6b7a06c7 100644
--- a/gst/multifile/gstmultifilesink.c
+++ b/gst/multifile/gstmultifilesink.c
@@ -3,6 +3,7 @@
* 2000 Wim Taymans
* 2006 Wim Taymans
* 2006 David A. Schleef
+ * 2011 Collabora Ltd.
*
* gstmultifilesink.c:
*
@@ -110,6 +111,7 @@
# include "config.h"
#endif
#include
+#include
#include
#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, ×tamp,
+ &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;
}
diff --git a/gst/multifile/gstmultifilesink.h b/gst/multifile/gstmultifilesink.h
index f2f005ff57..5dbd6cc714 100644
--- a/gst/multifile/gstmultifilesink.h
+++ b/gst/multifile/gstmultifilesink.h
@@ -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
diff --git a/gst/multifile/gstsplitfilesrc.c b/gst/multifile/gstsplitfilesrc.c
new file mode 100644
index 0000000000..b06a1155ed
--- /dev/null
+++ b/gst/multifile/gstsplitfilesrc.c
@@ -0,0 +1,603 @@
+/* GStreamer Split File Source
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * 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.
+ *
+ *
+ * Example launch line
+ * |[
+ * gst-launch splitfilesrc location="/path/to/part-*.mpg" ! decodebin ! ... \
+ * ]| Plays the different parts as if they were one single MPEG file.
+ *
+ *
+ * Since: 0.10.31
+ */
+
+/* TODO:
+ * - implement splitfile:// URI handler?
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "gstsplitfilesrc.h"
+#include "patternspec.h"
+
+#include
+
+#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 ");
+}
+
+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;
+ }
+}
diff --git a/gst/multifile/gstsplitfilesrc.h b/gst/multifile/gstsplitfilesrc.h
new file mode 100644
index 0000000000..f52b3bf2a8
--- /dev/null
+++ b/gst/multifile/gstsplitfilesrc.h
@@ -0,0 +1,74 @@
+/* GStreamer Split File Source
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * 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
+#include
+#include
+
+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__ */
diff --git a/gst/multifile/patternspec.c b/gst/multifile/patternspec.c
new file mode 100644
index 0000000000..59de8d1ffb
--- /dev/null
+++ b/gst/multifile/patternspec.c
@@ -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
+
+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);
+}
diff --git a/gst/multifile/patternspec.h b/gst/multifile/patternspec.h
new file mode 100644
index 0000000000..c3e9436384
--- /dev/null
+++ b/gst/multifile/patternspec.h
@@ -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
+
+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__ */
diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am
index 059d3326fc..f438c5e40f 100644
--- a/tests/check/Makefile.am
+++ b/tests/check/Makefile.am
@@ -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)
diff --git a/tests/check/elements/multifile.c b/tests/check/elements/multifile.c
index 52ce2ceb87..0a4849a3be 100644
--- a/tests/check/elements/multifile.c
+++ b/tests/check/elements/multifile.c
@@ -26,6 +26,7 @@
#include
#include
+#include
#include
#include
@@ -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;