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 gst-plugins-good - 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;