Merge tag 'upstream/1.7.1' into debian-experimental

Upstream version 1.7.1
diff --git a/ChangeLog b/ChangeLog
index ed5ebed..132f689 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,159 +1,150 @@
-=== release 1.6.2 ===
+=== release 1.7.1 ===
 
-2015-12-14  Sebastian Dröge <slomo@coaxion.net>
+2015-12-24  Sebastian Dröge <slomo@coaxion.net>
 
 	* configure.ac:
-	  releasing 1.6.2
+	  releasing 1.7.1
 
-2015-12-14 19:12:53 +0100  Sebastian Dröge <sebastian@centricular.com>
+2015-12-24 12:22:32 +0100  Sebastian Dröge <sebastian@centricular.com>
 
+	* po/cs.po:
+	* po/de.po:
 	* po/el.po:
 	* po/hu.po:
+	* po/nb.po:
+	* po/nl.po:
+	* po/pl.po:
+	* po/ru.po:
+	* po/sr.po:
 	* po/sv.po:
 	* po/uk.po:
+	* po/vi.po:
+	* po/zh_CN.po:
 	  po: Update translations
 
-2015-12-14 14:15:00 +0100  Thomas Roos <thomas.roos@industronic.de>
-
-	* sys/directsound/gstdirectsoundsink.c:
-	  directsoundsink: Fix handling of the mute property
-	  - set mute value at startup
-	  - correct set and get mute functions
-	  https://bugzilla.gnome.org/show_bug.cgi?id=755106
-
-2015-12-01 18:20:23 +0100  Wim Taymans <wtaymans@redhat.com>
-
-	* sys/v4l2/gstv4l2bufferpool.c:
-	  v4l2bufferpool: don't block when resurecting a buffer
-	  When we are resurecting a buffer, don't block. instead let us copy a
-	  buffer.
-
-2015-12-11 11:23:13 +0100  Thomas Roos <thomas.roos@industronic.de>
-
-	* sys/directsound/gstdirectsoundsink.c:
-	  directsoundsink: Check the return value of GetStatus() too to decide if there was an error
-	  If GetStatus() fails, the status itself won't be very meaningful but we also
-	  have to look at its return value. This fixes blocking pipelines when removing
-	  sound devices or during other errors, where we wouldn't notice the error and
-	  then wait forever.
-	  https://bugzilla.gnome.org/show_bug.cgi?id=734098
-
-2015-11-15 17:16:29 -0800  Josep Torra <n770galaxy@gmail.com>
-
-	* gst/rtp/gstrtpgstdepay.c:
-	  rtpgstdepay: Properly handle backward compat for event deserialization
-	  Actual code is checking for a NULL terminator and a ';' terminator,
-	  for backward compat, in a chained way that cause all events being rejected.
-	  The proper condition is to reject the events when terminator isn't
-	  in ['\0', ';'] set.
-	  https://bugzilla.gnome.org/show_bug.cgi?id=758151
-
-2015-11-15 17:11:02 -0800  Josep Torra <n770galaxy@gmail.com>
-
-	* tests/check/elements/rtp-payloading.c:
-	  tests: rtp-payloading: Test for handling of custom events in rtpgst
-	  Add a simple test that checks proper serialization/deserialization
-	  of custom events with rtpgstpay and rtpgstdepay.
-
-2015-12-09 12:24:09 +0200  Sebastian Dröge <sebastian@centricular.com>
-
-	* gst/rtpmanager/gstrtpjitterbuffer.c:
-	  rtpjitterbuffer: Fix packet dropping after a big discont
-	  We would queue 5 consective packets before considering a reset and a proper
-	  discont here. Instead of expecting the next output packet to have the current
-	  seqnum (i.e. the fifth), expect it to have the first seqnum. Otherwise we're
-	  going to drop all queued up packets.
-
-2015-11-18 16:10:11 +0100  Michael Olbrich <m.olbrich@pengutronix.de>
-
-	* gst/avi/gstavimux.c:
-	  avimux: don't crash if we never got audio caps before stopping
-	  auds.blockalign is set once the first caps arrive. If
-	  gst_avi_mux_stop_file() is called before this happens then auds.blockalign
-	  is zero and gst_avi_mux_audsink_set_fields() cause a crash:
-	  [...]
-	  avipad->parent.hdr.rate = avipad->auds.av_bps / avipad->auds.blockalign;
-	  [...]
-	  https://bugzilla.gnome.org/show_bug.cgi?id=758912
-
-2015-12-01 00:03:21 -0300  Thiago Santos <thiagoss@osg.samsung.com>
-
-	* gst/wavparse/gstwavparse.c:
-	  wavparse: flush upstream when seeking in pull mode
-	  Makes sure upstream will unblock and return the thread so that
-	  seeking can continue
-	  https://bugzilla.gnome.org/show_bug.cgi?id=758861
-
-2015-11-18 19:07:53 +0200  Sebastian Dröge <sebastian@centricular.com>
-
-	* gst/isomp4/qtdemux.c:
-	  qtdemux: Cast to signed integers to prevent unsigned compare between negative and positive numbers
-	  This fixes seeking if the first entries in the samples table are negative. The
-	  binary search would always fail on this as the array would not be sorted if
-	  interpreting the negative numbers as huge positive numbers. This caused us to
-	  always output buffers from the beginning after a seek instead of close to the
-	  seek position.
-	  Also add a case to the comparison function for equality.
-
-2015-11-11 14:10:53 +0900  Vineeth TM <vineeth.tm@samsung.com>
-
-	* gst/multifile/gstsplitmuxpartreader.c:
-	  splitmuxpartreader: Fix GCond leak
-	  inactive_cond is not being cleared resulting in memory leak.
-	  https://bugzilla.gnome.org/show_bug.cgi?id=757924
-
-2015-11-05 18:39:33 +0530  Nirbheek Chauhan <nirbheek@centricular.com>
-
-	* ext/pulse/pulsedeviceprovider.c:
-	  pulse: Don't leak caps and structures in the device provider
-
-2015-08-12 13:35:40 +0200  Philippe Normand <philn@igalia.com>
+2015-12-21 09:57:33 -0300  Thiago Santos <thiagoss@osg.samsung.com>
 
 	* gst/isomp4/qtdemux.c:
 	* gst/isomp4/qtdemux.h:
-	  qtdemux: support for cenc auxiliary info parsing outside of moof box
-	  When the cenc aux info index is out of moof boundaries, keep track of
-	  it and parse the beginning of the mdat box, before the first sample.
-	  https://bugzilla.gnome.org/show_bug.cgi?id=755614
+	  qtdemux: drop flushes from our own offset seek
+	  Prevents downstream from receiving flushes for a seek only in
+	  upstream. Those seeks are only to start reading from the right
+	  offset when skipping or returning to qt atoms.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=758928
 
-2015-11-03 22:01:07 +0530  Arun Raghavan <git@arunraghavan.net>
+2015-11-11 16:53:19 +0100  Thibault Saunier <tsaunier@gnome.org>
 
-	* sys/v4l2/gstv4l2.c:
-	  v4l2: Set O_CLOEXEC on the device fd
-	  This is needed to make sure that child processes don't inherit the video
-	  device fd which can cause problems with some drivers.
+	* gst/matroska/matroska-demux.c:
+	  matroskademux: Always set the channel mask for PCM streams
+	  Just use the gst_audio_channel_get_fallback_mask function for now as
+	  the specification is too complicated and nobody implements it.
 
-2015-10-21 11:16:01 +0100  Tim-Philipp Müller <tim@centricular.com>
+2015-12-21 11:37:26 +0100  Thomas Roos <thomas.roos@industronic.de>
 
-	* gst/flv/gstflvmux.c:
-	  flvmux: fix writing of creation time
-	  Don't write time as e.g. 11:9:42
+	* sys/directsound/gstdirectsoundsink.c:
+	  directsoundsink: Fix sleep for buffer-time lower than 200000
+	  https://bugzilla.gnome.org/show_bug.cgi?id=748680
 
-2015-09-22 22:59:16 +0200  Havard Graff <havard.graff@gmail.com>
+2015-12-21 12:31:19 +0100  Sebastian Dröge <sebastian@centricular.com>
 
-	* gst/flv/gstflvmux.c:
-	* tests/check/elements/flvmux.c:
-	  flvmux: GST_BUFFER_OFFSETs should be GST_BUFFER_OFFSET_NONE
-	  Or else flvdemux don't understand it
-	  https://bugzilla.gnome.org/show_bug.cgi?id=754435
-
-2015-09-02 10:44:59 +0200  Havard Graff <havard.graff@gmail.com>
-
-	* gst/flv/gstflvmux.c:
-	* tests/check/elements/flvmux.c:
-	  flvmux: use time segment and copy timestamps when streamable
-	  Add a basic test using speex data to verify timestamping.
-	  https://bugzilla.gnome.org/show_bug.cgi?id=754435
-
-=== release 1.6.1 ===
-
-2015-10-30 16:40:55 +0200  Sebastian Dröge <sebastian@centricular.com>
-
-	* ChangeLog:
-	* NEWS:
-	* RELEASE:
 	* configure.ac:
+	  configure: Use -Bsymbolic-functions if available
+	  While this is more useful for libraries, some of our plugins with multiple
+	  files and some internal API can also benefit from this.
+
+2015-12-18 15:34:52 +0000  William Manley <will@williammanley.net>
+
+	* gst/debugutils/progressreport.c:
+	* gst/debugutils/progressreport.h:
+	  progressreport: add support for using format=buffers with do-query=false
+	  This is useful for investigating and debugging pipelines which are
+	  producing buffers at a slower/faster rate than you would expect.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=759635
+
+2015-12-18 15:49:43 -0500  Nicolas Dufresne <nicolas.dufresne@collabora.com>
+
+	* sys/v4l2/gstv4l2object.c:
+	  v4l2object: Update formats table
+	  This change add all the new RGB based format. Those format removes the
+	  ambiguity with the ALPHA channel. Some other missing multiplanar format
+	  has been added with some additional cleanup.
+
+2015-12-18 05:17:15 +1100  Jan Schmidt <jan@centricular.com>
+
+	* gst/isomp4/gstqtmux.c:
+	  qtmux: Don't write invalid edit list start time.
+	  Avoid writing a negative number as a large positive
+	  integer in an edit list when the first_ts is smaller
+	  than the first_dts - which can happen when the first
+	  packet received has a PTS but no DTS.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=759615
+
+2015-12-04 23:16:45 +1100  Jan Schmidt <jan@centricular.com>
+
+	* gst/multifile/gstsplitmuxsink.c:
+	  splitmuxsink: Only update running time when it increases.
+	  Don't increment running time from every buffer. The correct
+	  logic to only increment when running time advances is a
+	  little further down, so delete this left-over line.
+
+2015-11-18 11:01:20 +0100  Thibault Saunier <tsaunier@gnome.org>
+
+	* gst/matroska/matroska-mux.c:
+	  matroska-mux: Implement prores support
+	  https://bugzilla.gnome.org/show_bug.cgi?id=758258
+
+2015-11-18 16:20:38 +1100  Jan Schmidt <jan@centricular.com>
+
+	* gst/matroska/matroska-demux.c:
+	* gst/matroska/matroska-ids.h:
+	  matroska-demux: Play ProRes video streams
+	  Generate video/x-prores caps for ProRes video streams.
+	  Every frame needs an 8 byte header prepended, as described in
+	  http://wiki.multimedia.cx/index.php?title=Apple_ProRes#Frame_layout
+	  so do that in a post-processing callback.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=758258
+
+2015-12-18 10:18:09 +0530  Ravi Kiran K N <ravi.kiran@samsung.com>
+
+	* ext/dv/gstdvdec.h:
+	  dvdec: Remove unused fields
+	  Remove unused fields frame_len and space
+	  https://bugzilla.gnome.org/show_bug.cgi?id=759614
+
+2015-12-17 16:03:04 +0100  Vincent Dehors <vincent.dehors@openwide.fr>
+
+	* gst/rtp/gstrtpj2kdepay.c:
+	  rtpj2kdepay: Push one JPEG2000 frame per buffer, not a buffer list with multiple buffers
+	  https://bugzilla.gnome.org/show_bug.cgi?id=758943
+
+2015-12-16 11:43:58 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* ext/raw1394/gstdv1394src.c:
+	* ext/raw1394/gsthdv1394src.c:
+	  dv1394: log error if failed to set socket status flag
+	  Log an error message if failed to set write or read socket as
+	  non-blocking.
+	  CID 1139608
+	  CID 1139609
+
+2015-12-15 17:10:00 +0000  Dave Craig <davecraig@unbalancedaudio.com>
+
+	* gst/audioparsers/gstaacparse.c:
+	* gst/audioparsers/gstac3parse.c:
+	* gst/audioparsers/gstamrparse.c:
+	* gst/audioparsers/gstdcaparse.c:
+	* gst/audioparsers/gstflacparse.c:
+	* gst/audioparsers/gstmpegaudioparse.c:
+	* gst/audioparsers/gstsbcparse.c:
+	* gst/audioparsers/gstwavpackparse.c:
+	  audioparsers: Check for NULL return value of gst_pad_get_current_caps()
+	  https://bugzilla.gnome.org/show_bug.cgi?id=759503
+
+2015-12-16 09:35:53 +0100  Sebastian Dröge <sebastian@centricular.com>
+
 	* docs/plugins/gst-plugins-good-plugins.args:
+	* docs/plugins/gst-plugins-good-plugins.hierarchy:
+	* docs/plugins/gst-plugins-good-plugins.interfaces:
 	* docs/plugins/inspect/plugin-1394.xml:
 	* docs/plugins/inspect/plugin-aasink.xml:
 	* docs/plugins/inspect/plugin-alaw.xml:
@@ -220,58 +211,768 @@
 	* docs/plugins/inspect/plugin-wavparse.xml:
 	* docs/plugins/inspect/plugin-ximagesrc.xml:
 	* docs/plugins/inspect/plugin-y4menc.xml:
-	* gst-plugins-good.doap:
-	* win32/common/config.h:
-	  Release 1.6.1
+	  docs: update to git
 
-2015-10-30 16:27:32 +0200  Sebastian Dröge <sebastian@centricular.com>
+2015-12-15 14:27:22 -0500  Nicolas Dufresne <nicolas.dufresne@collabora.com>
 
-	* po/af.po:
-	* po/az.po:
-	* po/bg.po:
-	* po/ca.po:
-	* po/da.po:
-	* po/el.po:
-	* po/en_GB.po:
-	* po/eo.po:
-	* po/es.po:
-	* po/eu.po:
-	* po/fi.po:
-	* po/fr.po:
-	* po/gl.po:
-	* po/hr.po:
-	* po/hu.po:
-	* po/id.po:
-	* po/it.po:
-	* po/ja.po:
-	* po/lt.po:
-	* po/lv.po:
-	* po/mt.po:
-	* po/nb.po:
-	* po/or.po:
-	* po/pt_BR.po:
-	* po/ro.po:
-	* po/sk.po:
-	* po/sl.po:
-	* po/sq.po:
-	* po/sr.po:
-	* po/sv.po:
-	* po/tr.po:
-	* po/uk.po:
-	* po/zh_HK.po:
-	* po/zh_TW.po:
-	  Update .po files
+	* ext/vpx/Makefile.am:
+	  vpx: Add missing headers in Makefile.am
+	  This fixes distcheck.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=755510
 
-2015-10-30 14:28:04 +0200  Sebastian Dröge <sebastian@centricular.com>
+2015-09-24 12:57:00 +0530  Prashant Gotarne <ps.gotarne@samsung.com>
 
-	* po/cs.po:
-	* po/de.po:
-	* po/nl.po:
-	* po/pl.po:
-	* po/ru.po:
-	* po/vi.po:
-	* po/zh_CN.po:
-	  po: Update translations
+	* ext/vpx/Makefile.am:
+	* ext/vpx/gstvp8enc.c:
+	* ext/vpx/gstvp8enc.h:
+	* ext/vpx/gstvp9enc.c:
+	* ext/vpx/gstvp9enc.h:
+	* ext/vpx/gstvpxenc.c:
+	* ext/vpx/gstvpxenc.h:
+	  vpx: created common baseclass GstVPXEnc
+	  GstVP8Enc and GstVP9Enc has almost 80% code in common.
+	  created common baseclass GstVPXEnc for GstVP8Enc and GstVP9Enc
+	  https://bugzilla.gnome.org/show_bug.cgi?id=755510
+
+2015-12-15 12:57:53 -0500  Nicolas Dufresne <nicolas.dufresne@collabora.com>
+
+	* ext/vpx/gstvp9dec.c:
+	* ext/vpx/gstvpxdec.c:
+	* ext/vpx/gstvpxdec.h:
+	  vpxdec: Remove unneeded add video_meta
+	  This also remove copies for VP8, which was not correctly in place
+	  in previous related patch.
+
+2015-12-15 09:49:24 +0530  Prashant Gotarne <ps.gotarne@samsung.com>
+
+	* ext/vpx/Makefile.am:
+	* ext/vpx/gstvp8dec.c:
+	* ext/vpx/gstvp8dec.h:
+	* ext/vpx/gstvp9dec.c:
+	* ext/vpx/gstvp9dec.h:
+	* ext/vpx/gstvpxdec.c:
+	* ext/vpx/gstvpxdec.h:
+	  vpx: created common base class GstVPXdec for vpx decoders
+	  Base class for the vp8dec and vp9dec.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=755510
+
+2015-06-10 09:17:08 -0400  Xavier Claessens <xavier.claessens@collabora.com>
+
+	* configure.ac:
+	* ext/soup/gstsouphttpsrc.c:
+	* ext/soup/gstsouphttpsrc.h:
+	  souphttpsrc: Add GTlsInteraction property
+	  https://bugzilla.gnome.org/show_bug.cgi?id=750709
+
+2015-12-14 09:05:06 -0500  Evan Callaway <evan.callaway@ipconfigure.com>
+
+	* gst/rtsp/gstrtspsrc.c:
+	  rtspsrc: Retry connection if tunneling needs authentication
+	  Leverage response from gst_rtsp_connection_connect_with_response to
+	  determine if the connection should be retried using authentication.  If
+	  so, add the appropriate authentication headers based upon the response
+	  and retry the connection.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=749596
+
+2015-12-14 14:19:05 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/rtsp/gstrtspsrc.c:
+	  rtspsrc: check port-range format
+	  The string could exist but with a wrong format, in that case we still want
+	  to reset the values of client_port_range.min and max like we do if there is
+	  no string.
+	  CID 1139593
+
+2015-12-14 14:55:12 +0100  Thomas Roos <thomas.roos@industronic.de>
+
+	* sys/directsound/gstdirectsoundsink.c:
+	  directsoundsink: Check device property and fail if device can't be found
+	  Don't use default if a specific device is set but it can't be found.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=759452
+
+2015-12-14 14:15:00 +0100  Thomas Roos <thomas.roos@industronic.de>
+
+	* sys/directsound/gstdirectsoundsink.c:
+	  directsoundsink: Fix handling of the mute property
+	  - set mute value at startup
+	  - correct set and get mute functions
+	  https://bugzilla.gnome.org/show_bug.cgi?id=755106
+
+2015-12-11 11:23:13 +0100  Thomas Roos <thomas.roos@industronic.de>
+
+	* sys/directsound/gstdirectsoundsink.c:
+	  directsoundsink: Check the return value of GetStatus() too to decide if there was an error
+	  If GetStatus() fails, the status itself won't be very meaningful but we also
+	  have to look at its return value. This fixes blocking pipelines when removing
+	  sound devices or during other errors, where we wouldn't notice the error and
+	  then wait forever.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=734098
+
+2015-12-10 17:41:46 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/isomp4/atoms.c:
+	* gst/isomp4/atoms.h:
+	* gst/isomp4/gstqtmux.c:
+	  isomp4: remove unused parameters in build_*_extension
+	  AtomTRAK parameter is not used by build_mov_alac_extension(),
+	  build_jp2h_extension(), or build_mov_alac_extension()  and can be
+	  removed.
+
+2015-12-10 15:11:07 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/isomp4/gstqtmux.c:
+	  isomp4: replace variable only used once
+	  Replace has_shift variable with value since it is only use once.
+
+2015-12-09 12:24:09 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/rtpmanager/gstrtpjitterbuffer.c:
+	  rtpjitterbuffer: Fix packet dropping after a big discont
+	  We would queue 5 consective packets before considering a reset and a proper
+	  discont here. Instead of expecting the next output packet to have the current
+	  seqnum (i.e. the fifth), expect it to have the first seqnum. Otherwise we're
+	  going to drop all queued up packets.
+
+2015-12-09 11:49:02 +0530  Ravi Kiran K N <ravi.kiran@samsung.com>
+
+	* gst/interleave/interleave.h:
+	  interleave: Remove unsed field
+	  Remove unused field collect_event in interleave.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=759226
+
+2015-12-07 16:33:14 +0100  Edward Hervey <edward@centricular.com>
+
+	* gst/isomp4/qtdemux.c:
+	  qtdemux: Stop pushing data as soon as possible in push-mode
+	  When working in push-mode, we attempt to push out everything currently
+	  buffered in the adapter.
+	  This has two pitfalls:
+	  * We could stop earlier (the moment we get a non-ok or non-not-linked)
+	  * We return the last combined flow return, which might be completely
+	  different from the previous combined flow return
+
+2015-12-07 09:08:09 -0500  Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
+
+	* autogen.sh:
+	* common:
+	  Automatic update of common submodule
+	  From b319909 to 86e4663
+
+2015-12-07 14:41:51 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/rtpmanager/rtpsession.c:
+	  rtpsession: Add a warning if an empty RTCP packet is tried to be sent
+	  https://bugzilla.gnome.org/show_bug.cgi?id=759119
+
+2015-11-30 19:20:13 -0500  Nicolas Dufresne <nicolas.dufresne@collabora.com>
+
+	* configure.ac:
+	* ext/vpx/gstvp8dec.c:
+	* ext/vpx/gstvp8dec.h:
+	* ext/vpx/gstvp9dec.c:
+	* ext/vpx/gstvp9dec.h:
+	  vpxdec: Use GstMemory to avoid copies
+	  With the VPX decoders it's not simple to use downstream buffer pool,
+	  because we don't know the image size and alignment when buffers get
+	  allocated. We can though use GstAllocator (for downstream, or the system
+	  allocator) to avoid a copy before pushing if downstream supports
+	  GstVideoMeta. This would still cause a copy for sink that requires
+	  specialized memory and does not have a GstAllocator for that, though
+	  it will greatly improve performance for sink like glimagesink and
+	  cluttersink. To avoid allocating for every buffer, we also use a
+	  internal buffer pool.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=745372
+
+2015-11-30 08:42:35 +0100  Edward Hervey <edward@centricular.com>
+
+	* gst/audioparsers/gstaacparse.c:
+	  aacparse: Avoid over-skipping when checking LOAS config
+	  There might be multiple LOAS config in a row in a full frame. The first
+	  one might be a multi-layer config (which we can't properly parse yet)...
+	  but then followed by a valid (single-layer) one.
+	  The code was previously skipping whole frames (instead of just the LOAS
+	  config we failed to read) resulting in multiple frames (seen up to 6s in
+	  some situation) being dropped before finally getting the configuration.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=758826
+
+2015-11-25 17:08:56 +0100  Edward Hervey <edward@centricular.com>
+
+	* gst/avi/gstavidemux.c:
+	  avidemux: Properly set SPARSE stream flags for subpicture/subtitle
+	  And while we're at it, also detect 'DXSA' as being a variant fourcc
+	  of 'DXSB' for XSUB
+
+2015-11-30 21:23:52 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* tests/check/elements/souphttpsrc.c:
+	  tests: souphttpsrc: grammar fix
+
+2015-11-30 21:01:17 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* tests/check/elements/souphttpsrc.c:
+	  tests: souphttpsrc: switch shoutcast stream provider
+	  Fixes failing ICY test. Previous provider has
+	  streaming disabled outside UK.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=758114
+
+2015-11-18 16:10:11 +0100  Michael Olbrich <m.olbrich@pengutronix.de>
+
+	* gst/avi/gstavimux.c:
+	  avimux: don't crash if we never got audio caps before stopping
+	  auds.blockalign is set once the first caps arrive. If
+	  gst_avi_mux_stop_file() is called before this happens then auds.blockalign
+	  is zero and gst_avi_mux_audsink_set_fields() cause a crash:
+	  [...]
+	  avipad->parent.hdr.rate = avipad->auds.av_bps / avipad->auds.blockalign;
+	  [...]
+	  https://bugzilla.gnome.org/show_bug.cgi?id=758912
+
+2015-12-01 18:20:23 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* sys/v4l2/gstv4l2bufferpool.c:
+	  v4l2bufferpool: don't block when resurecting a buffer
+	  When we are resurecting a buffer, don't block. instead let us copy a
+	  buffer.
+
+2015-12-01 00:30:08 -0300  Thiago Santos <thiagoss@osg.samsung.com>
+
+	* gst/wavparse/gstwavparse.c:
+	  wavparse: remove extra variable to improve readability
+	  Makes it easier to see that the event is being replaced/unrefed
+
+2015-12-01 00:22:36 -0300  Thiago Santos <thiagoss@osg.samsung.com>
+
+	* gst/wavparse/gstwavparse.c:
+	  wavparse: respect seqnum in seek events
+	  Propagate the original seek seqnum to events originated from
+	  seeking to make sure they have the same value
+
+2015-12-01 00:03:21 -0300  Thiago Santos <thiagoss@osg.samsung.com>
+
+	* gst/wavparse/gstwavparse.c:
+	  wavparse: flush upstream when seeking in pull mode
+	  Makes sure upstream will unblock and return the thread so that
+	  seeking can continue
+	  https://bugzilla.gnome.org/show_bug.cgi?id=758861
+
+2015-11-27 09:27:29 +0100  Anton Bondarenko <antonbo@axis.com>
+
+	* gst/rtp/gstrtph264pay.c:
+	  rtph264pay: add "send SPS/PPS with every key frame" mode
+	  It's not enough to have timeout or event based SPS/PPS information sent
+	  in RTP packets. There are some scenarios when key frames may appear
+	  more frequently than once a second, in which case the minimum timeout
+	  for "config-interval" of 1 second for sending SPS/PPS is not sufficient.
+	  It might also be desirable in general to make sure the SPS/PPS is
+	  available with every keyframe (packet loss aside), so receivers can
+	  actually pick up decoding immediately from the first keyframe if
+	  SPS/PPS is not signaled out of band.
+	  This patch adds the possibility to send SPS/PPS with every key frame. This
+	  mode can be enabled by setting "config-interval" property to -1. In this
+	  case the payloader will add SPS and PPS before every key (IDR) frame.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=757892
+
+2015-11-27 09:03:51 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst/rtp/gstrtph264pay.c:
+	* gst/rtp/gstrtph264pay.h:
+	* tests/check/elements/rtp-payloading.c:
+	  rtph264pay: change config-interval property type from uint to int
+	  This way we can use -1 as special value, which is nicer than MAXUINT.
+	  This is backwards compatible even with the GValue API, as shown by
+	  a unit test.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=757892
+
+2015-11-26 21:46:11 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/isomp4/qtdemux.c:
+	  qtdemux: add support for Opus
+	  Add support for demuxing Opus encapsulated in MP4 files, based on the
+	  following spec: https://www.opus-codec.org/docs/opus_in_isobmff.html
+	  https://bugzilla.gnome.org/show_bug.cgi?id=742643
+
+2015-11-25 22:48:32 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/isomp4/qtdemux.c:
+	  qtdemux: use macro for codec_name
+	  Use _codec() macro instead of duplicating code.
+
+2015-03-25 16:32:55 +0100  Philipp Zabel <p.zabel@pengutronix.de>
+
+	* sys/v4l2/gstv4l2videodec.c:
+	  v4l2: videodec: choose format from caps
+	  https://bugzilla.gnome.org/show_bug.cgi?id=733827
+
+2015-03-27 15:02:33 +0100  Philipp Zabel <p.zabel@pengutronix.de>
+
+	* sys/v4l2/gstv4l2object.c:
+	* sys/v4l2/gstv4l2object.h:
+	  v4l2: add gst_v4l2_object_probe_caps
+	  Add a variant of gst_v4l2_object_get_caps that bypasses the probed_caps cache.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=733827
+
+2015-11-19 17:20:55 -0500  Nicolas Dufresne <nicolas.dufresne@collabora.com>
+
+	* sys/v4l2/gstv4l2.c:
+	  v4l2-probe: Skip devices without supported formats
+
+2015-11-13 12:35:59 -0500  Nicolas Dufresne <nicolas.dufresne@collabora.com>
+
+	* configure.ac:
+	* sys/v4l2/gstv4l2.c:
+	  v4l2: Track /dev/video* to triggered required probe
+	  If something in /dev/video* get added, removed or replaced, we need to
+	  probe the devices again in order to ensure the dynamic devices are up to
+	  date.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=758085
+
+2015-11-25 14:51:40 +1100  Alessandro Decina <alessandro.d@gmail.com>
+
+	* gst/rtpmanager/rtpsession.c:
+	  rtpmanager: rtpsession: don't send empty RTCP packets
+	  generate_rtcp can produce empty packets when reduced size RTCP is turned on.
+	  Skip them since it doesn't make sense to push them and they cause errors with
+	  elements that expect RTCP packets to contain data (like srtpenc).
+
+2015-11-24 10:57:28 -0300  Thiago Santos <thiagoss@osg.samsung.com>
+
+	* gst/isomp4/qtdemux.c:
+	  qtdemux: restore the segment on case of soft reset
+	  When seeking back to restore the mdat position a flush is pushed
+	  through and it resets downstream segment information. Make sure
+	  that after the flush (that does a soft reset) a segment will
+	  be pushed again
+	  Fixes regressions spotted at
+	  https://ci.gstreamer.net/job/GStreamer-master-validate/2100/
+
+2015-11-20 12:44:22 +0000  Graham Leggett <minfrin@sharp.fm>
+
+	* gst/multifile/gstmultifilesink.c:
+	  multifilesink: fix spelling of variable
+	  https://bugzilla.gnome.org/show_bug.cgi?id=758390
+
+2015-11-20 11:05:51 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/isomp4/fourcc.h:
+	* gst/isomp4/qtdemux.c:
+	  qtdemux: unite duplicate FourCC
+	  Unite in fourcc.h the FourCCs that are used twice or more in qtdemux
+
+2015-11-19 15:33:45 -0500  Nicolas Dufresne <nicolas.dufresne@collabora.com>
+
+	* sys/v4l2/gstv4l2transform.c:
+	* sys/v4l2/gstv4l2videodec.c:
+	  v4l2: Fix capture/output-io-mode properties
+	  There was some miss-match in the implementation. This makes it
+	  concistent, though functionally it worked, except the video decoder
+	  output-io-mode getter.
+
+2015-11-19 19:48:06 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/isomp4/atoms.c:
+	  atoms: remove unused argument of build_mov_wave_extension()
+	  AtomTrak * trak argument of build_move_wave_extension() isn't used.
+	  Removing it.
+
+2015-11-19 19:28:20 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/isomp4/fourcc.h:
+	* gst/isomp4/qtdemux.c:
+	  qtdemux: remove duplicate FourCC
+	  Use the available FourCCs in fourcc.h instead of duplicating them.
+
+2015-11-19 18:36:39 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/isomp4/atoms.c:
+	* gst/isomp4/fourcc.h:
+	* gst/isomp4/gstqtmux.c:
+	  isomp4: centralize all FourCC
+	  10 FourCCs generated with GST_MAKE_FOURCC() in gstqtmux.c and atoms.c
+	  already exist in fourcc.h. Don't duplicate these and use them directly.
+	  Plus moving 6 to fourcc.h, to centralize them all.
+
+2015-11-19 17:32:12 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/matroska/webm-mux.c:
+	  matroska/webmmux: fix outdated example launch lines
+	  Update gst-launch-0.10 lines to gst-launch-1.0
+
+2015-11-16 13:26:50 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/isomp4/atoms.c:
+	* gst/isomp4/atoms.h:
+	* gst/isomp4/fourcc.h:
+	* gst/isomp4/gstqtmux.c:
+	* gst/isomp4/gstqtmuxmap.c:
+	  isomp4: add support for Opus in mp4mpux
+	  Add support for muxing MP4 files containing Opus. Based on the spec
+	  detailed here:
+	  https://www.opus-codec.org/docs/opus_in_isobmff.html
+	  https://bugzilla.gnome.org/show_bug.cgi?id=742643
+
+2015-11-18 19:10:56 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/isomp4/qtdemux.c:
+	  qtdemux: Replace tabs with spaces
+
+2015-11-18 19:07:53 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/isomp4/qtdemux.c:
+	  qtdemux: Cast to signed integers to prevent unsigned compare between negative and positive numbers
+	  This fixes seeking if the first entries in the samples table are negative. The
+	  binary search would always fail on this as the array would not be sorted if
+	  interpreting the negative numbers as huge positive numbers. This caused us to
+	  always output buffers from the beginning after a seek instead of close to the
+	  seek position.
+	  Also add a case to the comparison function for equality.
+
+2015-11-18 16:01:48 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/matroska/matroska-mux.c:
+	  matroskamux: remove duplicate check
+	  We want 1 or 2 streamheaders, the check  if (bufarr->len != 1 &&
+	  bufarr->len != 2) is enough. Not need to check if bufarr->len is <= 0 or
+	  > 255.
+
+2015-11-18 14:48:36 +0900  Vineeth TM <vineeth.tm@samsung.com>
+
+	* ext/soup/gstsouphttpclientsink.c:
+	  souphttpclientsink: Fix error leak and handle error
+	  g_thread_try_new allows for possiblity of failures. In case it fails,
+	  error is not handled and leaked.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=758260
+
+2015-11-15 17:16:29 -0800  Josep Torra <n770galaxy@gmail.com>
+
+	* gst/rtp/gstrtpgstdepay.c:
+	  rtpgstdepay: Properly handle backward compat for event deserialization
+	  Actual code is checking for a NULL terminator and a ';' terminator,
+	  for backward compat, in a chained way that cause all events being rejected.
+	  The proper condition is to reject the events when terminator isn't
+	  in ['\0', ';'] set.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=758151
+
+2015-11-15 17:11:02 -0800  Josep Torra <n770galaxy@gmail.com>
+
+	* tests/check/elements/rtp-payloading.c:
+	  tests: rtp-payloading: Test for handling of custom events in rtpgst
+	  Add a simple test that checks proper serialization/deserialization
+	  of custom events with rtpgstpay and rtpgstdepay.
+
+2015-11-16 16:23:43 -0500  Nicolas Dufresne <nicolas.dufresne@collabora.com>
+
+	* ext/vpx/gstvp8dec.c:
+	* ext/vpx/gstvp9dec.c:
+	  vpxdec: Use threads on multi-core systems
+	  This adds an automatic mode to the threads property of vpxdec in order to
+	  use as many threads as there is CPU on the platform. This brings back
+	  GStreamer VPX decoding performance closer to what is achieved by other
+	  players, including Chromium.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=758195
+
+2015-11-16 10:58:32 -0300  Thiago Santos <thiagoss@osg.samsung.com>
+
+	* gst/isomp4/qtdemux.c:
+	  qtdemux: only send initial gaps for non-fragmented streams
+	  It would be unusual to have the header segment with an 'edts' atom
+	  indicating gaps at the beginning when handling fragmented streams.
+	  The header usually doesn't contain any timestamping information, this
+	  should come from the playlist/manifest and the segments with media
+	  in those scenarios.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=758171
+
+2015-11-17 09:41:34 -0300  Thiago Santos <thiagoss@osg.samsung.com>
+
+	* gst/isomp4/qtdemux.c:
+	  Revert "Revert "qtdemux: respect qt segments in push-mode for empty starts""
+	  This reverts commit d842ff288a9d01214a046becbfd9cbff3a4acea0.
+	  This was reverted by accident
+
+2015-11-17 12:39:05 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/udp/gstudpsrc.c:
+	* gst/udp/gstudpsrc.h:
+	  udpsrc: Add "loop" property for enabling/disabling multicast loopback
+	  On POSIX, IP_MULTICAST_LOOP is a setting for the sender socket. On Windows it
+	  is a setting for the receiver socket. As such we will need it on udpsrc too to
+	  allow filtering out our own multicast packets.
+
+2015-11-16 13:52:05 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/isomp4/qtdemux.c:
+	  Revert "qtdemux: respect qt segments in push-mode for empty starts"
+	  This reverts commit 142d8e2d23e5602e7382977af1043d621625f8c8.
+
+2015-11-16 16:56:04 +0900  Vineeth TM <vineeth.tm@samsung.com>
+
+	* gst/isomp4/qtdemux.c:
+	  qtdemux: Fix string memory leak
+	  The string got using g_strdup_printf will be allocated memory
+	  and should be freed after use.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=758161
+
+2015-11-14 21:51:11 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* sys/v4l2/gstv4l2object.c:
+	  v4l2/object: remove unnecessary NULL check before g_free()
+
+2015-11-14 21:45:29 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* sys/oss/gstosssrc.c:
+	  osssrc: remove unnecessary NULL check before g_free()
+
+2015-11-14 21:43:24 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* sys/sunaudio/gstsunaudiosrc.c:
+	  sunaudiosrc: remove unnecessary NULL checks before g_free()
+
+2015-11-14 21:36:30 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* gst/wavparse/gstwavparse.c:
+	  wavparse: remove unnecessary NULL checks before g_free()
+
+2015-11-14 21:31:08 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* gst/matroska/matroska-mux.c:
+	  matroskamux: remove unnecessary NULL checks before g_free()
+
+2015-11-14 21:26:21 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* gst/matroska/matroska-read-common.c:
+	  matroska/read-common: remove unnecessary NULL checks before g_free()
+
+2015-11-14 20:43:10 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* gst/isomp4/atoms.c:
+	  isomp4/atoms: remove unnecessary NULL checks before g_free()
+
+2015-11-14 20:35:54 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* gst/rtp/gstrtptheorapay.c:
+	  rtp/theorapay: remove unnecessary NULL checks before g_free()
+
+2015-11-14 20:33:54 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* gst/rtp/gstrtpvorbispay.c:
+	  rtp/vorbispay: remove unnecessary NULL checks before g_free()
+
+2015-11-14 20:31:34 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* gst/rtp/gstrtpjpegpay.c:
+	  rtp/jpegpay: remove unnecessary NULL checks before g_free()
+
+2015-11-14 20:27:04 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* gst/rtp/gstrtpgstpay.c:
+	  rtpgstpay: remove unnecessary NULL checks before g_free()
+
+2015-11-14 20:22:09 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* gst/rtsp/gstrtspsrc.c:
+	  rtspsrc: remove unnecessary NULL checks before g_free()
+
+2015-11-14 20:14:25 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* gst/flx/gstflxdec.c:
+	  flxdec: remove unnecessary NULL check before g_free()
+
+2015-11-14 20:09:54 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* gst/effectv/gstop.c:
+	  effectv/optv: remove unnecessary NULL checks before g_free()
+
+2015-11-14 20:05:03 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* gst/effectv/gstshagadelic.c:
+	  effectv/shagadelictv: remove unnecessary NULL checks before g_free()
+
+2015-11-14 20:01:43 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* gst/effectv/gstripple.c:
+	  effectv/ripple: remove unnecessary NULL checks before g_free()
+
+2015-11-14 19:56:57 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* gst/effectv/gstradioac.c:
+	  effectv/radioac: remove unnecessary NULL checks before g_free()
+
+2015-11-14 19:52:12 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* gst/effectv/gststreak.c:
+	  effectv/streak: remove unnecessary NULL check before g_free()
+
+2015-11-14 17:04:55 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* ext/shout2/gstshout2.c:
+	  shout2: remove unnecessary NULL checks before g_free()
+
+2015-11-14 16:57:13 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* ext/vpx/gstvp9enc.c:
+	  vp9enc: remove unnecessary NULL check before g_free()
+
+2015-11-14 16:54:42 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* ext/vpx/gstvp8enc.c:
+	  vp8enc: remove unnecessary NULL check before g_free()
+
+2015-11-14 16:20:33 -0800  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* ext/soup/gstsouphttpsrc.c:
+	  souphttpsrc: remove unnecessary NULL checks before g_free()
+
+2015-11-13 13:34:02 +0100  Aurélien Zanelli <aurelien.zanelli@parrot.com>
+
+	* sys/v4l2/gstv4l2object.c:
+	  v4l2object: add support of NV16, NV61 and NV24 formats
+	  Mapped respectively to V4L2_PIX_FMT_NV16/V4L2_PIX_FMT_NV16M,
+	  V4L2_PIX_FMT_NV61,V4L2_PIX_FMT_NV61M and V4L2_PIX_FMT_NV24 v4l2 formats.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=758058
+
+2015-11-11 14:10:53 +0900  Vineeth TM <vineeth.tm@samsung.com>
+
+	* gst/multifile/gstsplitmuxpartreader.c:
+	  splitmuxpartreader: Fix GCond leak
+	  inactive_cond is not being cleared resulting in memory leak.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=757924
+
+2015-08-06 12:44:20 +0900  Vineeth TM <vineeth.tm@samsung.com>
+
+	* ext/jpeg/gstjpegdec.c:
+	  jpegdec: fix output state memory leak
+	  When jpeg_finish_decompress is called, output state reference is being created.
+	  But if there is any failures in finishing decompress, it jumps to setjmp,
+	  and at that point state was not referenced. Resulting in leak of output state.
+	  Hence adding another setjmp after output state is referenced.
+	  Similarly adding another setjmp to unmap the frame in case error happens before
+	  finish_decompress
+	  https://bugzilla.gnome.org/show_bug.cgi?id=753087
+
+2015-08-10 11:23:45 -0300  Thiago Santos <thiagoss@osg.samsung.com>
+
+	* gst/isomp4/qtdemux.c:
+	  qtdemux: respect qt segments in push-mode for empty starts
+	  In push-mode it is hard to support qt segments overall but it is
+	  possible to support when the file isn't heavily edited but just contain
+	  a segment to indicate a gap at the beginning. This also allows properly
+	  timestamping data that has negative DTS in push-mode.
+	  It is relevant to support those for 2 scenarios:
+	  1) fragmented streaming
+	  2) HTTP playback of 'regular' mp4
+	  https://bugzilla.gnome.org/show_bug.cgi?id=753484
+
+2015-11-05 18:39:33 +0530  Nirbheek Chauhan <nirbheek@centricular.com>
+
+	* ext/pulse/pulsedeviceprovider.c:
+	  pulse: Don't leak caps and structures in the device provider
+
+2015-11-04 19:01:20 +0530  Arun Raghavan <arun@centricular.com>
+
+	* gst/rtpmanager/rtpsession.c:
+	  rtpmanager: Document properties that are expressed in bits per second
+	  This changed in 928cd110bcea5d143cab3ea747991851d52ecbad and
+	  73c0c2920f9aca96982a4de0c20b3417aa148b81 but was not documented.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=747863
+
+2015-11-04 18:51:32 +0530  Arun Raghavan <arun@centricular.com>
+
+	* gst/rtpmanager/gstrtpsession.c:
+	* gst/rtpmanager/rtpsession.c:
+	  rtpmanager: Trivial gst-indent fixes
+
+2015-08-12 13:35:40 +0200  Philippe Normand <philn@igalia.com>
+
+	* gst/isomp4/qtdemux.c:
+	* gst/isomp4/qtdemux.h:
+	  qtdemux: support for cenc auxiliary info parsing outside of moof box
+	  When the cenc aux info index is out of moof boundaries, keep track of
+	  it and parse the beginning of the mdat box, before the first sample.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=755614
+
+2015-11-03 20:33:10 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/matroska/matroska-demux.c:
+	  matroskademux: Use codecutils helpers for creating Opus caps
+	  Also fix up codec data with values from the container.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=757152
+
+2015-11-03 14:51:48 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/matroska/matroska-demux.c:
+	  matroskademux: There is no multistream field for Opus anymore
+	  https://bugzilla.gnome.org/show_bug.cgi?id=757152
+
+2015-11-03 12:42:52 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/matroska/matroska-mux.c:
+	* gst/matroska/webm-mux.c:
+	  matroska/webmmux: Support Opus in webmmux and VP9 in matroskamux
+	  https://bugzilla.gnome.org/show_bug.cgi?id=729950
+
+2015-11-03 12:40:15 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/matroska/matroska-demux.c:
+	  matroskademux: Parse and handle CodecDelay, SeekPreroll and DiscardPadding
+	  https://bugzilla.gnome.org/show_bug.cgi?id=727305
+
+2015-11-03 12:18:19 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/matroska/matroska-ids.h:
+	* gst/matroska/matroska-mux.c:
+	  matroskamux: Write CodecDelay, DiscardPadding and SeekPreroll for Opus
+	  And also adjust timestamps and durations according to the codec delay, both
+	  should include it for whatever reason.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=727305
+
+2015-11-03 11:49:54 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/matroska/matroska-mux.c:
+	  matroskamux: Opus headers are not in-band
+	  https://bugzilla.gnome.org/show_bug.cgi?id=727305
+
+2015-11-03 22:01:07 +0530  Arun Raghavan <git@arunraghavan.net>
+
+	* sys/v4l2/gstv4l2.c:
+	  v4l2: Set O_CLOEXEC on the device fd
+	  This is needed to make sure that child processes don't inherit the video
+	  device fd which can cause problems with some drivers.
+
+2015-11-03 14:46:30 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/rtpmanager/gstrtpjitterbuffer.c:
+	  rtpmanager: switch G_GINT64_FORMAT for GST_STIME_ARGS
+	  No need to use G_GINT64_FORMAT for potentially negative values of
+	  GstClockTimeDiff. Since 1.6 these can be handled with GST_STIME_ARGS.
+	  Plus it creates more readable values in the logs.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=757480
+
+2015-11-03 14:26:29 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/rtpmanager/rtpsource.c:
+	  rtpmanager: use GST_STIME_ARGS for GstClockTimeDiff
+	  No need to manually handle negative values of diff, GST_STIME_ARGS does
+	  exactly this.
+
+2015-11-02 16:53:15 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/videomixer/videomixer2.c:
+	  videomixer: use GST_STIME_ARGS for GstClockTimeDiff
+	  No need to manually handle negative values of diff, GST_STIME_ARGS does
+	  exactly this.
+
+2015-11-02 16:43:46 +0000  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/deinterlace/gstdeinterlace.c:
+	  deinterlace: use GST_STIME_ARGS for GstClockTimeDiff
+	  No need to manually handle negative values of diff, GST_STIME_ARGS is
+	  available for this.
+
+2015-10-30 10:05:37 +0530  Ravi Kiran K N <ravi.kiran@samsung.com>
+
+	* gst/audiofx/audiochebband.c:
+	  audiochebband: Fix typo in example pipeline
+	  Fix typo in example pipeline.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=757340
 
 2015-10-28 23:47:30 +0530  Nirbheek Chauhan <nirbheek@centricular.com>
 
@@ -292,22 +993,6 @@
 	  Fixes regression with input JPEG frames that only have PTS set on them.
 	  https://bugzilla.gnome.org/show_bug.cgi?id=756967
 
-2015-10-11 12:06:26 +0100  Thibault Saunier <tsaunier@gnome.org>
-
-	* gst/isomp4/gstqtmux.c:
-	* gst/isomp4/gstqtmuxmap.c:
-	  qtmux: Allow negotiating to S8 as a raw format but stop making it best choice
-	  Negotiation to audio/x-raw,format=S8 was not possible because S8 does
-	  not have a bit order so we ended up doing `if (!entry.fourcc) goto refuse_caps;`
-	  https://bugzilla.gnome.org/show_bug.cgi?id=756387
-
-2015-10-11 09:18:40 +0100  Thibault Saunier <tsaunier@gnome.org>
-
-	* gst/isomp4/gstqtmux.c:
-	* gst/isomp4/gstqtmuxmap.c:
-	  qtmux: Add prores support
-	  https://bugzilla.gnome.org/show_bug.cgi?id=756388
-
 2015-10-24 23:57:38 +0200  George Kiagiadakis <george.kiagiadakis@collabora.com>
 
 	* tests/check/elements/splitmux.c:
@@ -325,10 +1010,11 @@
 	  pads are released and some resources are leaked.
 	  https://bugzilla.gnome.org/show_bug.cgi?id=753622
 
-2015-10-27 17:32:22 +0200  Sebastian Dröge <sebastian@centricular.com>
+2015-10-20 15:28:10 +0300  Sebastian Dröge <sebastian@centricular.com>
 
-	* gst/audiofx/gstscaletempo.c:
-	  scaletempo: F64 support is only available in GIT master at this point
+	* gst/matroska/matroska-demux.c:
+	  matroskademux: Read buffer timestamp *after* actually setting it
+	  https://bugzilla.gnome.org/show_bug.cgi?id=756809
 
 2015-10-24 17:14:07 +0300  Sebastian Dröge <sebastian@centricular.com>
 
@@ -344,11 +1030,109 @@
 	  we're at it.
 	  https://bugzilla.gnome.org/show_bug.cgi?id=757033
 
+2015-10-19 18:04:56 -0300  Thiago Santos <thiagoss@osg.samsung.com>
+
+	* gst/deinterlace/gstdeinterlace.c:
+	  deinterlace: break as soon as non-interlaced if found
+	  It looks for a non-interlaced entry on the filter caps, break
+	  as soon as one is found to avoid wasting cpu
+
+2015-10-19 17:50:28 -0300  Thiago Santos <thiagoss@osg.samsung.com>
+
+	* gst/deinterlace/gstdeinterlace.c:
+	  deinterlace: implement accept-caps
+	  Implement accept-caps handler to avoid doing a full caps query
+	  downstream to handle it.
+	  This commit implements accept-caps as a simplification of the _getcaps
+	  function, so it exposes the same limitations that getcaps would.
+	  For example, not accepting renegotiation to caps with capsfeatures when
+	  it was last configured to a caps that it has to deinterlace.
+
+2015-10-19 17:06:28 -0300  Thiago Santos <thiagoss@osg.samsung.com>
+
+	* tests/check/elements/deinterlace.c:
+	  tests: deinterlace: fix small typo in comment
+
 2015-10-26 00:41:28 +1100  Jan Schmidt <jan@centricular.com>
 
 	* tests/files/Makefile.am:
 	  check: Dist splitvideo0[012].ogg test files.
 
+2015-10-23 20:16:17 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/audiofx/gstscaletempo.c:
+	* gst/audiofx/gstscaletempo.h:
+	  scaletempo: Add support for F64
+
+2015-10-22 17:40:38 -0700  Mischa Spiegelmock <mspiegelmock@gmail.com>
+
+	* docs/plugins/inspect/plugin-rtp.xml:
+	* gst/multipart/multipartdemux.c:
+	* gst/rtp/README:
+	* gst/rtp/gstrtpvp8pay.c:
+	* gst/rtpmanager/gstrtprtxreceive.c:
+	* gst/udp/gstudpsrc.c:
+	  docs: Minor fixes in various places
+	  https://bugzilla.gnome.org/show_bug.cgi?id=756996
+
+2015-10-21 17:43:31 +0100  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/goom/plugin_info.c:
+	  goom: remove compiler trick
+	  After commit 2cb6cfed22166b262ae50cb58f3ff11dd8ba91f9 there is no need to
+	  trick the compiler anymore about the usage of variable cpuFlavour.
+
+2015-10-21 14:35:02 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* common:
+	  Automatic update of common submodule
+	  From b99800a to b319909
+
+2015-10-21 17:41:38 +0530  Ravi Kiran K N <ravi.kiran@samsung.com>
+
+	* gst/audiofx/audiofxbaseiirfilter.h:
+	  audiofx: remove unused variable
+	  Remove unsued variable have_coeffs in audiofxbaseiirfilter
+	  https://bugzilla.gnome.org/show_bug.cgi?id=756905
+
+2015-10-20 17:29:42 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* configure.ac:
+	  Use new GST_ENABLE_EXTRA_CHECKS #define
+	  https://bugzilla.gnome.org/show_bug.cgi?id=756870
+
+2015-10-21 14:25:55 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* README:
+	* common:
+	  Automatic update of common submodule
+	  From 9aed1d7 to b99800a
+
+2015-10-21 11:53:09 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst/flv/gstflvdemux.c:
+	  flvdemux: relax creation time parsing
+	  Parse wrong timestamps like we used to write as well,
+	  e.g. 10:9:42, and the hour might be without a leading
+	  zero in any case.
+
+2015-10-21 11:45:35 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst/flv/gstflvdemux.c:
+	  flvdemux: fix indentation
+
+2015-10-21 11:44:50 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst/flv/gstflvdemux.c:
+	  flvdemux: extract both creation date and time
+	  Before we only extracted the date part.
+
+2015-10-21 11:16:01 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst/flv/gstflvmux.c:
+	  flvmux: fix writing of creation time
+	  Don't write time as e.g. 11:9:42
+
 2015-10-13 12:42:56 -0300  Thiago Santos <thiagoss@osg.samsung.com>
 
 	* gst/rtp/gstrtpj2kpay.c:
@@ -364,13 +1148,6 @@
 	  It's not available on older OSX and we can as well use memchr() here.
 	  https://bugzilla.gnome.org/show_bug.cgi?id=756154
 
-2015-10-12 10:48:23 +0900  Vineeth TM <vineeth.tm@samsung.com>
-
-	* gst/audioparsers/gstmpegaudioparse.c:
-	  mpegaudioparse: Fix buffer memory leak during failures
-	  mapped buffer is not being unmapped during failures
-	  https://bugzilla.gnome.org/show_bug.cgi?id=756231
-
 2015-10-19 17:38:32 +0900  Vineeth TM <vineeth.tm@samsung.com>
 
 	* gst/auparse/gstauparse.c:
@@ -378,6 +1155,52 @@
 	  Free the event after being handled to prevent memory leak.
 	  https://bugzilla.gnome.org/show_bug.cgi?id=756799
 
+2015-10-19 09:14:19 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst/isomp4/gstqtmuxmap.c:
+	  qtmux: unify raw audio caps into a single caps structure
+
+2015-10-14 15:42:50 -0700  Reynaldo H. Verdejo Pinochet <reynaldo@osg.samsung.com>
+
+	* gst/isomp4/qtdemux.c:
+	  qtdemux: add support for FFV1 coded streams in mov
+	  https://bugzilla.gnome.org/show_bug.cgi?id=752495
+
+2015-10-14 15:53:26 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* ext/soup/gstsouphttpsrc.c:
+	  souphttpsrc: EOS immediately if we have an empty seek segment
+	  https://bugzilla.gnome.org/show_bug.cgi?id=748316
+
+2015-10-14 10:43:19 +0300  Stavros Vagionitis <stavrosv@digisoft.tv>
+
+	* ext/soup/gstsouphttpsrc.c:
+	  souphttpsrc: Make non-inclusive segment boundaries inclusive
+	  The problem is that the filesrc and souphttpsrc are behaving
+	  differently regarding the calculation of the segment boundaries. The
+	  filesrc is using a non-inclusive boundaries, while the souphttpsrc
+	  uses inclusive. Currently the hlsdemux calculates the boundaries as
+	  inclusive, so for this reason there is no problem with the souphttpsrc,
+	  but there is an issue in the filesrc.
+	  The GstSegment is non-inclusive, so the proposed solution is to use
+	  non-inclusive boundaries in the hlsdemux in order to be consistent.
+	  Make the change in the hlsdemux, will break the souphttpsrc, which
+	  will expect inclusive boundaries, but the hlsdemux will offer
+	  non-inclusive. This change makes sure that the non-inclusive
+	  boundaries are converted to inclusive.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=748316
+
+2015-10-11 22:07:54 +0000  Graham Leggett <minfrin@sharp.fm>
+
+	* ext/soup/gstsouphttpclientsink.c:
+	* ext/soup/gstsouphttpclientsink.h:
+	  souphttpclientsink: Add the retry and retry-delay properties
+	  These allow a failed request to be retried after the given number of seconds
+	  instead of failing the pipeline. Take account of the Retry-After header if
+	  present. Add retries parameter that controls the number of times an HTTP
+	  request will be retried before failing.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=756318
+
 2015-10-14 12:03:15 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
 
 	* gst/isomp4/qtdemux.c:
@@ -396,6 +1219,200 @@
 	  Free the stream and its sub items instead of just the stream
 	  https://bugzilla.gnome.org/show_bug.cgi?id=756544
 
+2015-10-11 12:06:26 +0100  Thibault Saunier <tsaunier@gnome.org>
+
+	* gst/isomp4/gstqtmux.c:
+	* gst/isomp4/gstqtmuxmap.c:
+	  qtmux: Allow negotiating to S8 as a raw format but stop making it best choice
+	  Negotiation to audio/x-raw,format=S8 was not possible because S8 does
+	  not have a bit order so we ended up doing `if (!entry.fourcc) goto refuse_caps;`
+	  https://bugzilla.gnome.org/show_bug.cgi?id=756387
+
+2015-10-11 09:18:40 +0100  Thibault Saunier <tsaunier@gnome.org>
+
+	* gst/isomp4/gstqtmux.c:
+	* gst/isomp4/gstqtmuxmap.c:
+	  qtmux: Add prores support
+	  https://bugzilla.gnome.org/show_bug.cgi?id=756388
+
+2015-10-12 18:56:32 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* tests/check/Makefile.am:
+	  tests: add GST_PLUGINS_BASE_LIBS for flvdemux check
+	  So it pulls in the right libgsttag-1.0.
+
+2015-10-11 22:27:47 +0100  Julien Isorce <j.isorce@samsung.com>
+
+	* gst/goom/Makefile.am:
+	* gst/goom/gstaudiovisualizer.c:
+	* gst/goom/gstaudiovisualizer.h:
+	* gst/goom/gstgoom.h:
+	* gst/goom2k1/Makefile.am:
+	* gst/goom2k1/gstaudiovisualizer.c:
+	* gst/goom2k1/gstaudiovisualizer.h:
+	* gst/goom2k1/gstgoom.h:
+	  goom/goom2k1: remove obsolete left over files
+	  They now use the new GstAudioVisualizer base class
+	  from gst-plugins-base/gst-libs/gst/pbutils
+	  Also fixed undefined reference to gst_audio_visualizer_get_type
+	  Added GST_PLUGINS_BASE_LIBS to Makefile.am and re-order LIBADD.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=742875
+
+2015-10-12 10:48:23 +0900  Vineeth TM <vineeth.tm@samsung.com>
+
+	* gst/audioparsers/gstmpegaudioparse.c:
+	  mpegaudioparse: Fix buffer memory leak during failures
+	  mapped buffer is not being unmapped during failures
+	  https://bugzilla.gnome.org/show_bug.cgi?id=756231
+
+2015-10-12 11:18:51 +0900  Vineeth TM <vineeth.tm@samsung.com>
+
+	* ext/soup/gstsouphttpclientsink.c:
+	  souphttpclientsink: Check if soup message is created
+	  If soup message is not created then the same should not be passed
+	  on, which is resulting in segfault. Hence throwing a warning message
+	  and returning
+	  https://bugzilla.gnome.org/show_bug.cgi?id=755326
+
+2015-10-12 11:15:15 +0900  Vineeth TM <vineeth.tm@samsung.com>
+
+	* ext/soup/gstsouphttpclientsink.c:
+	  souphttpclientsink: Check if location being set is valid
+	  Adding a check in set_property to find if the location uri is valid
+	  and printing warning if not valid.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=755326
+
+2015-10-12 11:09:30 +0900  Vineeth TM <vineeth.tm@samsung.com>
+
+	* ext/soup/gstsouphttpclientsink.c:
+	  souphttpclientsink: Fix memory leaks during failures
+	  freeing streamheader_buffers and sent_buffers during failure cases.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=755326
+
+2015-10-12 11:03:17 +0900  Vineeth TM <vineeth.tm@samsung.com>
+
+	* ext/soup/gstsouphttpclientsink.c:
+	  souphttpclientsink: Replace redundant free_buffer_list function
+	  Removing free_buffer_list and replacing it with already available function
+	  g_list_free_full
+	  https://bugzilla.gnome.org/show_bug.cgi?id=755326
+
+2015-10-11 16:40:01 +0200  Edward Hervey <bilboed@bilboed.com>
+
+	* tests/check/Makefile.am:
+	  check: Don't forget base CFLAGS for flvdemux check
+	  elements/flvdemux.c:25:25: fatal error: gst/tag/tag.h: No such file or directory
+
+2015-10-11 11:37:51 +0100  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/matroska/ebml-write.c:
+	* gst/matroska/ebml-write.h:
+	* gst/matroska/matroska-mux.c:
+	* gst/matroska/matroska-mux.h:
+	  matroskamux: Create a TIME segment when creating streamable output
+	  Related to https://bugzilla.gnome.org/show_bug.cgi?id=754435 which
+	  does the same for flvmux.
+
+2015-09-23 13:50:52 +0200  Havard Graff <havard.graff@gmail.com>
+
+	* gst/flv/Makefile.am:
+	* gst/flv/gstflvdemux.c:
+	* tests/check/Makefile.am:
+	* tests/check/elements/flvdemux.c:
+	  flvdemux: output speex vorbiscomment as a GstTagList
+	  This is what speexdec expects.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=755478
+
+2015-09-22 22:59:16 +0200  Havard Graff <havard.graff@gmail.com>
+
+	* gst/flv/gstflvmux.c:
+	* tests/check/elements/flvmux.c:
+	  flvmux: GST_BUFFER_OFFSETs should be GST_BUFFER_OFFSET_NONE
+	  Or else flvdemux don't understand it
+	  https://bugzilla.gnome.org/show_bug.cgi?id=754435
+
+2015-09-02 10:44:59 +0200  Havard Graff <havard.graff@gmail.com>
+
+	* gst/flv/gstflvmux.c:
+	* tests/check/elements/flvmux.c:
+	  flvmux: use time segment and copy timestamps when streamable
+	  Add a basic test using speex data to verify timestamping.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=754435
+
+2015-09-23 13:14:03 +0200  Havard Graff <havard.graff@gmail.com>
+
+	* gst/flv/gstflvdemux.c:
+	  flvdemux: speex is also always 16KHz
+	  This is just a cosmetic change for the logs, since the right caps
+	  for Speex is being set elsewhere.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=755479
+
+2015-07-14 15:19:44 +0200  Stian Selnes <stian@pexip.com>
+
+	* gst/rtpmanager/gstrtpsession.c:
+	* gst/rtpmanager/rtpsession.c:
+	  rtpmanager: Add 'source-stats' to stats and notify
+	  Add statitics from each rtp source to the rtp session property.
+	  'source-stats' is a GValueArray where each element is a GstStructure of
+	  stats for one rtp source.
+	  The availability of new stats is signaled via g_object_notify.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=752669
+
+2015-06-05 17:20:33 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/rtpmanager/rtpsession.c:
+	* gst/rtpmanager/rtpsession.h:
+	  rtpsession: Implement sending of reduced size RTCP packets
+	  https://bugzilla.gnome.org/show_bug.cgi?id=750456
+
+2015-10-08 15:01:13 +0530  Ravi Kiran K N <ravi.kiran@samsung.com>
+
+	* gst/audiofx/audiodynamic.h:
+	  audiofx: Remove unused variable
+	  Remove unused variable 'degree' in audiodynamic
+	  https://bugzilla.gnome.org/show_bug.cgi?id=756234
+
+2015-10-08 14:44:07 +0900  Vineeth TM <vineeth.tm@samsung.com>
+
+	* gst/isomp4/qtdemux.c:
+	  qtdemux: Fix memory leak for corrupted file
+	  Free brands before overriding them.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=756226
+
+2015-10-08 11:44:04 +0900  Vineeth TM <vineeth.tm@samsung.com>
+
+	* ext/gdk_pixbuf/gstgdkpixbufdec.c:
+	  gdkpixbufdec: Fix pixbuf_loader leak during failures
+	  https://bugzilla.gnome.org/show_bug.cgi?id=756219
+
+2015-10-07 23:23:45 +0100  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/rtpmanager/gstrtpbin.c:
+	  rtpbin: Add missing break
+
+2015-10-07 13:03:02 +0200  Miguel París Díaz <mparisdiaz@gmail.com>
+
+	* gst/rtpmanager/gstrtpjitterbuffer.c:
+	* gst/rtpmanager/rtpsource.c:
+	* gst/rtpmanager/rtpsource.h:
+	* gst/rtpmanager/rtpstats.c:
+	* gst/rtpmanager/rtpstats.h:
+	  rtpmanager: Take into account packet rate for max-dropout and max-misorder calculations
+	  https://bugzilla.gnome.org/show_bug.cgi?id=751311
+
+2015-10-07 13:02:12 +0200  Miguel París Díaz <mparisdiaz@gmail.com>
+
+	* gst/rtpmanager/gstrtpbin.c:
+	* gst/rtpmanager/gstrtpbin.h:
+	* gst/rtpmanager/gstrtpjitterbuffer.c:
+	* gst/rtpmanager/gstrtpsession.c:
+	* gst/rtpmanager/rtpsession.c:
+	* gst/rtpmanager/rtpsession.h:
+	* gst/rtpmanager/rtpsource.c:
+	* gst/rtpmanager/rtpsource.h:
+	  rtpmanager: add "max-dropout-time" and "max-misorder-time" props
+	  https://bugzilla.gnome.org/show_bug.cgi?id=751311
+
 2015-10-07 17:14:57 +0900  Vineeth TM <vineeth.tm@samsung.com>
 
 	* gst/isomp4/gstqtmux.c:
@@ -421,6 +1438,66 @@
 	  is not freed. Freeing the cache when the state changes from PAUSED to READY.
 	  https://bugzilla.gnome.org/show_bug.cgi?id=754212
 
+2015-08-31 21:10:16 -0400  Olivier Crête <olivier.crete@collabora.com>
+
+	* gst/rtpmanager/gstrtpmux.c:
+	  rtpmux: Use default upstream event handling
+	  https://bugzilla.gnome.org/show_bug.cgi?id=752694
+
+2015-08-31 21:05:03 -0400  Olivier Crête <olivier.crete@collabora.com>
+
+	* gst/rtpmanager/gstrtpmux.c:
+	* gst/rtpmanager/gstrtpmux.h:
+	  rtpmux: As 0xFFFFFFFF is a valid ssrc, check if it has been set
+	  https://bugzilla.gnome.org/show_bug.cgi?id=752694
+
+2015-07-22 09:47:22 +0200  Havard Graff <havard.graff@gmail.com>
+
+	* gst/rtpmanager/gstrtpmux.c:
+	* gst/rtpmanager/gstrtpmux.h:
+	* tests/check/elements/rtpmux.c:
+	  gstrtpmux: allow the ssrc-property to decide ssrc on outgoing buffers
+	  By not doing this, the muxer is not effectively a rtpmuxer, rather a
+	  funnel, since it should be a single stream that exists the muxer.
+	  If not specified, take the first ssrc seen on a sinkpad, allowing upstream
+	  to decide ssrc in "passthrough" with only one sinkpad.
+	  Also, let downstream ssrc overrule internal configured one
+	  We hence has the following order for determining the ssrc used by
+	  rtpmux:
+	  0. Suggestion from GstRTPCollision event
+	  1. Downstream caps
+	  2. ssrc-Property
+	  3. (First) upstream caps containing ssrc
+	  4. Randomly generated
+	  https://bugzilla.gnome.org/show_bug.cgi?id=752694
+
+2015-10-02 22:42:20 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/udp/gstudpsrc.c:
+	  udpsrc: Fixup last commit
+
+2015-10-02 22:21:45 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* configure.ac:
+	* gst/udp/gstudpsrc.c:
+	  Update GLib dependency to 2.40.0
+
+2015-06-30 16:56:19 +0200  Miguel París Díaz <mparisdiaz@gmail.com>
+
+	* gst/rtpmanager/rtpstats.c:
+	* gst/rtpmanager/rtpstats.h:
+	  rtpstats: add utility for calculating RTP packet rate
+
+2015-08-10 18:14:39 -0300  Thiago Santos <thiagoss@osg.samsung.com>
+
+	* gst/isomp4/qtdemux.c:
+	  qtdemux: handle empty segments in seeking adjust
+	  If seeking targets an empty segment skip it as there is no media
+	  offset to get from it. Instead look for the next one.
+	  This doesn't make seeking in push-mode work if you seek to an
+	  empty segment but at least won't get you to wrong offsets.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=753484
+
 2015-04-17 14:25:43 +0200  George Kiagiadakis <george.kiagiadakis@collabora.com>
 
 	* gst/multifile/gstsplitmuxsink.c:
@@ -458,6 +1535,146 @@
 	  in the meantime.
 	  https://bugzilla.gnome.org/show_bug.cgi?id=753624
 
+2015-09-16 16:03:02 +0900  Vineeth T M <vineeth.tm@samsung.com>
+
+	* gst/avi/gstavidemux.c:
+	  avidemux: Reverse playback does not consider segment.start
+	  During reverse playback, the media should stop playing at segment.start
+	  This does not happen, and avidemux continues to process data even when
+	  current timestamp is less that segment.start.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=755094
+
+2015-09-23 12:39:35 +0900  Manasa Athreya <manasa.athreya@lge.com>
+
+	* gst/isomp4/qtdemux.c:
+	  qtdemux: Check multi trex to find track id in mp4 mpeg-dash stream
+	  If stream has more than one trex box which is not matched to actual
+	  track id, it makes qtdemux crashed.
+	  Author : Manasa Athreya (manasa.athreya@lge.com)
+	  https://bugzilla.gnome.org/show_bug.cgi?id=754864
+
+2015-09-04 14:24:45 +0530  Ravi Kiran K N <ravi.kiran@samsung.com>
+
+	* gst/smpte/gstsmpte.c:
+	  smpte: get size, stride info using VideoInfo
+	  Use VideoInfo data to get size stride and
+	  offset, instead of hard coded macros.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=754558
+
+2015-09-04 14:18:50 +0530  Ravi Kiran K N <ravi.kiran@samsung.com>
+
+	* gst/smpte/gstsmpte.c:
+	  smpte: free mask
+	  Free the memory allocated to 'mask' to avoid
+	  memory leak.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=754555
+
+2015-08-20 11:02:58 +0900  Vineeth TM <vineeth.tm@samsung.com>
+
+	* tests/examples/equalizer/demo.c:
+	* tests/icles/equalizer-test.c:
+	* tests/icles/gdkpixbufoverlay-test.c:
+	* tests/icles/gdkpixbufsink-test.c:
+	* tests/icles/test-oss4.c:
+	* tests/icles/videocrop-test.c:
+	  gstreamer: good: tests: Fix memory leaks when context parse fails.
+	  When g_option_context_parse fails, context and error variables are not getting free'd
+	  which results in memory leaks. Free'ing the same.
+	  And replacing g_error_free with g_clear_error, which checks if the error being passed
+	  https://bugzilla.gnome.org/show_bug.cgi?id=753853
+
+2015-10-02 16:18:15 +0900  Hyunjun Ko <zzoon.ko@samsung.com>
+
+	* gst/rtpmanager/rtpsource.c:
+	  rtpsource: doesn't handle probation and rtp gap in case of sender
+	  https://bugzilla.gnome.org/show_bug.cgi?id=754548
+
+2015-10-02 16:16:32 +0900  Hyunjun Ko <zzoon.ko@samsung.com>
+
+	* docs/plugins/gst-plugins-good-plugins.signals:
+	* gst/rtpmanager/gstrtpbin.c:
+	* gst/rtpmanager/gstrtpbin.h:
+	* gst/rtpmanager/gstrtpsession.c:
+	* gst/rtpmanager/gstrtpsession.h:
+	* gst/rtpmanager/rtpsession.c:
+	* gst/rtpmanager/rtpsession.h:
+	  rtpmanager: add new on-new-sender-ssrc, on-sender-ssrc-active signals
+	  Allows for applications to get internal source's RTP statistics.
+	  (eg. sender sources for a server/client)
+	  https://bugzilla.gnome.org/show_bug.cgi?id=746747
+
+2015-10-02 14:17:48 +1000  Jan Schmidt <jan@centricular.com>
+
+	* sys/ximage/gstximagesrc.c:
+	  ximagesrc: Gather and coalesce all damaged areas before retrieving.
+	  These days the xserver seems to give us the same damage regions
+	  over and over for entire windows, and we retrieve them multiple
+	  times, which gives time for more damage to appear. Instead, just
+	  quickly gather all damaged areas into a region list and copy
+	  out once.
+
+2015-10-01 16:24:32 +0100  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/goom2k1/Makefile.am:
+	* gst/goom2k1/gstgoom.h:
+	  goom2k1: use the new audiovisualizer base class
+	  Rebase to have goom using the GstAudioVisualizer base class in
+	  gst-plugins-base/gst-libs/gst/pbutils
+	  https://bugzilla.gnome.org/show_bug.cgi?id=742875
+
+2015-10-01 16:16:08 +0100  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/goom/Makefile.am:
+	* gst/goom/gstgoom.h:
+	  goom: use the new audiovisualizer base class
+	  Rebase to have goom using the GstAudioVisualizer base class in
+	  gst-plugins-base/gst-libs/gst/pbutils
+	  https://bugzilla.gnome.org/show_bug.cgi?id=742875
+
+2015-09-30 17:35:33 -0300  Thiago Santos <thiagoss@osg.samsung.com>
+
+	* gst/interleave/deinterleave.c:
+	* tests/check/elements/deinterleave.c:
+	  deinterleave: implement accept-caps
+	  Avoid using default accept-caps handler that will query downstream
+	  and is more expensive. Just check if the caps is compatible with
+	  the template and check if the channels are the same.
+
+2015-09-30 09:35:39 -0300  Thiago Santos <thiagoss@osg.samsung.com>
+
+	* tests/check/elements/deinterleave.c:
+	  tests: deinterleave: also check for caps query results
+
+2015-09-30 12:30:59 -0300  Thiago Santos <thiagoss@osg.samsung.com>
+
+	* gst/interleave/deinterleave.c:
+	  deinterleave: use the caps query filter
+	  It was being ignored and would lead to wrong results if the
+	  element doing the query would rely on the intersection being made.
+
+2015-09-30 10:00:31 -0300  Thiago Santos <thiagoss@osg.samsung.com>
+
+	* gst/interleave/deinterleave.c:
+	  deinterleave: implement a caps query handler for the sinkpad
+	  It was missing and apparently code relied on having it there
+	  for not allowing a change in the number of channels
+
+2015-09-30 09:05:03 -0300  Thiago Santos <thiagoss@osg.samsung.com>
+
+	* gst/interleave/deinterleave.c:
+	  deinterleave: fix caps leak
+	  Caps from the pad template are being leaked. In any case it is
+	  from a static pad template and will 'leak' in the end, just doing
+	  the cleanup for the good practice.
+
+2015-09-29 11:15:01 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* tests/check/Makefile.am:
+	* tests/check/elements/.gitignore:
+	* tests/check/elements/gdkpixbufoverlay.c:
+	  tests: gdkpixbufoverlay: add minimal unit test
+	  https://bugzilla.gnome.org/show_bug.cgi?id=755773
+
 2015-09-29 11:12:48 +0100  Tim-Philipp Müller <tim@centricular.com>
 
 	* ext/gdk_pixbuf/gstgdkpixbufoverlay.c:
@@ -495,6 +1712,54 @@
 	  rate and channels on src caps.
 	  https://bugzilla.gnome.org/show_bug.cgi?id=755611
 
+2015-09-18 00:58:23 +1000  Jan Schmidt <thaytan@noraisin.net>
+
+	* ext/gdk_pixbuf/gstgdkpixbufsink.c:
+	* gst/rtpmanager/gstrtpbin.c:
+	* gst/rtpmanager/gstrtpsession.c:
+	  Fix some compiler warnings when building with G_DISABLE_ASSERT
+	  Touches rtpmanager and gdkpixbufsink
+
+2015-08-18 14:30:57 +0100  Chris Bass <floobleflam@gmail.com>
+
+	* gst/isomp4/fourcc.h:
+	* gst/isomp4/qtdemux.c:
+	* gst/isomp4/qtdemux_types.c:
+	  qtdemux: support timed-text subtitle tracks.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=752818
+
+2015-09-26 00:12:46 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/matroska/matroska-demux.c:
+	* gst/matroska/matroska-parse.c:
+	* gst/rtpmanager/gstrtpjitterbuffer.c:
+	  gst: Don't use deprecated gst_segment_to_position()
+
+2015-09-21 13:47:21 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/rtpmanager/gstrtpbin.c:
+	* gst/rtpmanager/gstrtpbin.h:
+	* gst/rtpmanager/gstrtpjitterbuffer.c:
+	* gst/rtsp/gstrtspsrc.c:
+	* gst/rtsp/gstrtspsrc.h:
+	  rtpbin/rtpjitterbuffer/rtspsrc: Add property to set maximum ms between RTCP SR RTP time and last observed RTP time
+	  https://bugzilla.gnome.org/show_bug.cgi?id=755125
+
+2015-09-16 19:28:11 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/rtpmanager/gstrtpbin.c:
+	* gst/rtpmanager/gstrtpbin.h:
+	* gst/rtpmanager/gstrtpsession.c:
+	  rtpbin/session: Allow RTCP sync to happen based on capture time or send time
+	  Send time is the previous behaviour and the default, but there are use cases
+	  where you want to synchronize based on the capture time.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=755125
+
+2015-09-25 23:51:09 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* configure.ac:
+	  Back to development
+
 === release 1.6.0 ===
 
 2015-09-25 23:15:55 +0200  Sebastian Dröge <sebastian@centricular.com>
diff --git a/Makefile.in b/Makefile.in
index 74c66e2..8a01710 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -490,6 +490,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
@@ -1198,6 +1200,9 @@
 	@if [ -d ../www/data/src ]; then \
 	  mv -v $(PACKAGE)-$(VERSION).tar.xz ../www/data/src/$(PACKAGE)/ ; \
 	  mv -v $(PACKAGE)-$(VERSION).tar.xz.sha256sum ../www/data/src/$(PACKAGE)/ ; \
+	elif [ -d ../../www/data/src ]; then \
+	  mv -v $(PACKAGE)-$(VERSION).tar.xz ../../www/data/src/$(PACKAGE)/ ; \
+	  mv -v $(PACKAGE)-$(VERSION).tar.xz.sha256sum ../../www/data/src/$(PACKAGE)/ ; \
 	fi
 	@echo "================================================================================================="
 
diff --git a/NEWS b/NEWS
index be30e41..a4bffc6 100644
--- a/NEWS
+++ b/NEWS
@@ -1,37 +1,2 @@
-This is GStreamer 1.6.2
-
-The GStreamer team is proud to announce the second bugfix release in the stable
-1.6 release series of your favourite cross-platform multimedia framework!
-
-This release only contains bugfixes and it is safe to update from 1.6.0 and
-1.6.1. For a full list of bugfixes see Bugzilla:
-  https://bugzilla.gnome.org/buglist.cgi?bug_status=RESOLVED&bug_status=VERIFIED&limit=0&list_id=83309&order=bug_id&product=GStreamer&resolution=FIXED&target_milestone=1.6.2
-
-See http://gstreamer.freedesktop.org/releases/1.6/ for the latest version of this document.
-
-Major bugfixes
-
-- Crashes in gst-libav with sinks that did not provide a buffer pool
-  but supported video metadata were fixed. This affected d3dvideosink
-  and some 3rd party sinks. Also related fixes for crashes when a downstream
-  buffer pool failed allocation.
-- Big GL performance improvement on iOS by a factor of 2 by using Apple's sync
-  extension.
-- Deadlocks in the DirectSound elements on Windows, and the behaviour of its
-  mute property were fixed.
-- The Direct3D video sink does not crash anymore when minimizing the window
-- The library soname generation on Android >= 6.0 was fixed, which previously
-  caused GStreamer to fail to load there.
-- File related elements have large-file (>2GB) support on Android now.
-- gst-libav was updated to ffmpeg 2.8.3.
-- Deserialization of custom events in the GDP depayloader was fixed.
-- Missing OpenGL context initialization in the Qt/QML video sink was fixed in
-  certain situations.
-- Interoperability with some broken RTSP servers using HTTP tunnel was
-  improved.
-- Various compilation fixes for Windows.
-- Various smaller memory leak and other fixes in different places.
-- and many, many more:
-  https://bugzilla.gnome.org/buglist.cgi?bug_status=RESOLVED&bug_status=VERIFIED&limit=0&list_id=83309&order=bug_id&product=GStreamer&resolution=FIXED&target_milestone=1.6.2
-
+This is GStreamer 1.7.1
 
diff --git a/README b/README
index f175b1b..fa53f95 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-GStreamer 1.5.x development series
+GStreamer 1.7.x development series
 
 WHAT IT IS
 ----------
diff --git a/RELEASE b/RELEASE
index 60563e3..7fe6af7 100644
--- a/RELEASE
+++ b/RELEASE
@@ -1,19 +1,17 @@
 
-Release notes for GStreamer Good Plugins 1.6.2
+Release notes for GStreamer Good Plugins 1.7.1
 
 
-The GStreamer team is proud to announce the second bugfix release in the stable
-1.6 release series of your favourite cross-platform multimedia framework!
+The GStreamer team is pleased to announce the first release of the unstable
+1.7 release series. The 1.7 release series is adding new features on top of
+the 1.0, 1.2, 1.4 and 1.6 series and is part of the API and ABI-stable 1.x release
+series of the GStreamer multimedia framework. The unstable 1.7 release series
+will lead to the stable 1.8 release series in the next weeks. Any newly added
+API can still change until that point.
 
 
-
-This release only contains bugfixes and it is safe to update from 1.6.0 and 1.6.1. For a
-full list of bugfixes see Bugzilla.
-
-
-
-See http://gstreamer.freedesktop.org/releases/1.6/
-for the full release notes.
+Binaries for Android, iOS, Mac OS X and Windows will be provided separately
+during the unstable 1.7 release series.
 
 
 
@@ -60,14 +58,56 @@
 
 Bugs fixed in this release
      
-      * 757961 : baseparse: do not overwrite header buffer timestamps
-      * 734098 : directsoundsink: gst_element_set_state blocked when plugout a usb audio device
-      * 755106 : directsoundsink: mute property doesn't work
-      * 755614 : qtdemux: support for cenc auxiliary info parsing outside of moof box
-      * 757924 : splitmuxpartreader: Fix GCond leak
-      * 758151 : rtpgstdepay does not deserialize custom events
-      * 758861 : wavparse: deadlock under some conditions
-      * 758912 : avimux: don't crash if we never got audio caps before  stopping
+      * 727305 : matroskademux: complete support for A_OPUS (SeekPreRoll, CodecDelay and DiscardPadding)
+      * 729950 : matroskamux: support video/x-vp9. webmmux: support audio/x-opus
+      * 734659 : qtdemux: Does not properly update base time for non-flushing seeks
+      * 745372 : vpxdec: Should try to avoid copies at output
+      * 746747 : rtpsession: Also report internal sources in on-new-ssrc and on-ssrc-active
+      * 748680 : directsoundsink: fix sleep for buffer-time lower than 200000
+      * 750456 : rtpsession: Implement sending of reduced size RTCP packets
+      * 750709 : souphttpsrc: add tls-interaction property
+      * 751311 : rtp: Dynamic dropout / reorder limits
+      * 752669 : rtpsession: Expose RTPSource stats through stats property
+      * 752694 : rtpmux: allow the ssrc-property to decide ssrc on outgoing  buffers
+      * 752818 : qtdemux: add support for XML timed-text subtitles
+      * 753087 : jpegdec: fix output state memory leak
+      * 753484 : qtdemux: support edit lists partially in push-mode
+      * 753853 : gstreamer: good: Fix memory leaks when context parse fails.
+      * 754435 : flvmux: use time segment and copy timestamps when streamable
+      * 754548 : rtpsource: In case of sender, doesn't need to think about probation and rtp gap.
+      * 754555 : smpte: Memory leak
+      * 754558 : smpte: Use video info data instead of macro
+      * 754864 : qtdemux: check multi trex to find track id in mp4 (DASH) stream.
+      * 755094 : avidemux: Reverse playback does not consider segment.start
+      * 755125 : rtp: RTCP mapping between NTP and RTP time could be capture or send time based
+      * 755326 : souphttpclientsink: Fix memory leaks and segfault crash
+      * 755478 : flvdemux: output speex vorbiscomment as a GstTagList
+      * 755479 : flvdemux: speex is also always 16KHz
+      * 755510 : vpx: create base class for vpx encoders and decoders
+      * 756219 : gdkpixbufdec: Fix pixbuf_loader leak during failures
+      * 756226 : qtdemux: fix memory leak for corrupted file
+      * 756231 : mpegaudioparse: Fix buffer memory leak
+      * 756234 : audiofx: Remove unused variable
+      * 756318 : souphttpclientsink: Add " retry " for request failures
+      * 756905 : audiofx: remove unused variable
+      * 757340 : audiochebband: Fix typo in example pipeline
+      * 757892 : rtph264pay: add config-interval option to send PPS/SPS before every key frame
+      * 758058 : v4l2object: add support of NV16, NV61 and NV24 formats
+      * 758085 : v4l2: Track /dev/video* to triggered required probe
+      * 758161 : qtdemux: Fix string memory leak
+      * 758171 : qtdemux: Seeking in dashdemux broken since edit list changes
+      * 758195 : vpxdec: Use more threads by default
+      * 758258 : matroska: Missing support for prores video
+      * 758260 : souphttpclientsink: Fix error leak and handle error
+      * 758390 : multifilesink: fix spelling on multi_file_sink_next_type variable
+      * 758826 : aacparse: Avoid over-skipping when checking LOAS config
+      * 758928 : qtdemux: letting flushes pass downstream on upstream offset seeks
+      * 759226 : interleave: Remove unsed field
+      * 759452 : directsoundsink: check device property, don't use default if a specific device is set
+      * 759614 : dvdec: Remove unused fields
+      * 759615 : DTS > PTS creates invalid mp4 files
+      * 759635 : progressreport: Add support for using format=buffers with do-query=false
+      * 758114 : tests: souphttpsrc test_icy_stream:0: Assertion 'caps != NULL' failed
 
 ==== Download ====
 
@@ -104,16 +144,50 @@
         
 Contributors to this release
     
+      * Alessandro Decina
+      * Anton Bondarenko
       * Arun Raghavan
+      * Aurélien Zanelli
+      * Chris Bass
+      * Dave Craig
+      * Edward Hervey
+      * Evan Callaway
+      * George Kiagiadakis
+      * Graham Leggett
+      * Guillaume Desmottes
+      * Guillaume Marquebielle
       * Havard Graff
+      * Hyunjun Ko
+      * Jan Schmidt
       * Josep Torra
+      * Julien Isorce
+      * Luis de Bethencourt
+      * Manasa Athreya
       * Michael Olbrich
+      * Miguel París Díaz
+      * Mischa Spiegelmock
+      * Nicola Murino
+      * Nicolas Dufresne
       * Nirbheek Chauhan
+      * Olivier Crête
+      * Philipp Zabel
       * Philippe Normand
+      * Prashant Gotarne
+      * Ramiro Polla
+      * Ravi Kiran K N
+      * Reynaldo H. Verdejo Pinochet
+      * Ryan Hendrickson
       * Sebastian Dröge
+      * Stavros Vagionitis
+      * Stian Selnes
       * Thiago Santos
+      * Thibault Saunier
       * Thomas Roos
       * Tim-Philipp Müller
+      * Vincent Dehors
+      * Vineeth T M
       * Vineeth TM
+      * William Manley
       * Wim Taymans
+      * Xavier Claessens
  
\ No newline at end of file
diff --git a/autogen.sh b/autogen.sh
index f7c047f..3d821a8 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -37,7 +37,11 @@
 if test ! \( -x .git/hooks/pre-commit -a -L .git/hooks/pre-commit \);
 then
     rm -f .git/hooks/pre-commit
-    ln -s ../../common/hooks/pre-commit.hook .git/hooks/pre-commit
+    if ! ln -s ../../common/hooks/pre-commit.hook .git/hooks/pre-commit 2> /dev/null
+    then
+        echo "Failed to create commit hook symlink, copying instead ..."
+        cp common/hooks/pre-commit.hook .git/hooks/pre-commit
+    fi
 fi
 
 # GNU gettext automake support doesn't get along with git.
diff --git a/common/Makefile.in b/common/Makefile.in
index 9d9647f..78be58f 100644
--- a/common/Makefile.in
+++ b/common/Makefile.in
@@ -450,6 +450,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/common/check.mak b/common/check.mak
index 8a90b5d..25a16e6 100644
--- a/common/check.mak
+++ b/common/check.mak
@@ -57,7 +57,7 @@
 	--show-possibly-lost=no                                 \
 	--leak-resolution=high --num-callers=20			\
 	./$* 2>&1 | tee $$valgrind_log ;			\
-	if grep "==" $$valgrind_log > /dev/null 2>&1; then	\
+	if grep "^==" $$valgrind_log > /dev/null 2>&1; then	\
 	    rm $$valgrind_log;					\
 	    exit 1;						\
 	fi ;							\
diff --git a/common/gst.supp b/common/gst.supp
index 81f98a9..2740e9a 100644
--- a/common/gst.supp
+++ b/common/gst.supp
@@ -3976,7 +3976,6 @@
 {
    closures aren't valgrind friendly (bgo#739850)
    Memcheck:Leak
-   match-leak-kinds: possible
    fun:calloc
    ...
    fun:g_cclosure_new
@@ -3985,7 +3984,6 @@
 {
    closures aren't valgrind friendly (bgo#739850)
    Memcheck:Leak
-   match-leak-kinds: possible
    fun:malloc
    ...
    fun:g_closure_add_invalidate_notifier
@@ -3994,7 +3992,6 @@
 {
    closures aren't valgrind friendly (bgo#739850)
    Memcheck:Leak
-   match-leak-kinds: possible
    fun:calloc
    ...
    fun:g_closure_new_simple
@@ -4020,3 +4017,12 @@
    Memcheck:Addr8
    fun:do_lookup_x
 }
+
+{
+   <quark tables are leaked on purpose when they are expanded, observed with glib 2.46 and gst-rtsp-server tests>
+   Memcheck:Leak
+   fun:malloc
+   ...
+   fun:g_quark_init
+   fun:glib_init_ctor
+}
diff --git a/common/m4/Makefile.in b/common/m4/Makefile.in
index f787529..670e903 100644
--- a/common/m4/Makefile.in
+++ b/common/m4/Makefile.in
@@ -390,6 +390,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/common/m4/gst-args.m4 b/common/m4/gst-args.m4
index b478c82..0628123 100644
--- a/common/m4/gst-args.m4
+++ b/common/m4/gst-args.m4
@@ -358,3 +358,29 @@
       fi
     ])
 ])
+
+dnl Enable extra checks by default only for development versions
+AC_DEFUN([AG_GST_ARG_ENABLE_EXTRA_CHECKS],
+[
+  AC_ARG_ENABLE(extra-check,
+    AC_HELP_STRING([--enable-extra-checks],
+                   [Enable extra runtime checks]),
+    [
+      case "${enableval}" in
+        yes) EXTRA_CHECKS=yes ;;
+        no)  EXTRA_CHECKS=no ;;
+        *)   AC_MSG_ERROR(bad value ${enableval} for --enable-extra-checks) ;;
+      esac
+    ],
+    [
+      if test "x`expr $PACKAGE_VERSION_MINOR % 2`" = "x1" -a "x`expr $PACKAGE_VERSION_MICRO '<' 90`" = "x1"; then
+        EXTRA_CHECKS=yes
+      else
+        EXTRA_CHECKS=no
+      fi
+    ])
+
+    if test "x$EXTRA_CHECKS" = "xyes"; then
+        AC_DEFINE(GST_ENABLE_EXTRA_CHECKS, 1, [Define if extra runtime checks should be enabled])
+    fi
+])
diff --git a/common/m4/gst-error.m4 b/common/m4/gst-error.m4
index d6487cc..0067588 100644
--- a/common/m4/gst-error.m4
+++ b/common/m4/gst-error.m4
@@ -52,31 +52,6 @@
   if test "x$1" != "xno"
   then
     AS_COMPILER_FLAG(-Werror, ERROR_CFLAGS="$ERROR_CFLAGS -Werror")
-
-    dnl if -Werror isn't suported, try -errwarn=%all (Sun Forte case)
-    if test "x$ERROR_CFLAGS" = "x"
-    then
-      AS_COMPILER_FLAG([-errwarn=%all], [
-          ERROR_CFLAGS="-errwarn=%all"
-          dnl try -errwarn=%all,no%E_EMPTY_DECLARATION,
-          dnl no%E_STATEMENT_NOT_REACHED,no%E_ARGUEMENT_MISMATCH,
-          dnl no%E_MACRO_REDEFINED (Sun Forte case)
-          dnl For Forte we need disable "empty declaration" warning produced by un-needed semicolon
-          dnl "statement not reached" disabled because there is g_assert_not_reached () in some places
-          dnl "macro redefined" because of gst/gettext.h
-          dnl FIXME: is it really supposed to be 'ARGUEMENT' and not 'ARGUMENT'?
-          for f in 'no%E_EMPTY_DECLARATION' \
-                   'no%E_STATEMENT_NOT_REACHED' \
-                   'no%E_ARGUEMENT_MISMATCH' \
-                   'no%E_MACRO_REDEFINED' \
-                   'no%E_LOOP_NOT_ENTERED_AT_TOP'
-          do
-            AS_COMPILER_FLAG([-errwarn=%all,$f], [
-              ERROR_CFLAGS="$ERROR_CFLAGS,$f"
-            ])
-          done
-      ])
-    fi
   fi
 
   if test "x$2" != "x"
@@ -142,28 +117,6 @@
 	  AS_CXX_COMPILER_FLAG([-fno-strict-aliasing],
 	    ERROR_CXXFLAGS="$ERROR_CXXFLAGS -fno-strict-aliasing")
 	  ])
-    else
-      dnl if -Werror isn't suported, try -errwarn=%all
-      AS_CXX_COMPILER_FLAG([-errwarn=%all], ERROR_CXXFLAGS="$ERROR_CXXFLAGS -errwarn=%all")
-      if test "x$ERROR_CXXFLAGS" != "x"; then
-        dnl try -errwarn=%all,no%E_EMPTY_DECLARATION,
-        dnl no%E_STATEMENT_NOT_REACHED,no%E_ARGUEMENT_MISMATCH,
-        dnl no%E_MACRO_REDEFINED (Sun Forte case)
-        dnl For Forte we need disable "empty declaration" warning produced by un-needed semicolon
-        dnl "statement not reached" disabled because there is g_assert_not_reached () in some places
-        dnl "macro redefined" because of gst/gettext.h
-        dnl FIXME: is it really supposed to be 'ARGUEMENT' and not 'ARGUMENT'?
-        dnl FIXME: do any of these work with the c++ compiler? if not, why
-        dnl do we check at all?
-        for f in 'no%E_EMPTY_DECLARATION' \
-                 'no%E_STATEMENT_NOT_REACHED' \
-                 'no%E_ARGUEMENT_MISMATCH' \
-                 'no%E_MACRO_REDEFINED' \
-                 'no%E_LOOP_NOT_ENTERED_AT_TOP'
-        do
-          AS_CXX_COMPILER_FLAG([-errwarn=%all,$f], [ERROR_CXXFLAGS="$ERROR_CXXFLAGS,$f"])
-        done
-      fi
     fi
   fi
 
@@ -227,28 +180,6 @@
 	  AS_OBJC_COMPILER_FLAG([-fno-strict-aliasing],
 	    ERROR_OBJCFLAGS="$ERROR_OBJCFLAGS -fno-strict-aliasing")
 	  ])
-    else
-      dnl if -Werror isn't suported, try -errwarn=%all
-      AS_OBJC_COMPILER_FLAG([-errwarn=%all], ERROR_OBJCFLAGS="$ERROR_OBJCFLAGS -errwarn=%all")
-      if test "x$ERROR_OBJCFLAGS" != "x"; then
-        dnl try -errwarn=%all,no%E_EMPTY_DECLARATION,
-        dnl no%E_STATEMENT_NOT_REACHED,no%E_ARGUEMENT_MISMATCH,
-        dnl no%E_MACRO_REDEFINED (Sun Forte case)
-        dnl For Forte we need disable "empty declaration" warning produced by un-needed semicolon
-        dnl "statement not reached" disabled because there is g_assert_not_reached () in some places
-        dnl "macro redefined" because of gst/gettext.h
-        dnl FIXME: is it really supposed to be 'ARGUEMENT' and not 'ARGUMENT'?
-        dnl FIXME: do any of these work with the c++ compiler? if not, why
-        dnl do we check at all?
-        for f in 'no%E_EMPTY_DECLARATION' \
-                 'no%E_STATEMENT_NOT_REACHED' \
-                 'no%E_ARGUEMENT_MISMATCH' \
-                 'no%E_MACRO_REDEFINED' \
-                 'no%E_LOOP_NOT_ENTERED_AT_TOP'
-        do
-          AS_OBJC_COMPILER_FLAG([-errwarn=%all,$f], [ERROR_OBJCFLAGS="$ERROR_OBJCFLAGS,$f"])
-        done
-      fi
     fi
   fi
 
diff --git a/common/m4/gst-glib2.m4 b/common/m4/gst-glib2.m4
index 5b9cd8b..5b72507 100644
--- a/common/m4/gst-glib2.m4
+++ b/common/m4/gst-glib2.m4
@@ -51,18 +51,9 @@
   fi
 
   AC_ARG_ENABLE(glib-asserts,
-    AS_HELP_STRING([--enable-glib-asserts[=@<:@no/auto/yes@:>@]],
+    AS_HELP_STRING([--enable-glib-asserts[=@<:@no/yes@:>@]],
       [Enable GLib assertion]),[enable_glib_assertions=$enableval],
-    [enable_glib_assertions=auto])
-
-  if test "x$enable_glib_assertions" = "xauto"; then
-    dnl Enable assertions only for development versions
-    if test "x`expr $PACKAGE_VERSION_MINOR % 2`" = "x1" -a "x`expr $PACKAGE_VERSION_MICRO '<' 90`" = "x1"; then
-      enable_glib_assertions=yes
-    else
-      enable_glib_assertions=no
-    fi
-  fi
+    [enable_glib_assertions=yes])
 
   if test "x$enable_glib_assertions" = "xno"; then
     GLIB_EXTRA_CFLAGS="$GLIB_EXTRA_CFLAGS -DG_DISABLE_ASSERT"
diff --git a/common/m4/gst-package-release-datetime.m4 b/common/m4/gst-package-release-datetime.m4
index bc885e3..4cf44e6 100644
--- a/common/m4/gst-package-release-datetime.m4
+++ b/common/m4/gst-package-release-datetime.m4
@@ -27,14 +27,16 @@
 AC_DEFUN([AG_GST_SET_PACKAGE_RELEASE_DATETIME],
 [
   dnl AG_GST_SET_PACKAGE_RELEASE_DATETIME()
-  dnl AG_GST_SET_PACKAGE_RELEASE_DATETIME([yes]...)
+  dnl AG_GST_SET_PACKAGE_RELEASE_DATETIME([no]...)
   if test "x$1" = "xno" -o "x$1" = "x"; then
     GST_PACKAGE_RELEASE_DATETIME=`date -u "+%Y-%m-%dT%H:%MZ"`
   elif test "x$1" = "xyes"; then
-    dnl AG_GST_SET_PACKAGE_RELEASE_DATETIME([no], ["YYYY-MM-DD"])
-    dnl AG_GST_SET_PACKAGE_RELEASE_DATETIME([no], [DOAP-FILE], [RELEASE-VERSION])
-    if ( echo $1 | grep '^20[1-9][0-9]-[0-1][0-9]-[0-3][0-9]' >/dev/null ) ; then
-      GST_PACKAGE_RELEASE_DATETIME=$1
+    dnl AG_GST_SET_PACKAGE_RELEASE_DATETIME([yes], [YYYY-MM-DD])
+    dnl AG_GST_SET_PACKAGE_RELEASE_DATETIME([yes], [DOAP-FILE], [RELEASE-VERSION])
+changequote(<<, >>)dnl
+    if ( echo $2 | grep '^20[1-9][0-9]-[0-1][0-9]-[0-3][0-9]' >/dev/null ) ; then
+changequote([, ])dnl
+      GST_PACKAGE_RELEASE_DATETIME=$2
     else
       dnl we assume the .doap file contains the date as YYYY-MM-DD
       YYYY_MM_DD=`sh "${srcdir}/common/extract-release-date-from-doap-file" $3 $2`;
@@ -47,7 +49,9 @@
       fi
     fi
   dnl AG_GST_SET_PACKAGE_RELEASE_DATETIME([YYYY-MM-DD])
+changequote(<<, >>)dnl
   elif ( echo $1 | grep '^20[1-9][0-9]-[0-1][0-9]-[0-3][0-9]' >/dev/null ) ; then
+changequote([, ])dnl
     GST_PACKAGE_RELEASE_DATETIME=$1
   else
     AC_MSG_WARN([SET_PACKAGE_RELEASE_DATETIME: invalid first argument])
diff --git a/common/release.mak b/common/release.mak
index 715657b..c84c2f1 100644
--- a/common/release.mak
+++ b/common/release.mak
@@ -14,6 +14,9 @@
 	@if [ -d ../www/data/src ]; then \
 	  mv -v $(PACKAGE)-$(VERSION).tar.xz ../www/data/src/$(PACKAGE)/ ; \
 	  mv -v $(PACKAGE)-$(VERSION).tar.xz.sha256sum ../www/data/src/$(PACKAGE)/ ; \
+	elif [ -d ../../www/data/src ]; then \
+	  mv -v $(PACKAGE)-$(VERSION).tar.xz ../../www/data/src/$(PACKAGE)/ ; \
+	  mv -v $(PACKAGE)-$(VERSION).tar.xz.sha256sum ../../www/data/src/$(PACKAGE)/ ; \
 	fi
 	@echo "================================================================================================="
 
diff --git a/config.h.in b/config.h.in
index 09bdbda..0d626a3 100644
--- a/config.h.in
+++ b/config.h.in
@@ -40,6 +40,9 @@
 /* GStreamer API Version */
 #undef GST_API_VERSION
 
+/* Define if extra runtime checks should be enabled */
+#undef GST_ENABLE_EXTRA_CHECKS
+
 /* Defined if gcov is enabled to force a rebuild due to config.h changing */
 #undef GST_GCOV_ENABLED
 
@@ -61,6 +64,9 @@
 /* Define if static plugins should be built */
 #undef GST_PLUGIN_BUILD_STATIC
 
+/* Define if Video4Linux probe shall be run at plugin load */
+#undef GST_V4L2_ENABLE_PROBE
+
 /* Define to enable aalib ASCII Art library (used by aasink). */
 #undef HAVE_AALIB
 
@@ -341,6 +347,9 @@
 /* Define to enable VPX decoder (used by vpx). */
 #undef HAVE_VPX
 
+/* Defined if the VPX library version is 1.4 or bigger */
+#undef HAVE_VPX_1_4
+
 /* Define to enable Win32 WaveForm (used by waveformsink). */
 #undef HAVE_WAVEFORM
 
diff --git a/configure b/configure
index a592e9c..903c72a 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for GStreamer Good Plug-ins 1.6.2.
+# Generated by GNU Autoconf 2.69 for GStreamer Good Plug-ins 1.7.1.
 #
 # Report bugs to <http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer>.
 #
@@ -591,8 +591,8 @@
 # Identity of this package.
 PACKAGE_NAME='GStreamer Good Plug-ins'
 PACKAGE_TARNAME='gst-plugins-good'
-PACKAGE_VERSION='1.6.2'
-PACKAGE_STRING='GStreamer Good Plug-ins 1.6.2'
+PACKAGE_VERSION='1.7.1'
+PACKAGE_STRING='GStreamer Good Plug-ins 1.7.1'
 PACKAGE_BUGREPORT='http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer'
 PACKAGE_URL=''
 
@@ -661,6 +661,8 @@
 WAVPACK_CFLAGS
 USE_VPX_FALSE
 USE_VPX_TRUE
+VPX_140_LIBS
+VPX_140_CFLAGS
 VPX_130_LIBS
 VPX_130_CFLAGS
 VPX_LIBS
@@ -1207,6 +1209,7 @@
 with_libiconv_prefix
 with_libintl_prefix
 enable_fatal_warnings
+enable_extra_check
 enable_debug
 enable_profiling
 enable_valgrind
@@ -1225,6 +1228,7 @@
 enable_gobject_cast_checks
 enable_glib_asserts
 enable_orc
+enable_Bsymbolic
 enable_static_plugins
 with_default_audiosink
 with_default_audiosrc
@@ -1284,6 +1288,7 @@
 enable_gst_v4l2
 with_gudev
 with_libv4l2
+enable_v4l2_probe
 enable_x
 enable_aalib
 with_aalib_prefix
@@ -1402,6 +1407,8 @@
 VPX_LIBS
 VPX_130_CFLAGS
 VPX_130_LIBS
+VPX_140_CFLAGS
+VPX_140_LIBS
 WAVPACK_CFLAGS
 WAVPACK_LIBS'
 
@@ -1954,7 +1961,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures GStreamer Good Plug-ins 1.6.2 to adapt to many kinds of systems.
+\`configure' configures GStreamer Good Plug-ins 1.7.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -2027,7 +2034,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of GStreamer Good Plug-ins 1.6.2:";;
+     short | recursive ) echo "Configuration of GStreamer Good Plug-ins 1.7.1:";;
    esac
   cat <<\_ACEOF
 
@@ -2053,6 +2060,7 @@
   --disable-rpath         do not hardcode runtime library paths
   --disable-fatal-warnings
                           Don't turn compiler warnings into fatal errors
+  --enable-extra-checks   Enable extra runtime checks
   --disable-debug         disable addition of -g debugging info
   --enable-profiling      adds -pg to compiler commandline, for profiling
   --disable-valgrind      disable run-time valgrind detection
@@ -2066,9 +2074,10 @@
   --enable-gtk-doc-pdf    build documentation in pdf format [[default=no]]
   --enable-gobject-cast-checks=[no/auto/yes]
                           Enable GObject cast checks
-  --enable-glib-asserts=[no/auto/yes]
+  --enable-glib-asserts=[no/yes]
                           Enable GLib assertion
   --enable-orc            use Orc if installed
+  --disable-Bsymbolic     avoid linking with -Bsymbolic
   --enable-static-plugins build static plugins [default=no]
   --disable-alpha         disable dependency-less alpha plugin
   --disable-apetag        disable dependency-less apetag plugin
@@ -2121,6 +2130,7 @@
   --disable-osx_audio          disable OSX audio: osxaudio
   --disable-osx_video          disable OSX video: osxvideosink
   --disable-gst_v4l2           disable Video 4 Linux 2: video4linux2
+  --enable-v4l2-probe     enable V4L2 plugin to probe devices [default=no]
   --disable-x                  disable X libraries and plugins: ximagesrc
   --disable-aalib              disable aalib ASCII Art library: aasink
   --disable-aalibtest     do not try to compile and run a test AALIB program
@@ -2320,6 +2330,10 @@
               C compiler flags for VPX_130, overriding pkg-config
   VPX_130_LIBS
               linker flags for VPX_130, overriding pkg-config
+  VPX_140_CFLAGS
+              C compiler flags for VPX_140, overriding pkg-config
+  VPX_140_LIBS
+              linker flags for VPX_140, overriding pkg-config
   WAVPACK_CFLAGS
               C compiler flags for WAVPACK, overriding pkg-config
   WAVPACK_LIBS
@@ -2391,7 +2405,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-GStreamer Good Plug-ins configure 1.6.2
+GStreamer Good Plug-ins configure 1.7.1
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -3202,7 +3216,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by GStreamer Good Plug-ins $as_me 1.6.2, which was
+It was created by GStreamer Good Plug-ins $as_me 1.7.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -4184,7 +4198,7 @@
 
 # Define the identity of the package.
  PACKAGE='gst-plugins-good'
- VERSION='1.6.2'
+ VERSION='1.7.1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -4395,9 +4409,9 @@
 
 
 
-  PACKAGE_VERSION_MAJOR=$(echo 1.6.2 | cut -d'.' -f1)
-  PACKAGE_VERSION_MINOR=$(echo 1.6.2 | cut -d'.' -f2)
-  PACKAGE_VERSION_MICRO=$(echo 1.6.2 | cut -d'.' -f3)
+  PACKAGE_VERSION_MAJOR=$(echo 1.7.1 | cut -d'.' -f1)
+  PACKAGE_VERSION_MINOR=$(echo 1.7.1 | cut -d'.' -f2)
+  PACKAGE_VERSION_MICRO=$(echo 1.7.1 | cut -d'.' -f3)
 
 
 
@@ -4408,7 +4422,7 @@
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking nano version" >&5
 $as_echo_n "checking nano version... " >&6; }
 
-  NANO=$(echo 1.6.2 | cut -d'.' -f4)
+  NANO=$(echo 1.7.1 | cut -d'.' -f4)
 
   if test x"$NANO" = x || test "x$NANO" = "x0" ; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: 0 (release)" >&5
@@ -9064,10 +9078,10 @@
 done
 
 
-  GST_CURRENT=602
+  GST_CURRENT=701
   GST_REVISION=0
-  GST_AGE=602
-  GST_LIBVERSION=602:0:602
+  GST_AGE=701
+  GST_LIBVERSION=701:0:701
 
 
 
@@ -13392,8 +13406,8 @@
 
 
 
-GST_REQ=1.6.2
-GSTPB_REQ=1.6.2
+GST_REQ=1.7.1
+GSTPB_REQ=1.7.1
 
 
 
@@ -15445,6 +15459,33 @@
 
 
 
+  # Check whether --enable-extra-check was given.
+if test "${enable_extra_check+set}" = set; then :
+  enableval=$enable_extra_check;
+      case "${enableval}" in
+        yes) EXTRA_CHECKS=yes ;;
+        no)  EXTRA_CHECKS=no ;;
+        *)   as_fn_error $? "bad value ${enableval} for --enable-extra-checks" "$LINENO" 5 ;;
+      esac
+
+else
+
+      if test "x`expr $PACKAGE_VERSION_MINOR % 2`" = "x1" -a "x`expr $PACKAGE_VERSION_MICRO '<' 90`" = "x1"; then
+        EXTRA_CHECKS=yes
+      else
+        EXTRA_CHECKS=no
+      fi
+
+fi
+
+
+    if test "x$EXTRA_CHECKS" = "xyes"; then
+
+$as_echo "#define GST_ENABLE_EXTRA_CHECKS 1" >>confdefs.h
+
+    fi
+
+
 
     # Check whether --enable-debug was given.
 if test "${enable_debug+set}" = set; then :
@@ -24068,7 +24109,7 @@
 
 
 
-GLIB_REQ=2.32.0
+GLIB_REQ=2.40.0
 
 
 
@@ -24209,18 +24250,10 @@
 if test "${enable_glib_asserts+set}" = set; then :
   enableval=$enable_glib_asserts; enable_glib_assertions=$enableval
 else
-  enable_glib_assertions=auto
+  enable_glib_assertions=yes
 fi
 
 
-  if test "x$enable_glib_assertions" = "xauto"; then
-        if test "x`expr $PACKAGE_VERSION_MINOR % 2`" = "x1" -a "x`expr $PACKAGE_VERSION_MICRO '<' 90`" = "x1"; then
-      enable_glib_assertions=yes
-    else
-      enable_glib_assertions=no
-    fi
-  fi
-
   if test "x$enable_glib_assertions" = "xno"; then
     GLIB_EXTRA_CFLAGS="$GLIB_EXTRA_CFLAGS -DG_DISABLE_ASSERT"
   fi
@@ -25418,6 +25451,41 @@
 fi
 
 
+# Check whether --enable-Bsymbolic was given.
+if test "${enable_Bsymbolic+set}" = set; then :
+  enableval=$enable_Bsymbolic;
+else
+  SAVED_LDFLAGS="${LDFLAGS}" SAVED_LIBS="${LIBS}"
+               { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Bsymbolic-functions linker flag" >&5
+$as_echo_n "checking for -Bsymbolic-functions linker flag... " >&6; }
+               LDFLAGS=-Wl,-Bsymbolic-functions
+               LIBS=
+               cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+return 0
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+                           enable_Bsymbolic=yes
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+                           enable_Bsymbolic=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+               LDFLAGS="${SAVED_LDFLAGS}" LIBS="${SAVED_LIBS}"
+fi
+
+
 
 GST_LICENSE="LGPL"
 
@@ -25474,8 +25542,8 @@
       if test "xyes" = "xno" -o "xyes" = "x"; then
     GST_PACKAGE_RELEASE_DATETIME=`date -u "+%Y-%m-%dT%H:%MZ"`
   elif test "xyes" = "xyes"; then
-            if ( echo yes | grep '^201-90-9-0-10-9-0-30-9' >/dev/null ) ; then
-      GST_PACKAGE_RELEASE_DATETIME=yes
+            if ( echo  "${srcdir}/gst-plugins-good.doap"  | grep '^20[1-9][0-9]-[0-1][0-9]-[0-3][0-9]' >/dev/null ) ; then
+      GST_PACKAGE_RELEASE_DATETIME= "${srcdir}/gst-plugins-good.doap"
     else
             YYYY_MM_DD=`sh "${srcdir}/common/extract-release-date-from-doap-file"  $PACKAGE_VERSION_MAJOR.$PACKAGE_VERSION_MINOR.$PACKAGE_VERSION_MICRO   "${srcdir}/gst-plugins-good.doap" `;
       if test "x$YYYY_MM_DD" != "x"; then
@@ -25486,7 +25554,7 @@
         GST_PACKAGE_RELEASE_DATETIME=""
       fi
     fi
-    elif ( echo yes | grep '^201-90-9-0-10-9-0-30-9' >/dev/null ) ; then
+    elif ( echo yes | grep '^20[1-9][0-9]-[0-1][0-9]-[0-3][0-9]' >/dev/null ) ; then
     GST_PACKAGE_RELEASE_DATETIME=yes
   else
     { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: SET_PACKAGE_RELEASE_DATETIME: invalid first argument" >&5
@@ -25513,8 +25581,8 @@
       if test "xno" = "xno" -o "xno" = "x"; then
     GST_PACKAGE_RELEASE_DATETIME=`date -u "+%Y-%m-%dT%H:%MZ"`
   elif test "xno" = "xyes"; then
-            if ( echo no | grep '^201-90-9-0-10-9-0-30-9' >/dev/null ) ; then
-      GST_PACKAGE_RELEASE_DATETIME=no
+            if ( echo  | grep '^20[1-9][0-9]-[0-1][0-9]-[0-3][0-9]' >/dev/null ) ; then
+      GST_PACKAGE_RELEASE_DATETIME=
     else
             YYYY_MM_DD=`sh "${srcdir}/common/extract-release-date-from-doap-file"  `;
       if test "x$YYYY_MM_DD" != "x"; then
@@ -25525,7 +25593,7 @@
         GST_PACKAGE_RELEASE_DATETIME=""
       fi
     fi
-    elif ( echo no | grep '^201-90-9-0-10-9-0-30-9' >/dev/null ) ; then
+    elif ( echo no | grep '^20[1-9][0-9]-[0-1][0-9]-[0-3][0-9]' >/dev/null ) ; then
     GST_PACKAGE_RELEASE_DATETIME=no
   else
     { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: SET_PACKAGE_RELEASE_DATETIME: invalid first argument" >&5
@@ -25829,93 +25897,6 @@
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5
 $as_echo "$flag_ok" >&6; }
 
-
-        if test "x$ERROR_CFLAGS" = "x"
-    then
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -errwarn=%all" >&5
-$as_echo_n "checking to see if compiler understands -errwarn=%all... " >&6; }
-
-  save_CFLAGS="$CFLAGS"
-  CFLAGS="$CFLAGS -errwarn=%all"
-
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  flag_ok=yes
-else
-  flag_ok=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  CFLAGS="$save_CFLAGS"
-
-  if test "X$flag_ok" = Xyes ; then
-
-          ERROR_CFLAGS="-errwarn=%all"
-                                                                                for f in 'no%E_EMPTY_DECLARATION' \
-                   'no%E_STATEMENT_NOT_REACHED' \
-                   'no%E_ARGUEMENT_MISMATCH' \
-                   'no%E_MACRO_REDEFINED' \
-                   'no%E_LOOP_NOT_ENTERED_AT_TOP'
-          do
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands -errwarn=%all,$f" >&5
-$as_echo_n "checking to see if compiler understands -errwarn=%all,$f... " >&6; }
-
-  save_CFLAGS="$CFLAGS"
-  CFLAGS="$CFLAGS -errwarn=%all,$f"
-
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  flag_ok=yes
-else
-  flag_ok=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  CFLAGS="$save_CFLAGS"
-
-  if test "X$flag_ok" = Xyes ; then
-
-              ERROR_CFLAGS="$ERROR_CFLAGS,$f"
-
-    true
-  else
-
-    true
-  fi
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5
-$as_echo "$flag_ok" >&6; }
-
-          done
-
-    true
-  else
-
-    true
-  fi
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5
-$as_echo "$flag_ok" >&6; }
-
-    fi
   fi
 
   if test "x
@@ -26271,122 +26252,6 @@
 
 
 fi
-    else
-
-
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if c++ compiler understands -errwarn=%all" >&5
-$as_echo_n "checking to see if c++ compiler understands -errwarn=%all... " >&6; }
-
-  save_CPPFLAGS="$CPPFLAGS"
-  CPPFLAGS="$CPPFLAGS -errwarn=%all"
-
-  ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-  flag_ok=yes
-else
-  flag_ok=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  CPPFLAGS="$save_CPPFLAGS"
-
-  if test "X$flag_ok" = Xyes ; then
-    ERROR_CXXFLAGS="$ERROR_CXXFLAGS -errwarn=%all"
-    true
-  else
-
-    true
-  fi
-
-  ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5
-$as_echo "$flag_ok" >&6; }
-
-      if test "x$ERROR_CXXFLAGS" != "x"; then
-                                                                                for f in 'no%E_EMPTY_DECLARATION' \
-                 'no%E_STATEMENT_NOT_REACHED' \
-                 'no%E_ARGUEMENT_MISMATCH' \
-                 'no%E_MACRO_REDEFINED' \
-                 'no%E_LOOP_NOT_ENTERED_AT_TOP'
-        do
-
-
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if c++ compiler understands -errwarn=%all,$f" >&5
-$as_echo_n "checking to see if c++ compiler understands -errwarn=%all,$f... " >&6; }
-
-  save_CPPFLAGS="$CPPFLAGS"
-  CPPFLAGS="$CPPFLAGS -errwarn=%all,$f"
-
-  ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-  flag_ok=yes
-else
-  flag_ok=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  CPPFLAGS="$save_CPPFLAGS"
-
-  if test "X$flag_ok" = Xyes ; then
-    ERROR_CXXFLAGS="$ERROR_CXXFLAGS,$f"
-    true
-  else
-
-    true
-  fi
-
-  ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5
-$as_echo "$flag_ok" >&6; }
-
-        done
-      fi
     fi
   fi
 
@@ -26707,122 +26572,6 @@
 
 
 fi
-    else
-
-
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if Objective C compiler understands -errwarn=%all" >&5
-$as_echo_n "checking to see if Objective C compiler understands -errwarn=%all... " >&6; }
-
-  save_CPPFLAGS="$CPPFLAGS"
-  CPPFLAGS="$CPPFLAGS -errwarn=%all"
-
-  ac_ext=m
-ac_cpp='$OBJCPP $CPPFLAGS'
-ac_compile='$OBJC -c $OBJCFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$OBJC -o conftest$ac_exeext $OBJCFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_objc_compiler_gnu
-
-
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_objc_try_compile "$LINENO"; then :
-  flag_ok=yes
-else
-  flag_ok=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  CPPFLAGS="$save_CPPFLAGS"
-
-  if test "X$flag_ok" = Xyes ; then
-    ERROR_OBJCFLAGS="$ERROR_OBJCFLAGS -errwarn=%all"
-    true
-  else
-
-    true
-  fi
-
-  ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5
-$as_echo "$flag_ok" >&6; }
-
-      if test "x$ERROR_OBJCFLAGS" != "x"; then
-                                                                                for f in 'no%E_EMPTY_DECLARATION' \
-                 'no%E_STATEMENT_NOT_REACHED' \
-                 'no%E_ARGUEMENT_MISMATCH' \
-                 'no%E_MACRO_REDEFINED' \
-                 'no%E_LOOP_NOT_ENTERED_AT_TOP'
-        do
-
-
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if Objective C compiler understands -errwarn=%all,$f" >&5
-$as_echo_n "checking to see if Objective C compiler understands -errwarn=%all,$f... " >&6; }
-
-  save_CPPFLAGS="$CPPFLAGS"
-  CPPFLAGS="$CPPFLAGS -errwarn=%all,$f"
-
-  ac_ext=m
-ac_cpp='$OBJCPP $CPPFLAGS'
-ac_compile='$OBJC -c $OBJCFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$OBJC -o conftest$ac_exeext $OBJCFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_objc_compiler_gnu
-
-
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_objc_try_compile "$LINENO"; then :
-  flag_ok=yes
-else
-  flag_ok=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  CPPFLAGS="$save_CPPFLAGS"
-
-  if test "X$flag_ok" = Xyes ; then
-    ERROR_OBJCFLAGS="$ERROR_OBJCFLAGS,$f"
-    true
-  else
-
-    true
-  fi
-
-  ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5
-$as_echo "$flag_ok" >&6; }
-
-        done
-      fi
     fi
   fi
 
@@ -30048,6 +29797,17 @@
   fi
 fi
 
+# Check whether --enable-v4l2-probe was given.
+if test "${enable_v4l2_probe+set}" = set; then :
+  enableval=$enable_v4l2_probe;
+fi
+
+if test "x$enable_v4l2_probe" = xyes; then
+
+$as_echo "#define GST_V4L2_ENABLE_PROBE 1" >>confdefs.h
+
+fi
+
 echo
 { $as_echo "$as_me:${as_lineno-$LINENO}: *** checking feature: X libraries and plugins ***" >&5
 $as_echo "$as_me: *** checking feature: X libraries and plugins ***" >&6;}
@@ -33587,12 +33347,12 @@
         pkg_cv_SOUP_CFLAGS="$SOUP_CFLAGS"
     else
         if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsoup-2.4 >= 2.40\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "libsoup-2.4 >= 2.40") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsoup-2.4 >= 2.48\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libsoup-2.4 >= 2.48") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_SOUP_CFLAGS=`$PKG_CONFIG --cflags "libsoup-2.4 >= 2.40" 2>/dev/null`
+  pkg_cv_SOUP_CFLAGS=`$PKG_CONFIG --cflags "libsoup-2.4 >= 2.48" 2>/dev/null`
 else
   pkg_failed=yes
 fi
@@ -33605,12 +33365,12 @@
         pkg_cv_SOUP_LIBS="$SOUP_LIBS"
     else
         if test -n "$PKG_CONFIG" && \
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsoup-2.4 >= 2.40\""; } >&5
-  ($PKG_CONFIG --exists --print-errors "libsoup-2.4 >= 2.40") 2>&5
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsoup-2.4 >= 2.48\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libsoup-2.4 >= 2.48") 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
-  pkg_cv_SOUP_LIBS=`$PKG_CONFIG --libs "libsoup-2.4 >= 2.40" 2>/dev/null`
+  pkg_cv_SOUP_LIBS=`$PKG_CONFIG --libs "libsoup-2.4 >= 2.48" 2>/dev/null`
 else
   pkg_failed=yes
 fi
@@ -33629,9 +33389,9 @@
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        SOUP_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "libsoup-2.4 >= 2.40"`
+	        SOUP_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "libsoup-2.4 >= 2.48"`
         else
-	        SOUP_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libsoup-2.4 >= 2.40"`
+	        SOUP_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libsoup-2.4 >= 2.48"`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$SOUP_PKG_ERRORS" >&5
@@ -34500,6 +34260,83 @@
 
 
 fi
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for VPX_140" >&5
+$as_echo_n "checking for VPX_140... " >&6; }
+
+if test -n "$PKG_CONFIG"; then
+    if test -n "$VPX_140_CFLAGS"; then
+        pkg_cv_VPX_140_CFLAGS="$VPX_140_CFLAGS"
+    else
+        if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"vpx >= 1.4.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "vpx >= 1.4.0") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_VPX_140_CFLAGS=`$PKG_CONFIG --cflags "vpx >= 1.4.0" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+    fi
+else
+	pkg_failed=untried
+fi
+if test -n "$PKG_CONFIG"; then
+    if test -n "$VPX_140_LIBS"; then
+        pkg_cv_VPX_140_LIBS="$VPX_140_LIBS"
+    else
+        if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"vpx >= 1.4.0\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "vpx >= 1.4.0") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_VPX_140_LIBS=`$PKG_CONFIG --libs "vpx >= 1.4.0" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+    fi
+else
+	pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        VPX_140_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "vpx >= 1.4.0"`
+        else
+	        VPX_140_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "vpx >= 1.4.0"`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$VPX_140_PKG_ERRORS" >&5
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+                true
+elif test $pkg_failed = untried; then
+	true
+else
+	VPX_140_CFLAGS=$pkg_cv_VPX_140_CFLAGS
+	VPX_140_LIBS=$pkg_cv_VPX_140_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+
+$as_echo "#define HAVE_VPX_1_4 1" >>confdefs.h
+
+
+fi
+
     LIBS="$OLD_LIBS"
     CFLAGS="$OLD_CFLAGS"
   fi
@@ -35258,6 +35095,9 @@
 
 
 GST_ALL_LDFLAGS="-no-undefined"
+if test "x${enable_Bsymbolic}" = "xyes"; then
+  GST_ALL_LDFLAGS="$GST_ALL_LDFLAGS -Wl,-Bsymbolic-functions"
+fi
 
 
 GST_PLUGIN_LDFLAGS="-module -avoid-version -export-symbols-regex '^_*gst_plugin_.*' $GST_ALL_LDFLAGS"
@@ -36407,7 +36247,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by GStreamer Good Plug-ins $as_me 1.6.2, which was
+This file was extended by GStreamer Good Plug-ins $as_me 1.7.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -36473,7 +36313,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-GStreamer Good Plug-ins config.status 1.6.2
+GStreamer Good Plug-ins config.status 1.7.1
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 4f893c9..5c10e73 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,7 +5,7 @@
 dnl initialize autoconf
 dnl releases only do -Wall, git and prerelease does -Werror too
 dnl use a three digit version number for releases, and four for git/pre
-AC_INIT([GStreamer Good Plug-ins],[1.6.2],[http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer],[gst-plugins-good])
+AC_INIT([GStreamer Good Plug-ins],[1.7.1],[http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer],[gst-plugins-good])
 
 AG_GST_INIT
 
@@ -43,11 +43,11 @@
   [GStreamer API Version])
 
 AG_GST_LIBTOOL_PREPARE
-AS_LIBTOOL(GST, 602, 0, 602)
+AS_LIBTOOL(GST, 701, 0, 701)
 
 dnl *** required versions of GStreamer stuff ***
-GST_REQ=1.6.2
-GSTPB_REQ=1.6.2
+GST_REQ=1.7.1
+GSTPB_REQ=1.7.1
 
 dnl *** autotools stuff ****
 
@@ -66,6 +66,7 @@
 dnl *** check for arguments to configure ***
 
 AG_GST_ARG_DISABLE_FATAL_WARNINGS
+AG_GST_ARG_ENABLE_EXTRA_CHECKS
 
 AG_GST_ARG_DEBUG
 AG_GST_ARG_PROFILING
@@ -203,7 +204,7 @@
 
 
 dnl GLib
-GLIB_REQ=2.32.0
+GLIB_REQ=2.40.0
 AG_GST_GLIB_CHECK([$GLIB_REQ])
 
 dnl Orc
@@ -250,6 +251,21 @@
 AM_CONDITIONAL(HAVE_GTK, test "x$HAVE_GTK" = "xyes")
 AM_CONDITIONAL(HAVE_GTK_X11, test "x$HAVE_GTK_X11" = "xyes")
 
+dnl Check for -Bsymbolic-functions linker flag used to avoid
+dnl intra-library PLT jumps, if available.
+AC_ARG_ENABLE(Bsymbolic,
+              [AS_HELP_STRING([--disable-Bsymbolic],[avoid linking with -Bsymbolic])],,
+              [SAVED_LDFLAGS="${LDFLAGS}" SAVED_LIBS="${LIBS}"
+               AC_MSG_CHECKING([for -Bsymbolic-functions linker flag])
+               LDFLAGS=-Wl,-Bsymbolic-functions
+               LIBS=
+               AC_TRY_LINK([], [return 0],
+                           AC_MSG_RESULT(yes)
+                           enable_Bsymbolic=yes,
+                           AC_MSG_RESULT(no)
+                           enable_Bsymbolic=no)
+               LDFLAGS="${SAVED_LDFLAGS}" LIBS="${SAVED_LIBS}"])
+
 dnl *** set variables based on configure arguments ***
 
 dnl set license and copyright notice
@@ -554,6 +570,17 @@
   fi
 fi
 
+dnl Allow enabling v4l2 device probing
+AC_ARG_ENABLE(
+  v4l2-probe,
+  AC_HELP_STRING(
+    [--enable-v4l2-probe],
+    [enable V4L2 plugin to probe devices @<:@default=no@:>@]))
+if test "x$enable_v4l2_probe" = xyes; then
+  AC_DEFINE(GST_V4L2_ENABLE_PROBE, 1,
+    [Define if Video4Linux probe shall be run at plugin load])
+fi
+
 dnl Check for X11
 translit(dnm, m, l) AM_CONDITIONAL(USE_X, true)
 AG_GST_CHECK_FEATURE(X, [X libraries and plugins],
@@ -742,7 +769,7 @@
 dnl *** soup ***
 translit(dnm, m, l) AM_CONDITIONAL(USE_SOUP, true)
 AG_GST_CHECK_FEATURE(SOUP, [soup http client plugin (2.4)], souphttpsrc, [
-  PKG_CHECK_MODULES(SOUP, libsoup-2.4 >= 2.40, [HAVE_SOUP="yes"], [HAVE_SOUP="no"])
+  PKG_CHECK_MODULES(SOUP, libsoup-2.4 >= 2.48, [HAVE_SOUP="yes"], [HAVE_SOUP="no"])
   AC_SUBST(SOUP_CFLAGS)
   AC_SUBST(SOUP_LIBS)
 ])
@@ -802,6 +829,11 @@
         AC_DEFINE(HAVE_VP9_DECODER, 1, [Defined if the VP9 decoder is available])
       ])
     ], [true])
+
+    PKG_CHECK_MODULES(VPX_140, vpx >= 1.4.0, [
+      AC_DEFINE(HAVE_VPX_1_4, 1, [Defined if the VPX library version is 1.4 or bigger])
+    ], [true])
+
     LIBS="$OLD_LIBS"
     CFLAGS="$OLD_CFLAGS"
   fi
@@ -928,6 +960,9 @@
 dnl LDFLAGS really should only contain flags, not libs - they get added before
 dnl whatevertarget_LIBS and -L flags here affect the rest of the linking
 GST_ALL_LDFLAGS="-no-undefined"
+if test "x${enable_Bsymbolic}" = "xyes"; then
+  GST_ALL_LDFLAGS="$GST_ALL_LDFLAGS -Wl,-Bsymbolic-functions"
+fi
 AC_SUBST(GST_ALL_LDFLAGS)
 
 dnl this really should only contain flags, not libs - they get added before
diff --git a/docs/Makefile.in b/docs/Makefile.in
index 9d8ea80..c181621 100644
--- a/docs/Makefile.in
+++ b/docs/Makefile.in
@@ -449,6 +449,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/docs/plugins/Makefile.in b/docs/plugins/Makefile.in
index 4e0c8b9..2a881a4 100644
--- a/docs/plugins/Makefile.in
+++ b/docs/plugins/Makefile.in
@@ -409,6 +409,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/docs/plugins/gst-plugins-good-plugins.args b/docs/plugins/gst-plugins-good-plugins.args
index 7959c85..bfd30ad 100644
--- a/docs/plugins/gst-plugins-good-plugins.args
+++ b/docs/plugins/gst-plugins-good-plugins.args
@@ -609,6 +609,16 @@
 </ARG>
 
 <ARG>
+<NAME>GstUDPSrc::loop</NAME>
+<TYPE>gboolean</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Multicast Loopback</NICK>
+<BLURB>Used for setting the multicast loop parameter. TRUE = enable, FALSE = disable.</BLURB>
+<DEFAULT>TRUE</DEFAULT>
+</ARG>
+
+<ARG>
 <NAME>GstSMPTE::border</NAME>
 <TYPE>gint</TYPE>
 <RANGE>>= 0</RANGE>
@@ -995,7 +1005,17 @@
 <FLAGS>rw</FLAGS>
 <NICK>User Agent</NICK>
 <BLURB>The User-Agent string to send to the server.</BLURB>
-<DEFAULT>"GStreamer/1.6.2"</DEFAULT>
+<DEFAULT>"GStreamer/1.7.1"</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstRTSPSrc::max-rtcp-rtp-time-diff</NAME>
+<TYPE>gint</TYPE>
+<RANGE>>= G_MAXULONG</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Max RTCP RTP Time Diff</NICK>
+<BLURB>Maximum amount of time in ms that the RTP time in RTCP SRs is allowed to be ahead (-1 disabled).</BLURB>
+<DEFAULT>1000</DEFAULT>
 </ARG>
 
 <ARG>
@@ -3569,6 +3589,16 @@
 </ARG>
 
 <ARG>
+<NAME>GstSoupHTTPSrc::tls-interaction</NAME>
+<TYPE>GTlsInteraction*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>TLS interaction</NICK>
+<BLURB>A GTlsInteraction object to be used when the connection or certificate database need to interact with the user.</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
 <NAME>GstRTPDVPay::mode</NAME>
 <TYPE>GstDVPayMode</TYPE>
 <RANGE></RANGE>
@@ -3590,11 +3620,11 @@
 
 <ARG>
 <NAME>GstRtpH264Pay::config-interval</NAME>
-<TYPE>guint</TYPE>
-<RANGE><= 3600</RANGE>
+<TYPE>gint</TYPE>
+<RANGE>[G_MAXULONG,3600]</RANGE>
 <FLAGS>rw</FLAGS>
 <NICK>SPS PPS Send Interval</NICK>
-<BLURB>Send SPS and PPS Insertion Interval in seconds (sprop parameter sets will be multiplexed in the data stream when detected.) (0 = disabled).</BLURB>
+<BLURB>Send SPS and PPS Insertion Interval in seconds (sprop parameter sets will be multiplexed in the data stream when detected.) (0 = disabled, -1 = send with every IDR frame).</BLURB>
 <DEFAULT>0</DEFAULT>
 </ARG>
 
@@ -20449,6 +20479,46 @@
 </ARG>
 
 <ARG>
+<NAME>GstRtpBin::max-dropout-time</NAME>
+<TYPE>guint</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Max dropout time</NICK>
+<BLURB>The maximum time (milliseconds) of missing packets tolerated.</BLURB>
+<DEFAULT>60000</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstRtpBin::max-misorder-time</NAME>
+<TYPE>guint</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Max misorder time</NICK>
+<BLURB>The maximum time (milliseconds) of misordered packets tolerated.</BLURB>
+<DEFAULT>2000</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstRtpBin::max-rtcp-rtp-time-diff</NAME>
+<TYPE>gint</TYPE>
+<RANGE>>= G_MAXULONG</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Max RTCP RTP Time Diff</NICK>
+<BLURB>Maximum amount of time in ms that the RTP time in RTCP SRs is allowed to be ahead (-1 disabled).</BLURB>
+<DEFAULT>1000</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstRtpBin::rtcp-sync-send-time</NAME>
+<TYPE>gboolean</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>RTCP Sync Send Time</NICK>
+<BLURB>Use send time or capture time for RTCP sync (TRUE = send time, FALSE = capture time).</BLURB>
+<DEFAULT>TRUE</DEFAULT>
+</ARG>
+
+<ARG>
 <NAME>GstRtpJitterBuffer::do-lost</NAME>
 <TYPE>gboolean</TYPE>
 <RANGE></RANGE>
@@ -20609,6 +20679,36 @@
 </ARG>
 
 <ARG>
+<NAME>GstRtpJitterBuffer::max-dropout-time</NAME>
+<TYPE>guint</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Max dropout time</NICK>
+<BLURB>The maximum time (milliseconds) of missing packets tolerated.</BLURB>
+<DEFAULT>60000</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstRtpJitterBuffer::max-misorder-time</NAME>
+<TYPE>guint</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Max misorder time</NICK>
+<BLURB>The maximum time (milliseconds) of misordered packets tolerated.</BLURB>
+<DEFAULT>2000</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstRtpJitterBuffer::max-rtcp-rtp-time-diff</NAME>
+<TYPE>gint</TYPE>
+<RANGE>>= G_MAXULONG</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Max RTCP RTP Time Diff</NICK>
+<BLURB>Maximum amount of time in ms that the RTP time in RTCP SRs is allowed to be ahead (-1 disabled).</BLURB>
+<DEFAULT>1000</DEFAULT>
+</ARG>
+
+<ARG>
 <NAME>GstRtpSession::bandwidth</NAME>
 <TYPE>gdouble</TYPE>
 <RANGE>>= 0</RANGE>
@@ -20749,6 +20849,36 @@
 </ARG>
 
 <ARG>
+<NAME>GstRtpSession::max-dropout-time</NAME>
+<TYPE>guint</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Max dropout time</NICK>
+<BLURB>The maximum time (milliseconds) of missing packets tolerated.</BLURB>
+<DEFAULT>60000</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstRtpSession::max-misorder-time</NAME>
+<TYPE>guint</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Max misorder time</NICK>
+<BLURB>The maximum time (milliseconds) of misordered packets tolerated.</BLURB>
+<DEFAULT>2000</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstRtpSession::rtcp-sync-send-time</NAME>
+<TYPE>gboolean</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>RTCP Sync Send Time</NICK>
+<BLURB>Use send time or capture time for RTCP sync (TRUE = send time, FALSE = capture time).</BLURB>
+<DEFAULT>TRUE</DEFAULT>
+</ARG>
+
+<ARG>
 <NAME>GstRtpRtxSend::max-size-time</NAME>
 <TYPE>guint</TYPE>
 <RANGE></RANGE>
@@ -22169,6 +22299,26 @@
 </ARG>
 
 <ARG>
+<NAME>GstSoupHttpClientSink::retries</NAME>
+<TYPE>gint</TYPE>
+<RANGE>>= G_MAXULONG</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Retries</NICK>
+<BLURB>Maximum number of retries, zero to disable, -1 to retry forever.</BLURB>
+<DEFAULT>0</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstSoupHttpClientSink::retry-delay</NAME>
+<TYPE>gint</TYPE>
+<RANGE>>= 1</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Retry Delay</NICK>
+<BLURB>Delay in seconds between retries after a failure.</BLURB>
+<DEFAULT>5</DEFAULT>
+</ARG>
+
+<ARG>
 <NAME>GstWavParse::ignore-length</NAME>
 <TYPE>gboolean</TYPE>
 <RANGE></RANGE>
@@ -22854,7 +23004,7 @@
 <RANGE></RANGE>
 <FLAGS>rw</FLAGS>
 <NICK>SSRC</NICK>
-<BLURB>The SSRC of the packets (-1 == random).</BLURB>
+<BLURB>The SSRC of the packets (default == random).</BLURB>
 <DEFAULT>4294967295</DEFAULT>
 </ARG>
 
diff --git a/docs/plugins/gst-plugins-good-plugins.hierarchy b/docs/plugins/gst-plugins-good-plugins.hierarchy
index 7f4bd0f..a472847 100644
--- a/docs/plugins/gst-plugins-good-plugins.hierarchy
+++ b/docs/plugins/gst-plugins-good-plugins.hierarchy
@@ -33,9 +33,8 @@
           GstMuLawEnc
           GstSpeexEnc
           GstWavpackEnc
-        GstAudioVisualizer-ExtGoom
+        GstAudioVisualizer-BaseExtLibvisual
           GstGoom
-        GstAudioVisualizer-ExtGoom2k1
           GstGoom2k1
         GstAviDemux
         GstAviMux
@@ -288,13 +287,15 @@
         GstVideoDecoder
           GstJpegDec
           GstPngDec
-          GstVP8Dec
-          GstVP9Dec
+          GstVPXDec
+            GstVP8Dec
+            GstVP9Dec
         GstVideoEncoder
           GstJpegEnc
           GstPngEnc
-          GstVP8Enc
-          GstVP9Enc
+          GstVPXEnc
+            GstVP8Enc
+            GstVP9Enc
           GstY4mEncode
         GstVideoMixer2
         GstWavEnc
@@ -307,6 +308,7 @@
       GstPluginFeature
         GstDeviceProviderFactory
         GstElementFactory
+        GstTracerFactory
         GstTypeFindFactory
       GstRegistry
       GstTask
@@ -314,8 +316,6 @@
   GSocket
   GTlsDatabase
   GTlsInteraction
-  GUdevClient
-  GUdevDevice
   GdkPixbuf
   GstColorBalanceChannel
   GstTunerChannel
diff --git a/docs/plugins/gst-plugins-good-plugins.interfaces b/docs/plugins/gst-plugins-good-plugins.interfaces
index fc7edd0..7681227 100644
--- a/docs/plugins/gst-plugins-good-plugins.interfaces
+++ b/docs/plugins/gst-plugins-good-plugins.interfaces
@@ -89,6 +89,7 @@
 GstV4l2Src GstURIHandler GstTuner GstColorBalance GstVideoOrientation
 GstVP8Enc GstPreset GstTagSetter
 GstVP9Enc GstPreset GstTagSetter
+GstVPXEnc GstPreset GstTagSetter
 GstVideoBalance GstColorBalance
 GstVideoBalance GstImplementsInterface GstColorBalance
 GstVideoEncoder GstPreset
diff --git a/docs/plugins/gst-plugins-good-plugins.signals b/docs/plugins/gst-plugins-good-plugins.signals
index ea2a04b..169f54e 100644
--- a/docs/plugins/gst-plugins-good-plugins.signals
+++ b/docs/plugins/gst-plugins-good-plugins.signals
@@ -349,6 +349,24 @@
 </SIGNAL>
 
 <SIGNAL>
+<NAME>GstRtpBin::on-new-sender-ssrc</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstRtpBin *gstrtpbin
+guint  arg1
+guint  arg2
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstRtpBin::on-sender-ssrc-active</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstRtpBin *gstrtpbin
+guint  arg1
+guint  arg2
+</SIGNAL>
+
+<SIGNAL>
 <NAME>GstRtpJitterBuffer::clear-pt-map</NAME>
 <RETURNS>void</RETURNS>
 <FLAGS>la</FLAGS>
@@ -507,6 +525,22 @@
 </SIGNAL>
 
 <SIGNAL>
+<NAME>GstRtpSession::on-new-sender-ssrc</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstRtpSession *gstrtpsession
+guint  arg1
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstRtpSession::on-sender-ssrc-active</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstRtpSession *gstrtpsession
+guint  arg1
+</SIGNAL>
+
+<SIGNAL>
 <NAME>GstRtpSsrcDemux::clear-ssrc</NAME>
 <RETURNS>void</RETURNS>
 <FLAGS>la</FLAGS>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-1.0.devhelp2 b/docs/plugins/html/gst-plugins-good-plugins-1.0.devhelp2
index 4717071..9a4f075 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-1.0.devhelp2
+++ b/docs/plugins/html/gst-plugins-good-plugins-1.0.devhelp2
@@ -753,6 +753,10 @@
     <keyword type="property" name="The “do-retransmission” property" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--do-retransmission"/>
     <keyword type="property" name="The “rtp-profile” property" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--rtp-profile"/>
     <keyword type="property" name="The “ntp-time-source” property" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--ntp-time-source"/>
+    <keyword type="property" name="The “max-dropout-time” property" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--max-dropout-time"/>
+    <keyword type="property" name="The “max-misorder-time” property" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--max-misorder-time"/>
+    <keyword type="property" name="The “max-rtcp-rtp-time-diff” property" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--max-rtcp-rtp-time-diff"/>
+    <keyword type="property" name="The “rtcp-sync-send-time” property" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--rtcp-sync-send-time"/>
     <keyword type="signal" name="The “clear-pt-map” signal" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-clear-pt-map"/>
     <keyword type="signal" name="The “get-internal-session” signal" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-get-internal-session"/>
     <keyword type="signal" name="The “on-bye-ssrc” signal" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-on-bye-ssrc"/>
@@ -775,6 +779,8 @@
     <keyword type="signal" name="The “request-rtcp-encoder” signal" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-request-rtcp-encoder"/>
     <keyword type="signal" name="The “request-rtp-decoder” signal" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-request-rtp-decoder"/>
     <keyword type="signal" name="The “request-rtp-encoder” signal" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-request-rtp-encoder"/>
+    <keyword type="signal" name="The “on-new-sender-ssrc” signal" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-on-new-sender-ssrc"/>
+    <keyword type="signal" name="The “on-sender-ssrc-active” signal" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-on-sender-ssrc-active"/>
     <keyword type="struct" name="struct GstRtpH261Depay" link="gst-plugins-good-plugins-rtph261depay.html#GstRtpH261Depay-struct"/>
     <keyword type="struct" name="struct GstRtpH261Pay" link="gst-plugins-good-plugins-rtph261pay.html#GstRtpH261Pay-struct"/>
     <keyword type="struct" name="struct GstRtpL16Depay" link="gst-plugins-good-plugins-rtpL16depay.html#GstRtpL16Depay-struct"/>
@@ -820,6 +826,7 @@
     <keyword type="property" name="The “tls-interaction” property" link="gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--tls-interaction"/>
     <keyword type="property" name="The “ntp-time-source” property" link="gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--ntp-time-source"/>
     <keyword type="property" name="The “user-agent” property" link="gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--user-agent"/>
+    <keyword type="property" name="The “max-rtcp-rtp-time-diff” property" link="gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--max-rtcp-rtp-time-diff"/>
     <keyword type="signal" name="The “handle-request” signal" link="gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc-handle-request"/>
     <keyword type="signal" name="The “on-sdp” signal" link="gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc-on-sdp"/>
     <keyword type="signal" name="The “select-stream” signal" link="gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc-select-stream"/>
@@ -843,6 +850,10 @@
     <keyword type="property" name="The “do-retransmission” property" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--do-retransmission"/>
     <keyword type="property" name="The “rtp-profile” property" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--rtp-profile"/>
     <keyword type="property" name="The “ntp-time-source” property" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--ntp-time-source"/>
+    <keyword type="property" name="The “max-dropout-time” property" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--max-dropout-time"/>
+    <keyword type="property" name="The “max-misorder-time” property" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--max-misorder-time"/>
+    <keyword type="property" name="The “max-rtcp-rtp-time-diff” property" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--max-rtcp-rtp-time-diff"/>
+    <keyword type="property" name="The “rtcp-sync-send-time” property" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--rtcp-sync-send-time"/>
     <keyword type="signal" name="The “clear-pt-map” signal" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-clear-pt-map"/>
     <keyword type="signal" name="The “get-internal-session” signal" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-get-internal-session"/>
     <keyword type="signal" name="The “on-bye-ssrc” signal" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-on-bye-ssrc"/>
@@ -865,6 +876,8 @@
     <keyword type="signal" name="The “request-rtcp-encoder” signal" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-request-rtcp-encoder"/>
     <keyword type="signal" name="The “request-rtp-decoder” signal" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-request-rtp-decoder"/>
     <keyword type="signal" name="The “request-rtp-encoder” signal" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-request-rtp-encoder"/>
+    <keyword type="signal" name="The “on-new-sender-ssrc” signal" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-on-new-sender-ssrc"/>
+    <keyword type="signal" name="The “on-sender-ssrc-active” signal" link="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-on-sender-ssrc-active"/>
     <keyword type="struct" name="struct GstRTPDec" link="gst-plugins-good-plugins-rtpdec.html#GstRTPDec-struct"/>
     <keyword type="property" name="The “latency” property" link="gst-plugins-good-plugins-rtpdec.html#GstRTPDec--latency"/>
     <keyword type="signal" name="The “clear-pt-map” signal" link="gst-plugins-good-plugins-rtpdec.html#GstRTPDec-clear-pt-map"/>
@@ -906,6 +919,9 @@
     <keyword type="property" name="The “rtx-min-retry-timeout” property" link="gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer--rtx-min-retry-timeout"/>
     <keyword type="property" name="The “rtx-max-retries” property" link="gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer--rtx-max-retries"/>
     <keyword type="property" name="The “rtx-next-seqnum” property" link="gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer--rtx-next-seqnum"/>
+    <keyword type="property" name="The “max-dropout-time” property" link="gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer--max-dropout-time"/>
+    <keyword type="property" name="The “max-misorder-time” property" link="gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer--max-misorder-time"/>
+    <keyword type="property" name="The “max-rtcp-rtp-time-diff” property" link="gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer--max-rtcp-rtp-time-diff"/>
     <keyword type="signal" name="The “clear-pt-map” signal" link="gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer-clear-pt-map"/>
     <keyword type="signal" name="The “handle-sync” signal" link="gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer-handle-sync"/>
     <keyword type="signal" name="The “on-npt-stop” signal" link="gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer-on-npt-stop"/>
@@ -957,6 +973,9 @@
     <keyword type="property" name="The “stats” property" link="gst-plugins-good-plugins-rtpsession.html#GstRtpSession--stats"/>
     <keyword type="property" name="The “rtp-profile” property" link="gst-plugins-good-plugins-rtpsession.html#GstRtpSession--rtp-profile"/>
     <keyword type="property" name="The “ntp-time-source” property" link="gst-plugins-good-plugins-rtpsession.html#GstRtpSession--ntp-time-source"/>
+    <keyword type="property" name="The “max-dropout-time” property" link="gst-plugins-good-plugins-rtpsession.html#GstRtpSession--max-dropout-time"/>
+    <keyword type="property" name="The “max-misorder-time” property" link="gst-plugins-good-plugins-rtpsession.html#GstRtpSession--max-misorder-time"/>
+    <keyword type="property" name="The “rtcp-sync-send-time” property" link="gst-plugins-good-plugins-rtpsession.html#GstRtpSession--rtcp-sync-send-time"/>
     <keyword type="signal" name="The “clear-pt-map” signal" link="gst-plugins-good-plugins-rtpsession.html#GstRtpSession-clear-pt-map"/>
     <keyword type="signal" name="The “on-bye-ssrc” signal" link="gst-plugins-good-plugins-rtpsession.html#GstRtpSession-on-bye-ssrc"/>
     <keyword type="signal" name="The “on-bye-timeout” signal" link="gst-plugins-good-plugins-rtpsession.html#GstRtpSession-on-bye-timeout"/>
@@ -968,6 +987,8 @@
     <keyword type="signal" name="The “on-ssrc-validated” signal" link="gst-plugins-good-plugins-rtpsession.html#GstRtpSession-on-ssrc-validated"/>
     <keyword type="signal" name="The “on-timeout” signal" link="gst-plugins-good-plugins-rtpsession.html#GstRtpSession-on-timeout"/>
     <keyword type="signal" name="The “request-pt-map” signal" link="gst-plugins-good-plugins-rtpsession.html#GstRtpSession-request-pt-map"/>
+    <keyword type="signal" name="The “on-new-sender-ssrc” signal" link="gst-plugins-good-plugins-rtpsession.html#GstRtpSession-on-new-sender-ssrc"/>
+    <keyword type="signal" name="The “on-sender-ssrc-active” signal" link="gst-plugins-good-plugins-rtpsession.html#GstRtpSession-on-sender-ssrc-active"/>
     <keyword type="struct" name="struct GstRtpSsrcDemux" link="gst-plugins-good-plugins-rtpssrcdemux.html#GstRtpSsrcDemux-struct"/>
     <keyword type="signal" name="The “clear-ssrc” signal" link="gst-plugins-good-plugins-rtpssrcdemux.html#GstRtpSsrcDemux-clear-ssrc"/>
     <keyword type="signal" name="The “new-ssrc-pad” signal" link="gst-plugins-good-plugins-rtpssrcdemux.html#GstRtpSsrcDemux-new-ssrc-pad"/>
@@ -1007,6 +1028,7 @@
     <keyword type="property" name="The “tls-interaction” property" link="gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--tls-interaction"/>
     <keyword type="property" name="The “ntp-time-source” property" link="gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--ntp-time-source"/>
     <keyword type="property" name="The “user-agent” property" link="gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--user-agent"/>
+    <keyword type="property" name="The “max-rtcp-rtp-time-diff” property" link="gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--max-rtcp-rtp-time-diff"/>
     <keyword type="signal" name="The “handle-request” signal" link="gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc-handle-request"/>
     <keyword type="signal" name="The “on-sdp” signal" link="gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc-on-sdp"/>
     <keyword type="signal" name="The “select-stream” signal" link="gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc-select-stream"/>
@@ -1072,6 +1094,7 @@
     <keyword type="property" name="The “ssl-use-system-ca-file” property" link="gst-plugins-good-plugins-souphttpsrc.html#GstSoupHTTPSrc--ssl-use-system-ca-file"/>
     <keyword type="property" name="The “tls-database” property" link="gst-plugins-good-plugins-souphttpsrc.html#GstSoupHTTPSrc--tls-database"/>
     <keyword type="property" name="The “method” property" link="gst-plugins-good-plugins-souphttpsrc.html#GstSoupHTTPSrc--method"/>
+    <keyword type="property" name="The “tls-interaction” property" link="gst-plugins-good-plugins-souphttpsrc.html#GstSoupHTTPSrc--tls-interaction"/>
     <keyword type="struct" name="struct GstSpectrum" link="gst-plugins-good-plugins-spectrum.html#GstSpectrum-struct"/>
     <keyword type="property" name="The “bands” property" link="gst-plugins-good-plugins-spectrum.html#GstSpectrum--bands"/>
     <keyword type="property" name="The “interval” property" link="gst-plugins-good-plugins-spectrum.html#GstSpectrum--interval"/>
@@ -1127,6 +1150,7 @@
     <keyword type="property" name="The “socket” property" link="gst-plugins-good-plugins-udpsrc.html#GstUDPSrc--socket"/>
     <keyword type="property" name="The “used-socket” property" link="gst-plugins-good-plugins-udpsrc.html#GstUDPSrc--used-socket"/>
     <keyword type="property" name="The “address” property" link="gst-plugins-good-plugins-udpsrc.html#GstUDPSrc--address"/>
+    <keyword type="property" name="The “loop” property" link="gst-plugins-good-plugins-udpsrc.html#GstUDPSrc--loop"/>
     <keyword type="struct" name="struct GstV4l2Radio" link="gst-plugins-good-plugins-v4l2radio.html#GstV4l2Radio-struct"/>
     <keyword type="property" name="The “device” property" link="gst-plugins-good-plugins-v4l2radio.html#GstV4l2Radio--device"/>
     <keyword type="property" name="The “frequency” property" link="gst-plugins-good-plugins-v4l2radio.html#GstV4l2Radio--frequency"/>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-audiochebband.html b/docs/plugins/html/gst-plugins-good-plugins-audiochebband.html
index 834cfda..0628e32 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-audiochebband.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-audiochebband.html
@@ -126,7 +126,7 @@
         <td class="listing_lines" align="right"><pre>1
 2
 3</pre></td>
-        <td class="listing_code"><pre class="programlisting">gst<span class="gtkdoc opt">-</span>launch<span class="gtkdoc opt">-</span><span class="number">1.0</span> audiotestsrc freq<span class="gtkdoc opt">=</span><span class="number">1500</span> <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> audiochebband mode<span class="gtkdoc opt">=</span>band<span class="gtkdoc opt">-</span>pass lower<span class="gtkdoc opt">-</span>frequency<span class="gtkdoc opt">=</span><span class="number">1000</span> upper<span class="gtkdoc opt">-</span>frequenc<span class="gtkdoc opt">=</span><span class="number">6000</span> poles<span class="gtkdoc opt">=</span><span class="number">4</span> <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> alsasink
+        <td class="listing_code"><pre class="programlisting">gst<span class="gtkdoc opt">-</span>launch<span class="gtkdoc opt">-</span><span class="number">1.0</span> audiotestsrc freq<span class="gtkdoc opt">=</span><span class="number">1500</span> <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> audiochebband mode<span class="gtkdoc opt">=</span>band<span class="gtkdoc opt">-</span>pass lower<span class="gtkdoc opt">-</span>frequency<span class="gtkdoc opt">=</span><span class="number">1000</span> upper<span class="gtkdoc opt">-</span>frequency<span class="gtkdoc opt">=</span><span class="number">6000</span> poles<span class="gtkdoc opt">=</span><span class="number">4</span> <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> alsasink
 gst<span class="gtkdoc opt">-</span>launch<span class="gtkdoc opt">-</span><span class="number">1.0</span> filesrc location<span class="gtkdoc opt">=</span><span class="string">&quot;melo1.ogg&quot;</span> <span class="gtkdoc opt">!</span> oggdemux <span class="gtkdoc opt">!</span> vorbisdec <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> audiochebband mode<span class="gtkdoc opt">=</span>band<span class="gtkdoc opt">-</span>reject lower<span class="gtkdoc opt">-</span>frequency<span class="gtkdoc opt">=</span><span class="number">1000</span> upper<span class="gtkdoc opt">-</span>frequency<span class="gtkdoc opt">=</span><span class="number">4000</span> ripple<span class="gtkdoc opt">=</span><span class="number">0.2</span> <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> alsasink
 gst<span class="gtkdoc opt">-</span>launch<span class="gtkdoc opt">-</span><span class="number">1.0</span> audiotestsrc wave<span class="gtkdoc opt">=</span>white<span class="gtkdoc opt">-</span>noise <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> audiochebband mode<span class="gtkdoc opt">=</span>band<span class="gtkdoc opt">-</span>pass lower<span class="gtkdoc opt">-</span>frequency<span class="gtkdoc opt">=</span><span class="number">1000</span> upper<span class="gtkdoc opt">-</span>frequency<span class="gtkdoc opt">=</span><span class="number">4000</span> type<span class="gtkdoc opt">=</span><span class="number">2</span> <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> alsasink</pre></td>
       </tr>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-avidemux.html b/docs/plugins/html/gst-plugins-good-plugins-avidemux.html
index 46c94ca..d1de2a6 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-avidemux.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-avidemux.html
@@ -558,10 +558,6 @@
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> video/x-raw, format=(string)YVU9, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]</td>
-</tr>
-<tr>
-<td><p><span class="term"></span></p></td>
 <td> video/x-zlib, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]</td>
 </tr>
 <tr>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-gdkpixbufsink.html b/docs/plugins/html/gst-plugins-good-plugins-gdkpixbufsink.html
index 9829350..bc5d210 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-gdkpixbufsink.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-gdkpixbufsink.html
@@ -44,7 +44,7 @@
 <tbody>
 <tr>
 <td class="property_type">
-<span class="type">GdkPixbuf</span> *</td>
+<a href="http://library.gnome.org/devel/gdk-pixbuf/unstable/gdk-pixbuf-The-GdkPixbuf-Structure.html#GdkPixbuf"><span class="type">GdkPixbuf</span></a> *</td>
 <td class="property_name"><a class="link" href="gst-plugins-good-plugins-gdkpixbufsink.html#GstGdkPixbufSink--last-pixbuf" title="The “last-pixbuf” property">last-pixbuf</a></td>
 <td class="property_flags">Read</td>
 </tr>
@@ -158,7 +158,7 @@
 <a name="gst-plugins-good-plugins-gdkpixbufsink.property-details"></a><h2>Property Details</h2>
 <div class="refsect2">
 <a name="GstGdkPixbufSink--last-pixbuf"></a><h3>The <code class="literal">“last-pixbuf”</code> property</h3>
-<pre class="programlisting">  “last-pixbuf”              <span class="type">GdkPixbuf</span> *</pre>
+<pre class="programlisting">  “last-pixbuf”              <a href="http://library.gnome.org/devel/gdk-pixbuf/unstable/gdk-pixbuf-The-GdkPixbuf-Structure.html#GdkPixbuf"><span class="type">GdkPixbuf</span></a> *</pre>
 <p>Last GdkPixbuf object rendered.</p>
 <p>Flags: Read</p>
 </div>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-goom.html b/docs/plugins/html/gst-plugins-good-plugins-goom.html
index d0a2bc6..2b21cdc 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-goom.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-goom.html
@@ -51,7 +51,7 @@
     <span class="lineart">╰──</span> <a href="https://developer.gnome.org/gobject/unstable/gobject-The-Base-Object-Type.html#GInitiallyUnowned">GInitiallyUnowned</a>
         <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstObject.html">GstObject</a>
             <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html">GstElement</a>
-                <span class="lineart">╰──</span> GstAudioVisualizer-ExtGoom
+                <span class="lineart">╰──</span> GstAudioVisualizer-BaseExtLibvisual
                     <span class="lineart">╰──</span> GstGoom
 </pre>
 </div>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-goom2k1.html b/docs/plugins/html/gst-plugins-good-plugins-goom2k1.html
index a3e04c5..8acd41b 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-goom2k1.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-goom2k1.html
@@ -51,7 +51,7 @@
     <span class="lineart">╰──</span> <a href="https://developer.gnome.org/gobject/unstable/gobject-The-Base-Object-Type.html#GInitiallyUnowned">GInitiallyUnowned</a>
         <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstObject.html">GstObject</a>
             <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html">GstElement</a>
-                <span class="lineart">╰──</span> GstAudioVisualizer-ExtGoom2k1
+                <span class="lineart">╰──</span> GstAudioVisualizer-BaseExtLibvisual
                     <span class="lineart">╰──</span> GstGoom2k1
 </pre>
 </div>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-matroskamux.html b/docs/plugins/html/gst-plugins-good-plugins-matroskamux.html
index ea87459..ec47bbf 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-matroskamux.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-matroskamux.html
@@ -362,10 +362,18 @@
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
+<td> video/x-vp9, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]</td>
+</tr>
+<tr>
+<td><p><span class="term"></span></p></td>
 <td> video/x-raw, format=(string){ YUY2, I420, YV12, UYVY, AYUV, GRAY8, BGR, RGB }, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
+<td> video/x-prores, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]</td>
+</tr>
+<tr>
+<td><p><span class="term"></span></p></td>
 <td> video/x-wmv, wmvversion=(int)[ 1, 3 ], width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]</td>
 </tr>
 </tbody>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-mj2mux.html b/docs/plugins/html/gst-plugins-good-plugins-mj2mux.html
index 4d4b3b0..5e885fc 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-mj2mux.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-mj2mux.html
@@ -237,11 +237,7 @@
 </tr>
 <tr>
 <td><p><span class="term">details</span></p></td>
-<td>audio/x-raw, format=(string){ S8, U8 }, layout=(string)interleaved, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]</td>
-</tr>
-<tr>
-<td><p><span class="term"></span></p></td>
-<td> audio/x-raw, format=(string){ S16LE, S16BE }, layout=(string)interleaved, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]</td>
+<td>audio/x-raw, format=(string){ S16LE, S16BE, S8, U8 }, layout=(string)interleaved, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]</td>
 </tr>
 </tbody>
 </table></div>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-mp4mux.html b/docs/plugins/html/gst-plugins-good-plugins-mp4mux.html
index e00baa9..74258bc 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-mp4mux.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-mp4mux.html
@@ -250,6 +250,10 @@
 <td><p><span class="term"></span></p></td>
 <td> audio/x-alac, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]</td>
 </tr>
+<tr>
+<td><p><span class="term"></span></p></td>
+<td> audio/x-opus, channel-mapping-family=(int)[ 0, 255 ], channels=(int)[ 1, 8 ], rate=(int)[ 1, 2147483647 ]</td>
+</tr>
 </tbody>
 </table></div>
 <div class="variablelist"><table border="0" class="variablelist">
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-1394.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-1394.html
index 13ade60..5d2a61f 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-1394.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-1394.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-aasink.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-aasink.html
index 41744c6..8a67b6f 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-aasink.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-aasink.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-alaw.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-alaw.html
index 5359954..7c0d8e3 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-alaw.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-alaw.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-alpha.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-alpha.html
index 806bcb8..af48d0d 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-alpha.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-alpha.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-alphacolor.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-alphacolor.html
index bc19ec5..a200714 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-alphacolor.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-alphacolor.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-apetag.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-apetag.html
index a604ca0..0d34fdd 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-apetag.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-apetag.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-audiofx.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-audiofx.html
index 1026154..cef51a3 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-audiofx.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-audiofx.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-audioparsers.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-audioparsers.html
index 9e1d9b9..e381574 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-audioparsers.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-audioparsers.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-auparse.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-auparse.html
index 809eeaa..2f75ab2 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-auparse.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-auparse.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-autodetect.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-autodetect.html
index 4f1bdb4..2175954 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-autodetect.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-autodetect.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-avi.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-avi.html
index 51a8a9f..78342b1 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-avi.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-avi.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-cacasink.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-cacasink.html
index 00a1a37..f71bd07 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-cacasink.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-cacasink.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-cairo.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-cairo.html
index 6e39ead..cc0d3f0 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-cairo.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-cairo.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-cutter.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-cutter.html
index 49dfe58..6f1e5f6 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-cutter.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-cutter.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-debug.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-debug.html
index 840e58e..b9f4866 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-debug.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-debug.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-deinterlace.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-deinterlace.html
index 6fa4c39..a0c13d3 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-deinterlace.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-deinterlace.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-dtmf.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-dtmf.html
index b0ca266..f5aceaa 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-dtmf.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-dtmf.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-dv.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-dv.html
index cab807e..0eac0f0 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-dv.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-dv.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-effectv.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-effectv.html
index 9879f35..125c995 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-effectv.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-effectv.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-equalizer.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-equalizer.html
index 3ad9d36..2031d5c 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-equalizer.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-equalizer.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-flac.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-flac.html
index 2a48d0e..85540f8 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-flac.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-flac.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-flv.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-flv.html
index 7b82b6a..ab20074 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-flv.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-flv.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-flxdec.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-flxdec.html
index a75c97c..f991d7d 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-flxdec.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-flxdec.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-gdkpixbuf.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-gdkpixbuf.html
index 934fc0a..4b26ed5 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-gdkpixbuf.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-gdkpixbuf.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-goom.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-goom.html
index ec541eb..a27e3b0 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-goom.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-goom.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-goom2k1.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-goom2k1.html
index 54cd310..260cca5 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-goom2k1.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-goom2k1.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-icydemux.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-icydemux.html
index 088a41f..abe12fe 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-icydemux.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-icydemux.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-id3demux.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-id3demux.html
index a65275b..d0a8c98 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-id3demux.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-id3demux.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-imagefreeze.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-imagefreeze.html
index 03b0be4..406eeb5 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-imagefreeze.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-imagefreeze.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-interleave.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-interleave.html
index 14adb31..bfa8d50 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-interleave.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-interleave.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-isomp4.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-isomp4.html
index 24a8dd3..0cb2523 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-isomp4.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-isomp4.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-jack.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-jack.html
index 79c1d8a..8c2fa11 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-jack.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-jack.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-jpeg.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-jpeg.html
index aff7714..74e72f6 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-jpeg.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-jpeg.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-level.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-level.html
index 5e34de6..47b6339 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-level.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-level.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-matroska.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-matroska.html
index f6195d9..4ee0093 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-matroska.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-matroska.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-mulaw.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-mulaw.html
index f56a07b..0d8106c 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-mulaw.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-mulaw.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-multifile.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-multifile.html
index acb6eb0..d8faedc 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-multifile.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-multifile.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-multipart.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-multipart.html
index 0b12739..dc766bc 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-multipart.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-multipart.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-navigationtest.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-navigationtest.html
index 7db9165..33ee76d 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-navigationtest.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-navigationtest.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-oss4.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-oss4.html
index ded0202..5e24fd1 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-oss4.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-oss4.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-ossaudio.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-ossaudio.html
index 3bd95a8..beaa40d 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-ossaudio.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-ossaudio.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-png.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-png.html
index cfbc419..2b47f6b 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-png.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-png.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-pulseaudio.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-pulseaudio.html
index fe414ab..ce1e543 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-pulseaudio.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-pulseaudio.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-replaygain.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-replaygain.html
index 86bc6f9..d5c18d9 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-replaygain.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-replaygain.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-rtp.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-rtp.html
index 3b1b9ba..c264e6e 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-rtp.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-rtp.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
@@ -377,7 +377,7 @@
 </tr>
 <tr>
 <td><p><span class="term">rtpvp8pay</span></p></td>
-<td>Puts VP8 video in RTP packets)</td>
+<td>Puts VP8 video in RTP packets</td>
 </tr>
 <tr>
 <td><p><span class="term">rtpvrawdepay</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-rtpmanager.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-rtpmanager.html
index 4f8c762..d4c6d8f 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-rtpmanager.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-rtpmanager.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-rtsp.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-rtsp.html
index 741f39d..fbac22a 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-rtsp.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-rtsp.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-shapewipe.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-shapewipe.html
index 1428ef9..aa0cd0f 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-shapewipe.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-shapewipe.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-shout2send.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-shout2send.html
index 50921a8..44b4f80 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-shout2send.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-shout2send.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-smpte.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-smpte.html
index 41e3880..b586c7b 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-smpte.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-smpte.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-soup.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-soup.html
index 496c271..29adaea 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-soup.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-soup.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-spectrum.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-spectrum.html
index ba59396..89de0eb 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-spectrum.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-spectrum.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-speex.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-speex.html
index b011204..e5b34d4 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-speex.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-speex.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-taglib.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-taglib.html
index 8841566..c7e1428 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-taglib.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-taglib.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-udp.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-udp.html
index 188dc4c..866aec3 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-udp.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-udp.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-video4linux2.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-video4linux2.html
index 6efa928..403f645 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-video4linux2.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-video4linux2.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-videobox.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-videobox.html
index 47cf8bc..ee4f757 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-videobox.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-videobox.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-videocrop.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-videocrop.html
index d23ec23..ce4e433 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-videocrop.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-videocrop.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-videofilter.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-videofilter.html
index 3bb264b..1b9db8b 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-videofilter.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-videofilter.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-videomixer.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-videomixer.html
index 2484aa1..a77937e 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-videomixer.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-videomixer.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-vpx.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-vpx.html
index a093670..99c3c07 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-vpx.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-vpx.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-wavenc.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-wavenc.html
index 6062646..1e33f2b 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-wavenc.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-wavenc.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-wavpack.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-wavpack.html
index cb3c1f3..e03a278 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-wavpack.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-wavpack.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-wavparse.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-wavparse.html
index eb44b77..76bca05 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-wavparse.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-wavparse.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-ximagesrc.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-ximagesrc.html
index e7e33af..4a6759e 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-ximagesrc.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-ximagesrc.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-plugin-y4menc.html b/docs/plugins/html/gst-plugins-good-plugins-plugin-y4menc.html
index 7f5ff85..b4ca6b8 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-plugin-y4menc.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-plugin-y4menc.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.6.2</td>
+<td>1.7.1</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-qtmux.html b/docs/plugins/html/gst-plugins-good-plugins-qtmux.html
index 769166e..bbe80bc 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-qtmux.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-qtmux.html
@@ -248,15 +248,7 @@
 </tr>
 <tr>
 <td><p><span class="term">details</span></p></td>
-<td>audio/x-raw, format=(string){ S32LE, S32BE, S24LE, S24BE }, layout=(string)interleaved, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]</td>
-</tr>
-<tr>
-<td><p><span class="term"></span></p></td>
-<td> audio/x-raw, format=(string){ S8, U8 }, layout=(string)interleaved, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]</td>
-</tr>
-<tr>
-<td><p><span class="term"></span></p></td>
-<td> audio/x-raw, format=(string){ S16LE, S16BE }, layout=(string)interleaved, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]</td>
+<td>audio/x-raw, format=(string){ S32LE, S32BE, S24LE, S24BE, S16LE, S16BE, S8, U8 }, layout=(string)interleaved, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-rtpbin.html b/docs/plugins/html/gst-plugins-good-plugins-rtpbin.html
index 4966cfc..3803d4b 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-rtpbin.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-rtpbin.html
@@ -120,6 +120,26 @@
 <td class="property_name"><a class="link" href="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--ntp-time-source" title="The “ntp-time-source” property">ntp-time-source</a></td>
 <td class="property_flags">Read / Write</td>
 </tr>
+<tr>
+<td class="property_type"><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a></td>
+<td class="property_name"><a class="link" href="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--max-dropout-time" title="The “max-dropout-time” property">max-dropout-time</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a></td>
+<td class="property_name"><a class="link" href="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--max-misorder-time" title="The “max-misorder-time” property">max-misorder-time</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gint"><span class="type">gint</span></a></td>
+<td class="property_name"><a class="link" href="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--max-rtcp-rtp-time-diff" title="The “max-rtcp-rtp-time-diff” property">max-rtcp-rtp-time-diff</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="gst-plugins-good-plugins-rtpbin.html#GstRtpBin--rtcp-sync-send-time" title="The “rtcp-sync-send-time” property">rtcp-sync-send-time</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -250,6 +270,16 @@
 <td class="signal_name"><a class="link" href="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-request-rtp-encoder" title="The “request-rtp-encoder” signal">request-rtp-encoder</a></td>
 <td class="signal_flags"><a href="https://developer.gnome.org/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
 </tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-on-new-sender-ssrc" title="The “on-new-sender-ssrc” signal">on-new-sender-ssrc</a></td>
+<td class="signal_flags"><a href="https://developer.gnome.org/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="gst-plugins-good-plugins-rtpbin.html#GstRtpBin-on-sender-ssrc-active" title="The “on-sender-ssrc-active” signal">on-sender-ssrc-active</a></td>
+<td class="signal_flags"><a href="https://developer.gnome.org/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -857,6 +887,39 @@
 <p>Flags: Read / Write</p>
 <p>Default value: NTP time based on realtime clock</p>
 </div>
+<hr>
+<div class="refsect2">
+<a name="GstRtpBin--max-dropout-time"></a><h3>The <code class="literal">“max-dropout-time”</code> property</h3>
+<pre class="programlisting">  “max-dropout-time”         <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a></pre>
+<p>The maximum time (milliseconds) of missing packets tolerated.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: 60000</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstRtpBin--max-misorder-time"></a><h3>The <code class="literal">“max-misorder-time”</code> property</h3>
+<pre class="programlisting">  “max-misorder-time”        <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a></pre>
+<p>The maximum time (milliseconds) of misordered packets tolerated.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: 2000</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstRtpBin--max-rtcp-rtp-time-diff"></a><h3>The <code class="literal">“max-rtcp-rtp-time-diff”</code> property</h3>
+<pre class="programlisting">  “max-rtcp-rtp-time-diff”   <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gint"><span class="type">gint</span></a></pre>
+<p>Maximum amount of time in ms that the RTP time in RTCP SRs is allowed to be ahead (-1 disabled).</p>
+<p>Flags: Read / Write</p>
+<p>Allowed values: &gt;= G_MAXULONG</p>
+<p>Default value: 1000</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstRtpBin--rtcp-sync-send-time"></a><h3>The <code class="literal">“rtcp-sync-send-time”</code> property</h3>
+<pre class="programlisting">  “rtcp-sync-send-time”      <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Use send time or capture time for RTCP sync (TRUE = send time, FALSE = capture time).</p>
+<p>Flags: Read / Write</p>
+<p>Default value: TRUE</p>
+</div>
 </div>
 <div class="refsect1">
 <a name="gst-plugins-good-plugins-rtpbin.signal-details"></a><h2>Signal Details</h2>
@@ -1153,9 +1216,8 @@
                <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a>      session,
                <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a>      ssrc,
                <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a>   user_data)</pre>
-<p>Notify of a SSRC that is active, i.e., sending RTCP.</p>
 <div class="refsect3">
-<a name="id-1.2.129.13.9.5"></a><h4>Parameters</h4>
+<a name="id-1.2.129.13.9.4"></a><h4>Parameters</h4>
 <div class="informaltable"><table width="100%" border="0">
 <colgroup>
 <col width="150px" class="parameters_name">
@@ -1175,7 +1237,7 @@
 </tr>
 <tr>
 <td class="parameter_name"><p>ssrc</p></td>
-<td class="parameter_description"><p>the SSRC</p></td>
+<td class="parameter_description"><p>the sender SSRC</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -1187,6 +1249,7 @@
 </table></div>
 </div>
 <p>Flags: <a href="https://developer.gnome.org/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+<p class="since">Since: 1.8</p>
 </div>
 <hr>
 <div class="refsect2">
@@ -1783,6 +1846,59 @@
 <p>Flags: <a href="https://developer.gnome.org/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
 <p class="since">Since: 1.4</p>
 </div>
+<hr>
+<div class="refsect2">
+<a name="GstRtpBin-on-new-sender-ssrc"></a><h3>The <code class="literal">“on-new-sender-ssrc”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="gst-plugins-good-plugins-rtpbin.html#GstRtpBin"><span class="type">GstRtpBin</span></a> *rtpbin,
+               <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a>      session,
+               <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a>      ssrc,
+               <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a>   user_data)</pre>
+<div class="refsect3">
+<a name="id-1.2.129.13.24.4"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>rtpbin</p></td>
+<td class="parameter_description"><p>the object which received the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>the session</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>ssrc</p></td>
+<td class="parameter_description"><p>the sender SSRC</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="https://developer.gnome.org/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+<p class="since">Since: 1.8</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstRtpBin-on-sender-ssrc-active"></a><h3>The <code class="literal">“on-sender-ssrc-active”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="gst-plugins-good-plugins-rtpbin.html#GstRtpBin"><span class="type">GstRtpBin</span></a> *gstrtpbin,
+               <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a>      arg1,
+               <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a>      arg2,
+               <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a>   user_data)</pre>
+<p>Flags: <a href="https://developer.gnome.org/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+</div>
 </div>
 <div class="refsect1">
 <a name="gst-plugins-good-plugins-rtpbin.see-also"></a><h2>See Also</h2>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-rtpjitterbuffer.html b/docs/plugins/html/gst-plugins-good-plugins-rtpjitterbuffer.html
index 6781397..1e60b72 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-rtpjitterbuffer.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-rtpjitterbuffer.html
@@ -124,6 +124,21 @@
 <td class="property_name"><a class="link" href="gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer--rtx-next-seqnum" title="The “rtx-next-seqnum” property">rtx-next-seqnum</a></td>
 <td class="property_flags">Read / Write</td>
 </tr>
+<tr>
+<td class="property_type"><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a></td>
+<td class="property_name"><a class="link" href="gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer--max-dropout-time" title="The “max-dropout-time” property">max-dropout-time</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a></td>
+<td class="property_name"><a class="link" href="gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer--max-misorder-time" title="The “max-misorder-time” property">max-misorder-time</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gint"><span class="type">gint</span></a></td>
+<td class="property_name"><a class="link" href="gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer--max-rtcp-rtp-time-diff" title="The “max-rtcp-rtp-time-diff” property">max-rtcp-rtp-time-diff</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -554,6 +569,34 @@
 <p>Default value: TRUE</p>
 <p class="since">Since: 1.6</p>
 </div>
+<hr>
+<div class="refsect2">
+<a name="GstRtpJitterBuffer--max-dropout-time"></a><h3>The <code class="literal">“max-dropout-time”</code> property</h3>
+<pre class="programlisting">  “max-dropout-time”         <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a></pre>
+<p>The maximum time (milliseconds) of missing packets tolerated.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: 60000</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstRtpJitterBuffer--max-misorder-time"></a><h3>The <code class="literal">“max-misorder-time”</code> property</h3>
+<pre class="programlisting">  “max-misorder-time”        <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a></pre>
+<p>The maximum time (milliseconds) of misordered packets tolerated.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: 2000</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstRtpJitterBuffer--max-rtcp-rtp-time-diff"></a><h3>The <code class="literal">“max-rtcp-rtp-time-diff”</code> property</h3>
+<pre class="programlisting">  “max-rtcp-rtp-time-diff”   <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gint"><span class="type">gint</span></a></pre>
+<p>The maximum amount of time in ms that the RTP time in the RTCP SRs
+is allowed to be ahead of the last RTP packet we received. Use
+-1 to disable ignoring of RTCP packets.</p>
+<p>Flags: Read / Write</p>
+<p>Allowed values: &gt;= G_MAXULONG</p>
+<p>Default value: 1000</p>
+<p class="since">Since: 1.8</p>
+</div>
 </div>
 <div class="refsect1">
 <a name="gst-plugins-good-plugins-rtpjitterbuffer.signal-details"></a><h2>Signal Details</h2>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-rtpmux.html b/docs/plugins/html/gst-plugins-good-plugins-rtpmux.html
index 8705aea..588535e 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-rtpmux.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-rtpmux.html
@@ -234,7 +234,7 @@
 <div class="refsect2">
 <a name="GstRTPMux--ssrc"></a><h3>The <code class="literal">“ssrc”</code> property</h3>
 <pre class="programlisting">  “ssrc”                     <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a></pre>
-<p>The SSRC of the packets (-1 == random).</p>
+<p>The SSRC of the packets (default == random).</p>
 <p>Flags: Read / Write</p>
 <p>Default value: 4294967295</p>
 </div>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-rtpsession.html b/docs/plugins/html/gst-plugins-good-plugins-rtpsession.html
index b1e1bee..be717e3 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-rtpsession.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-rtpsession.html
@@ -116,6 +116,21 @@
 <td class="property_name"><a class="link" href="gst-plugins-good-plugins-rtpsession.html#GstRtpSession--ntp-time-source" title="The “ntp-time-source” property">ntp-time-source</a></td>
 <td class="property_flags">Read / Write</td>
 </tr>
+<tr>
+<td class="property_type"><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a></td>
+<td class="property_name"><a class="link" href="gst-plugins-good-plugins-rtpsession.html#GstRtpSession--max-dropout-time" title="The “max-dropout-time” property">max-dropout-time</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a></td>
+<td class="property_name"><a class="link" href="gst-plugins-good-plugins-rtpsession.html#GstRtpSession--max-misorder-time" title="The “max-misorder-time” property">max-misorder-time</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="gst-plugins-good-plugins-rtpsession.html#GstRtpSession--rtcp-sync-send-time" title="The “rtcp-sync-send-time” property">rtcp-sync-send-time</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -184,6 +199,16 @@
 <td class="signal_name"><a class="link" href="gst-plugins-good-plugins-rtpsession.html#GstRtpSession-request-pt-map" title="The “request-pt-map” signal">request-pt-map</a></td>
 <td class="signal_flags"><a href="https://developer.gnome.org/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
 </tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="gst-plugins-good-plugins-rtpsession.html#GstRtpSession-on-new-sender-ssrc" title="The “on-new-sender-ssrc” signal">on-new-sender-ssrc</a></td>
+<td class="signal_flags"><a href="https://developer.gnome.org/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="gst-plugins-good-plugins-rtpsession.html#GstRtpSession-on-sender-ssrc-active" title="The “on-sender-ssrc-active” signal">on-sender-ssrc-active</a></td>
+<td class="signal_flags"><a href="https://developer.gnome.org/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -639,6 +664,30 @@
 <p>Flags: Read / Write</p>
 <p>Default value: NTP time based on realtime clock</p>
 </div>
+<hr>
+<div class="refsect2">
+<a name="GstRtpSession--max-dropout-time"></a><h3>The <code class="literal">“max-dropout-time”</code> property</h3>
+<pre class="programlisting">  “max-dropout-time”         <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a></pre>
+<p>The maximum time (milliseconds) of missing packets tolerated.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: 60000</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstRtpSession--max-misorder-time"></a><h3>The <code class="literal">“max-misorder-time”</code> property</h3>
+<pre class="programlisting">  “max-misorder-time”        <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a></pre>
+<p>The maximum time (milliseconds) of misordered packets tolerated.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: 2000</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstRtpSession--rtcp-sync-send-time"></a><h3>The <code class="literal">“rtcp-sync-send-time”</code> property</h3>
+<pre class="programlisting">  “rtcp-sync-send-time”      <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Use send time or capture time for RTCP sync (TRUE = send time, FALSE = capture time).</p>
+<p>Flags: Read / Write</p>
+<p>Default value: TRUE</p>
+</div>
 </div>
 <div class="refsect1">
 <a name="gst-plugins-good-plugins-rtpsession.signal-details"></a><h2>Signal Details</h2>
@@ -825,9 +874,37 @@
 <div class="refsect2">
 <a name="GstRtpSession-on-ssrc-active"></a><h3>The <code class="literal">“on-ssrc-active”</code> signal</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-user_function (<a class="link" href="gst-plugins-good-plugins-rtpsession.html#GstRtpSession"><span class="type">GstRtpSession</span></a> *gstrtpsession,
-               <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a>          arg1,
+user_function (<a class="link" href="gst-plugins-good-plugins-rtpsession.html#GstRtpSession"><span class="type">GstRtpSession</span></a> *sess,
+               <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a>          ssrc,
                <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a>       user_data)</pre>
+<p>Notify of a SSRC that is active, i.e., sending RTCP.</p>
+<div class="refsect3">
+<a name="id-1.2.146.12.7.5"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>sess</p></td>
+<td class="parameter_description"><p>the object which received the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>ssrc</p></td>
+<td class="parameter_description"><p>the SSRC</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
 <p>Flags: <a href="https://developer.gnome.org/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
 </div>
 <hr>
@@ -960,6 +1037,80 @@
 </div>
 <p>Flags: <a href="https://developer.gnome.org/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
 </div>
+<hr>
+<div class="refsect2">
+<a name="GstRtpSession-on-new-sender-ssrc"></a><h3>The <code class="literal">“on-new-sender-ssrc”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="gst-plugins-good-plugins-rtpsession.html#GstRtpSession"><span class="type">GstRtpSession</span></a> *sess,
+               <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a>          ssrc,
+               <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a>       user_data)</pre>
+<div class="refsect3">
+<a name="id-1.2.146.12.13.4"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>sess</p></td>
+<td class="parameter_description"><p>the object which received the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>ssrc</p></td>
+<td class="parameter_description"><p>the sender SSRC</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="https://developer.gnome.org/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+<p class="since">Since: 1.8</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstRtpSession-on-sender-ssrc-active"></a><h3>The <code class="literal">“on-sender-ssrc-active”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="gst-plugins-good-plugins-rtpsession.html#GstRtpSession"><span class="type">GstRtpSession</span></a> *sess,
+               <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a>          ssrc,
+               <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a>       user_data)</pre>
+<div class="refsect3">
+<a name="id-1.2.146.12.14.4"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>sess</p></td>
+<td class="parameter_description"><p>the object which received the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>ssrc</p></td>
+<td class="parameter_description"><p>the sender SSRC</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="https://developer.gnome.org/gobject/unstable/gobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+<p class="since">Since: 1.8</p>
+</div>
 </div>
 <div class="refsect1">
 <a name="gst-plugins-good-plugins-rtpsession.see-also"></a><h2>See Also</h2>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-rtspsrc.html b/docs/plugins/html/gst-plugins-good-plugins-rtspsrc.html
index 17997d0..85c299a 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-rtspsrc.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-rtspsrc.html
@@ -226,6 +226,11 @@
 <td class="property_name"><a class="link" href="gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--user-agent" title="The “user-agent” property">user-agent</a></td>
 <td class="property_flags">Read / Write</td>
 </tr>
+<tr>
+<td class="property_type"><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gint"><span class="type">gint</span></a></td>
+<td class="property_name"><a class="link" href="gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--max-rtcp-rtp-time-diff" title="The “max-rtcp-rtp-time-diff” property">max-rtcp-rtp-time-diff</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -683,7 +688,16 @@
 <pre class="programlisting">  “user-agent”               <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
 <p>The User-Agent string to send to the server.</p>
 <p>Flags: Read / Write</p>
-<p>Default value: "GStreamer/1.6.2"</p>
+<p>Default value: "GStreamer/1.7.1"</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstRTSPSrc--max-rtcp-rtp-time-diff"></a><h3>The <code class="literal">“max-rtcp-rtp-time-diff”</code> property</h3>
+<pre class="programlisting">  “max-rtcp-rtp-time-diff”   <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gint"><span class="type">gint</span></a></pre>
+<p>Maximum amount of time in ms that the RTP time in RTCP SRs is allowed to be ahead (-1 disabled).</p>
+<p>Flags: Read / Write</p>
+<p>Allowed values: &gt;= G_MAXULONG</p>
+<p>Default value: 1000</p>
 </div>
 </div>
 <div class="refsect1">
diff --git a/docs/plugins/html/gst-plugins-good-plugins-scaletempo.html b/docs/plugins/html/gst-plugins-good-plugins-scaletempo.html
index 5f1e98c..2c271ee 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-scaletempo.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-scaletempo.html
@@ -199,6 +199,10 @@
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
+<td> audio/x-raw, format=(string)F64LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]</td>
+</tr>
+<tr>
+<td><p><span class="term"></span></p></td>
 <td> audio/x-raw, format=(string)S16LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]</td>
 </tr>
 </tbody>
@@ -227,6 +231,10 @@
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
+<td> audio/x-raw, format=(string)F64LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]</td>
+</tr>
+<tr>
+<td><p><span class="term"></span></p></td>
 <td> audio/x-raw, format=(string)S16LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]</td>
 </tr>
 </tbody>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-souphttpsrc.html b/docs/plugins/html/gst-plugins-good-plugins-souphttpsrc.html
index 5741c13..92a5fc2 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-souphttpsrc.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-souphttpsrc.html
@@ -164,6 +164,12 @@
 <td class="property_name"><a class="link" href="gst-plugins-good-plugins-souphttpsrc.html#GstSoupHTTPSrc--method" title="The “method” property">method</a></td>
 <td class="property_flags">Read / Write</td>
 </tr>
+<tr>
+<td class="property_type">
+<a href="https://developer.gnome.org/gio/unstable/GTlsInteraction.html"><span class="type">GTlsInteraction</span></a> *</td>
+<td class="property_name"><a class="link" href="gst-plugins-good-plugins-souphttpsrc.html#GstSoupHTTPSrc--tls-interaction" title="The “tls-interaction” property">tls-interaction</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -443,6 +449,13 @@
 <p>Flags: Read / Write</p>
 <p>Default value: NULL</p>
 </div>
+<hr>
+<div class="refsect2">
+<a name="GstSoupHTTPSrc--tls-interaction"></a><h3>The <code class="literal">“tls-interaction”</code> property</h3>
+<pre class="programlisting">  “tls-interaction”          <a href="https://developer.gnome.org/gio/unstable/GTlsInteraction.html"><span class="type">GTlsInteraction</span></a> *</pre>
+<p>A GTlsInteraction object to be used when the connection or certificate database need to interact with the user.</p>
+<p>Flags: Read / Write</p>
+</div>
 </div>
 </div>
 <div class="footer">
diff --git a/docs/plugins/html/gst-plugins-good-plugins-udpsrc.html b/docs/plugins/html/gst-plugins-good-plugins-udpsrc.html
index f213185..d642c1f 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-udpsrc.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-udpsrc.html
@@ -120,6 +120,11 @@
 <td class="property_name"><a class="link" href="gst-plugins-good-plugins-udpsrc.html#GstUDPSrc--address" title="The “address” property">address</a></td>
 <td class="property_flags">Read / Write</td>
 </tr>
+<tr>
+<td class="property_type"><a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="gst-plugins-good-plugins-udpsrc.html#GstUDPSrc--loop" title="The “loop” property">loop</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -166,7 +171,7 @@
 property, udpsrc will then not allocate a socket itself but use the provided
 one.</p>
 <p>The <a class="link" href="gst-plugins-good-plugins-udpsrc.html#GstUDPSrc--caps" title="The “caps” property"><span class="type">“caps”</span></a> property is mainly used to give a type to the UDP packet
-so that they can be autoplugged in GStreamer pipelines. This is very usefull
+so that they can be autoplugged in GStreamer pipelines. This is very useful
 for RTP implementations where the contents of the UDP packets is transfered
 out-of-bounds using SDP or other means.</p>
 <p>The <a class="link" href="gst-plugins-good-plugins-udpsrc.html#GstUDPSrc--buffer-size" title="The “buffer-size” property"><span class="type">“buffer-size”</span></a> property is used to change the default kernel
@@ -420,6 +425,14 @@
 <p>Flags: Read / Write</p>
 <p>Default value: "0.0.0.0"</p>
 </div>
+<hr>
+<div class="refsect2">
+<a name="GstUDPSrc--loop"></a><h3>The <code class="literal">“loop”</code> property</h3>
+<pre class="programlisting">  “loop”                     <a href="https://developer.gnome.org/glib/unstable/glib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Used for setting the multicast loop parameter. TRUE = enable, FALSE = disable.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: TRUE</p>
+</div>
 </div>
 <div class="refsect1">
 <a name="gst-plugins-good-plugins-udpsrc.see-also"></a><h2>See Also</h2>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-v4l2sink.html b/docs/plugins/html/gst-plugins-good-plugins-v4l2sink.html
index 31d363a..dee6962 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-v4l2sink.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-v4l2sink.html
@@ -265,7 +265,7 @@
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> video/x-h264, stream-format=(string)byte-stream, alignment=(string)au</td>
+<td> video/x-h264, stream-format=(string){ byte-stream, avc }, alignment=(string)au</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
@@ -277,7 +277,7 @@
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> video/x-raw, format=(string){ RGB15, RGB16, BGR, RGB, BGRx, BGRA, xRGB, ARGB, GRAY8, YVU9, YV12, YUY2, UYVY, Y42B, Y41B, NV12_64Z32, YUV9, I420, YVYU, NV21, NV12 }, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td> video/x-raw, format=(string){ RGB16, BGR, RGB, GRAY8, GRAY16_LE, GRAY16_BE, YVU9, YV12, YUY2, YVYU, UYVY, Y42B, Y41B, YUV9, NV12_64Z32, NV24, NV61, NV16, NV21, NV12, I420, BGRA, BGRx, ARGB, xRGB, BGR15, RGB15 }, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
@@ -287,6 +287,10 @@
 <td><p><span class="term"></span></p></td>
 <td> video/x-vp8</td>
 </tr>
+<tr>
+<td><p><span class="term"></span></p></td>
+<td> video/x-wmv, wmvversion=(int)3, format=(string)WVC1</td>
+</tr>
 </tbody>
 </table></div>
 </div>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-v4l2src.html b/docs/plugins/html/gst-plugins-good-plugins-v4l2src.html
index 8d35db9..fbb4a56 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-v4l2src.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-v4l2src.html
@@ -241,7 +241,7 @@
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> video/x-h264, stream-format=(string)byte-stream, alignment=(string)au</td>
+<td> video/x-h264, stream-format=(string){ byte-stream, avc }, alignment=(string)au</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
@@ -253,7 +253,7 @@
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> video/x-raw, format=(string){ RGB15, RGB16, BGR, RGB, BGRx, BGRA, xRGB, ARGB, GRAY8, YVU9, YV12, YUY2, UYVY, Y42B, Y41B, NV12_64Z32, YUV9, I420, YVYU, NV21, NV12 }, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td> video/x-raw, format=(string){ RGB16, BGR, RGB, GRAY8, GRAY16_LE, GRAY16_BE, YVU9, YV12, YUY2, YVYU, UYVY, Y42B, Y41B, YUV9, NV12_64Z32, NV24, NV61, NV16, NV21, NV12, I420, BGRA, BGRx, ARGB, xRGB, BGR15, RGB15 }, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
@@ -263,6 +263,10 @@
 <td><p><span class="term"></span></p></td>
 <td> video/x-vp8</td>
 </tr>
+<tr>
+<td><p><span class="term"></span></p></td>
+<td> video/x-wmv, wmvversion=(int)3, format=(string)WVC1</td>
+</tr>
 </tbody>
 </table></div>
 </div>
diff --git a/docs/plugins/html/gst-plugins-good-plugins-vp8dec.html b/docs/plugins/html/gst-plugins-good-plugins-vp8dec.html
index e4215c2..dd9408d 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-vp8dec.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-vp8dec.html
@@ -90,7 +90,8 @@
         <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstObject.html">GstObject</a>
             <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html">GstElement</a>
                 <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-GstVideoDecoder.html#GstVideoDecoder">GstVideoDecoder</a>
-                    <span class="lineart">╰──</span> GstVP8Dec
+                    <span class="lineart">╰──</span> GstVPXDec
+                        <span class="lineart">╰──</span> GstVP8Dec
 </pre>
 </div>
 <div class="refsect1">
diff --git a/docs/plugins/html/gst-plugins-good-plugins-vp8enc.html b/docs/plugins/html/gst-plugins-good-plugins-vp8enc.html
index ad2dfe2..4ee469a 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-vp8enc.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-vp8enc.html
@@ -290,7 +290,8 @@
         <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstObject.html">GstObject</a>
             <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html">GstElement</a>
                 <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-GstVideoEncoder.html#GstVideoEncoder">GstVideoEncoder</a>
-                    <span class="lineart">╰──</span> GstVP8Enc
+                    <span class="lineart">╰──</span> GstVPXEnc
+                        <span class="lineart">╰──</span> GstVP8Enc
 </pre>
 </div>
 <div class="refsect1">
diff --git a/docs/plugins/html/gst-plugins-good-plugins-webmmux.html b/docs/plugins/html/gst-plugins-good-plugins-webmmux.html
index e0ac4b1..916e3ec 100644
--- a/docs/plugins/html/gst-plugins-good-plugins-webmmux.html
+++ b/docs/plugins/html/gst-plugins-good-plugins-webmmux.html
@@ -75,7 +75,7 @@
 2
 3
 4</pre></td>
-        <td class="listing_code"><pre class="programlisting">gst<span class="gtkdoc opt">-</span>launch<span class="gtkdoc opt">-</span><span class="number">0.10</span> webmmux name<span class="gtkdoc opt">=</span>mux <span class="gtkdoc opt">!</span> filesink location<span class="gtkdoc opt">=</span>newfile<span class="gtkdoc opt">.</span>webm         \
+        <td class="listing_code"><pre class="programlisting">gst<span class="gtkdoc opt">-</span>launch<span class="gtkdoc opt">-</span><span class="number">1.0</span> webmmux name<span class="gtkdoc opt">=</span>mux <span class="gtkdoc opt">!</span> filesink location<span class="gtkdoc opt">=</span>newfile<span class="gtkdoc opt">.</span>webm         \
   uridecodebin uri<span class="gtkdoc opt">=</span>file<span class="gtkdoc opt">:</span><span class="gtkdoc slc">///path/to/somefile.ogv name=demux                \</span>
   demux<span class="gtkdoc opt">. !</span> videoconvert <span class="gtkdoc opt">!</span> vp8enc <span class="gtkdoc opt">!</span> queue <span class="gtkdoc opt">!</span> mux<span class="gtkdoc opt">.</span>video_0    \
   demux<span class="gtkdoc opt">. !</span> progressreport <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> audiorate <span class="gtkdoc opt">!</span> vorbisenc <span class="gtkdoc opt">!</span> queue <span class="gtkdoc opt">!</span> mux<span class="gtkdoc opt">.</span>audio_0</pre></td>
@@ -91,7 +91,7 @@
         <td class="listing_lines" align="right"><pre>1
 2
 3</pre></td>
-        <td class="listing_code"><pre class="programlisting">gst<span class="gtkdoc opt">-</span>launch<span class="gtkdoc opt">-</span><span class="number">0.10</span> webmmux name<span class="gtkdoc opt">=</span>mux <span class="gtkdoc opt">!</span> filesink location<span class="gtkdoc opt">=</span>test<span class="gtkdoc opt">.</span>webm            \
+        <td class="listing_code"><pre class="programlisting">gst<span class="gtkdoc opt">-</span>launch<span class="gtkdoc opt">-</span><span class="number">1.0</span> webmmux name<span class="gtkdoc opt">=</span>mux <span class="gtkdoc opt">!</span> filesink location<span class="gtkdoc opt">=</span>test<span class="gtkdoc opt">.</span>webm            \
   videotestsrc num<span class="gtkdoc opt">-</span>buffers<span class="gtkdoc opt">=</span><span class="number">250</span> <span class="gtkdoc opt">!</span> video<span class="gtkdoc opt">/</span>x<span class="gtkdoc opt">-</span>raw<span class="gtkdoc opt">,</span>framerate<span class="gtkdoc opt">=</span><span class="number">25</span><span class="gtkdoc opt">/</span><span class="number">1</span> <span class="gtkdoc opt">!</span> videoconvert <span class="gtkdoc opt">!</span> vp8enc <span class="gtkdoc opt">!</span> queue <span class="gtkdoc opt">!</span> mux<span class="gtkdoc opt">.</span>video_0 \
   audiotestsrc samplesperbuffer<span class="gtkdoc opt">=</span><span class="number">44100</span> num<span class="gtkdoc opt">-</span>buffers<span class="gtkdoc opt">=</span><span class="number">10</span> <span class="gtkdoc opt">!</span> audio<span class="gtkdoc opt">/</span>x<span class="gtkdoc opt">-</span>raw<span class="gtkdoc opt">,</span>rate<span class="gtkdoc opt">=</span><span class="number">44100</span> <span class="gtkdoc opt">!</span> vorbisenc <span class="gtkdoc opt">!</span> queue <span class="gtkdoc opt">!</span> mux<span class="gtkdoc opt">.</span>audio_0</pre></td>
       </tr>
@@ -152,6 +152,10 @@
 <td><p><span class="term">details</span></p></td>
 <td>audio/x-vorbis, channels=(int)[ 1, 2147483647 ], rate=(int)[ 1, 2147483647 ]</td>
 </tr>
+<tr>
+<td><p><span class="term"></span></p></td>
+<td> audio/x-opus, channels=(int)[ 1, 2147483647 ], rate=(int)[ 1, 2147483647 ]</td>
+</tr>
 </tbody>
 </table></div>
 <div class="variablelist"><table border="0" class="variablelist">
diff --git a/docs/plugins/html/index.html b/docs/plugins/html/index.html
index ca98af4..2e206a3 100644
--- a/docs/plugins/html/index.html
+++ b/docs/plugins/html/index.html
@@ -15,7 +15,7 @@
 <div>
 <div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">GStreamer Good Plugins 1.0 Plugins Reference Manual</p></th></tr></table></div>
 <div><p class="releaseinfo">
-      for GStreamer Good Plugins 1.0 (1.6.2)
+      for GStreamer Good Plugins 1.0 (1.7.1)
       The latest version of this documentation can be found on-line at
       <a class="ulink" href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good/html/" target="_top">http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good/html/</a>.
     </p></div>
diff --git a/docs/plugins/html/index.sgml b/docs/plugins/html/index.sgml
index 069dbfd..671dc48 100644
--- a/docs/plugins/html/index.sgml
+++ b/docs/plugins/html/index.sgml
@@ -1520,6 +1520,10 @@
 <ANCHOR id="GstRtpBin--do-retransmission" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin--do-retransmission">
 <ANCHOR id="GstRtpBin--rtp-profile" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin--rtp-profile">
 <ANCHOR id="GstRtpBin--ntp-time-source" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin--ntp-time-source">
+<ANCHOR id="GstRtpBin--max-dropout-time" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin--max-dropout-time">
+<ANCHOR id="GstRtpBin--max-misorder-time" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin--max-misorder-time">
+<ANCHOR id="GstRtpBin--max-rtcp-rtp-time-diff" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin--max-rtcp-rtp-time-diff">
+<ANCHOR id="GstRtpBin--rtcp-sync-send-time" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin--rtcp-sync-send-time">
 <ANCHOR id="gst-plugins-good-plugins-rtpbin.signal-details" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#gst-plugins-good-plugins-rtpbin.signal-details">
 <ANCHOR id="GstRtpBin-clear-pt-map" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin-clear-pt-map">
 <ANCHOR id="GstRtpBin-get-internal-session" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin-get-internal-session">
@@ -1543,6 +1547,8 @@
 <ANCHOR id="GstRtpBin-request-rtcp-encoder" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin-request-rtcp-encoder">
 <ANCHOR id="GstRtpBin-request-rtp-decoder" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin-request-rtp-decoder">
 <ANCHOR id="GstRtpBin-request-rtp-encoder" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin-request-rtp-encoder">
+<ANCHOR id="GstRtpBin-on-new-sender-ssrc" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin-on-new-sender-ssrc">
+<ANCHOR id="GstRtpBin-on-sender-ssrc-active" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin-on-sender-ssrc-active">
 <ANCHOR id="gst-plugins-good-plugins-rtpbin.see-also" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#gst-plugins-good-plugins-rtpbin.see-also">
 <ANCHOR id="gst-plugins-good-plugins-rtpbvdepay" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbvdepay.html">
 <ANCHOR id="gst-plugins-good-plugins-rtpbvdepay.description" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbvdepay.html#gst-plugins-good-plugins-rtpbvdepay.description">
@@ -1667,6 +1673,7 @@
 <ANCHOR id="GstRTSPSrc--tls-interaction" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--tls-interaction">
 <ANCHOR id="GstRTSPSrc--ntp-time-source" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--ntp-time-source">
 <ANCHOR id="GstRTSPSrc--user-agent" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--user-agent">
+<ANCHOR id="GstRTSPSrc--max-rtcp-rtp-time-diff" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--max-rtcp-rtp-time-diff">
 <ANCHOR id="gst-plugins-good-plugins-rtspsrc.signal-details" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtspsrc.html#gst-plugins-good-plugins-rtspsrc.signal-details">
 <ANCHOR id="GstRTSPSrc-handle-request" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc-handle-request">
 <ANCHOR id="GstRTSPSrc-on-sdp" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc-on-sdp">
@@ -1710,6 +1717,10 @@
 <ANCHOR id="GstRtpBin--do-retransmission" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin--do-retransmission">
 <ANCHOR id="GstRtpBin--rtp-profile" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin--rtp-profile">
 <ANCHOR id="GstRtpBin--ntp-time-source" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin--ntp-time-source">
+<ANCHOR id="GstRtpBin--max-dropout-time" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin--max-dropout-time">
+<ANCHOR id="GstRtpBin--max-misorder-time" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin--max-misorder-time">
+<ANCHOR id="GstRtpBin--max-rtcp-rtp-time-diff" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin--max-rtcp-rtp-time-diff">
+<ANCHOR id="GstRtpBin--rtcp-sync-send-time" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin--rtcp-sync-send-time">
 <ANCHOR id="gst-plugins-good-plugins-rtpbin.signal-details" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#gst-plugins-good-plugins-rtpbin.signal-details">
 <ANCHOR id="GstRtpBin-clear-pt-map" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin-clear-pt-map">
 <ANCHOR id="GstRtpBin-get-internal-session" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin-get-internal-session">
@@ -1733,6 +1744,8 @@
 <ANCHOR id="GstRtpBin-request-rtcp-encoder" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin-request-rtcp-encoder">
 <ANCHOR id="GstRtpBin-request-rtp-decoder" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin-request-rtp-decoder">
 <ANCHOR id="GstRtpBin-request-rtp-encoder" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin-request-rtp-encoder">
+<ANCHOR id="GstRtpBin-on-new-sender-ssrc" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin-on-new-sender-ssrc">
+<ANCHOR id="GstRtpBin-on-sender-ssrc-active" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#GstRtpBin-on-sender-ssrc-active">
 <ANCHOR id="gst-plugins-good-plugins-rtpbin.see-also" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpbin.html#gst-plugins-good-plugins-rtpbin.see-also">
 <ANCHOR id="gst-plugins-good-plugins-rtpdec" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpdec.html">
 <ANCHOR id="gst-plugins-good-plugins-rtpdec.properties" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpdec.html#gst-plugins-good-plugins-rtpdec.properties">
@@ -1831,6 +1844,9 @@
 <ANCHOR id="GstRtpJitterBuffer--rtx-min-retry-timeout" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer--rtx-min-retry-timeout">
 <ANCHOR id="GstRtpJitterBuffer--rtx-max-retries" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer--rtx-max-retries">
 <ANCHOR id="GstRtpJitterBuffer--rtx-next-seqnum" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer--rtx-next-seqnum">
+<ANCHOR id="GstRtpJitterBuffer--max-dropout-time" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer--max-dropout-time">
+<ANCHOR id="GstRtpJitterBuffer--max-misorder-time" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer--max-misorder-time">
+<ANCHOR id="GstRtpJitterBuffer--max-rtcp-rtp-time-diff" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer--max-rtcp-rtp-time-diff">
 <ANCHOR id="gst-plugins-good-plugins-rtpjitterbuffer.signal-details" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpjitterbuffer.html#gst-plugins-good-plugins-rtpjitterbuffer.signal-details">
 <ANCHOR id="GstRtpJitterBuffer-clear-pt-map" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer-clear-pt-map">
 <ANCHOR id="GstRtpJitterBuffer-handle-sync" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpjitterbuffer.html#GstRtpJitterBuffer-handle-sync">
@@ -1981,6 +1997,9 @@
 <ANCHOR id="GstRtpSession--stats" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpsession.html#GstRtpSession--stats">
 <ANCHOR id="GstRtpSession--rtp-profile" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpsession.html#GstRtpSession--rtp-profile">
 <ANCHOR id="GstRtpSession--ntp-time-source" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpsession.html#GstRtpSession--ntp-time-source">
+<ANCHOR id="GstRtpSession--max-dropout-time" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpsession.html#GstRtpSession--max-dropout-time">
+<ANCHOR id="GstRtpSession--max-misorder-time" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpsession.html#GstRtpSession--max-misorder-time">
+<ANCHOR id="GstRtpSession--rtcp-sync-send-time" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpsession.html#GstRtpSession--rtcp-sync-send-time">
 <ANCHOR id="gst-plugins-good-plugins-rtpsession.signal-details" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpsession.html#gst-plugins-good-plugins-rtpsession.signal-details">
 <ANCHOR id="GstRtpSession-clear-pt-map" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpsession.html#GstRtpSession-clear-pt-map">
 <ANCHOR id="GstRtpSession-on-bye-ssrc" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpsession.html#GstRtpSession-on-bye-ssrc">
@@ -1993,6 +2012,8 @@
 <ANCHOR id="GstRtpSession-on-ssrc-validated" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpsession.html#GstRtpSession-on-ssrc-validated">
 <ANCHOR id="GstRtpSession-on-timeout" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpsession.html#GstRtpSession-on-timeout">
 <ANCHOR id="GstRtpSession-request-pt-map" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpsession.html#GstRtpSession-request-pt-map">
+<ANCHOR id="GstRtpSession-on-new-sender-ssrc" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpsession.html#GstRtpSession-on-new-sender-ssrc">
+<ANCHOR id="GstRtpSession-on-sender-ssrc-active" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpsession.html#GstRtpSession-on-sender-ssrc-active">
 <ANCHOR id="gst-plugins-good-plugins-rtpsession.see-also" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpsession.html#gst-plugins-good-plugins-rtpsession.see-also">
 <ANCHOR id="gst-plugins-good-plugins-rtpssrcdemux" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpssrcdemux.html">
 <ANCHOR id="gst-plugins-good-plugins-rtpssrcdemux.signals" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtpssrcdemux.html#gst-plugins-good-plugins-rtpssrcdemux.signals">
@@ -2053,6 +2074,7 @@
 <ANCHOR id="GstRTSPSrc--tls-interaction" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--tls-interaction">
 <ANCHOR id="GstRTSPSrc--ntp-time-source" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--ntp-time-source">
 <ANCHOR id="GstRTSPSrc--user-agent" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--user-agent">
+<ANCHOR id="GstRTSPSrc--max-rtcp-rtp-time-diff" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc--max-rtcp-rtp-time-diff">
 <ANCHOR id="gst-plugins-good-plugins-rtspsrc.signal-details" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtspsrc.html#gst-plugins-good-plugins-rtspsrc.signal-details">
 <ANCHOR id="GstRTSPSrc-handle-request" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc-handle-request">
 <ANCHOR id="GstRTSPSrc-on-sdp" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-rtspsrc.html#GstRTSPSrc-on-sdp">
@@ -2202,6 +2224,7 @@
 <ANCHOR id="GstSoupHTTPSrc--ssl-use-system-ca-file" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-souphttpsrc.html#GstSoupHTTPSrc--ssl-use-system-ca-file">
 <ANCHOR id="GstSoupHTTPSrc--tls-database" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-souphttpsrc.html#GstSoupHTTPSrc--tls-database">
 <ANCHOR id="GstSoupHTTPSrc--method" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-souphttpsrc.html#GstSoupHTTPSrc--method">
+<ANCHOR id="GstSoupHTTPSrc--tls-interaction" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-souphttpsrc.html#GstSoupHTTPSrc--tls-interaction">
 <ANCHOR id="gst-plugins-good-plugins-spectrum" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-spectrum.html">
 <ANCHOR id="gst-plugins-good-plugins-spectrum.properties" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-spectrum.html#gst-plugins-good-plugins-spectrum.properties">
 <ANCHOR id="GstSpectrum" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-spectrum.html#GstSpectrum">
@@ -2357,6 +2380,7 @@
 <ANCHOR id="GstUDPSrc--socket" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-udpsrc.html#GstUDPSrc--socket">
 <ANCHOR id="GstUDPSrc--used-socket" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-udpsrc.html#GstUDPSrc--used-socket">
 <ANCHOR id="GstUDPSrc--address" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-udpsrc.html#GstUDPSrc--address">
+<ANCHOR id="GstUDPSrc--loop" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-udpsrc.html#GstUDPSrc--loop">
 <ANCHOR id="gst-plugins-good-plugins-udpsrc.see-also" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-udpsrc.html#gst-plugins-good-plugins-udpsrc.see-also">
 <ANCHOR id="gst-plugins-good-plugins-v4l2radio" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-v4l2radio.html">
 <ANCHOR id="gst-plugins-good-plugins-v4l2radio.properties" href="gst-plugins-good-plugins-1.0/gst-plugins-good-plugins-v4l2radio.html#gst-plugins-good-plugins-v4l2radio.properties">
diff --git a/docs/plugins/inspect/plugin-1394.xml b/docs/plugins/inspect/plugin-1394.xml
index cd14ff7..4352b53 100644
--- a/docs/plugins/inspect/plugin-1394.xml
+++ b/docs/plugins/inspect/plugin-1394.xml
@@ -3,7 +3,7 @@
   <description>Source for video data via IEEE1394 interface</description>
   <filename>../../ext/raw1394/.libs/libgst1394.so</filename>
   <basename>libgst1394.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-aasink.xml b/docs/plugins/inspect/plugin-aasink.xml
index d46997a..e432d0e 100644
--- a/docs/plugins/inspect/plugin-aasink.xml
+++ b/docs/plugins/inspect/plugin-aasink.xml
@@ -3,7 +3,7 @@
   <description>ASCII Art video sink</description>
   <filename>../../ext/aalib/.libs/libgstaasink.so</filename>
   <basename>libgstaasink.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-alaw.xml b/docs/plugins/inspect/plugin-alaw.xml
index 8733e45..75e5913 100644
--- a/docs/plugins/inspect/plugin-alaw.xml
+++ b/docs/plugins/inspect/plugin-alaw.xml
@@ -3,7 +3,7 @@
   <description>ALaw audio conversion routines</description>
   <filename>../../gst/law/.libs/libgstalaw.so</filename>
   <basename>libgstalaw.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-alpha.xml b/docs/plugins/inspect/plugin-alpha.xml
index 6da9153..cb9f1c3 100644
--- a/docs/plugins/inspect/plugin-alpha.xml
+++ b/docs/plugins/inspect/plugin-alpha.xml
@@ -3,7 +3,7 @@
   <description>adds an alpha channel to video - constant or via chroma-keying</description>
   <filename>../../gst/alpha/.libs/libgstalpha.so</filename>
   <basename>libgstalpha.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-alphacolor.xml b/docs/plugins/inspect/plugin-alphacolor.xml
index 2aac441..a49bbca 100644
--- a/docs/plugins/inspect/plugin-alphacolor.xml
+++ b/docs/plugins/inspect/plugin-alphacolor.xml
@@ -3,7 +3,7 @@
   <description>RGBA from/to AYUV colorspace conversion preserving the alpha channel</description>
   <filename>../../gst/alpha/.libs/libgstalphacolor.so</filename>
   <basename>libgstalphacolor.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-apetag.xml b/docs/plugins/inspect/plugin-apetag.xml
index e5149ae..8d3ebfd 100644
--- a/docs/plugins/inspect/plugin-apetag.xml
+++ b/docs/plugins/inspect/plugin-apetag.xml
@@ -3,7 +3,7 @@
   <description>APEv1/2 tag reader</description>
   <filename>../../gst/apetag/.libs/libgstapetag.so</filename>
   <basename>libgstapetag.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-audiofx.xml b/docs/plugins/inspect/plugin-audiofx.xml
index 374cac8..9be69df 100644
--- a/docs/plugins/inspect/plugin-audiofx.xml
+++ b/docs/plugins/inspect/plugin-audiofx.xml
@@ -3,7 +3,7 @@
   <description>Audio effects plugin</description>
   <filename>../../gst/audiofx/.libs/libgstaudiofx.so</filename>
   <basename>libgstaudiofx.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
@@ -272,13 +272,13 @@
           <name>sink</name>
           <direction>sink</direction>
           <presence>always</presence>
-          <details>audio/x-raw, format=(string)F32LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]; audio/x-raw, format=(string)S16LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]</details>
+          <details>audio/x-raw, format=(string)F32LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]; audio/x-raw, format=(string)F64LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]; audio/x-raw, format=(string)S16LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]</details>
         </caps>
         <caps>
           <name>src</name>
           <direction>source</direction>
           <presence>always</presence>
-          <details>audio/x-raw, format=(string)F32LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]; audio/x-raw, format=(string)S16LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]</details>
+          <details>audio/x-raw, format=(string)F32LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]; audio/x-raw, format=(string)F64LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]; audio/x-raw, format=(string)S16LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]</details>
         </caps>
       </pads>
     </element>
diff --git a/docs/plugins/inspect/plugin-audioparsers.xml b/docs/plugins/inspect/plugin-audioparsers.xml
index 327b3eb..00274de 100644
--- a/docs/plugins/inspect/plugin-audioparsers.xml
+++ b/docs/plugins/inspect/plugin-audioparsers.xml
@@ -3,7 +3,7 @@
   <description>Parsers for various audio formats</description>
   <filename>../../gst/audioparsers/.libs/libgstaudioparsers.so</filename>
   <basename>libgstaudioparsers.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-auparse.xml b/docs/plugins/inspect/plugin-auparse.xml
index b17ed26..bffb04c 100644
--- a/docs/plugins/inspect/plugin-auparse.xml
+++ b/docs/plugins/inspect/plugin-auparse.xml
@@ -3,7 +3,7 @@
   <description>parses au streams</description>
   <filename>../../gst/auparse/.libs/libgstauparse.so</filename>
   <basename>libgstauparse.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-autodetect.xml b/docs/plugins/inspect/plugin-autodetect.xml
index a615c7a..e637384 100644
--- a/docs/plugins/inspect/plugin-autodetect.xml
+++ b/docs/plugins/inspect/plugin-autodetect.xml
@@ -3,7 +3,7 @@
   <description>Plugin contains auto-detection plugins for video/audio in- and outputs</description>
   <filename>../../gst/autodetect/.libs/libgstautodetect.so</filename>
   <basename>libgstautodetect.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-avi.xml b/docs/plugins/inspect/plugin-avi.xml
index 20379a9..aec863b 100644
--- a/docs/plugins/inspect/plugin-avi.xml
+++ b/docs/plugins/inspect/plugin-avi.xml
@@ -3,7 +3,7 @@
   <description>AVI stream handling</description>
   <filename>../../gst/avi/.libs/libgstavi.so</filename>
   <basename>libgstavi.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
@@ -44,7 +44,7 @@
           <name>video_%u</name>
           <direction>source</direction>
           <presence>sometimes</presence>
-          <details>video/mpeg, mpegversion=(int)4, systemstream=(boolean)false, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-asus, asusversion=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-asus, asusversion=(int)2, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-cirrus-logic-accupak, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-camstudio, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-compressed-yuv, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-raw, format=(string){ RGB8P, BGR, BGRx }, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-divx, divxversion=(int)3, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-divx, divxversion=(int)4, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-truemotion, trueversion=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-dv, systemstream=(boolean)false, dvversion=(int)25, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-dv, systemstream=(boolean)false, dvversion=(int)50, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-divx, divxversion=(int)5, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/mpeg, mpegversion=(int)4, systemstream=(boolean)false, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-flash-video, flvversion=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-vp6-flash, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, variant=(string)itu, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, variant=(string)lucent, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h264, variant=(string)itu, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-huffyuv, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-intel-h263, variant=(string)intel, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-raw, format=(string)I420, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-indeo, indeoversion=(int)3, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-indeo, indeoversion=(int)4, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-indeo, indeoversion=(int)5, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, variant=(string)lead, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h264, variant=(string)lead, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, variant=(string)microsoft, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/mpeg, mpegversion=(int)4, systemstream=(boolean)false, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; image/jpeg, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-msmpeg, msmpegversion=(int)42, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-msmpeg, msmpegversion=(int)43, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/mpeg, systemstream=(boolean)false, mpegversion=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/mpeg, systemstream=(boolean)false, mpegversion=(int)2, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-msmpeg, msmpegversion=(int)41, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-mszh, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; image/png, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-rle, layout=(string)microsoft, depth=(int)[ 1, 64 ], framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-indeo, indeoversion=(int)2, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/sp5x, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-truemotion, trueversion=(int)2, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-camtasia, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-ultimotion, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-raw, format=(string)UYVY, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-ati-vcr, vcrversion=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-ati-vcr, vcrversion=(int)2, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, variant=(string)vdolive, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, variant=(string)vivo, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-vmnc, version=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-vp3, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h264, variant=(string)videosoft, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-wmv, wmvversion=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-wmv, wmvversion=(int)2, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-wmv, wmvversion=(int)3, format=(string)WMV3, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/mpeg, mpegversion=(int)4, systemstream=(boolean)false, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-xan, wcversion=(int)4, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-raw, format=(string)YUY2, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-raw, format=(string)YVU9, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-zlib, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-cinepak, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h264, variant=(string)itu, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-msvideocodec, msvideoversion=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, variant=(string)xirlink, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-dirac, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-ffv, ffvversion=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-kmvc, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-vp5, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-vp6, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-vp6-flash, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-vp7, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-vp8, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-mimic, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-apple-video, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-theora, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-fraps, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-aasc, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-raw, format=(string)YV12, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-loco, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-zmbv, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-raw, format=(string)v210, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-raw, format=(string)r210, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-dv, systemstream=(boolean)true; video/x-avi-unknown</details>
+          <details>video/mpeg, mpegversion=(int)4, systemstream=(boolean)false, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-asus, asusversion=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-asus, asusversion=(int)2, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-cirrus-logic-accupak, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-camstudio, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-compressed-yuv, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-raw, format=(string){ RGB8P, BGR, BGRx }, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-divx, divxversion=(int)3, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-divx, divxversion=(int)4, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-truemotion, trueversion=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-dv, systemstream=(boolean)false, dvversion=(int)25, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-dv, systemstream=(boolean)false, dvversion=(int)50, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-divx, divxversion=(int)5, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/mpeg, mpegversion=(int)4, systemstream=(boolean)false, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-flash-video, flvversion=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-vp6-flash, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, variant=(string)itu, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, variant=(string)lucent, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h264, variant=(string)itu, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-huffyuv, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-intel-h263, variant=(string)intel, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-raw, format=(string)I420, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-indeo, indeoversion=(int)3, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-indeo, indeoversion=(int)4, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-indeo, indeoversion=(int)5, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, variant=(string)lead, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h264, variant=(string)lead, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, variant=(string)microsoft, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/mpeg, mpegversion=(int)4, systemstream=(boolean)false, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; image/jpeg, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-msmpeg, msmpegversion=(int)42, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-msmpeg, msmpegversion=(int)43, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/mpeg, systemstream=(boolean)false, mpegversion=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/mpeg, systemstream=(boolean)false, mpegversion=(int)2, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-msmpeg, msmpegversion=(int)41, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-mszh, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; image/png, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-rle, layout=(string)microsoft, depth=(int)[ 1, 64 ], framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-indeo, indeoversion=(int)2, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/sp5x, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-truemotion, trueversion=(int)2, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-camtasia, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-ultimotion, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-raw, format=(string)UYVY, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-ati-vcr, vcrversion=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-ati-vcr, vcrversion=(int)2, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, variant=(string)vdolive, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, variant=(string)vivo, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-vmnc, version=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-vp3, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h264, variant=(string)videosoft, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-wmv, wmvversion=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-wmv, wmvversion=(int)2, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-wmv, wmvversion=(int)3, format=(string)WMV3, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/mpeg, mpegversion=(int)4, systemstream=(boolean)false, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-xan, wcversion=(int)4, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-raw, format=(string)YUY2, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-zlib, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-cinepak, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h264, variant=(string)itu, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-msvideocodec, msvideoversion=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-h263, variant=(string)xirlink, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-dirac, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-ffv, ffvversion=(int)1, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-kmvc, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-vp5, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-vp6, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-vp6-flash, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-vp7, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-vp8, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-mimic, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-apple-video, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-theora, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-fraps, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-aasc, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-raw, format=(string)YV12, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-loco, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-zmbv, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-raw, format=(string)v210, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-raw, format=(string)r210, framerate=(fraction)[ 0/1, 2147483647/1 ], width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ]; video/x-dv, systemstream=(boolean)true; video/x-avi-unknown</details>
         </caps>
       </pads>
     </element>
diff --git a/docs/plugins/inspect/plugin-cacasink.xml b/docs/plugins/inspect/plugin-cacasink.xml
index 9adfea9..5bf7d1c 100644
--- a/docs/plugins/inspect/plugin-cacasink.xml
+++ b/docs/plugins/inspect/plugin-cacasink.xml
@@ -3,7 +3,7 @@
   <description>Colored ASCII Art video sink</description>
   <filename>../../ext/libcaca/.libs/libgstcacasink.so</filename>
   <basename>libgstcacasink.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-cairo.xml b/docs/plugins/inspect/plugin-cairo.xml
index be902ee..fe6980b 100644
--- a/docs/plugins/inspect/plugin-cairo.xml
+++ b/docs/plugins/inspect/plugin-cairo.xml
@@ -3,7 +3,7 @@
   <description>Cairo-based elements</description>
   <filename>../../ext/cairo/.libs/libgstcairo.so</filename>
   <basename>libgstcairo.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-cutter.xml b/docs/plugins/inspect/plugin-cutter.xml
index feb1ee2..2ac57da 100644
--- a/docs/plugins/inspect/plugin-cutter.xml
+++ b/docs/plugins/inspect/plugin-cutter.xml
@@ -3,7 +3,7 @@
   <description>Audio Cutter to split audio into non-silent bits</description>
   <filename>../../gst/cutter/.libs/libgstcutter.so</filename>
   <basename>libgstcutter.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-debug.xml b/docs/plugins/inspect/plugin-debug.xml
index 9eec626..aab3bee 100644
--- a/docs/plugins/inspect/plugin-debug.xml
+++ b/docs/plugins/inspect/plugin-debug.xml
@@ -3,7 +3,7 @@
   <description>elements for testing and debugging</description>
   <filename>../../gst/debugutils/.libs/libgstdebug.so</filename>
   <basename>libgstdebug.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-deinterlace.xml b/docs/plugins/inspect/plugin-deinterlace.xml
index 4b77ed5..f1484e0 100644
--- a/docs/plugins/inspect/plugin-deinterlace.xml
+++ b/docs/plugins/inspect/plugin-deinterlace.xml
@@ -3,7 +3,7 @@
   <description>Deinterlacer</description>
   <filename>../../gst/deinterlace/.libs/libgstdeinterlace.so</filename>
   <basename>libgstdeinterlace.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-dtmf.xml b/docs/plugins/inspect/plugin-dtmf.xml
index 08c3f67..2c47f2e 100644
--- a/docs/plugins/inspect/plugin-dtmf.xml
+++ b/docs/plugins/inspect/plugin-dtmf.xml
@@ -3,7 +3,7 @@
   <description>DTMF plugins</description>
   <filename>../../gst/dtmf/.libs/libgstdtmf.so</filename>
   <basename>libgstdtmf.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-dv.xml b/docs/plugins/inspect/plugin-dv.xml
index 183cc9b..54e1991 100644
--- a/docs/plugins/inspect/plugin-dv.xml
+++ b/docs/plugins/inspect/plugin-dv.xml
@@ -3,7 +3,7 @@
   <description>DV demuxer and decoder based on libdv (libdv.sf.net)</description>
   <filename>../../ext/dv/.libs/libgstdv.so</filename>
   <basename>libgstdv.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-effectv.xml b/docs/plugins/inspect/plugin-effectv.xml
index 88e4d0e..8b1ac54 100644
--- a/docs/plugins/inspect/plugin-effectv.xml
+++ b/docs/plugins/inspect/plugin-effectv.xml
@@ -3,7 +3,7 @@
   <description>effect plugins from the effectv project</description>
   <filename>../../gst/effectv/.libs/libgsteffectv.so</filename>
   <basename>libgsteffectv.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-equalizer.xml b/docs/plugins/inspect/plugin-equalizer.xml
index 73d5768..0d518c8 100644
--- a/docs/plugins/inspect/plugin-equalizer.xml
+++ b/docs/plugins/inspect/plugin-equalizer.xml
@@ -3,7 +3,7 @@
   <description>GStreamer audio equalizers</description>
   <filename>../../gst/equalizer/.libs/libgstequalizer.so</filename>
   <basename>libgstequalizer.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-flac.xml b/docs/plugins/inspect/plugin-flac.xml
index a74497b..62a17bc 100644
--- a/docs/plugins/inspect/plugin-flac.xml
+++ b/docs/plugins/inspect/plugin-flac.xml
@@ -3,7 +3,7 @@
   <description>The FLAC Lossless compressor Codec</description>
   <filename>../../ext/flac/.libs/libgstflac.so</filename>
   <basename>libgstflac.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-flv.xml b/docs/plugins/inspect/plugin-flv.xml
index ceec696..ad45b0d 100644
--- a/docs/plugins/inspect/plugin-flv.xml
+++ b/docs/plugins/inspect/plugin-flv.xml
@@ -3,7 +3,7 @@
   <description>FLV muxing and demuxing plugin</description>
   <filename>../../gst/flv/.libs/libgstflv.so</filename>
   <basename>libgstflv.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-flxdec.xml b/docs/plugins/inspect/plugin-flxdec.xml
index 7d56a16..299d775 100644
--- a/docs/plugins/inspect/plugin-flxdec.xml
+++ b/docs/plugins/inspect/plugin-flxdec.xml
@@ -3,7 +3,7 @@
   <description>FLC/FLI/FLX video decoder</description>
   <filename>../../gst/flx/.libs/libgstflxdec.so</filename>
   <basename>libgstflxdec.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-gdkpixbuf.xml b/docs/plugins/inspect/plugin-gdkpixbuf.xml
index 0ee6030..c1d7114 100644
--- a/docs/plugins/inspect/plugin-gdkpixbuf.xml
+++ b/docs/plugins/inspect/plugin-gdkpixbuf.xml
@@ -3,7 +3,7 @@
   <description>GdkPixbuf-based image decoder, overlay and sink</description>
   <filename>../../ext/gdk_pixbuf/.libs/libgstgdkpixbuf.so</filename>
   <basename>libgstgdkpixbuf.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-goom.xml b/docs/plugins/inspect/plugin-goom.xml
index ce9b092..00df088 100644
--- a/docs/plugins/inspect/plugin-goom.xml
+++ b/docs/plugins/inspect/plugin-goom.xml
@@ -3,7 +3,7 @@
   <description>GOOM visualization filter</description>
   <filename>../../gst/goom/.libs/libgstgoom.so</filename>
   <basename>libgstgoom.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-goom2k1.xml b/docs/plugins/inspect/plugin-goom2k1.xml
index 239b1c4..7d0c108 100644
--- a/docs/plugins/inspect/plugin-goom2k1.xml
+++ b/docs/plugins/inspect/plugin-goom2k1.xml
@@ -3,7 +3,7 @@
   <description>GOOM 2k1 visualization filter</description>
   <filename>../../gst/goom2k1/.libs/libgstgoom2k1.so</filename>
   <basename>libgstgoom2k1.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-icydemux.xml b/docs/plugins/inspect/plugin-icydemux.xml
index 47a610d..5f243c1 100644
--- a/docs/plugins/inspect/plugin-icydemux.xml
+++ b/docs/plugins/inspect/plugin-icydemux.xml
@@ -3,7 +3,7 @@
   <description>Demux ICY tags from a stream</description>
   <filename>../../gst/icydemux/.libs/libgsticydemux.so</filename>
   <basename>libgsticydemux.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-id3demux.xml b/docs/plugins/inspect/plugin-id3demux.xml
index 88ef546..8f6af4c 100644
--- a/docs/plugins/inspect/plugin-id3demux.xml
+++ b/docs/plugins/inspect/plugin-id3demux.xml
@@ -3,7 +3,7 @@
   <description>Demux ID3v1 and ID3v2 tags from a file</description>
   <filename>../../gst/id3demux/.libs/libgstid3demux.so</filename>
   <basename>libgstid3demux.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-imagefreeze.xml b/docs/plugins/inspect/plugin-imagefreeze.xml
index ee7883f..b63e090 100644
--- a/docs/plugins/inspect/plugin-imagefreeze.xml
+++ b/docs/plugins/inspect/plugin-imagefreeze.xml
@@ -3,7 +3,7 @@
   <description>Still frame stream generator</description>
   <filename>../../gst/imagefreeze/.libs/libgstimagefreeze.so</filename>
   <basename>libgstimagefreeze.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-interleave.xml b/docs/plugins/inspect/plugin-interleave.xml
index 7a92591..3d8d887 100644
--- a/docs/plugins/inspect/plugin-interleave.xml
+++ b/docs/plugins/inspect/plugin-interleave.xml
@@ -3,7 +3,7 @@
   <description>Audio interleaver/deinterleaver</description>
   <filename>../../gst/interleave/.libs/libgstinterleave.so</filename>
   <basename>libgstinterleave.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-isomp4.xml b/docs/plugins/inspect/plugin-isomp4.xml
index 5432f57..aa43a06 100644
--- a/docs/plugins/inspect/plugin-isomp4.xml
+++ b/docs/plugins/inspect/plugin-isomp4.xml
@@ -3,7 +3,7 @@
   <description>ISO base media file format support (mp4, 3gpp, qt, mj2)</description>
   <filename>../../gst/isomp4/.libs/libgstisomp4.so</filename>
   <basename>libgstisomp4.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
@@ -80,7 +80,7 @@
           <name>audio_%u</name>
           <direction>sink</direction>
           <presence>request</presence>
-          <details>audio/x-raw, format=(string){ S8, U8 }, layout=(string)interleaved, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]; audio/x-raw, format=(string){ S16LE, S16BE }, layout=(string)interleaved, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]</details>
+          <details>audio/x-raw, format=(string){ S16LE, S16BE, S8, U8 }, layout=(string)interleaved, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]</details>
         </caps>
         <caps>
           <name>video_%u</name>
@@ -107,7 +107,7 @@
           <name>audio_%u</name>
           <direction>sink</direction>
           <presence>request</presence>
-          <details>audio/mpeg, mpegversion=(int)1, layer=(int)3, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]; audio/mpeg, mpegversion=(int)4, stream-format=(string)raw, channels=(int)[ 1, 8 ], rate=(int)[ 1, 2147483647 ]; audio/x-ac3, channels=(int)[ 1, 6 ], rate=(int)[ 1, 2147483647 ]; audio/x-alac, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]</details>
+          <details>audio/mpeg, mpegversion=(int)1, layer=(int)3, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]; audio/mpeg, mpegversion=(int)4, stream-format=(string)raw, channels=(int)[ 1, 8 ], rate=(int)[ 1, 2147483647 ]; audio/x-ac3, channels=(int)[ 1, 6 ], rate=(int)[ 1, 2147483647 ]; audio/x-alac, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]; audio/x-opus, channel-mapping-family=(int)[ 0, 255 ], channels=(int)[ 1, 8 ], rate=(int)[ 1, 2147483647 ]</details>
         </caps>
         <caps>
           <name>subtitle_%u</name>
@@ -182,7 +182,7 @@
           <name>audio_%u</name>
           <direction>sink</direction>
           <presence>request</presence>
-          <details>audio/x-raw, format=(string){ S32LE, S32BE, S24LE, S24BE }, layout=(string)interleaved, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]; audio/x-raw, format=(string){ S8, U8 }, layout=(string)interleaved, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]; audio/x-raw, format=(string){ S16LE, S16BE }, layout=(string)interleaved, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]; audio/mpeg, mpegversion=(int)1, layer=(int)3, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]; audio/mpeg, mpegversion=(int)4, stream-format=(string)raw, channels=(int)[ 1, 8 ], rate=(int)[ 1, 2147483647 ]; audio/x-adpcm, layout=(string)dvi, block_align=(int)[ 64, 8096 ], channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]; audio/x-alaw, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]; audio/x-mulaw, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]; audio/AMR, rate=(int)8000, channels=(int)[ 1, 2 ]; audio/AMR-WB, rate=(int)16000, channels=(int)[ 1, 2 ]; audio/x-alac, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]</details>
+          <details>audio/x-raw, format=(string){ S32LE, S32BE, S24LE, S24BE, S16LE, S16BE, S8, U8 }, layout=(string)interleaved, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]; audio/mpeg, mpegversion=(int)1, layer=(int)3, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]; audio/mpeg, mpegversion=(int)4, stream-format=(string)raw, channels=(int)[ 1, 8 ], rate=(int)[ 1, 2147483647 ]; audio/x-adpcm, layout=(string)dvi, block_align=(int)[ 64, 8096 ], channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]; audio/x-alaw, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]; audio/x-mulaw, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]; audio/AMR, rate=(int)8000, channels=(int)[ 1, 2 ]; audio/AMR-WB, rate=(int)16000, channels=(int)[ 1, 2 ]; audio/x-alac, channels=(int)[ 1, 2 ], rate=(int)[ 1, 2147483647 ]</details>
         </caps>
         <caps>
           <name>subtitle_%u</name>
diff --git a/docs/plugins/inspect/plugin-jack.xml b/docs/plugins/inspect/plugin-jack.xml
index 773abe6..accc864 100644
--- a/docs/plugins/inspect/plugin-jack.xml
+++ b/docs/plugins/inspect/plugin-jack.xml
@@ -3,7 +3,7 @@
   <description>JACK audio elements</description>
   <filename>../../ext/jack/.libs/libgstjack.so</filename>
   <basename>libgstjack.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-jpeg.xml b/docs/plugins/inspect/plugin-jpeg.xml
index 9588eb3..b527dee 100644
--- a/docs/plugins/inspect/plugin-jpeg.xml
+++ b/docs/plugins/inspect/plugin-jpeg.xml
@@ -3,7 +3,7 @@
   <description>JPeg plugin library</description>
   <filename>../../ext/jpeg/.libs/libgstjpeg.so</filename>
   <basename>libgstjpeg.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-level.xml b/docs/plugins/inspect/plugin-level.xml
index 308b545..8055bbd 100644
--- a/docs/plugins/inspect/plugin-level.xml
+++ b/docs/plugins/inspect/plugin-level.xml
@@ -3,7 +3,7 @@
   <description>Audio level plugin</description>
   <filename>../../gst/level/.libs/libgstlevel.so</filename>
   <basename>libgstlevel.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-matroska.xml b/docs/plugins/inspect/plugin-matroska.xml
index 382ed4c..f658fad 100644
--- a/docs/plugins/inspect/plugin-matroska.xml
+++ b/docs/plugins/inspect/plugin-matroska.xml
@@ -3,7 +3,7 @@
   <description>Matroska and WebM stream handling</description>
   <filename>../../gst/matroska/.libs/libgstmatroska.so</filename>
   <basename>libgstmatroska.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
@@ -65,7 +65,7 @@
           <name>video_%u</name>
           <direction>sink</direction>
           <presence>request</presence>
-          <details>video/mpeg, mpegversion=(int){ 1, 2, 4 }, systemstream=(boolean)false, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-h264, stream-format=(string)avc, alignment=(string)au, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-h265, stream-format=(string)hvc1, alignment=(string)au, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-divx, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-huffyuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-dv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-h263, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-msmpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; image/jpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-theora; video/x-dirac, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-pn-realvideo, rmversion=(int)[ 1, 4 ], width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-vp8, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-raw, format=(string){ YUY2, I420, YV12, UYVY, AYUV, GRAY8, BGR, RGB }, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-wmv, wmvversion=(int)[ 1, 3 ], width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]</details>
+          <details>video/mpeg, mpegversion=(int){ 1, 2, 4 }, systemstream=(boolean)false, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-h264, stream-format=(string)avc, alignment=(string)au, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-h265, stream-format=(string)hvc1, alignment=(string)au, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-divx, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-huffyuv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-dv, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-h263, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-msmpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; image/jpeg, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-theora; video/x-dirac, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-pn-realvideo, rmversion=(int)[ 1, 4 ], width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-vp8, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-vp9, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-raw, format=(string){ YUY2, I420, YV12, UYVY, AYUV, GRAY8, BGR, RGB }, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-prores, width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-wmv, wmvversion=(int)[ 1, 3 ], width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]</details>
         </caps>
         <caps>
           <name>src</name>
@@ -107,7 +107,7 @@
           <name>audio_%u</name>
           <direction>sink</direction>
           <presence>request</presence>
-          <details>audio/x-vorbis, channels=(int)[ 1, 2147483647 ], rate=(int)[ 1, 2147483647 ]</details>
+          <details>audio/x-vorbis, channels=(int)[ 1, 2147483647 ], rate=(int)[ 1, 2147483647 ]; audio/x-opus, channels=(int)[ 1, 2147483647 ], rate=(int)[ 1, 2147483647 ]</details>
         </caps>
         <caps>
           <name>subtitle_%u</name>
diff --git a/docs/plugins/inspect/plugin-mulaw.xml b/docs/plugins/inspect/plugin-mulaw.xml
index d8edf1f..3c88705 100644
--- a/docs/plugins/inspect/plugin-mulaw.xml
+++ b/docs/plugins/inspect/plugin-mulaw.xml
@@ -3,7 +3,7 @@
   <description>MuLaw audio conversion routines</description>
   <filename>../../gst/law/.libs/libgstmulaw.so</filename>
   <basename>libgstmulaw.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-multifile.xml b/docs/plugins/inspect/plugin-multifile.xml
index 3fa202b..84f923d 100644
--- a/docs/plugins/inspect/plugin-multifile.xml
+++ b/docs/plugins/inspect/plugin-multifile.xml
@@ -3,7 +3,7 @@
   <description>Reads/Writes buffers from/to sequentially named files</description>
   <filename>../../gst/multifile/.libs/libgstmultifile.so</filename>
   <basename>libgstmultifile.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-multipart.xml b/docs/plugins/inspect/plugin-multipart.xml
index d07e3e1..bb14155 100644
--- a/docs/plugins/inspect/plugin-multipart.xml
+++ b/docs/plugins/inspect/plugin-multipart.xml
@@ -3,7 +3,7 @@
   <description>multipart stream manipulation</description>
   <filename>../../gst/multipart/.libs/libgstmultipart.so</filename>
   <basename>libgstmultipart.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-navigationtest.xml b/docs/plugins/inspect/plugin-navigationtest.xml
index a80a959..6d6e3bc 100644
--- a/docs/plugins/inspect/plugin-navigationtest.xml
+++ b/docs/plugins/inspect/plugin-navigationtest.xml
@@ -3,7 +3,7 @@
   <description>Template for a video filter</description>
   <filename>../../gst/debugutils/.libs/libgstnavigationtest.so</filename>
   <basename>libgstnavigationtest.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-oss4.xml b/docs/plugins/inspect/plugin-oss4.xml
index e02b9f9..c478176 100644
--- a/docs/plugins/inspect/plugin-oss4.xml
+++ b/docs/plugins/inspect/plugin-oss4.xml
@@ -3,7 +3,7 @@
   <description>Open Sound System (OSS) version 4 support for GStreamer</description>
   <filename>../../sys/oss4/.libs/libgstoss4audio.so</filename>
   <basename>libgstoss4audio.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-ossaudio.xml b/docs/plugins/inspect/plugin-ossaudio.xml
index 4fac164..672b426 100644
--- a/docs/plugins/inspect/plugin-ossaudio.xml
+++ b/docs/plugins/inspect/plugin-ossaudio.xml
@@ -3,7 +3,7 @@
   <description>OSS (Open Sound System) support for GStreamer</description>
   <filename>../../sys/oss/.libs/libgstossaudio.so</filename>
   <basename>libgstossaudio.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-png.xml b/docs/plugins/inspect/plugin-png.xml
index 783d139..6c6d710 100644
--- a/docs/plugins/inspect/plugin-png.xml
+++ b/docs/plugins/inspect/plugin-png.xml
@@ -3,7 +3,7 @@
   <description>PNG plugin library</description>
   <filename>../../ext/libpng/.libs/libgstpng.so</filename>
   <basename>libgstpng.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-pulseaudio.xml b/docs/plugins/inspect/plugin-pulseaudio.xml
index c85a960..a632c83 100644
--- a/docs/plugins/inspect/plugin-pulseaudio.xml
+++ b/docs/plugins/inspect/plugin-pulseaudio.xml
@@ -3,7 +3,7 @@
   <description>PulseAudio plugin library</description>
   <filename>../../ext/pulse/.libs/libgstpulse.so</filename>
   <basename>libgstpulse.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-replaygain.xml b/docs/plugins/inspect/plugin-replaygain.xml
index 5e7cb53..32e8544 100644
--- a/docs/plugins/inspect/plugin-replaygain.xml
+++ b/docs/plugins/inspect/plugin-replaygain.xml
@@ -3,7 +3,7 @@
   <description>ReplayGain volume normalization</description>
   <filename>../../gst/replaygain/.libs/libgstreplaygain.so</filename>
   <basename>libgstreplaygain.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-rtp.xml b/docs/plugins/inspect/plugin-rtp.xml
index 9f29598..266de86 100644
--- a/docs/plugins/inspect/plugin-rtp.xml
+++ b/docs/plugins/inspect/plugin-rtp.xml
@@ -3,7 +3,7 @@
   <description>Real-time protocol plugins</description>
   <filename>../../gst/rtp/.libs/libgstrtp.so</filename>
   <basename>libgstrtp.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
@@ -1630,7 +1630,7 @@
       <name>rtpvp8pay</name>
       <longname>RTP VP8 payloader</longname>
       <class>Codec/Payloader/Network/RTP</class>
-      <description>Puts VP8 video in RTP packets)</description>
+      <description>Puts VP8 video in RTP packets</description>
       <author>Sjoerd Simons &lt;sjoerd@luon.net&gt;</author>
       <pads>
         <caps>
diff --git a/docs/plugins/inspect/plugin-rtpmanager.xml b/docs/plugins/inspect/plugin-rtpmanager.xml
index 661e0ac..9822b33 100644
--- a/docs/plugins/inspect/plugin-rtpmanager.xml
+++ b/docs/plugins/inspect/plugin-rtpmanager.xml
@@ -3,7 +3,7 @@
   <description>RTP session management plugin library</description>
   <filename>../../gst/rtpmanager/.libs/libgstrtpmanager.so</filename>
   <basename>libgstrtpmanager.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-rtsp.xml b/docs/plugins/inspect/plugin-rtsp.xml
index 419a25b..21c2c11 100644
--- a/docs/plugins/inspect/plugin-rtsp.xml
+++ b/docs/plugins/inspect/plugin-rtsp.xml
@@ -3,7 +3,7 @@
   <description>transfer data via RTSP</description>
   <filename>../../gst/rtsp/.libs/libgstrtsp.so</filename>
   <basename>libgstrtsp.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-shapewipe.xml b/docs/plugins/inspect/plugin-shapewipe.xml
index a5c1fe8..91e0d50 100644
--- a/docs/plugins/inspect/plugin-shapewipe.xml
+++ b/docs/plugins/inspect/plugin-shapewipe.xml
@@ -3,7 +3,7 @@
   <description>Shape Wipe transition filter</description>
   <filename>../../gst/shapewipe/.libs/libgstshapewipe.so</filename>
   <basename>libgstshapewipe.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-shout2send.xml b/docs/plugins/inspect/plugin-shout2send.xml
index 1dab992..a567c9c 100644
--- a/docs/plugins/inspect/plugin-shout2send.xml
+++ b/docs/plugins/inspect/plugin-shout2send.xml
@@ -3,7 +3,7 @@
   <description>Sends data to an icecast server using libshout2</description>
   <filename>../../ext/shout2/.libs/libgstshout2.so</filename>
   <basename>libgstshout2.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>libshout2</package>
diff --git a/docs/plugins/inspect/plugin-smpte.xml b/docs/plugins/inspect/plugin-smpte.xml
index ba4dc77..b8bed6f 100644
--- a/docs/plugins/inspect/plugin-smpte.xml
+++ b/docs/plugins/inspect/plugin-smpte.xml
@@ -3,7 +3,7 @@
   <description>Apply the standard SMPTE transitions on video images</description>
   <filename>../../gst/smpte/.libs/libgstsmpte.so</filename>
   <basename>libgstsmpte.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-soup.xml b/docs/plugins/inspect/plugin-soup.xml
index ac80ea1..e6bb36d 100644
--- a/docs/plugins/inspect/plugin-soup.xml
+++ b/docs/plugins/inspect/plugin-soup.xml
@@ -3,7 +3,7 @@
   <description>libsoup HTTP client src/sink</description>
   <filename>../../ext/soup/.libs/libgstsouphttpsrc.so</filename>
   <basename>libgstsouphttpsrc.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-spectrum.xml b/docs/plugins/inspect/plugin-spectrum.xml
index f939899..d4e740a 100644
--- a/docs/plugins/inspect/plugin-spectrum.xml
+++ b/docs/plugins/inspect/plugin-spectrum.xml
@@ -3,7 +3,7 @@
   <description>Run an FFT on the audio signal, output spectrum data</description>
   <filename>../../gst/spectrum/.libs/libgstspectrum.so</filename>
   <basename>libgstspectrum.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-speex.xml b/docs/plugins/inspect/plugin-speex.xml
index 0353413..13364c3 100644
--- a/docs/plugins/inspect/plugin-speex.xml
+++ b/docs/plugins/inspect/plugin-speex.xml
@@ -3,7 +3,7 @@
   <description>Speex plugin library</description>
   <filename>../../ext/speex/.libs/libgstspeex.so</filename>
   <basename>libgstspeex.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-taglib.xml b/docs/plugins/inspect/plugin-taglib.xml
index 0db4ab4..06997aa 100644
--- a/docs/plugins/inspect/plugin-taglib.xml
+++ b/docs/plugins/inspect/plugin-taglib.xml
@@ -3,7 +3,7 @@
   <description>Tag writing plug-in based on taglib</description>
   <filename>../../ext/taglib/.libs/libgsttaglib.so</filename>
   <basename>libgsttaglib.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-udp.xml b/docs/plugins/inspect/plugin-udp.xml
index ed92266..6751e80 100644
--- a/docs/plugins/inspect/plugin-udp.xml
+++ b/docs/plugins/inspect/plugin-udp.xml
@@ -3,7 +3,7 @@
   <description>transfer data via UDP</description>
   <filename>../../gst/udp/.libs/libgstudp.so</filename>
   <basename>libgstudp.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-video4linux2.xml b/docs/plugins/inspect/plugin-video4linux2.xml
index 7e6887b..6fbc5d0 100644
--- a/docs/plugins/inspect/plugin-video4linux2.xml
+++ b/docs/plugins/inspect/plugin-video4linux2.xml
@@ -3,7 +3,7 @@
   <description>elements for Video 4 Linux</description>
   <filename>../../sys/v4l2/.libs/libgstvideo4linux2.so</filename>
   <basename>libgstvideo4linux2.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
@@ -29,7 +29,7 @@
           <name>sink</name>
           <direction>sink</direction>
           <presence>always</presence>
-          <details>image/jpeg; video/mpeg, mpegversion=(int)4, systemstream=(boolean)false; video/mpeg, mpegversion=(int)2; video/mpegts, systemstream=(boolean)true; video/x-bayer, format=(string){ bggr, gbrg, grbg, rggb }, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-dv, systemstream=(boolean)true; video/x-h263, variant=(string)itu; video/x-h264, stream-format=(string)byte-stream, alignment=(string)au; video/x-pwc1, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-pwc2, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ RGB15, RGB16, BGR, RGB, BGRx, BGRA, xRGB, ARGB, GRAY8, YVU9, YV12, YUY2, UYVY, Y42B, Y41B, NV12_64Z32, YUV9, I420, YVYU, NV21, NV12 }, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-sonix, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-vp8</details>
+          <details>image/jpeg; video/mpeg, mpegversion=(int)4, systemstream=(boolean)false; video/mpeg, mpegversion=(int)2; video/mpegts, systemstream=(boolean)true; video/x-bayer, format=(string){ bggr, gbrg, grbg, rggb }, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-dv, systemstream=(boolean)true; video/x-h263, variant=(string)itu; video/x-h264, stream-format=(string){ byte-stream, avc }, alignment=(string)au; video/x-pwc1, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-pwc2, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ RGB16, BGR, RGB, GRAY8, GRAY16_LE, GRAY16_BE, YVU9, YV12, YUY2, YVYU, UYVY, Y42B, Y41B, YUV9, NV12_64Z32, NV24, NV61, NV16, NV21, NV12, I420, BGRA, BGRx, ARGB, xRGB, BGR15, RGB15 }, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-sonix, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-vp8; video/x-wmv, wmvversion=(int)3, format=(string)WVC1</details>
         </caps>
       </pads>
     </element>
@@ -44,7 +44,7 @@
           <name>src</name>
           <direction>source</direction>
           <presence>always</presence>
-          <details>image/jpeg; video/mpeg, mpegversion=(int)4, systemstream=(boolean)false; video/mpeg, mpegversion=(int)2; video/mpegts, systemstream=(boolean)true; video/x-bayer, format=(string){ bggr, gbrg, grbg, rggb }, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-dv, systemstream=(boolean)true; video/x-h263, variant=(string)itu; video/x-h264, stream-format=(string)byte-stream, alignment=(string)au; video/x-pwc1, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-pwc2, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ RGB15, RGB16, BGR, RGB, BGRx, BGRA, xRGB, ARGB, GRAY8, YVU9, YV12, YUY2, UYVY, Y42B, Y41B, NV12_64Z32, YUV9, I420, YVYU, NV21, NV12 }, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-sonix, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-vp8</details>
+          <details>image/jpeg; video/mpeg, mpegversion=(int)4, systemstream=(boolean)false; video/mpeg, mpegversion=(int)2; video/mpegts, systemstream=(boolean)true; video/x-bayer, format=(string){ bggr, gbrg, grbg, rggb }, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-dv, systemstream=(boolean)true; video/x-h263, variant=(string)itu; video/x-h264, stream-format=(string){ byte-stream, avc }, alignment=(string)au; video/x-pwc1, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-pwc2, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw, format=(string){ RGB16, BGR, RGB, GRAY8, GRAY16_LE, GRAY16_BE, YVU9, YV12, YUY2, YVYU, UYVY, Y42B, Y41B, YUV9, NV12_64Z32, NV24, NV61, NV16, NV21, NV12, I420, BGRA, BGRx, ARGB, xRGB, BGR15, RGB15 }, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-sonix, width=(int)[ 1, 32768 ], height=(int)[ 1, 32768 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-vp8; video/x-wmv, wmvversion=(int)3, format=(string)WVC1</details>
         </caps>
       </pads>
     </element>
diff --git a/docs/plugins/inspect/plugin-videobox.xml b/docs/plugins/inspect/plugin-videobox.xml
index 2cd03f3..eae3059 100644
--- a/docs/plugins/inspect/plugin-videobox.xml
+++ b/docs/plugins/inspect/plugin-videobox.xml
@@ -3,7 +3,7 @@
   <description>resizes a video by adding borders or cropping</description>
   <filename>../../gst/videobox/.libs/libgstvideobox.so</filename>
   <basename>libgstvideobox.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-videocrop.xml b/docs/plugins/inspect/plugin-videocrop.xml
index af3515d..acf8a7b 100644
--- a/docs/plugins/inspect/plugin-videocrop.xml
+++ b/docs/plugins/inspect/plugin-videocrop.xml
@@ -3,7 +3,7 @@
   <description>Crops video into a user-defined region</description>
   <filename>../../gst/videocrop/.libs/libgstvideocrop.so</filename>
   <basename>libgstvideocrop.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-videofilter.xml b/docs/plugins/inspect/plugin-videofilter.xml
index 870b5a8..d713074 100644
--- a/docs/plugins/inspect/plugin-videofilter.xml
+++ b/docs/plugins/inspect/plugin-videofilter.xml
@@ -3,7 +3,7 @@
   <description>Video filters plugin</description>
   <filename>../../gst/videofilter/.libs/libgstvideofilter.so</filename>
   <basename>libgstvideofilter.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-videomixer.xml b/docs/plugins/inspect/plugin-videomixer.xml
index 1681a72..ca01144 100644
--- a/docs/plugins/inspect/plugin-videomixer.xml
+++ b/docs/plugins/inspect/plugin-videomixer.xml
@@ -3,7 +3,7 @@
   <description>Video mixer</description>
   <filename>../../gst/videomixer/.libs/libgstvideomixer.so</filename>
   <basename>libgstvideomixer.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-vpx.xml b/docs/plugins/inspect/plugin-vpx.xml
index d07388e..793ba2e 100644
--- a/docs/plugins/inspect/plugin-vpx.xml
+++ b/docs/plugins/inspect/plugin-vpx.xml
@@ -3,7 +3,7 @@
   <description>VP8 plugin</description>
   <filename>../../ext/vpx/.libs/libgstvpx.so</filename>
   <basename>libgstvpx.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-wavenc.xml b/docs/plugins/inspect/plugin-wavenc.xml
index d58285e..707f1bf 100644
--- a/docs/plugins/inspect/plugin-wavenc.xml
+++ b/docs/plugins/inspect/plugin-wavenc.xml
@@ -3,7 +3,7 @@
   <description>Encode raw audio into WAV</description>
   <filename>../../gst/wavenc/.libs/libgstwavenc.so</filename>
   <basename>libgstwavenc.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-wavpack.xml b/docs/plugins/inspect/plugin-wavpack.xml
index 34cafeb..7cf24c9 100644
--- a/docs/plugins/inspect/plugin-wavpack.xml
+++ b/docs/plugins/inspect/plugin-wavpack.xml
@@ -3,7 +3,7 @@
   <description>Wavpack lossless/lossy audio format handling</description>
   <filename>../../ext/wavpack/.libs/libgstwavpack.so</filename>
   <basename>libgstwavpack.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-wavparse.xml b/docs/plugins/inspect/plugin-wavparse.xml
index 45244bc..1cd2daf 100644
--- a/docs/plugins/inspect/plugin-wavparse.xml
+++ b/docs/plugins/inspect/plugin-wavparse.xml
@@ -3,7 +3,7 @@
   <description>Parse a .wav file into raw audio</description>
   <filename>../../gst/wavparse/.libs/libgstwavparse.so</filename>
   <basename>libgstwavparse.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-ximagesrc.xml b/docs/plugins/inspect/plugin-ximagesrc.xml
index bf0377d..191b531 100644
--- a/docs/plugins/inspect/plugin-ximagesrc.xml
+++ b/docs/plugins/inspect/plugin-ximagesrc.xml
@@ -3,7 +3,7 @@
   <description>X11 video input plugin using standard Xlib calls</description>
   <filename>../../sys/ximage/.libs/libgstximagesrc.so</filename>
   <basename>libgstximagesrc.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-y4menc.xml b/docs/plugins/inspect/plugin-y4menc.xml
index 37142ec..6274245 100644
--- a/docs/plugins/inspect/plugin-y4menc.xml
+++ b/docs/plugins/inspect/plugin-y4menc.xml
@@ -3,7 +3,7 @@
   <description>Encodes a YUV frame into the yuv4mpeg format (mjpegtools)</description>
   <filename>../../gst/y4m/.libs/libgsty4menc.so</filename>
   <basename>libgsty4menc.so</basename>
-  <version>1.6.2</version>
+  <version>1.7.1</version>
   <license>LGPL</license>
   <source>gst-plugins-good</source>
   <package>GStreamer Good Plug-ins source release</package>
diff --git a/ext/Makefile.in b/ext/Makefile.in
index af9201f..f2a4370 100644
--- a/ext/Makefile.in
+++ b/ext/Makefile.in
@@ -455,6 +455,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/ext/aalib/Makefile.in b/ext/aalib/Makefile.in
index 0101144..999b791 100644
--- a/ext/aalib/Makefile.in
+++ b/ext/aalib/Makefile.in
@@ -477,6 +477,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/ext/cairo/Makefile.in b/ext/cairo/Makefile.in
index 77fb097..c5156ec 100644
--- a/ext/cairo/Makefile.in
+++ b/ext/cairo/Makefile.in
@@ -478,6 +478,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/ext/dv/Makefile.in b/ext/dv/Makefile.in
index 74b15be..297b31f 100644
--- a/ext/dv/Makefile.in
+++ b/ext/dv/Makefile.in
@@ -487,6 +487,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/ext/dv/gstdvdec.h b/ext/dv/gstdvdec.h
index 8dda7df..4031ef0 100644
--- a/ext/dv/gstdvdec.h
+++ b/ext/dv/gstdvdec.h
@@ -61,7 +61,6 @@
   gboolean       PAL;
   gboolean       interlaced;
   gboolean       wide;
-  gint           frame_len;
 
   /* input caps */
   gboolean       sink_negotiated;
@@ -74,7 +73,6 @@
   gboolean       need_par;
 
   /* negotiated output */
-  dv_color_space_t space;
   gint           bpp;
   gboolean       src_negotiated;
   
diff --git a/ext/flac/Makefile.in b/ext/flac/Makefile.in
index c416130..759c66d 100644
--- a/ext/flac/Makefile.in
+++ b/ext/flac/Makefile.in
@@ -479,6 +479,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/ext/gdk_pixbuf/Makefile.in b/ext/gdk_pixbuf/Makefile.in
index 62af39a..27ef876 100644
--- a/ext/gdk_pixbuf/Makefile.in
+++ b/ext/gdk_pixbuf/Makefile.in
@@ -480,6 +480,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/ext/gdk_pixbuf/gstgdkpixbufdec.c b/ext/gdk_pixbuf/gstgdkpixbufdec.c
index 02e780c..36cfbc0 100644
--- a/ext/gdk_pixbuf/gstgdkpixbufdec.c
+++ b/ext/gdk_pixbuf/gstgdkpixbufdec.c
@@ -547,6 +547,11 @@
       }
       g_list_free_full (dec->pending_events, (GDestroyNotify) gst_event_unref);
       dec->pending_events = NULL;
+      if (dec->pixbuf_loader != NULL) {
+        gdk_pixbuf_loader_close (dec->pixbuf_loader, NULL);
+        g_object_unref (G_OBJECT (dec->pixbuf_loader));
+        dec->pixbuf_loader = NULL;
+      }
       break;
     default:
       break;
diff --git a/ext/gdk_pixbuf/gstgdkpixbufsink.c b/ext/gdk_pixbuf/gstgdkpixbufsink.c
index 5e79378..0151569 100644
--- a/ext/gdk_pixbuf/gstgdkpixbufsink.c
+++ b/ext/gdk_pixbuf/gstgdkpixbufsink.c
@@ -229,7 +229,7 @@
   GstGdkPixbufSink *sink = GST_GDK_PIXBUF_SINK (basesink);
   GstVideoInfo info;
   GstVideoFormat fmt;
-  gint w, h, s, par_n, par_d;
+  gint w, h, par_n, par_d;
 
   GST_LOG_OBJECT (sink, "caps: %" GST_PTR_FORMAT, caps);
 
@@ -241,12 +241,17 @@
   fmt = GST_VIDEO_INFO_FORMAT (&info);
   w = GST_VIDEO_INFO_WIDTH (&info);
   h = GST_VIDEO_INFO_HEIGHT (&info);
-  s = GST_VIDEO_INFO_COMP_PSTRIDE (&info, 0);
   par_n = GST_VIDEO_INFO_PAR_N (&info);
   par_d = GST_VIDEO_INFO_PAR_N (&info);
 
-  g_assert ((fmt == GST_VIDEO_FORMAT_RGB && s == 3) ||
-      (fmt == GST_VIDEO_FORMAT_RGBA && s == 4));
+#ifndef G_DISABLE_ASSERT
+  {
+    gint s;
+    s = GST_VIDEO_INFO_COMP_PSTRIDE (&info, 0);
+    g_assert ((fmt == GST_VIDEO_FORMAT_RGB && s == 3) ||
+        (fmt == GST_VIDEO_FORMAT_RGBA && s == 4));
+  }
+#endif
 
   GST_VIDEO_SINK_WIDTH (sink) = w;
   GST_VIDEO_SINK_HEIGHT (sink) = h;
diff --git a/ext/jack/Makefile.in b/ext/jack/Makefile.in
index 5afdee9..6de6de4 100644
--- a/ext/jack/Makefile.in
+++ b/ext/jack/Makefile.in
@@ -479,6 +479,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/ext/jpeg/Makefile.in b/ext/jpeg/Makefile.in
index 1bf9458..6ef84b6 100644
--- a/ext/jpeg/Makefile.in
+++ b/ext/jpeg/Makefile.in
@@ -478,6 +478,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/ext/jpeg/gstjpegdec.c b/ext/jpeg/gstjpegdec.c
index d67f1de..edf616e 100644
--- a/ext/jpeg/gstjpegdec.c
+++ b/ext/jpeg/gstjpegdec.c
@@ -1108,6 +1108,12 @@
           GST_MAP_READWRITE))
     goto alloc_failed;
 
+  if (setjmp (dec->jerr.setjmp_buffer)) {
+    code = dec->jerr.pub.msg_code;
+    gst_video_frame_unmap (&vframe);
+    goto decode_error;
+  }
+
   GST_LOG_OBJECT (dec, "width %d, height %d", width, height);
 
   if (dec->cinfo.jpeg_color_space == JCS_RGB) {
@@ -1141,6 +1147,11 @@
 
   gst_video_frame_unmap (&vframe);
 
+  if (setjmp (dec->jerr.setjmp_buffer)) {
+    code = dec->jerr.pub.msg_code;
+    goto decode_error;
+  }
+
   GST_LOG_OBJECT (dec, "decompressing finished");
   jpeg_finish_decompress (&dec->cinfo);
 
diff --git a/ext/libcaca/Makefile.in b/ext/libcaca/Makefile.in
index 75fca4e..0b2a467 100644
--- a/ext/libcaca/Makefile.in
+++ b/ext/libcaca/Makefile.in
@@ -477,6 +477,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/ext/libpng/Makefile.in b/ext/libpng/Makefile.in
index 84b0d64..8169de0 100644
--- a/ext/libpng/Makefile.in
+++ b/ext/libpng/Makefile.in
@@ -478,6 +478,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/ext/pulse/Makefile.in b/ext/pulse/Makefile.in
index 36a1cde..ee295e4 100644
--- a/ext/pulse/Makefile.in
+++ b/ext/pulse/Makefile.in
@@ -480,6 +480,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/ext/raw1394/Makefile.in b/ext/raw1394/Makefile.in
index e856c6b..4e527d9 100644
--- a/ext/raw1394/Makefile.in
+++ b/ext/raw1394/Makefile.in
@@ -484,6 +484,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/ext/raw1394/gstdv1394src.c b/ext/raw1394/gstdv1394src.c
index 09755ba..dbc7607 100644
--- a/ext/raw1394/gstdv1394src.c
+++ b/ext/raw1394/gstdv1394src.c
@@ -790,8 +790,12 @@
   READ_SOCKET (src) = control_sock[0];
   WRITE_SOCKET (src) = control_sock[1];
 
-  fcntl (READ_SOCKET (src), F_SETFL, O_NONBLOCK);
-  fcntl (WRITE_SOCKET (src), F_SETFL, O_NONBLOCK);
+  if (fcntl (READ_SOCKET (src), F_SETFL, O_NONBLOCK) < 0)
+    GST_ERROR_OBJECT (src, "failed to make read socket non-blocking: %s",
+        g_strerror (errno));
+  if (fcntl (WRITE_SOCKET (src), F_SETFL, O_NONBLOCK) < 0)
+    GST_ERROR_OBJECT (src, "failed to make write socket non-blocking: %s",
+        g_strerror (errno));
 
   src->handle = raw1394_new_handle ();
 
diff --git a/ext/raw1394/gsthdv1394src.c b/ext/raw1394/gsthdv1394src.c
index f81f70f..0b07a37 100644
--- a/ext/raw1394/gsthdv1394src.c
+++ b/ext/raw1394/gsthdv1394src.c
@@ -527,8 +527,12 @@
   READ_SOCKET (src) = control_sock[0];
   WRITE_SOCKET (src) = control_sock[1];
 
-  fcntl (READ_SOCKET (src), F_SETFL, O_NONBLOCK);
-  fcntl (WRITE_SOCKET (src), F_SETFL, O_NONBLOCK);
+  if (fcntl (READ_SOCKET (src), F_SETFL, O_NONBLOCK) < 0)
+    GST_ERROR_OBJECT (src, "failed to make read socket non-blocking: %s",
+        g_strerror (errno));
+  if (fcntl (WRITE_SOCKET (src), F_SETFL, O_NONBLOCK) < 0)
+    GST_ERROR_OBJECT (src, "failed to make write socket non-blocking: %s",
+        g_strerror (errno));
 
   src->handle = raw1394_new_handle ();
 
diff --git a/ext/shout2/Makefile.in b/ext/shout2/Makefile.in
index 171a9a5..e0cee84 100644
--- a/ext/shout2/Makefile.in
+++ b/ext/shout2/Makefile.in
@@ -476,6 +476,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/ext/shout2/gstshout2.c b/ext/shout2/gstshout2.c
index 2384ebc..e154ba8 100644
--- a/ext/shout2/gstshout2.c
+++ b/ext/shout2/gstshout2.c
@@ -688,52 +688,44 @@
   switch (prop_id) {
 
     case ARG_IP:
-      if (shout2send->ip)
-        g_free (shout2send->ip);
+      g_free (shout2send->ip);
       shout2send->ip = g_strdup (g_value_get_string (value));
       break;
     case ARG_PORT:
       shout2send->port = g_value_get_int (value);
       break;
     case ARG_PASSWORD:
-      if (shout2send->password)
-        g_free (shout2send->password);
+      g_free (shout2send->password);
       shout2send->password = g_strdup (g_value_get_string (value));
       break;
     case ARG_USERNAME:
-      if (shout2send->username)
-        g_free (shout2send->username);
+      g_free (shout2send->username);
       shout2send->username = g_strdup (g_value_get_string (value));
       break;
     case ARG_PUBLIC:
       shout2send->ispublic = g_value_get_boolean (value);
       break;
     case ARG_STREAMNAME:       /* Name of the stream */
-      if (shout2send->streamname)
-        g_free (shout2send->streamname);
+      g_free (shout2send->streamname);
       shout2send->streamname = g_strdup (g_value_get_string (value));
       break;
     case ARG_DESCRIPTION:      /* Description of the stream */
-      if (shout2send->description)
-        g_free (shout2send->description);
+      g_free (shout2send->description);
       shout2send->description = g_strdup (g_value_get_string (value));
       break;
     case ARG_GENRE:            /* Genre of the stream */
-      if (shout2send->genre)
-        g_free (shout2send->genre);
+      g_free (shout2send->genre);
       shout2send->genre = g_strdup (g_value_get_string (value));
       break;
     case ARG_PROTOCOL:         /* protocol to connect with */
       shout2send->protocol = g_value_get_enum (value);
       break;
     case ARG_MOUNT:            /* mountpoint of stream (icecast only) */
-      if (shout2send->mount)
-        g_free (shout2send->mount);
+      g_free (shout2send->mount);
       shout2send->mount = g_strdup (g_value_get_string (value));
       break;
     case ARG_URL:              /* the stream's homepage URL */
-      if (shout2send->url)
-        g_free (shout2send->url);
+      g_free (shout2send->url);
       shout2send->url = g_strdup (g_value_get_string (value));
       break;
     default:
diff --git a/ext/soup/Makefile.in b/ext/soup/Makefile.in
index b860fdf..8d8aaaf 100644
--- a/ext/soup/Makefile.in
+++ b/ext/soup/Makefile.in
@@ -480,6 +480,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/ext/soup/gstsouphttpclientsink.c b/ext/soup/gstsouphttpclientsink.c
index b38953f..108aabf 100644
--- a/ext/soup/gstsouphttpclientsink.c
+++ b/ext/soup/gstsouphttpclientsink.c
@@ -43,8 +43,6 @@
 #include "gstsouphttpclientsink.h"
 #include "gstsouputils.h"
 
-#include <gst/glib-compat-private.h>
-
 GST_DEBUG_CATEGORY_STATIC (souphttpclientsink_dbg);
 #define GST_CAT_DEFAULT souphttpclientsink_dbg
 
@@ -72,7 +70,6 @@
 static GstFlowReturn gst_soup_http_client_sink_render (GstBaseSink * sink,
     GstBuffer * buffer);
 
-static void free_buffer_list (GList * list);
 static void gst_soup_http_client_sink_reset (GstSoupHttpClientSink *
     souphttpsink);
 static void authenticate (SoupSession * session, SoupMessage * msg,
@@ -95,7 +92,9 @@
   PROP_PROXY_PW,
   PROP_COOKIES,
   PROP_SESSION,
-  PROP_SOUP_LOG_LEVEL
+  PROP_SOUP_LOG_LEVEL,
+  PROP_RETRY_DELAY,
+  PROP_RETRIES
 };
 
 #define DEFAULT_USER_AGENT           "GStreamer souphttpclientsink "
@@ -171,6 +170,14 @@
   g_object_class_install_property (gobject_class, PROP_COOKIES,
       g_param_spec_boxed ("cookies", "Cookies", "HTTP request cookies",
           G_TYPE_STRV, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_RETRY_DELAY,
+      g_param_spec_int ("retry-delay", "Retry Delay",
+          "Delay in seconds between retries after a failure", 1, G_MAXINT, 5,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_RETRIES,
+      g_param_spec_int ("retries", "Retries",
+          "Maximum number of retries, zero to disable, -1 to retry forever",
+          -1, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
    * GstSoupHttpClientSink::http-log-level:
    *
@@ -231,6 +238,8 @@
   souphttpsink->prop_session = NULL;
   souphttpsink->timeout = 1;
   souphttpsink->log_level = DEFAULT_SOUP_LOG_LEVEL;
+  souphttpsink->retry_delay = 5;
+  souphttpsink->retries = 0;
   proxy = g_getenv ("http_proxy");
   if (proxy && !gst_soup_http_client_sink_set_proxy (souphttpsink, proxy)) {
     GST_WARNING_OBJECT (souphttpsink,
@@ -251,7 +260,12 @@
   souphttpsink->reason_phrase = NULL;
   souphttpsink->status_code = 0;
   souphttpsink->offset = 0;
+  souphttpsink->failures = 0;
 
+  g_list_free_full (souphttpsink->streamheader_buffers,
+      (GDestroyNotify) gst_buffer_unref);
+  g_list_free_full (souphttpsink->sent_buffers,
+      (GDestroyNotify) gst_buffer_unref);
 }
 
 static gboolean
@@ -292,6 +306,14 @@
       g_free (souphttpsink->location);
       souphttpsink->location = g_value_dup_string (value);
       souphttpsink->offset = 0;
+      if ((souphttpsink->location == NULL)
+          || !gst_uri_is_valid (souphttpsink->location)) {
+        GST_WARNING_OBJECT (souphttpsink,
+            "The location (\"%s\") set, is not a valid uri.",
+            souphttpsink->location);
+        g_free (souphttpsink->location);
+        souphttpsink->location = NULL;
+      }
       break;
     case PROP_USER_AGENT:
       g_free (souphttpsink->user_agent);
@@ -339,6 +361,12 @@
     case PROP_SOUP_LOG_LEVEL:
       souphttpsink->log_level = g_value_get_enum (value);
       break;
+    case PROP_RETRY_DELAY:
+      souphttpsink->retry_delay = g_value_get_int (value);
+      break;
+    case PROP_RETRIES:
+      souphttpsink->retries = g_value_get_int (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -394,6 +422,12 @@
     case PROP_SOUP_LOG_LEVEL:
       g_value_set_enum (value, souphttpsink->log_level);
       break;
+    case PROP_RETRY_DELAY:
+      g_value_set_int (value, souphttpsink->retry_delay);
+      break;
+    case PROP_RETRIES:
+      g_value_set_int (value, souphttpsink->retries);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -450,7 +484,8 @@
   structure = gst_caps_get_structure (caps, 0);
   value_array = gst_structure_get_value (structure, "streamheader");
   if (value_array) {
-    free_buffer_list (souphttpsink->streamheader_buffers);
+    g_list_free_full (souphttpsink->streamheader_buffers,
+        (GDestroyNotify) gst_buffer_unref);
     souphttpsink->streamheader_buffers = NULL;
 
     n = gst_value_array_get_size (value_array);
@@ -527,10 +562,17 @@
 
     g_mutex_lock (&souphttpsink->mutex);
 
-    /* FIXME: error handling */
     souphttpsink->thread = g_thread_try_new ("souphttpclientsink-thread",
         thread_func, souphttpsink, &error);
 
+    if (error != NULL) {
+      GST_DEBUG_OBJECT (souphttpsink, "failed to start thread, %s",
+          error->message);
+      g_error_free (error);
+      g_mutex_unlock (&souphttpsink->mutex);
+      return FALSE;
+    }
+
     GST_LOG_OBJECT (souphttpsink, "waiting for main loop thread to start up");
     g_cond_wait (&souphttpsink->cond, &souphttpsink->mutex);
     g_mutex_unlock (&souphttpsink->mutex);
@@ -573,8 +615,19 @@
     g_object_unref (souphttpsink->session);
   }
 
+  g_mutex_lock (&souphttpsink->mutex);
+  if (souphttpsink->timer) {
+    g_source_destroy (souphttpsink->timer);
+    g_source_unref (souphttpsink->timer);
+    souphttpsink->timer = NULL;
+  }
+  g_mutex_unlock (&souphttpsink->mutex);
+
   if (souphttpsink->loop) {
     g_main_loop_quit (souphttpsink->loop);
+    g_mutex_lock (&souphttpsink->mutex);
+    g_cond_signal (&souphttpsink->cond);
+    g_mutex_unlock (&souphttpsink->mutex);
     g_thread_join (souphttpsink->thread);
     g_main_loop_unref (souphttpsink->loop);
     souphttpsink->loop = NULL;
@@ -627,17 +680,6 @@
 }
 
 static void
-free_buffer_list (GList * list)
-{
-  GList *g;
-  for (g = list; g; g = g_list_next (g)) {
-    GstBuffer *buffer = g->data;
-    gst_buffer_unref (buffer);
-  }
-  g_list_free (list);
-}
-
-static void
 send_message_locked (GstSoupHttpClientSink * souphttpsink)
 {
   GList *g;
@@ -650,12 +692,22 @@
   /* If the URI went away, drop all these buffers */
   if (souphttpsink->location == NULL) {
     GST_DEBUG_OBJECT (souphttpsink, "URI went away, dropping queued buffers");
-    free_buffer_list (souphttpsink->queued_buffers);
+    g_list_free_full (souphttpsink->queued_buffers,
+        (GDestroyNotify) gst_buffer_unref);
     souphttpsink->queued_buffers = NULL;
     return;
   }
 
   souphttpsink->message = soup_message_new ("PUT", souphttpsink->location);
+  if (souphttpsink->message == NULL) {
+    GST_WARNING_OBJECT (souphttpsink,
+        "URI could not be parsed while creating message.");
+    g_list_free_full (souphttpsink->queued_buffers,
+        (GDestroyNotify) gst_buffer_unref);
+    souphttpsink->queued_buffers = NULL;
+    return;
+  }
+
   soup_message_set_flags (souphttpsink->message,
       (souphttpsink->automatic_redirect ? 0 : SOUP_MESSAGE_NO_REDIRECT));
 
@@ -715,7 +767,8 @@
   if (n == 0) {
     GST_DEBUG_OBJECT (souphttpsink,
         "total size of buffers queued is 0, freeing everything");
-    free_buffer_list (souphttpsink->queued_buffers);
+    g_list_free_full (souphttpsink->queued_buffers,
+        (GDestroyNotify) gst_buffer_unref);
     souphttpsink->queued_buffers = NULL;
     g_object_unref (souphttpsink->message);
     souphttpsink->message = NULL;
@@ -739,6 +792,11 @@
 {
   g_mutex_lock (&souphttpsink->mutex);
   send_message_locked (souphttpsink);
+  if (souphttpsink->timer) {
+    g_source_destroy (souphttpsink->timer);
+    g_source_unref (souphttpsink->timer);
+    souphttpsink->timer = NULL;
+  }
   g_mutex_unlock (&souphttpsink->mutex);
 
   return FALSE;
@@ -757,14 +815,48 @@
   souphttpsink->message = NULL;
 
   if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
-    souphttpsink->status_code = msg->status_code;
-    souphttpsink->reason_phrase = g_strdup (msg->reason_phrase);
+    souphttpsink->failures++;
+    if (souphttpsink->retries &&
+        (souphttpsink->retries < 0 ||
+            souphttpsink->retries >= souphttpsink->failures)) {
+      guint64 retry_delay;
+      const char *retry_after =
+          soup_message_headers_get_one (msg->response_headers,
+          "Retry-After");
+      if (retry_after) {
+        gchar *end = NULL;
+        retry_delay = g_ascii_strtoull (retry_after, &end, 10);
+        if (end || errno) {
+          retry_delay = souphttpsink->retry_delay;
+        } else {
+          retry_delay = MAX (retry_delay, souphttpsink->retry_delay);
+        }
+        GST_WARNING_OBJECT (souphttpsink, "Could not write to HTTP URI: "
+            "status: %d %s (retrying PUT after %" G_GINT64_FORMAT
+            " seconds with Retry-After: %s)", msg->status_code,
+            msg->reason_phrase, retry_delay, retry_after);
+      } else {
+        retry_delay = souphttpsink->retry_delay;
+        GST_WARNING_OBJECT (souphttpsink, "Could not write to HTTP URI: "
+            "status: %d %s (retrying PUT after %" G_GINT64_FORMAT
+            " seconds)", msg->status_code, msg->reason_phrase, retry_delay);
+      }
+      souphttpsink->timer = g_timeout_source_new_seconds (retry_delay);
+      g_source_set_callback (souphttpsink->timer, (GSourceFunc) (send_message),
+          souphttpsink, NULL);
+      g_source_attach (souphttpsink->timer, souphttpsink->context);
+    } else {
+      souphttpsink->status_code = msg->status_code;
+      souphttpsink->reason_phrase = g_strdup (msg->reason_phrase);
+    }
     g_mutex_unlock (&souphttpsink->mutex);
     return;
   }
 
-  free_buffer_list (souphttpsink->sent_buffers);
+  g_list_free_full (souphttpsink->sent_buffers,
+      (GDestroyNotify) gst_buffer_unref);
   souphttpsink->sent_buffers = NULL;
+  souphttpsink->failures = 0;
 
   send_message_locked (souphttpsink);
   g_mutex_unlock (&souphttpsink->mutex);
@@ -778,10 +870,9 @@
   gboolean wake;
 
   if (souphttpsink->status_code != 0) {
-    /* FIXME we should allow a moderate amount of retries. */
     GST_ELEMENT_ERROR (souphttpsink, RESOURCE, WRITE,
         ("Could not write to HTTP URI"),
-        ("error: %d %s", souphttpsink->status_code,
+        ("status: %d %s", souphttpsink->status_code,
             souphttpsink->reason_phrase));
     return GST_FLOW_ERROR;
   }
diff --git a/ext/soup/gstsouphttpclientsink.h b/ext/soup/gstsouphttpclientsink.h
index a330275..29c4500 100644
--- a/ext/soup/gstsouphttpclientsink.h
+++ b/ext/soup/gstsouphttpclientsink.h
@@ -43,6 +43,7 @@
   GMainContext *context;
   GMainLoop *loop;
   GThread *thread;
+  GSource *timer;
   SoupMessage *message;
   SoupSession *session;
   GList *queued_buffers;
@@ -54,6 +55,7 @@
 
   guint64 offset;
   int timeout;
+  gint failures;
 
   /* properties */
   SoupSession *prop_session;
@@ -67,6 +69,8 @@
   gboolean automatic_redirect;
   gchar **cookies;
   SoupLoggerLogLevel log_level;
+  gint retry_delay;
+  gint retries;
 };
 
 struct _GstSoupHttpClientSinkClass
diff --git a/ext/soup/gstsouphttpsrc.c b/ext/soup/gstsouphttpsrc.c
index d9ae2e7..9c652d8 100644
--- a/ext/soup/gstsouphttpsrc.c
+++ b/ext/soup/gstsouphttpsrc.c
@@ -124,7 +124,8 @@
   PROP_SSL_USE_SYSTEM_CA_FILE,
   PROP_TLS_DATABASE,
   PROP_RETRIES,
-  PROP_METHOD
+  PROP_METHOD,
+  PROP_TLS_INTERACTION,
 };
 
 #define DEFAULT_USER_AGENT           "GStreamer souphttpsrc "
@@ -136,6 +137,7 @@
 #define DEFAULT_SSL_CA_FILE          NULL
 #define DEFAULT_SSL_USE_SYSTEM_CA_FILE TRUE
 #define DEFAULT_TLS_DATABASE         NULL
+#define DEFAULT_TLS_INTERACTION      NULL
 #define DEFAULT_TIMEOUT              15
 #define DEFAULT_RETRIES              3
 #define DEFAULT_SOUP_METHOD          NULL
@@ -380,6 +382,20 @@
           "TLS database with anchor certificate authorities used to validate the server certificate",
           G_TYPE_TLS_DATABASE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  /**
+   * GstSoupHTTPSrc::tls-interaction:
+   *
+   * A #GTlsInteraction object to be used when the connection or certificate
+   * database need to interact with the user. This will be used to prompt the
+   * user for passwords or certificate where necessary.
+   *
+   * Since: 1.8
+   */
+  g_object_class_install_property (gobject_class, PROP_TLS_INTERACTION,
+      g_param_spec_object ("tls-interaction", "TLS interaction",
+          "A GTlsInteraction object to be used when the connection or certificate database need to interact with the user.",
+          G_TYPE_TLS_INTERACTION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
  /**
    * GstSoupHTTPSrc::retries:
    *
@@ -484,6 +500,7 @@
   src->ssl_strict = DEFAULT_SSL_STRICT;
   src->ssl_use_system_ca_file = DEFAULT_SSL_USE_SYSTEM_CA_FILE;
   src->tls_database = DEFAULT_TLS_DATABASE;
+  src->tls_interaction = DEFAULT_TLS_INTERACTION;
   src->max_retries = DEFAULT_RETRIES;
   src->method = DEFAULT_SOUP_METHOD;
   proxy = g_getenv ("http_proxy");
@@ -520,9 +537,7 @@
   g_mutex_clear (&src->mutex);
   g_cond_clear (&src->request_finished_cond);
   g_free (src->location);
-  if (src->redirection_uri) {
-    g_free (src->redirection_uri);
-  }
+  g_free (src->redirection_uri);
   g_free (src->user_agent);
   if (src->proxy != NULL) {
     soup_uri_free (src->proxy);
@@ -544,6 +559,9 @@
     g_object_unref (src->tls_database);
   g_free (src->method);
 
+  if (src->tls_interaction)
+    g_object_unref (src->tls_interaction);
+
   G_OBJECT_CLASS (parent_class)->finalize (gobject);
 }
 
@@ -571,8 +589,7 @@
       break;
     }
     case PROP_USER_AGENT:
-      if (src->user_agent)
-        g_free (src->user_agent);
+      g_free (src->user_agent);
       src->user_agent = g_value_dup_string (value);
       break;
     case PROP_IRADIO_MODE:
@@ -600,23 +617,19 @@
       gst_base_src_set_live (GST_BASE_SRC (src), g_value_get_boolean (value));
       break;
     case PROP_USER_ID:
-      if (src->user_id)
-        g_free (src->user_id);
+      g_free (src->user_id);
       src->user_id = g_value_dup_string (value);
       break;
     case PROP_USER_PW:
-      if (src->user_pw)
-        g_free (src->user_pw);
+      g_free (src->user_pw);
       src->user_pw = g_value_dup_string (value);
       break;
     case PROP_PROXY_ID:
-      if (src->proxy_id)
-        g_free (src->proxy_id);
+      g_free (src->proxy_id);
       src->proxy_id = g_value_dup_string (value);
       break;
     case PROP_PROXY_PW:
-      if (src->proxy_pw)
-        g_free (src->proxy_pw);
+      g_free (src->proxy_pw);
       src->proxy_pw = g_value_dup_string (value);
       break;
     case PROP_TIMEOUT:
@@ -644,8 +657,7 @@
       src->ssl_strict = g_value_get_boolean (value);
       break;
     case PROP_SSL_CA_FILE:
-      if (src->ssl_ca_file)
-        g_free (src->ssl_ca_file);
+      g_free (src->ssl_ca_file);
       src->ssl_ca_file = g_value_dup_string (value);
       break;
     case PROP_SSL_USE_SYSTEM_CA_FILE:
@@ -655,6 +667,10 @@
       g_clear_object (&src->tls_database);
       src->tls_database = g_value_dup_object (value);
       break;
+    case PROP_TLS_INTERACTION:
+      g_clear_object (&src->tls_interaction);
+      src->tls_interaction = g_value_dup_object (value);
+      break;
     case PROP_RETRIES:
       src->max_retries = g_value_get_int (value);
       break;
@@ -744,6 +760,9 @@
     case PROP_TLS_DATABASE:
       g_value_set_object (value, src->tls_database);
       break;
+    case PROP_TLS_INTERACTION:
+      g_value_set_object (value, src->tls_interaction);
+      break;
     case PROP_RETRIES:
       g_value_set_int (value, src->max_retries);
       break;
@@ -791,14 +810,16 @@
     guint64 stop_offset)
 {
   gchar buf[64];
-
   gint rc;
 
   soup_message_headers_remove (src->msg->request_headers, "Range");
   if (offset || stop_offset != -1) {
     if (stop_offset != -1) {
+      g_assert (offset != stop_offset);
+
       rc = g_snprintf (buf, sizeof (buf), "bytes=%" G_GUINT64_FORMAT "-%"
-          G_GUINT64_FORMAT, offset, stop_offset);
+          G_GUINT64_FORMAT, offset, (stop_offset > 0) ? stop_offset - 1 :
+          stop_offset);
     } else {
       rc = g_snprintf (buf, sizeof (buf), "bytes=%" G_GUINT64_FORMAT "-",
           offset);
@@ -934,14 +955,15 @@
           SOUP_SESSION_TIMEOUT, src->timeout,
           SOUP_SESSION_SSL_STRICT, src->ssl_strict,
           SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_PROXY_RESOLVER_DEFAULT,
-          NULL);
+          SOUP_SESSION_TLS_INTERACTION, src->tls_interaction, NULL);
     } else {
       src->session =
           soup_session_async_new_with_options (SOUP_SESSION_ASYNC_CONTEXT,
           src->context, SOUP_SESSION_PROXY_URI, src->proxy,
           SOUP_SESSION_TIMEOUT, src->timeout,
           SOUP_SESSION_SSL_STRICT, src->ssl_strict,
-          SOUP_SESSION_USER_AGENT, src->user_agent, NULL);
+          SOUP_SESSION_USER_AGENT, src->user_agent,
+          SOUP_SESSION_TLS_INTERACTION, src->tls_interaction, NULL);
     }
 
     if (!src->session) {
@@ -1685,6 +1707,10 @@
   GST_LOG_OBJECT (src, "Running request for method: %s", method);
   if (src->msg && (src->request_position != src->read_position)) {
     if (src->session_io_status == GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_IDLE) {
+      /* EOS immediately if we have an empty segment */
+      if (src->request_position == src->stop_position)
+        return GST_FLOW_EOS;
+
       gst_soup_http_src_add_range_header (src, src->request_position,
           src->stop_position);
     } else {
@@ -1694,10 +1720,14 @@
       gst_soup_http_src_cancel_message (src);
     }
   }
-  if (!src->msg)
-    if (!gst_soup_http_src_build_message (src, method)) {
+  if (!src->msg) {
+    /* EOS immediately if we have an empty segment */
+    if (src->request_position == src->stop_position)
+      return GST_FLOW_EOS;
+
+    if (!gst_soup_http_src_build_message (src, method))
       return GST_FLOW_ERROR;
-    }
+  }
 
   src->ret = GST_FLOW_CUSTOM_ERROR;
   src->outbuf = outbuf;
@@ -1709,9 +1739,13 @@
     }
     if (src->retry) {
       GST_INFO_OBJECT (src, "Reconnecting");
-      if (!gst_soup_http_src_build_message (src, method)) {
+
+      /* EOS immediately if we have an empty segment */
+      if (src->request_position == src->stop_position)
+        return GST_FLOW_EOS;
+
+      if (!gst_soup_http_src_build_message (src, method))
         return GST_FLOW_ERROR;
-      }
       src->retry = FALSE;
       continue;
     }
diff --git a/ext/soup/gstsouphttpsrc.h b/ext/soup/gstsouphttpsrc.h
index ef9539c..7172581 100644
--- a/ext/soup/gstsouphttpsrc.h
+++ b/ext/soup/gstsouphttpsrc.h
@@ -92,6 +92,7 @@
   gchar *ssl_ca_file;
   gboolean ssl_use_system_ca_file;
   GTlsDatabase *tls_database;
+  GTlsInteraction *tls_interaction;
 
   /* Shoutcast/icecast metadata extraction handling. */
   gboolean iradio_mode;
diff --git a/ext/speex/Makefile.in b/ext/speex/Makefile.in
index 7c1df31..48db8d8 100644
--- a/ext/speex/Makefile.in
+++ b/ext/speex/Makefile.in
@@ -478,6 +478,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/ext/taglib/Makefile.in b/ext/taglib/Makefile.in
index a00ec34..210bfa6 100644
--- a/ext/taglib/Makefile.in
+++ b/ext/taglib/Makefile.in
@@ -495,6 +495,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/ext/vpx/Makefile.am b/ext/vpx/Makefile.am
index 1763638..4453fc0 100644
--- a/ext/vpx/Makefile.am
+++ b/ext/vpx/Makefile.am
@@ -2,6 +2,8 @@
 	libgstvpx.la
 
 libgstvpx_la_SOURCES = \
+    gstvpxdec.c \
+    gstvpxenc.c \
 	gstvp8dec.c \
 	gstvp8enc.c \
 	gstvp8utils.c \
@@ -22,6 +24,8 @@
 libgstvpx_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = \
+    gstvpxdec.h \
+    gstvpxenc.h \
 	gstvp8dec.h \
 	gstvp8enc.h \
 	gstvp9dec.h \
diff --git a/ext/vpx/Makefile.in b/ext/vpx/Makefile.in
index 2ca8687..b424d0b 100644
--- a/ext/vpx/Makefile.in
+++ b/ext/vpx/Makefile.in
@@ -166,7 +166,8 @@
 libgstvpx_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_1)
-am_libgstvpx_la_OBJECTS = libgstvpx_la-gstvp8dec.lo \
+am_libgstvpx_la_OBJECTS = libgstvpx_la-gstvpxdec.lo \
+	libgstvpx_la-gstvpxenc.lo libgstvpx_la-gstvp8dec.lo \
 	libgstvpx_la-gstvp8enc.lo libgstvpx_la-gstvp8utils.lo \
 	libgstvpx_la-gstvp9dec.lo libgstvpx_la-gstvp9enc.lo \
 	libgstvpx_la-plugin.lo
@@ -482,6 +483,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
@@ -571,6 +574,8 @@
 	libgstvpx.la
 
 libgstvpx_la_SOURCES = \
+    gstvpxdec.c \
+    gstvpxenc.c \
 	gstvp8dec.c \
 	gstvp8enc.c \
 	gstvp8utils.c \
@@ -592,6 +597,8 @@
 libgstvpx_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstvpx_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 noinst_HEADERS = \
+    gstvpxdec.h \
+    gstvpxenc.h \
 	gstvp8dec.h \
 	gstvp8enc.h \
 	gstvp9dec.h \
@@ -684,6 +691,8 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvpx_la-gstvp8utils.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvpx_la-gstvp9dec.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvpx_la-gstvp9enc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvpx_la-gstvpxdec.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvpx_la-gstvpxenc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvpx_la-plugin.Plo@am__quote@
 
 .c.o:
@@ -710,6 +719,20 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
+libgstvpx_la-gstvpxdec.lo: gstvpxdec.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstvpx_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstvpx_la_CFLAGS) $(CFLAGS) -MT libgstvpx_la-gstvpxdec.lo -MD -MP -MF $(DEPDIR)/libgstvpx_la-gstvpxdec.Tpo -c -o libgstvpx_la-gstvpxdec.lo `test -f 'gstvpxdec.c' || echo '$(srcdir)/'`gstvpxdec.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstvpx_la-gstvpxdec.Tpo $(DEPDIR)/libgstvpx_la-gstvpxdec.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gstvpxdec.c' object='libgstvpx_la-gstvpxdec.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstvpx_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstvpx_la_CFLAGS) $(CFLAGS) -c -o libgstvpx_la-gstvpxdec.lo `test -f 'gstvpxdec.c' || echo '$(srcdir)/'`gstvpxdec.c
+
+libgstvpx_la-gstvpxenc.lo: gstvpxenc.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstvpx_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstvpx_la_CFLAGS) $(CFLAGS) -MT libgstvpx_la-gstvpxenc.lo -MD -MP -MF $(DEPDIR)/libgstvpx_la-gstvpxenc.Tpo -c -o libgstvpx_la-gstvpxenc.lo `test -f 'gstvpxenc.c' || echo '$(srcdir)/'`gstvpxenc.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstvpx_la-gstvpxenc.Tpo $(DEPDIR)/libgstvpx_la-gstvpxenc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gstvpxenc.c' object='libgstvpx_la-gstvpxenc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstvpx_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstvpx_la_CFLAGS) $(CFLAGS) -c -o libgstvpx_la-gstvpxenc.lo `test -f 'gstvpxenc.c' || echo '$(srcdir)/'`gstvpxenc.c
+
 libgstvpx_la-gstvp8dec.lo: gstvp8dec.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstvpx_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstvpx_la_CFLAGS) $(CFLAGS) -MT libgstvpx_la-gstvp8dec.lo -MD -MP -MF $(DEPDIR)/libgstvpx_la-gstvp8dec.Tpo -c -o libgstvpx_la-gstvp8dec.lo `test -f 'gstvp8dec.c' || echo '$(srcdir)/'`gstvp8dec.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstvpx_la-gstvp8dec.Tpo $(DEPDIR)/libgstvpx_la-gstvp8dec.Plo
diff --git a/ext/vpx/gstvp8dec.c b/ext/vpx/gstvp8dec.c
index c86cc4c..5b8eade 100644
--- a/ext/vpx/gstvp8dec.c
+++ b/ext/vpx/gstvp8dec.c
@@ -54,63 +54,12 @@
 GST_DEBUG_CATEGORY_STATIC (gst_vp8dec_debug);
 #define GST_CAT_DEFAULT gst_vp8dec_debug
 
-#define DEFAULT_POST_PROCESSING FALSE
-#define DEFAULT_POST_PROCESSING_FLAGS (VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE)
-#define DEFAULT_DEBLOCKING_LEVEL 4
-#define DEFAULT_NOISE_LEVEL 0
-#define DEFAULT_THREADS 1
+#define VP8_DECODER_VIDEO_TAG "VP8 video"
 
-enum
-{
-  PROP_0,
-  PROP_POST_PROCESSING,
-  PROP_POST_PROCESSING_FLAGS,
-  PROP_DEBLOCKING_LEVEL,
-  PROP_NOISE_LEVEL,
-  PROP_THREADS
-};
-
-#define C_FLAGS(v) ((guint) v)
-#define GST_VP8_DEC_TYPE_POST_PROCESSING_FLAGS (gst_vp8_dec_post_processing_flags_get_type())
-static GType
-gst_vp8_dec_post_processing_flags_get_type (void)
-{
-  static const GFlagsValue values[] = {
-    {C_FLAGS (VP8_DEBLOCK), "Deblock", "deblock"},
-    {C_FLAGS (VP8_DEMACROBLOCK), "Demacroblock", "demacroblock"},
-    {C_FLAGS (VP8_ADDNOISE), "Add noise", "addnoise"},
-    {C_FLAGS (VP8_MFQE), "Multi-frame quality enhancement", "mfqe"},
-    {0, NULL, NULL}
-  };
-  static volatile GType id = 0;
-
-  if (g_once_init_enter ((gsize *) & id)) {
-    GType _id;
-
-    _id = g_flags_register_static ("GstVP8DecPostProcessingFlags", values);
-
-    g_once_init_leave ((gsize *) & id, _id);
-  }
-
-  return id;
-}
-
-#undef C_FLAGS
-
-static void gst_vp8_dec_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-static void gst_vp8_dec_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-
-static gboolean gst_vp8_dec_start (GstVideoDecoder * decoder);
-static gboolean gst_vp8_dec_stop (GstVideoDecoder * decoder);
-static gboolean gst_vp8_dec_set_format (GstVideoDecoder * decoder,
-    GstVideoCodecState * state);
-static gboolean gst_vp8_dec_flush (GstVideoDecoder * decoder);
-static GstFlowReturn gst_vp8_dec_handle_frame (GstVideoDecoder * decoder,
-    GstVideoCodecFrame * frame);
-static gboolean gst_vp8_dec_decide_allocation (GstVideoDecoder * decoder,
-    GstQuery * query);
+static void gst_vp8_dec_set_default_format (GstVPXDec * dec, GstVideoFormat fmt,
+    int width, int height);
+static void gst_vp8_dec_handle_resolution_change (GstVPXDec * dec,
+    vpx_image_t * img, GstVideoFormat fmt);
 
 static GstStaticPadTemplate gst_vp8_dec_sink_template =
 GST_STATIC_PAD_TEMPLATE ("sink",
@@ -127,54 +76,22 @@
     );
 
 #define parent_class gst_vp8_dec_parent_class
-G_DEFINE_TYPE (GstVP8Dec, gst_vp8_dec, GST_TYPE_VIDEO_DECODER);
+G_DEFINE_TYPE (GstVP8Dec, gst_vp8_dec, GST_TYPE_VPX_DEC);
 
 static void
 gst_vp8_dec_class_init (GstVP8DecClass * klass)
 {
-  GObjectClass *gobject_class;
   GstElementClass *element_class;
-  GstVideoDecoderClass *base_video_decoder_class;
+  GstVPXDecClass *vpx_class;
 
-  gobject_class = G_OBJECT_CLASS (klass);
   element_class = GST_ELEMENT_CLASS (klass);
-  base_video_decoder_class = GST_VIDEO_DECODER_CLASS (klass);
+  vpx_class = GST_VPX_DEC_CLASS (klass);
 
-  gobject_class->set_property = gst_vp8_dec_set_property;
-  gobject_class->get_property = gst_vp8_dec_get_property;
-
-  g_object_class_install_property (gobject_class, PROP_POST_PROCESSING,
-      g_param_spec_boolean ("post-processing", "Post Processing",
-          "Enable post processing", DEFAULT_POST_PROCESSING,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_POST_PROCESSING_FLAGS,
-      g_param_spec_flags ("post-processing-flags", "Post Processing Flags",
-          "Flags to control post processing",
-          GST_VP8_DEC_TYPE_POST_PROCESSING_FLAGS, DEFAULT_POST_PROCESSING_FLAGS,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_DEBLOCKING_LEVEL,
-      g_param_spec_uint ("deblocking-level", "Deblocking Level",
-          "Deblocking level",
-          0, 16, DEFAULT_DEBLOCKING_LEVEL,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_NOISE_LEVEL,
-      g_param_spec_uint ("noise-level", "Noise Level",
-          "Noise level",
-          0, 16, DEFAULT_NOISE_LEVEL,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_THREADS,
-      g_param_spec_uint ("threads", "Max Threads",
-          "Maximum number of decoding threads",
-          1, 16, DEFAULT_THREADS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&gst_vp8_dec_sink_template));
 
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&gst_vp8_dec_src_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_vp8_dec_sink_template));
 
   gst_element_class_set_static_metadata (element_class,
       "On2 VP8 Decoder",
@@ -182,14 +99,12 @@
       "Decode VP8 video streams", "David Schleef <ds@entropywave.com>, "
       "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
 
-  base_video_decoder_class->start = GST_DEBUG_FUNCPTR (gst_vp8_dec_start);
-  base_video_decoder_class->stop = GST_DEBUG_FUNCPTR (gst_vp8_dec_stop);
-  base_video_decoder_class->flush = GST_DEBUG_FUNCPTR (gst_vp8_dec_flush);
-  base_video_decoder_class->set_format =
-      GST_DEBUG_FUNCPTR (gst_vp8_dec_set_format);
-  base_video_decoder_class->handle_frame =
-      GST_DEBUG_FUNCPTR (gst_vp8_dec_handle_frame);
-  base_video_decoder_class->decide_allocation = gst_vp8_dec_decide_allocation;
+  vpx_class->video_codec_tag = VP8_DECODER_VIDEO_TAG;
+  vpx_class->codec_algo = &vpx_codec_vp8_dx_algo;
+  vpx_class->set_default_format =
+      GST_DEBUG_FUNCPTR (gst_vp8_dec_set_default_format);
+  vpx_class->handle_resolution_change =
+      GST_DEBUG_FUNCPTR (gst_vp8_dec_handle_resolution_change);
 
   GST_DEBUG_CATEGORY_INIT (gst_vp8dec_debug, "vp8dec", 0, "VP8 Decoder");
 }
@@ -197,437 +112,47 @@
 static void
 gst_vp8_dec_init (GstVP8Dec * gst_vp8_dec)
 {
-  GstVideoDecoder *decoder = (GstVideoDecoder *) gst_vp8_dec;
-
   GST_DEBUG_OBJECT (gst_vp8_dec, "gst_vp8_dec_init");
-  gst_video_decoder_set_packetized (decoder, TRUE);
-  gst_vp8_dec->post_processing = DEFAULT_POST_PROCESSING;
-  gst_vp8_dec->post_processing_flags = DEFAULT_POST_PROCESSING_FLAGS;
-  gst_vp8_dec->deblocking_level = DEFAULT_DEBLOCKING_LEVEL;
-  gst_vp8_dec->noise_level = DEFAULT_NOISE_LEVEL;
-
-  gst_video_decoder_set_needs_format (decoder, TRUE);
-  gst_video_decoder_set_use_default_pad_acceptcaps (decoder, TRUE);
-  GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_DECODER_SINK_PAD (decoder));
 }
 
 static void
-gst_vp8_dec_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
+gst_vp8_dec_set_default_format (GstVPXDec * dec, GstVideoFormat fmt, int width,
+    int height)
 {
-  GstVP8Dec *dec;
-
-  g_return_if_fail (GST_IS_VP8_DEC (object));
-  dec = GST_VP8_DEC (object);
-
-  GST_DEBUG_OBJECT (object, "gst_vp8_dec_set_property");
-  switch (prop_id) {
-    case PROP_POST_PROCESSING:
-      dec->post_processing = g_value_get_boolean (value);
-      break;
-    case PROP_POST_PROCESSING_FLAGS:
-      dec->post_processing_flags = g_value_get_flags (value);
-      break;
-    case PROP_DEBLOCKING_LEVEL:
-      dec->deblocking_level = g_value_get_uint (value);
-      break;
-    case PROP_NOISE_LEVEL:
-      dec->noise_level = g_value_get_uint (value);
-      break;
-    case PROP_THREADS:
-      dec->threads = g_value_get_uint (value);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_vp8_dec_get_property (GObject * object, guint prop_id, GValue * value,
-    GParamSpec * pspec)
-{
-  GstVP8Dec *dec;
-
-  g_return_if_fail (GST_IS_VP8_DEC (object));
-  dec = GST_VP8_DEC (object);
-
-  switch (prop_id) {
-    case PROP_POST_PROCESSING:
-      g_value_set_boolean (value, dec->post_processing);
-      break;
-    case PROP_POST_PROCESSING_FLAGS:
-      g_value_set_flags (value, dec->post_processing_flags);
-      break;
-    case PROP_DEBLOCKING_LEVEL:
-      g_value_set_uint (value, dec->deblocking_level);
-      break;
-    case PROP_NOISE_LEVEL:
-      g_value_set_uint (value, dec->noise_level);
-      break;
-    case PROP_THREADS:
-      g_value_set_uint (value, dec->threads);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static gboolean
-gst_vp8_dec_start (GstVideoDecoder * decoder)
-{
-  GstVP8Dec *gst_vp8_dec = GST_VP8_DEC (decoder);
-
-  GST_DEBUG_OBJECT (gst_vp8_dec, "start");
-  gst_vp8_dec->decoder_inited = FALSE;
-
-  return TRUE;
-}
-
-static gboolean
-gst_vp8_dec_stop (GstVideoDecoder * base_video_decoder)
-{
-  GstVP8Dec *gst_vp8_dec = GST_VP8_DEC (base_video_decoder);
-
-  GST_DEBUG_OBJECT (gst_vp8_dec, "stop");
-
-  if (gst_vp8_dec->output_state) {
-    gst_video_codec_state_unref (gst_vp8_dec->output_state);
-    gst_vp8_dec->output_state = NULL;
-  }
-
-  if (gst_vp8_dec->input_state) {
-    gst_video_codec_state_unref (gst_vp8_dec->input_state);
-    gst_vp8_dec->input_state = NULL;
-  }
-
-  if (gst_vp8_dec->decoder_inited)
-    vpx_codec_destroy (&gst_vp8_dec->decoder);
-  gst_vp8_dec->decoder_inited = FALSE;
-
-  return TRUE;
-}
-
-static gboolean
-gst_vp8_dec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
-{
-  GstVP8Dec *gst_vp8_dec = GST_VP8_DEC (decoder);
-
-  GST_DEBUG_OBJECT (gst_vp8_dec, "set_format");
-
-  if (gst_vp8_dec->decoder_inited)
-    vpx_codec_destroy (&gst_vp8_dec->decoder);
-  gst_vp8_dec->decoder_inited = FALSE;
-
-  if (gst_vp8_dec->output_state) {
-    gst_video_codec_state_unref (gst_vp8_dec->output_state);
-    gst_vp8_dec->output_state = NULL;
-  }
-
-  if (gst_vp8_dec->input_state) {
-    gst_video_codec_state_unref (gst_vp8_dec->input_state);
-    gst_vp8_dec->input_state = NULL;
-  }
-
-  gst_vp8_dec->input_state = gst_video_codec_state_ref (state);
-
-  return TRUE;
-}
-
-static gboolean
-gst_vp8_dec_flush (GstVideoDecoder * base_video_decoder)
-{
-  GstVP8Dec *decoder;
-
-  GST_DEBUG_OBJECT (base_video_decoder, "flush");
-
-  decoder = GST_VP8_DEC (base_video_decoder);
-
-  if (decoder->output_state) {
-    gst_video_codec_state_unref (decoder->output_state);
-    decoder->output_state = NULL;
-  }
-
-  if (decoder->decoder_inited)
-    vpx_codec_destroy (&decoder->decoder);
-  decoder->decoder_inited = FALSE;
-
-  return TRUE;
-}
-
-static void
-gst_vp8_dec_send_tags (GstVP8Dec * dec)
-{
-  GstTagList *list;
-
-  list = gst_tag_list_new_empty ();
-  gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
-      GST_TAG_VIDEO_CODEC, "VP8 video", NULL);
-
-  gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (dec),
-      gst_event_new_tag (list));
-}
-
-static void
-gst_vp8_dec_image_to_buffer (GstVP8Dec * dec, const vpx_image_t * img,
-    GstBuffer * buffer)
-{
-  int deststride, srcstride, height, width, line, comp;
-  guint8 *dest, *src;
-  GstVideoFrame frame;
-  GstVideoInfo *info = &dec->output_state->info;
-
-  if (!gst_video_frame_map (&frame, info, buffer, GST_MAP_WRITE)) {
-    GST_ERROR_OBJECT (dec, "Could not map video buffer");
-    return;
-  }
-
-  for (comp = 0; comp < 3; comp++) {
-    dest = GST_VIDEO_FRAME_COMP_DATA (&frame, comp);
-    src = img->planes[comp];
-    width = GST_VIDEO_FRAME_COMP_WIDTH (&frame, comp)
-        * GST_VIDEO_FRAME_COMP_PSTRIDE (&frame, comp);
-    height = GST_VIDEO_FRAME_COMP_HEIGHT (&frame, comp);
-    deststride = GST_VIDEO_FRAME_COMP_STRIDE (&frame, comp);
-    srcstride = img->stride[comp];
-
-    if (srcstride == deststride) {
-      GST_TRACE_OBJECT (dec, "Stride matches. Comp %d: %d, copying full plane",
-          comp, srcstride);
-      memcpy (dest, src, srcstride * height);
-    } else {
-      GST_TRACE_OBJECT (dec, "Stride mismatch. Comp %d: %d != %d, copying "
-          "line by line.", comp, srcstride, deststride);
-      for (line = 0; line < height; line++) {
-        memcpy (dest, src, width);
-        dest += deststride;
-        src += srcstride;
-      }
-    }
-  }
-
-  gst_video_frame_unmap (&frame);
-}
-
-static GstFlowReturn
-open_codec (GstVP8Dec * dec, GstVideoCodecFrame * frame)
-{
-  int flags = 0;
-  vpx_codec_stream_info_t stream_info;
-  vpx_codec_caps_t caps;
-  vpx_codec_dec_cfg_t cfg;
-  GstVideoCodecState *state = dec->input_state;
-  vpx_codec_err_t status;
-  GstMapInfo minfo;
-
-  memset (&stream_info, 0, sizeof (stream_info));
-  memset (&cfg, 0, sizeof (cfg));
-  stream_info.sz = sizeof (stream_info);
-
-  if (!gst_buffer_map (frame->input_buffer, &minfo, GST_MAP_READ)) {
-    GST_ERROR_OBJECT (dec, "Failed to map input buffer");
-    return GST_FLOW_ERROR;
-  }
-
-  status = vpx_codec_peek_stream_info (&vpx_codec_vp8_dx_algo,
-      minfo.data, minfo.size, &stream_info);
-
-  gst_buffer_unmap (frame->input_buffer, &minfo);
-
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (dec, "VPX preprocessing error: %s",
-        gst_vpx_error_name (status));
-    gst_video_decoder_drop_frame (GST_VIDEO_DECODER (dec), frame);
-    return GST_FLOW_CUSTOM_SUCCESS_1;
-  }
-  if (!stream_info.is_kf) {
-    GST_WARNING_OBJECT (dec, "No keyframe, skipping");
-    gst_video_decoder_drop_frame (GST_VIDEO_DECODER (dec), frame);
-    return GST_FLOW_CUSTOM_SUCCESS_1;
-  }
-
+  GstVPXDecClass *vpxclass = GST_VPX_DEC_GET_CLASS (dec);
   g_assert (dec->output_state == NULL);
   dec->output_state =
       gst_video_decoder_set_output_state (GST_VIDEO_DECODER (dec),
-      GST_VIDEO_FORMAT_I420, stream_info.w, stream_info.h, state);
+      GST_VIDEO_FORMAT_I420, width, height, dec->input_state);
   gst_video_decoder_negotiate (GST_VIDEO_DECODER (dec));
-  gst_vp8_dec_send_tags (dec);
-
-  cfg.w = stream_info.w;
-  cfg.h = stream_info.h;
-  cfg.threads = dec->threads;
-
-  caps = vpx_codec_get_caps (&vpx_codec_vp8_dx_algo);
-
-  if (dec->post_processing) {
-    if (!(caps & VPX_CODEC_CAP_POSTPROC)) {
-      GST_WARNING_OBJECT (dec, "Decoder does not support post processing");
-    } else {
-      flags |= VPX_CODEC_USE_POSTPROC;
-    }
-  }
-
-  status =
-      vpx_codec_dec_init (&dec->decoder, &vpx_codec_vp8_dx_algo, &cfg, flags);
-  if (status != VPX_CODEC_OK) {
-    GST_ELEMENT_ERROR (dec, LIBRARY, INIT,
-        ("Failed to initialize VP8 decoder"), ("%s",
-            gst_vpx_error_name (status)));
-    return GST_FLOW_ERROR;
-  }
-
-  if ((caps & VPX_CODEC_CAP_POSTPROC) && dec->post_processing) {
-    vp8_postproc_cfg_t pp_cfg = { 0, };
-
-    pp_cfg.post_proc_flag = dec->post_processing_flags;
-    pp_cfg.deblocking_level = dec->deblocking_level;
-    pp_cfg.noise_level = dec->noise_level;
-
-    status = vpx_codec_control (&dec->decoder, VP8_SET_POSTPROC, &pp_cfg);
-    if (status != VPX_CODEC_OK) {
-      GST_WARNING_OBJECT (dec, "Couldn't set postprocessing settings: %s",
-          gst_vpx_error_name (status));
-    }
-  }
-
-  dec->decoder_inited = TRUE;
-
-  return GST_FLOW_OK;
+  vpxclass->send_tags (dec);
 }
 
-static GstFlowReturn
-gst_vp8_dec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
+static void
+gst_vp8_dec_handle_resolution_change (GstVPXDec * dec, vpx_image_t * img,
+    GstVideoFormat fmt)
 {
-  GstVP8Dec *dec;
-  GstFlowReturn ret = GST_FLOW_OK;
-  vpx_codec_err_t status;
-  vpx_codec_iter_t iter = NULL;
-  vpx_image_t *img;
-  long decoder_deadline = 0;
-  GstClockTimeDiff deadline;
-  GstMapInfo minfo;
   GstVideoInfo *info;
   GstVideoCodecState *new_output_state;
 
-  GST_LOG_OBJECT (decoder, "handle_frame");
+  info = &dec->output_state->info;
+  if (GST_VIDEO_INFO_WIDTH (info) != img->d_w
+      || GST_VIDEO_INFO_HEIGHT (info) != img->d_h) {
+    GST_DEBUG_OBJECT (dec,
+        "Changed output resolution was %d x %d now is got %u x %u (display %u x %u)",
+        GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info), img->w,
+        img->h, img->d_w, img->d_h);
 
-  dec = GST_VP8_DEC (decoder);
-
-  if (!dec->decoder_inited) {
-    ret = open_codec (dec, frame);
-    if (ret == GST_FLOW_CUSTOM_SUCCESS_1)
-      return GST_FLOW_OK;
-    else if (ret != GST_FLOW_OK)
-      return ret;
-  }
-
-  deadline = gst_video_decoder_get_max_decode_time (decoder, frame);
-  if (deadline < 0) {
-    decoder_deadline = 1;
-  } else if (deadline == G_MAXINT64) {
-    decoder_deadline = 0;
-  } else {
-    decoder_deadline = MAX (1, deadline / GST_MSECOND);
-  }
-
-  if (!gst_buffer_map (frame->input_buffer, &minfo, GST_MAP_READ)) {
-    GST_ERROR_OBJECT (dec, "Failed to map input buffer");
-    return GST_FLOW_ERROR;
-  }
-
-  status = vpx_codec_decode (&dec->decoder,
-      minfo.data, minfo.size, NULL, decoder_deadline);
-
-  gst_buffer_unmap (frame->input_buffer, &minfo);
-
-  if (status) {
-    GST_VIDEO_DECODER_ERROR (decoder, 1, LIBRARY, ENCODE,
-        ("Failed to decode frame"), ("%s", gst_vpx_error_name (status)), ret);
-    return ret;
-  }
-
-  img = vpx_codec_get_frame (&dec->decoder, &iter);
-  if (img) {
-    if (img->fmt != VPX_IMG_FMT_I420) {
-      vpx_img_free (img);
-      GST_ELEMENT_ERROR (decoder, LIBRARY, ENCODE,
-          ("Failed to decode frame"), ("Unsupported color format %d",
-              img->fmt));
-      return GST_FLOW_ERROR;
+    new_output_state =
+        gst_video_decoder_set_output_state (GST_VIDEO_DECODER (dec),
+        GST_VIDEO_FORMAT_I420, img->d_w, img->d_h, dec->output_state);
+    if (dec->output_state) {
+      gst_video_codec_state_unref (dec->output_state);
     }
-
-    if (deadline < 0) {
-      GST_LOG_OBJECT (dec, "Skipping late frame (%f s past deadline)",
-          (double) -deadline / GST_SECOND);
-      gst_video_decoder_drop_frame (decoder, frame);
-    } else {
-      info = &dec->output_state->info;
-      if (GST_VIDEO_INFO_WIDTH (info) != img->d_w
-          || GST_VIDEO_INFO_HEIGHT (info) != img->d_h) {
-        GST_DEBUG_OBJECT (dec,
-            "Changed output resolution was %d x %d now is got %u x %u (display %u x %u)",
-            GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info), img->w,
-            img->h, img->d_w, img->d_h);
-
-        new_output_state =
-            gst_video_decoder_set_output_state (GST_VIDEO_DECODER (dec),
-            GST_VIDEO_FORMAT_I420, img->d_w, img->d_h, dec->output_state);
-        if (dec->output_state) {
-          gst_video_codec_state_unref (dec->output_state);
-        }
-        dec->output_state = new_output_state;
-        /* No need to call negotiate() here, it will be automatically called
-         * by allocate_output_frame() below */
-      }
-
-      ret = gst_video_decoder_allocate_output_frame (decoder, frame);
-
-      if (ret == GST_FLOW_OK) {
-        gst_vp8_dec_image_to_buffer (dec, img, frame->output_buffer);
-        ret = gst_video_decoder_finish_frame (decoder, frame);
-      } else {
-        gst_video_decoder_drop_frame (decoder, frame);
-      }
-    }
-
-    vpx_img_free (img);
-
-    while ((img = vpx_codec_get_frame (&dec->decoder, &iter))) {
-      GST_WARNING_OBJECT (decoder, "Multiple decoded frames... dropping");
-      vpx_img_free (img);
-    }
-  } else {
-    /* Invisible frame */
-    GST_VIDEO_CODEC_FRAME_SET_DECODE_ONLY (frame);
-    gst_video_decoder_finish_frame (decoder, frame);
+    dec->output_state = new_output_state;
+    /* No need to call negotiate() here, it will be automatically called
+     * by allocate_output_frame()*/
   }
-
-  return ret;
-}
-
-static gboolean
-gst_vp8_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query)
-{
-  GstBufferPool *pool;
-  GstStructure *config;
-
-  if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (bdec, query))
-    return FALSE;
-
-  g_assert (gst_query_get_n_allocation_pools (query) > 0);
-  gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL);
-  g_assert (pool != NULL);
-
-  config = gst_buffer_pool_get_config (pool);
-  if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) {
-    gst_buffer_pool_config_add_option (config,
-        GST_BUFFER_POOL_OPTION_VIDEO_META);
-  }
-  gst_buffer_pool_set_config (pool, config);
-  gst_object_unref (pool);
-
-  return TRUE;
 }
 
 #endif /* HAVE_VP8_DECODER */
diff --git a/ext/vpx/gstvp8dec.h b/ext/vpx/gstvp8dec.h
index 8692f01..fc3b161 100644
--- a/ext/vpx/gstvp8dec.h
+++ b/ext/vpx/gstvp8dec.h
@@ -31,6 +31,7 @@
 
 #include <gst/gst.h>
 #include <gst/video/gstvideodecoder.h>
+#include <gstvpxdec.h>
 
 /* FIXME: Undef HAVE_CONFIG_H because vpx_codec.h uses it,
  * which causes compilation failures */
@@ -59,28 +60,12 @@
 
 struct _GstVP8Dec
 {
-  GstVideoDecoder base_video_decoder;
-
-  /* < private > */
-  vpx_codec_ctx_t decoder;
-
-  /* state */
-  gboolean decoder_inited;
-
-  /* properties */
-  gboolean post_processing;
-  enum vp8_postproc_level post_processing_flags;
-  gint deblocking_level;
-  gint noise_level;
-  gint threads;
-
-  GstVideoCodecState *input_state;
-  GstVideoCodecState *output_state;
+  GstVPXDec base_vpx_decoder;
 };
 
 struct _GstVP8DecClass
 {
-  GstVideoDecoderClass base_video_decoder_class;
+  GstVPXDecClass base_vpx_class;
 };
 
 GType gst_vp8_dec_get_type (void);
diff --git a/ext/vpx/gstvp8enc.c b/ext/vpx/gstvp8enc.c
index a538192..c7bca12 100644
--- a/ext/vpx/gstvp8enc.c
+++ b/ext/vpx/gstvp8enc.c
@@ -93,293 +93,21 @@
   g_slice_free (GstVP8EncUserData, user_data);
 }
 
-/* From vp8/vp8_cx_iface.c */
-#define DEFAULT_PROFILE 0
+static vpx_codec_iface_t *gst_vp8_enc_get_algo (GstVPXEnc * enc);
+static gboolean gst_vp8_enc_enable_scaling (GstVPXEnc * enc);
+static void gst_vp8_enc_set_image_format (GstVPXEnc * enc, vpx_image_t * image);
+static GstCaps *gst_vp8_enc_get_new_simple_caps (GstVPXEnc * enc);
+static void gst_vp8_enc_set_stream_info (GstVPXEnc * enc, GstCaps * caps,
+    GstVideoInfo * info);
+static void *gst_vp8_enc_process_frame_user_data (GstVPXEnc * enc,
+    GstVideoCodecFrame * frame);
+static GstFlowReturn gst_vp8_enc_handle_invisible_frame_buffer (GstVPXEnc * enc,
+    void *user_data, GstBuffer * buffer);
+static void gst_vp8_enc_set_frame_user_data (GstVPXEnc * enc,
+    GstVideoCodecFrame * frame, vpx_image_t * image);
 
-#define DEFAULT_RC_END_USAGE VPX_VBR
-#define DEFAULT_RC_TARGET_BITRATE 256000
-#define DEFAULT_RC_MIN_QUANTIZER 4
-#define DEFAULT_RC_MAX_QUANTIZER 63
-
-#define DEFAULT_RC_DROPFRAME_THRESH 0
-#define DEFAULT_RC_RESIZE_ALLOWED 0
-#define DEFAULT_RC_RESIZE_UP_THRESH 30
-#define DEFAULT_RC_RESIZE_DOWN_THRESH 60
-#define DEFAULT_RC_UNDERSHOOT_PCT 100
-#define DEFAULT_RC_OVERSHOOT_PCT 100
-#define DEFAULT_RC_BUF_SZ 6000
-#define DEFAULT_RC_BUF_INITIAL_SZ 4000
-#define DEFAULT_RC_BUF_OPTIMAL_SZ 5000
-#define DEFAULT_RC_2PASS_VBR_BIAS_PCT 50
-#define DEFAULT_RC_2PASS_VBR_MINSECTION_PCT 0
-#define DEFAULT_RC_2PASS_VBR_MAXSECTION_PCT 400
-
-#define DEFAULT_KF_MODE VPX_KF_AUTO
-#define DEFAULT_KF_MAX_DIST 128
-
-#define DEFAULT_MULTIPASS_MODE VPX_RC_ONE_PASS
-#define DEFAULT_MULTIPASS_CACHE_FILE "multipass.cache"
-
-#define DEFAULT_TS_NUMBER_LAYERS 1
-#define DEFAULT_TS_TARGET_BITRATE NULL
-#define DEFAULT_TS_RATE_DECIMATOR NULL
-#define DEFAULT_TS_PERIODICITY 0
-#define DEFAULT_TS_LAYER_ID NULL
-
-#define DEFAULT_ERROR_RESILIENT 0
-#define DEFAULT_LAG_IN_FRAMES 0
-
-#define DEFAULT_THREADS 0
-
-#define DEFAULT_H_SCALING_MODE VP8E_NORMAL
-#define DEFAULT_V_SCALING_MODE VP8E_NORMAL
-#define DEFAULT_CPU_USED 0
-#define DEFAULT_ENABLE_AUTO_ALT_REF FALSE
-#define DEFAULT_DEADLINE VPX_DL_BEST_QUALITY
-#define DEFAULT_NOISE_SENSITIVITY 0
-#define DEFAULT_SHARPNESS 0
-#define DEFAULT_STATIC_THRESHOLD 0
-#define DEFAULT_TOKEN_PARTITIONS 0
-#define DEFAULT_ARNR_MAXFRAMES 0
-#define DEFAULT_ARNR_STRENGTH 3
-#define DEFAULT_ARNR_TYPE 3
-#define DEFAULT_TUNING VP8_TUNE_PSNR
-#define DEFAULT_CQ_LEVEL 10
-#define DEFAULT_MAX_INTRA_BITRATE_PCT 0
-#define DEFAULT_TIMEBASE_N 0
-#define DEFAULT_TIMEBASE_D 1
-
-enum
-{
-  PROP_0,
-  PROP_RC_END_USAGE,
-  PROP_RC_TARGET_BITRATE,
-  PROP_RC_MIN_QUANTIZER,
-  PROP_RC_MAX_QUANTIZER,
-  PROP_RC_DROPFRAME_THRESH,
-  PROP_RC_RESIZE_ALLOWED,
-  PROP_RC_RESIZE_UP_THRESH,
-  PROP_RC_RESIZE_DOWN_THRESH,
-  PROP_RC_UNDERSHOOT_PCT,
-  PROP_RC_OVERSHOOT_PCT,
-  PROP_RC_BUF_SZ,
-  PROP_RC_BUF_INITIAL_SZ,
-  PROP_RC_BUF_OPTIMAL_SZ,
-  PROP_RC_2PASS_VBR_BIAS_PCT,
-  PROP_RC_2PASS_VBR_MINSECTION_PCT,
-  PROP_RC_2PASS_VBR_MAXSECTION_PCT,
-  PROP_KF_MODE,
-  PROP_KF_MAX_DIST,
-  PROP_TS_NUMBER_LAYERS,
-  PROP_TS_TARGET_BITRATE,
-  PROP_TS_RATE_DECIMATOR,
-  PROP_TS_PERIODICITY,
-  PROP_TS_LAYER_ID,
-  PROP_MULTIPASS_MODE,
-  PROP_MULTIPASS_CACHE_FILE,
-  PROP_ERROR_RESILIENT,
-  PROP_LAG_IN_FRAMES,
-  PROP_THREADS,
-  PROP_DEADLINE,
-  PROP_H_SCALING_MODE,
-  PROP_V_SCALING_MODE,
-  PROP_CPU_USED,
-  PROP_ENABLE_AUTO_ALT_REF,
-  PROP_NOISE_SENSITIVITY,
-  PROP_SHARPNESS,
-  PROP_STATIC_THRESHOLD,
-  PROP_TOKEN_PARTITIONS,
-  PROP_ARNR_MAXFRAMES,
-  PROP_ARNR_STRENGTH,
-  PROP_ARNR_TYPE,
-  PROP_TUNING,
-  PROP_CQ_LEVEL,
-  PROP_MAX_INTRA_BITRATE_PCT,
-  PROP_TIMEBASE
-};
-
-#define GST_VP8_ENC_END_USAGE_TYPE (gst_vp8_enc_end_usage_get_type())
-static GType
-gst_vp8_enc_end_usage_get_type (void)
-{
-  static const GEnumValue values[] = {
-    {VPX_VBR, "Variable Bit Rate (VBR) mode", "vbr"},
-    {VPX_CBR, "Constant Bit Rate (CBR) mode", "cbr"},
-    {VPX_CQ, "Constant Quality Mode (CQ) mode", "cq"},
-    {0, NULL, NULL}
-  };
-  static volatile GType id = 0;
-
-  if (g_once_init_enter ((gsize *) & id)) {
-    GType _id;
-
-    _id = g_enum_register_static ("GstVP8EncEndUsage", values);
-
-    g_once_init_leave ((gsize *) & id, _id);
-  }
-
-  return id;
-}
-
-#define GST_VP8_ENC_MULTIPASS_MODE_TYPE (gst_vp8_enc_multipass_mode_get_type())
-static GType
-gst_vp8_enc_multipass_mode_get_type (void)
-{
-  static const GEnumValue values[] = {
-    {VPX_RC_ONE_PASS, "One pass encoding (default)", "one-pass"},
-    {VPX_RC_FIRST_PASS, "First pass of multipass encoding", "first-pass"},
-    {VPX_RC_LAST_PASS, "Last pass of multipass encoding", "last-pass"},
-    {0, NULL, NULL}
-  };
-  static volatile GType id = 0;
-
-  if (g_once_init_enter ((gsize *) & id)) {
-    GType _id;
-
-    _id = g_enum_register_static ("GstVP8EncMultipassMode", values);
-
-    g_once_init_leave ((gsize *) & id, _id);
-  }
-
-  return id;
-}
-
-#define GST_VP8_ENC_KF_MODE_TYPE (gst_vp8_enc_kf_mode_get_type())
-static GType
-gst_vp8_enc_kf_mode_get_type (void)
-{
-  static const GEnumValue values[] = {
-    {VPX_KF_AUTO, "Determine optimal placement automatically", "auto"},
-    {VPX_KF_DISABLED, "Don't automatically place keyframes", "disabled"},
-    {0, NULL, NULL}
-  };
-  static volatile GType id = 0;
-
-  if (g_once_init_enter ((gsize *) & id)) {
-    GType _id;
-
-    _id = g_enum_register_static ("GstVP8EncKfMode", values);
-
-    g_once_init_leave ((gsize *) & id, _id);
-  }
-
-  return id;
-}
-
-#define GST_VP8_ENC_TUNING_TYPE (gst_vp8_enc_tuning_get_type())
-static GType
-gst_vp8_enc_tuning_get_type (void)
-{
-  static const GEnumValue values[] = {
-    {VP8_TUNE_PSNR, "Tune for PSNR", "psnr"},
-    {VP8_TUNE_SSIM, "Tune for SSIM", "ssim"},
-    {0, NULL, NULL}
-  };
-  static volatile GType id = 0;
-
-  if (g_once_init_enter ((gsize *) & id)) {
-    GType _id;
-
-    _id = g_enum_register_static ("GstVP8EncTuning", values);
-
-    g_once_init_leave ((gsize *) & id, _id);
-  }
-
-  return id;
-}
-
-#define GST_VP8_ENC_SCALING_MODE_TYPE (gst_vp8_enc_scaling_mode_get_type())
-static GType
-gst_vp8_enc_scaling_mode_get_type (void)
-{
-  static const GEnumValue values[] = {
-    {VP8E_NORMAL, "Normal", "normal"},
-    {VP8E_FOURFIVE, "4:5", "4:5"},
-    {VP8E_THREEFIVE, "3:5", "3:5"},
-    {VP8E_ONETWO, "1:2", "1:2"},
-    {0, NULL, NULL}
-  };
-  static volatile GType id = 0;
-
-  if (g_once_init_enter ((gsize *) & id)) {
-    GType _id;
-
-    _id = g_enum_register_static ("GstVP8EncScalingMode", values);
-
-    g_once_init_leave ((gsize *) & id, _id);
-  }
-
-  return id;
-}
-
-#define GST_VP8_ENC_TOKEN_PARTITIONS_TYPE (gst_vp8_enc_token_partitions_get_type())
-static GType
-gst_vp8_enc_token_partitions_get_type (void)
-{
-  static const GEnumValue values[] = {
-    {VP8_ONE_TOKENPARTITION, "One token partition", "1"},
-    {VP8_TWO_TOKENPARTITION, "Two token partitions", "2"},
-    {VP8_FOUR_TOKENPARTITION, "Four token partitions", "4"},
-    {VP8_EIGHT_TOKENPARTITION, "Eight token partitions", "8"},
-    {0, NULL, NULL}
-  };
-  static volatile GType id = 0;
-
-  if (g_once_init_enter ((gsize *) & id)) {
-    GType _id;
-
-    _id = g_enum_register_static ("GstVP8EncTokenPartitions", values);
-
-    g_once_init_leave ((gsize *) & id, _id);
-  }
-
-  return id;
-}
-
-#define GST_VP8_ENC_ER_FLAGS_TYPE (gst_vp8_enc_er_flags_get_type())
-static GType
-gst_vp8_enc_er_flags_get_type (void)
-{
-  static const GFlagsValue values[] = {
-    {VPX_ERROR_RESILIENT_DEFAULT, "Default error resilience", "default"},
-    {VPX_ERROR_RESILIENT_PARTITIONS,
-        "Allow partitions to be decoded independently", "partitions"},
-    {0, NULL, NULL}
-  };
-  static volatile GType id = 0;
-
-  if (g_once_init_enter ((gsize *) & id)) {
-    GType _id;
-
-    _id = g_flags_register_static ("GstVP8EncErFlags", values);
-
-    g_once_init_leave ((gsize *) & id, _id);
-  }
-
-  return id;
-}
-
-static void gst_vp8_enc_finalize (GObject * object);
-static void gst_vp8_enc_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-static void gst_vp8_enc_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-
-static gboolean gst_vp8_enc_start (GstVideoEncoder * encoder);
-static gboolean gst_vp8_enc_stop (GstVideoEncoder * encoder);
-static gboolean gst_vp8_enc_set_format (GstVideoEncoder *
-    video_encoder, GstVideoCodecState * state);
-static GstFlowReturn gst_vp8_enc_finish (GstVideoEncoder * video_encoder);
-static gboolean gst_vp8_enc_flush (GstVideoEncoder * video_encoder);
-static GstFlowReturn gst_vp8_enc_drain (GstVideoEncoder * video_encoder);
-static GstFlowReturn gst_vp8_enc_handle_frame (GstVideoEncoder *
-    video_encoder, GstVideoCodecFrame * frame);
 static GstFlowReturn gst_vp8_enc_pre_push (GstVideoEncoder * encoder,
     GstVideoCodecFrame * frame);
-static gboolean gst_vp8_enc_sink_event (GstVideoEncoder *
-    video_encoder, GstEvent * event);
-static gboolean gst_vp8_enc_propose_allocation (GstVideoEncoder * encoder,
-    GstQuery * query);
 
 static GstStaticPadTemplate gst_vp8_enc_sink_template =
 GST_STATIC_PAD_TEMPLATE ("sink",
@@ -399,24 +127,19 @@
     );
 
 #define parent_class gst_vp8_enc_parent_class
-G_DEFINE_TYPE_WITH_CODE (GstVP8Enc, gst_vp8_enc, GST_TYPE_VIDEO_ENCODER,
-    G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL);
-    G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL););
+G_DEFINE_TYPE (GstVP8Enc, gst_vp8_enc, GST_TYPE_VPX_ENC);
 
 static void
 gst_vp8_enc_class_init (GstVP8EncClass * klass)
 {
-  GObjectClass *gobject_class;
   GstElementClass *element_class;
   GstVideoEncoderClass *video_encoder_class;
+  GstVPXEncClass *vpx_encoder_class;
 
-  gobject_class = G_OBJECT_CLASS (klass);
   element_class = GST_ELEMENT_CLASS (klass);
   video_encoder_class = GST_VIDEO_ENCODER_CLASS (klass);
+  vpx_encoder_class = GST_VPX_ENC_CLASS (klass);
 
-  gobject_class->set_property = gst_vp8_enc_set_property;
-  gobject_class->get_property = gst_vp8_enc_get_property;
-  gobject_class->finalize = gst_vp8_enc_finalize;
 
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&gst_vp8_enc_src_template));
@@ -429,293 +152,18 @@
       "Encode VP8 video streams", "David Schleef <ds@entropywave.com>, "
       "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
 
-  video_encoder_class->start = gst_vp8_enc_start;
-  video_encoder_class->stop = gst_vp8_enc_stop;
-  video_encoder_class->handle_frame = gst_vp8_enc_handle_frame;
-  video_encoder_class->set_format = gst_vp8_enc_set_format;
-  video_encoder_class->flush = gst_vp8_enc_flush;
-  video_encoder_class->finish = gst_vp8_enc_finish;
   video_encoder_class->pre_push = gst_vp8_enc_pre_push;
-  video_encoder_class->sink_event = gst_vp8_enc_sink_event;
-  video_encoder_class->propose_allocation = gst_vp8_enc_propose_allocation;
 
-  g_object_class_install_property (gobject_class, PROP_RC_END_USAGE,
-      g_param_spec_enum ("end-usage", "Rate control mode",
-          "Rate control mode",
-          GST_VP8_ENC_END_USAGE_TYPE, DEFAULT_RC_END_USAGE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_TARGET_BITRATE,
-      g_param_spec_int ("target-bitrate", "Target bitrate",
-          "Target bitrate (in bits/sec)",
-          0, G_MAXINT, DEFAULT_RC_TARGET_BITRATE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_MIN_QUANTIZER,
-      g_param_spec_int ("min-quantizer", "Minimum Quantizer",
-          "Minimum Quantizer (best)",
-          0, 63, DEFAULT_RC_MIN_QUANTIZER,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_MAX_QUANTIZER,
-      g_param_spec_int ("max-quantizer", "Maximum Quantizer",
-          "Maximum Quantizer (worst)",
-          0, 63, DEFAULT_RC_MAX_QUANTIZER,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_DROPFRAME_THRESH,
-      g_param_spec_int ("dropframe-threshold", "Drop Frame Threshold",
-          "Temporal resampling threshold (buf %)",
-          0, 100, DEFAULT_RC_DROPFRAME_THRESH,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_RESIZE_ALLOWED,
-      g_param_spec_boolean ("resize-allowed", "Resize Allowed",
-          "Allow spatial resampling",
-          DEFAULT_RC_RESIZE_ALLOWED,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_RESIZE_UP_THRESH,
-      g_param_spec_int ("resize-up-threshold", "Resize Up Threshold",
-          "Upscale threshold (buf %)",
-          0, 100, DEFAULT_RC_RESIZE_UP_THRESH,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_RESIZE_DOWN_THRESH,
-      g_param_spec_int ("resize-down-threshold", "Resize Down Threshold",
-          "Downscale threshold (buf %)",
-          0, 100, DEFAULT_RC_RESIZE_DOWN_THRESH,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_UNDERSHOOT_PCT,
-      g_param_spec_int ("undershoot", "Undershoot PCT",
-          "Datarate undershoot (min) target (%)",
-          0, 1000, DEFAULT_RC_UNDERSHOOT_PCT,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_OVERSHOOT_PCT,
-      g_param_spec_int ("overshoot", "Overshoot PCT",
-          "Datarate overshoot (max) target (%)",
-          0, 1000, DEFAULT_RC_OVERSHOOT_PCT,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_BUF_SZ,
-      g_param_spec_int ("buffer-size", "Buffer size",
-          "Client buffer size (ms)",
-          0, G_MAXINT, DEFAULT_RC_BUF_SZ,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_BUF_INITIAL_SZ,
-      g_param_spec_int ("buffer-initial-size", "Buffer initial size",
-          "Initial client buffer size (ms)",
-          0, G_MAXINT, DEFAULT_RC_BUF_INITIAL_SZ,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_BUF_OPTIMAL_SZ,
-      g_param_spec_int ("buffer-optimal-size", "Buffer optimal size",
-          "Optimal client buffer size (ms)",
-          0, G_MAXINT, DEFAULT_RC_BUF_OPTIMAL_SZ,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_2PASS_VBR_BIAS_PCT,
-      g_param_spec_int ("twopass-vbr-bias", "2-pass VBR bias",
-          "CBR/VBR bias (0=CBR, 100=VBR)",
-          0, 100, DEFAULT_RC_2PASS_VBR_BIAS_PCT,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class,
-      PROP_RC_2PASS_VBR_MINSECTION_PCT,
-      g_param_spec_int ("twopass-vbr-minsection", "2-pass GOP min bitrate",
-          "GOP minimum bitrate (% target)", 0, G_MAXINT,
-          DEFAULT_RC_2PASS_VBR_MINSECTION_PCT,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class,
-      PROP_RC_2PASS_VBR_MAXSECTION_PCT,
-      g_param_spec_int ("twopass-vbr-maxsection", "2-pass GOP max bitrate",
-          "GOP maximum bitrate (% target)", 0, G_MAXINT,
-          DEFAULT_RC_2PASS_VBR_MINSECTION_PCT,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_KF_MODE,
-      g_param_spec_enum ("keyframe-mode", "Keyframe Mode",
-          "Keyframe placement",
-          GST_VP8_ENC_KF_MODE_TYPE, DEFAULT_KF_MODE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_KF_MAX_DIST,
-      g_param_spec_int ("keyframe-max-dist", "Keyframe max distance",
-          "Maximum distance between keyframes (number of frames)",
-          0, G_MAXINT, DEFAULT_KF_MAX_DIST,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_MULTIPASS_MODE,
-      g_param_spec_enum ("multipass-mode", "Multipass Mode",
-          "Multipass encode mode",
-          GST_VP8_ENC_MULTIPASS_MODE_TYPE, DEFAULT_MULTIPASS_MODE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_MULTIPASS_CACHE_FILE,
-      g_param_spec_string ("multipass-cache-file", "Multipass Cache File",
-          "Multipass cache file. "
-          "If stream caps reinited, multiple files will be created: "
-          "file, file.1, file.2, ... and so on.",
-          DEFAULT_MULTIPASS_CACHE_FILE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_TS_NUMBER_LAYERS,
-      g_param_spec_int ("temporal-scalability-number-layers",
-          "Number of coding layers", "Number of coding layers to use", 1, 5,
-          DEFAULT_TS_NUMBER_LAYERS,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_TS_TARGET_BITRATE,
-      g_param_spec_value_array ("temporal-scalability-target-bitrate",
-          "Coding layer target bitrates",
-          "Target bitrates for coding layers (one per layer, decreasing)",
-          g_param_spec_int ("target-bitrate", "Target bitrate",
-              "Target bitrate", 0, G_MAXINT, DEFAULT_RC_TARGET_BITRATE,
-              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_TS_RATE_DECIMATOR,
-      g_param_spec_value_array ("temporal-scalability-rate-decimator",
-          "Coding layer rate decimator",
-          "Rate decimation factors for each layer",
-          g_param_spec_int ("rate-decimator", "Rate decimator",
-              "Rate decimator", 0, 1000000000, 0,
-              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_TS_PERIODICITY,
-      g_param_spec_int ("temporal-scalability-periodicity",
-          "Coding layer periodicity",
-          "Length of sequence that defines layer membership periodicity", 0, 16,
-          DEFAULT_TS_PERIODICITY,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_TS_LAYER_ID,
-      g_param_spec_value_array ("temporal-scalability-layer-id",
-          "Coding layer identification",
-          "Sequence defining coding layer membership",
-          g_param_spec_int ("layer-id", "Layer ID", "Layer ID", 0, 4, 0,
-              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_LAG_IN_FRAMES,
-      g_param_spec_int ("lag-in-frames", "Lag in frames",
-          "Maximum number of frames to lag",
-          0, 25, DEFAULT_LAG_IN_FRAMES,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_ERROR_RESILIENT,
-      g_param_spec_flags ("error-resilient", "Error resilient",
-          "Error resilience flags",
-          GST_VP8_ENC_ER_FLAGS_TYPE, DEFAULT_ERROR_RESILIENT,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_THREADS,
-      g_param_spec_int ("threads", "Threads",
-          "Number of threads to use",
-          0, 64, DEFAULT_THREADS,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_DEADLINE,
-      g_param_spec_int64 ("deadline", "Deadline",
-          "Deadline per frame (usec, 0=disabled)",
-          0, G_MAXINT64, DEFAULT_DEADLINE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_H_SCALING_MODE,
-      g_param_spec_enum ("horizontal-scaling-mode", "Horizontal scaling mode",
-          "Horizontal scaling mode",
-          GST_VP8_ENC_SCALING_MODE_TYPE, DEFAULT_H_SCALING_MODE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_V_SCALING_MODE,
-      g_param_spec_enum ("vertical-scaling-mode", "Vertical scaling mode",
-          "Vertical scaling mode",
-          GST_VP8_ENC_SCALING_MODE_TYPE, DEFAULT_V_SCALING_MODE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_CPU_USED,
-      g_param_spec_int ("cpu-used", "CPU used",
-          "CPU used",
-          -16, 16, DEFAULT_CPU_USED,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_ENABLE_AUTO_ALT_REF,
-      g_param_spec_boolean ("auto-alt-ref", "Auto alt reference frames",
-          "Automatically generate AltRef frames",
-          DEFAULT_ENABLE_AUTO_ALT_REF,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_NOISE_SENSITIVITY,
-      g_param_spec_int ("noise-sensitivity", "Noise sensitivity",
-          "Noise sensisivity (frames to blur)",
-          0, 6, DEFAULT_NOISE_SENSITIVITY,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_SHARPNESS,
-      g_param_spec_int ("sharpness", "Sharpness",
-          "Filter sharpness",
-          0, 7, DEFAULT_SHARPNESS,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_STATIC_THRESHOLD,
-      g_param_spec_int ("static-threshold", "Static Threshold",
-          "Motion detection threshold",
-          0, G_MAXINT, DEFAULT_STATIC_THRESHOLD,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_TOKEN_PARTITIONS,
-      g_param_spec_enum ("token-partitions", "Token partitions",
-          "Number of token partitions",
-          GST_VP8_ENC_TOKEN_PARTITIONS_TYPE, DEFAULT_TOKEN_PARTITIONS,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_ARNR_MAXFRAMES,
-      g_param_spec_int ("arnr-maxframes", "AltRef max frames",
-          "AltRef maximum number of frames",
-          0, 15, DEFAULT_ARNR_MAXFRAMES,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_ARNR_STRENGTH,
-      g_param_spec_int ("arnr-strength", "AltRef strength",
-          "AltRef strength",
-          0, 6, DEFAULT_ARNR_STRENGTH,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_ARNR_TYPE,
-      g_param_spec_int ("arnr-type", "AltRef type",
-          "AltRef type",
-          1, 3, DEFAULT_ARNR_TYPE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
-              G_PARAM_DEPRECATED)));
-
-  g_object_class_install_property (gobject_class, PROP_TUNING,
-      g_param_spec_enum ("tuning", "Tuning",
-          "Tuning",
-          GST_VP8_ENC_TUNING_TYPE, DEFAULT_TUNING,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_CQ_LEVEL,
-      g_param_spec_int ("cq-level", "Constrained quality level",
-          "Constrained quality level",
-          0, 63, DEFAULT_CQ_LEVEL,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_MAX_INTRA_BITRATE_PCT,
-      g_param_spec_int ("max-intra-bitrate", "Max Intra bitrate",
-          "Maximum Intra frame bitrate",
-          0, G_MAXINT, DEFAULT_MAX_INTRA_BITRATE_PCT,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_TIMEBASE,
-      gst_param_spec_fraction ("timebase", "Shortest interframe time",
-          "Fraction of one second that is the shortest interframe time - normally left as zero which will default to the framerate",
-          0, 1, G_MAXINT, 1, DEFAULT_TIMEBASE_N, DEFAULT_TIMEBASE_D,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  vpx_encoder_class->get_algo = gst_vp8_enc_get_algo;
+  vpx_encoder_class->enable_scaling = gst_vp8_enc_enable_scaling;
+  vpx_encoder_class->set_image_format = gst_vp8_enc_set_image_format;
+  vpx_encoder_class->get_new_vpx_caps = gst_vp8_enc_get_new_simple_caps;
+  vpx_encoder_class->set_stream_info = gst_vp8_enc_set_stream_info;
+  vpx_encoder_class->process_frame_user_data =
+      gst_vp8_enc_process_frame_user_data;
+  vpx_encoder_class->handle_invisible_frame_buffer =
+      gst_vp8_enc_handle_invisible_frame_buffer;
+  vpx_encoder_class->set_frame_user_data = gst_vp8_enc_set_frame_user_data;
 
   GST_DEBUG_CATEGORY_INIT (gst_vp8enc_debug, "vp8enc", 0, "VP8 Encoder");
 }
@@ -724,1346 +172,149 @@
 gst_vp8_enc_init (GstVP8Enc * gst_vp8_enc)
 {
   vpx_codec_err_t status;
-
-  GST_DEBUG_OBJECT (gst_vp8_enc, "init");
-  GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_ENCODER_SINK_PAD (gst_vp8_enc));
-
+  GstVPXEnc *gst_vpx_enc = GST_VPX_ENC (gst_vp8_enc);
+  GST_DEBUG_OBJECT (gst_vp8_enc, "gst_vp8_enc_init");
   status =
-      vpx_codec_enc_config_default (&vpx_codec_vp8_cx_algo, &gst_vp8_enc->cfg,
-      0);
+      vpx_codec_enc_config_default (gst_vp8_enc_get_algo (gst_vpx_enc),
+      &gst_vpx_enc->cfg, 0);
   if (status != VPX_CODEC_OK) {
-    GST_ERROR_OBJECT (gst_vp8_enc,
+    GST_ERROR_OBJECT (gst_vpx_enc,
         "Failed to get default encoder configuration: %s",
         gst_vpx_error_name (status));
-    gst_vp8_enc->have_default_config = FALSE;
+    gst_vpx_enc->have_default_config = FALSE;
   } else {
-    gst_vp8_enc->have_default_config = TRUE;
-  }
-
-  gst_vp8_enc->cfg.rc_end_usage = DEFAULT_RC_END_USAGE;
-  gst_vp8_enc->cfg.rc_target_bitrate = DEFAULT_RC_TARGET_BITRATE / 1000;
-  gst_vp8_enc->rc_target_bitrate_set = FALSE;
-  gst_vp8_enc->cfg.rc_min_quantizer = DEFAULT_RC_MIN_QUANTIZER;
-  gst_vp8_enc->cfg.rc_max_quantizer = DEFAULT_RC_MAX_QUANTIZER;
-  gst_vp8_enc->cfg.rc_dropframe_thresh = DEFAULT_RC_DROPFRAME_THRESH;
-  gst_vp8_enc->cfg.rc_resize_allowed = DEFAULT_RC_RESIZE_ALLOWED;
-  gst_vp8_enc->cfg.rc_resize_up_thresh = DEFAULT_RC_RESIZE_UP_THRESH;
-  gst_vp8_enc->cfg.rc_resize_down_thresh = DEFAULT_RC_RESIZE_DOWN_THRESH;
-  gst_vp8_enc->cfg.rc_undershoot_pct = DEFAULT_RC_UNDERSHOOT_PCT;
-  gst_vp8_enc->cfg.rc_overshoot_pct = DEFAULT_RC_OVERSHOOT_PCT;
-  gst_vp8_enc->cfg.rc_buf_sz = DEFAULT_RC_BUF_SZ;
-  gst_vp8_enc->cfg.rc_buf_initial_sz = DEFAULT_RC_BUF_INITIAL_SZ;
-  gst_vp8_enc->cfg.rc_buf_optimal_sz = DEFAULT_RC_BUF_OPTIMAL_SZ;
-  gst_vp8_enc->cfg.rc_2pass_vbr_bias_pct = DEFAULT_RC_2PASS_VBR_BIAS_PCT;
-  gst_vp8_enc->cfg.rc_2pass_vbr_minsection_pct =
-      DEFAULT_RC_2PASS_VBR_MINSECTION_PCT;
-  gst_vp8_enc->cfg.rc_2pass_vbr_maxsection_pct =
-      DEFAULT_RC_2PASS_VBR_MAXSECTION_PCT;
-  gst_vp8_enc->cfg.kf_mode = DEFAULT_KF_MODE;
-  gst_vp8_enc->cfg.kf_max_dist = DEFAULT_KF_MAX_DIST;
-  gst_vp8_enc->cfg.g_pass = DEFAULT_MULTIPASS_MODE;
-  gst_vp8_enc->multipass_cache_prefix = g_strdup (DEFAULT_MULTIPASS_CACHE_FILE);
-  gst_vp8_enc->multipass_cache_file = NULL;
-  gst_vp8_enc->multipass_cache_idx = 0;
-  gst_vp8_enc->cfg.ts_number_layers = DEFAULT_TS_NUMBER_LAYERS;
-  gst_vp8_enc->n_ts_target_bitrate = 0;
-  gst_vp8_enc->n_ts_rate_decimator = 0;
-  gst_vp8_enc->cfg.ts_periodicity = DEFAULT_TS_PERIODICITY;
-  gst_vp8_enc->n_ts_layer_id = 0;
-  gst_vp8_enc->cfg.g_error_resilient = DEFAULT_ERROR_RESILIENT;
-  gst_vp8_enc->cfg.g_lag_in_frames = DEFAULT_LAG_IN_FRAMES;
-  gst_vp8_enc->cfg.g_threads = DEFAULT_THREADS;
-  gst_vp8_enc->deadline = DEFAULT_DEADLINE;
-  gst_vp8_enc->h_scaling_mode = DEFAULT_H_SCALING_MODE;
-  gst_vp8_enc->v_scaling_mode = DEFAULT_V_SCALING_MODE;
-  gst_vp8_enc->cpu_used = DEFAULT_CPU_USED;
-  gst_vp8_enc->enable_auto_alt_ref = DEFAULT_ENABLE_AUTO_ALT_REF;
-  gst_vp8_enc->noise_sensitivity = DEFAULT_NOISE_SENSITIVITY;
-  gst_vp8_enc->sharpness = DEFAULT_SHARPNESS;
-  gst_vp8_enc->static_threshold = DEFAULT_STATIC_THRESHOLD;
-  gst_vp8_enc->token_partitions = DEFAULT_TOKEN_PARTITIONS;
-  gst_vp8_enc->arnr_maxframes = DEFAULT_ARNR_MAXFRAMES;
-  gst_vp8_enc->arnr_strength = DEFAULT_ARNR_STRENGTH;
-  gst_vp8_enc->arnr_type = DEFAULT_ARNR_TYPE;
-  gst_vp8_enc->tuning = DEFAULT_TUNING;
-  gst_vp8_enc->cq_level = DEFAULT_CQ_LEVEL;
-  gst_vp8_enc->max_intra_bitrate_pct = DEFAULT_MAX_INTRA_BITRATE_PCT;
-  gst_vp8_enc->timebase_n = DEFAULT_TIMEBASE_N;
-  gst_vp8_enc->timebase_d = DEFAULT_TIMEBASE_D;
-
-  gst_vp8_enc->cfg.g_profile = DEFAULT_PROFILE;
-
-  g_mutex_init (&gst_vp8_enc->encoder_lock);
-}
-
-static void
-gst_vp8_enc_finalize (GObject * object)
-{
-  GstVP8Enc *gst_vp8_enc;
-
-  GST_DEBUG_OBJECT (object, "finalize");
-
-  g_return_if_fail (GST_IS_VP8_ENC (object));
-  gst_vp8_enc = GST_VP8_ENC (object);
-
-  g_free (gst_vp8_enc->multipass_cache_prefix);
-  g_free (gst_vp8_enc->multipass_cache_file);
-  gst_vp8_enc->multipass_cache_idx = 0;
-
-
-  if (gst_vp8_enc->input_state)
-    gst_video_codec_state_unref (gst_vp8_enc->input_state);
-
-  g_mutex_clear (&gst_vp8_enc->encoder_lock);
-
-  G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_vp8_enc_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstVP8Enc *gst_vp8_enc;
-  gboolean global = FALSE;
-  vpx_codec_err_t status;
-
-  g_return_if_fail (GST_IS_VP8_ENC (object));
-  gst_vp8_enc = GST_VP8_ENC (object);
-
-  GST_DEBUG_OBJECT (object, "gst_vp8_enc_set_property");
-  g_mutex_lock (&gst_vp8_enc->encoder_lock);
-  switch (prop_id) {
-    case PROP_RC_END_USAGE:
-      gst_vp8_enc->cfg.rc_end_usage = g_value_get_enum (value);
-      global = TRUE;
-      break;
-    case PROP_RC_TARGET_BITRATE:
-      gst_vp8_enc->cfg.rc_target_bitrate = g_value_get_int (value) / 1000;
-      gst_vp8_enc->rc_target_bitrate_set = TRUE;
-      global = TRUE;
-      break;
-    case PROP_RC_MIN_QUANTIZER:
-      gst_vp8_enc->cfg.rc_min_quantizer = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_MAX_QUANTIZER:
-      gst_vp8_enc->cfg.rc_max_quantizer = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_DROPFRAME_THRESH:
-      gst_vp8_enc->cfg.rc_dropframe_thresh = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_RESIZE_ALLOWED:
-      gst_vp8_enc->cfg.rc_resize_allowed = g_value_get_boolean (value);
-      global = TRUE;
-      break;
-    case PROP_RC_RESIZE_UP_THRESH:
-      gst_vp8_enc->cfg.rc_resize_up_thresh = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_RESIZE_DOWN_THRESH:
-      gst_vp8_enc->cfg.rc_resize_down_thresh = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_UNDERSHOOT_PCT:
-      gst_vp8_enc->cfg.rc_undershoot_pct = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_OVERSHOOT_PCT:
-      gst_vp8_enc->cfg.rc_overshoot_pct = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_BUF_SZ:
-      gst_vp8_enc->cfg.rc_buf_sz = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_BUF_INITIAL_SZ:
-      gst_vp8_enc->cfg.rc_buf_initial_sz = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_BUF_OPTIMAL_SZ:
-      gst_vp8_enc->cfg.rc_buf_optimal_sz = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_2PASS_VBR_BIAS_PCT:
-      gst_vp8_enc->cfg.rc_2pass_vbr_bias_pct = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_2PASS_VBR_MINSECTION_PCT:
-      gst_vp8_enc->cfg.rc_2pass_vbr_minsection_pct = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_2PASS_VBR_MAXSECTION_PCT:
-      gst_vp8_enc->cfg.rc_2pass_vbr_maxsection_pct = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_KF_MODE:
-      gst_vp8_enc->cfg.kf_mode = g_value_get_enum (value);
-      global = TRUE;
-      break;
-    case PROP_KF_MAX_DIST:
-      gst_vp8_enc->cfg.kf_max_dist = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_MULTIPASS_MODE:
-      gst_vp8_enc->cfg.g_pass = g_value_get_enum (value);
-      global = TRUE;
-      break;
-    case PROP_MULTIPASS_CACHE_FILE:
-      if (gst_vp8_enc->multipass_cache_prefix)
-        g_free (gst_vp8_enc->multipass_cache_prefix);
-      gst_vp8_enc->multipass_cache_prefix = g_value_dup_string (value);
-      break;
-    case PROP_TS_NUMBER_LAYERS:
-      gst_vp8_enc->cfg.ts_number_layers = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_TS_TARGET_BITRATE:{
-      GValueArray *va = g_value_get_boxed (value);
-
-      memset (&gst_vp8_enc->cfg.ts_target_bitrate, 0,
-          sizeof (gst_vp8_enc->cfg.ts_target_bitrate));
-      if (va == NULL) {
-        gst_vp8_enc->n_ts_target_bitrate = 0;
-      } else if (va->n_values > VPX_TS_MAX_LAYERS) {
-        g_warning ("%s: Only %d layers allowed at maximum",
-            GST_ELEMENT_NAME (gst_vp8_enc), VPX_TS_MAX_LAYERS);
-      } else {
-        gint i;
-
-        for (i = 0; i < va->n_values; i++)
-          gst_vp8_enc->cfg.ts_target_bitrate[i] =
-              g_value_get_int (g_value_array_get_nth (va, i));
-        gst_vp8_enc->n_ts_target_bitrate = va->n_values;
-      }
-      global = TRUE;
-      break;
-    }
-    case PROP_TS_RATE_DECIMATOR:{
-      GValueArray *va = g_value_get_boxed (value);
-
-      memset (&gst_vp8_enc->cfg.ts_rate_decimator, 0,
-          sizeof (gst_vp8_enc->cfg.ts_rate_decimator));
-      if (va == NULL) {
-        gst_vp8_enc->n_ts_rate_decimator = 0;
-      } else if (va->n_values > VPX_TS_MAX_LAYERS) {
-        g_warning ("%s: Only %d layers allowed at maximum",
-            GST_ELEMENT_NAME (gst_vp8_enc), VPX_TS_MAX_LAYERS);
-      } else {
-        gint i;
-
-        for (i = 0; i < va->n_values; i++)
-          gst_vp8_enc->cfg.ts_rate_decimator[i] =
-              g_value_get_int (g_value_array_get_nth (va, i));
-        gst_vp8_enc->n_ts_rate_decimator = va->n_values;
-      }
-      global = TRUE;
-      break;
-    }
-    case PROP_TS_PERIODICITY:
-      gst_vp8_enc->cfg.ts_periodicity = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_TS_LAYER_ID:{
-      GValueArray *va = g_value_get_boxed (value);
-
-      memset (&gst_vp8_enc->cfg.ts_layer_id, 0,
-          sizeof (gst_vp8_enc->cfg.ts_layer_id));
-      if (va && va->n_values > VPX_TS_MAX_PERIODICITY) {
-        g_warning ("%s: Only %d sized layer sequences allowed at maximum",
-            GST_ELEMENT_NAME (gst_vp8_enc), VPX_TS_MAX_PERIODICITY);
-      } else if (va) {
-        gint i;
-
-        for (i = 0; i < va->n_values; i++)
-          gst_vp8_enc->cfg.ts_layer_id[i] =
-              g_value_get_int (g_value_array_get_nth (va, i));
-        gst_vp8_enc->n_ts_layer_id = va->n_values;
-      } else {
-        gst_vp8_enc->n_ts_layer_id = 0;
-      }
-      global = TRUE;
-      break;
-    }
-    case PROP_ERROR_RESILIENT:
-      gst_vp8_enc->cfg.g_error_resilient = g_value_get_flags (value);
-      global = TRUE;
-      break;
-    case PROP_LAG_IN_FRAMES:
-      gst_vp8_enc->cfg.g_lag_in_frames = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_THREADS:
-      gst_vp8_enc->cfg.g_threads = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_DEADLINE:
-      gst_vp8_enc->deadline = g_value_get_int64 (value);
-      break;
-    case PROP_H_SCALING_MODE:
-      gst_vp8_enc->h_scaling_mode = g_value_get_enum (value);
-      if (gst_vp8_enc->inited) {
-        vpx_scaling_mode_t sm;
-
-        sm.h_scaling_mode = gst_vp8_enc->h_scaling_mode;
-        sm.v_scaling_mode = gst_vp8_enc->v_scaling_mode;
-
-        status =
-            vpx_codec_control (&gst_vp8_enc->encoder, VP8E_SET_SCALEMODE, &sm);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp8_enc,
-              "Failed to set VP8E_SET_SCALEMODE: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_V_SCALING_MODE:
-      gst_vp8_enc->v_scaling_mode = g_value_get_enum (value);
-      if (gst_vp8_enc->inited) {
-        vpx_scaling_mode_t sm;
-
-        sm.h_scaling_mode = gst_vp8_enc->h_scaling_mode;
-        sm.v_scaling_mode = gst_vp8_enc->v_scaling_mode;
-
-        status =
-            vpx_codec_control (&gst_vp8_enc->encoder, VP8E_SET_SCALEMODE, &sm);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp8_enc,
-              "Failed to set VP8E_SET_SCALEMODE: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_CPU_USED:
-      gst_vp8_enc->cpu_used = g_value_get_int (value);
-      if (gst_vp8_enc->inited) {
-        status =
-            vpx_codec_control (&gst_vp8_enc->encoder, VP8E_SET_CPUUSED,
-            gst_vp8_enc->cpu_used);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp8_enc, "Failed to set VP8E_SET_CPUUSED: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_ENABLE_AUTO_ALT_REF:
-      gst_vp8_enc->enable_auto_alt_ref = g_value_get_boolean (value);
-      if (gst_vp8_enc->inited) {
-        status =
-            vpx_codec_control (&gst_vp8_enc->encoder, VP8E_SET_ENABLEAUTOALTREF,
-            (gst_vp8_enc->enable_auto_alt_ref ? 1 : 0));
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp8_enc,
-              "Failed to set VP8E_SET_ENABLEAUTOALTREF: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_NOISE_SENSITIVITY:
-      gst_vp8_enc->noise_sensitivity = g_value_get_int (value);
-      if (gst_vp8_enc->inited) {
-        status =
-            vpx_codec_control (&gst_vp8_enc->encoder,
-            VP8E_SET_NOISE_SENSITIVITY, gst_vp8_enc->noise_sensitivity);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp8_enc,
-              "Failed to set VP8E_SET_NOISE_SENSITIVITY: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_SHARPNESS:
-      gst_vp8_enc->sharpness = g_value_get_int (value);
-      if (gst_vp8_enc->inited) {
-        status = vpx_codec_control (&gst_vp8_enc->encoder, VP8E_SET_SHARPNESS,
-            gst_vp8_enc->sharpness);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp8_enc,
-              "Failed to set VP8E_SET_SHARPNESS: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_STATIC_THRESHOLD:
-      gst_vp8_enc->static_threshold = g_value_get_int (value);
-      if (gst_vp8_enc->inited) {
-        status =
-            vpx_codec_control (&gst_vp8_enc->encoder, VP8E_SET_STATIC_THRESHOLD,
-            gst_vp8_enc->static_threshold);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp8_enc,
-              "Failed to set VP8E_SET_STATIC_THRESHOLD: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_TOKEN_PARTITIONS:
-      gst_vp8_enc->token_partitions = g_value_get_enum (value);
-      if (gst_vp8_enc->inited) {
-        status =
-            vpx_codec_control (&gst_vp8_enc->encoder, VP8E_SET_TOKEN_PARTITIONS,
-            gst_vp8_enc->token_partitions);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp8_enc,
-              "Failed to set VP8E_SET_TOKEN_PARTIONS: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_ARNR_MAXFRAMES:
-      gst_vp8_enc->arnr_maxframes = g_value_get_int (value);
-      if (gst_vp8_enc->inited) {
-        status =
-            vpx_codec_control (&gst_vp8_enc->encoder, VP8E_SET_ARNR_MAXFRAMES,
-            gst_vp8_enc->arnr_maxframes);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp8_enc,
-              "Failed to set VP8E_SET_ARNR_MAXFRAMES: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_ARNR_STRENGTH:
-      gst_vp8_enc->arnr_strength = g_value_get_int (value);
-      if (gst_vp8_enc->inited) {
-        status =
-            vpx_codec_control (&gst_vp8_enc->encoder, VP8E_SET_ARNR_STRENGTH,
-            gst_vp8_enc->arnr_strength);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp8_enc,
-              "Failed to set VP8E_SET_ARNR_STRENGTH: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_ARNR_TYPE:
-      gst_vp8_enc->arnr_type = g_value_get_int (value);
-      g_warning ("arnr-type is a no-op since control has been deprecated "
-          "in libvpx");
-      break;
-    case PROP_TUNING:
-      gst_vp8_enc->tuning = g_value_get_enum (value);
-      if (gst_vp8_enc->inited) {
-        status = vpx_codec_control (&gst_vp8_enc->encoder, VP8E_SET_TUNING,
-            gst_vp8_enc->tuning);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp8_enc,
-              "Failed to set VP8E_SET_TUNING: %s", gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_CQ_LEVEL:
-      gst_vp8_enc->cq_level = g_value_get_int (value);
-      if (gst_vp8_enc->inited) {
-        status = vpx_codec_control (&gst_vp8_enc->encoder, VP8E_SET_CQ_LEVEL,
-            gst_vp8_enc->cq_level);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp8_enc,
-              "Failed to set VP8E_SET_CQ_LEVEL: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_MAX_INTRA_BITRATE_PCT:
-      gst_vp8_enc->max_intra_bitrate_pct = g_value_get_int (value);
-      if (gst_vp8_enc->inited) {
-        status =
-            vpx_codec_control (&gst_vp8_enc->encoder,
-            VP8E_SET_MAX_INTRA_BITRATE_PCT, gst_vp8_enc->max_intra_bitrate_pct);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp8_enc,
-              "Failed to set VP8E_SET_MAX_INTRA_BITRATE_PCT: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_TIMEBASE:
-      gst_vp8_enc->timebase_n = gst_value_get_fraction_numerator (value);
-      gst_vp8_enc->timebase_d = gst_value_get_fraction_denominator (value);
-      break;
-    default:
-      break;
-  }
-
-  if (global &&gst_vp8_enc->inited) {
-    status =
-        vpx_codec_enc_config_set (&gst_vp8_enc->encoder, &gst_vp8_enc->cfg);
-    if (status != VPX_CODEC_OK) {
-      g_mutex_unlock (&gst_vp8_enc->encoder_lock);
-      GST_ELEMENT_ERROR (gst_vp8_enc, LIBRARY, INIT,
-          ("Failed to set encoder configuration"), ("%s",
-              gst_vpx_error_name (status)));
-    } else {
-      g_mutex_unlock (&gst_vp8_enc->encoder_lock);
-    }
-  } else {
-    g_mutex_unlock (&gst_vp8_enc->encoder_lock);
+    gst_vpx_enc->have_default_config = TRUE;
   }
 }
 
-static void
-gst_vp8_enc_get_property (GObject * object, guint prop_id, GValue * value,
-    GParamSpec * pspec)
+static vpx_codec_iface_t *
+gst_vp8_enc_get_algo (GstVPXEnc * enc)
 {
-  GstVP8Enc *gst_vp8_enc;
-
-  g_return_if_fail (GST_IS_VP8_ENC (object));
-  gst_vp8_enc = GST_VP8_ENC (object);
-
-  g_mutex_lock (&gst_vp8_enc->encoder_lock);
-  switch (prop_id) {
-    case PROP_RC_END_USAGE:
-      g_value_set_enum (value, gst_vp8_enc->cfg.rc_end_usage);
-      break;
-    case PROP_RC_TARGET_BITRATE:
-      g_value_set_int (value, gst_vp8_enc->cfg.rc_target_bitrate * 1000);
-      break;
-    case PROP_RC_MIN_QUANTIZER:
-      g_value_set_int (value, gst_vp8_enc->cfg.rc_min_quantizer);
-      break;
-    case PROP_RC_MAX_QUANTIZER:
-      g_value_set_int (value, gst_vp8_enc->cfg.rc_max_quantizer);
-      break;
-    case PROP_RC_DROPFRAME_THRESH:
-      g_value_set_int (value, gst_vp8_enc->cfg.rc_dropframe_thresh);
-      break;
-    case PROP_RC_RESIZE_ALLOWED:
-      g_value_set_boolean (value, gst_vp8_enc->cfg.rc_resize_allowed);
-      break;
-    case PROP_RC_RESIZE_UP_THRESH:
-      g_value_set_int (value, gst_vp8_enc->cfg.rc_resize_up_thresh);
-      break;
-    case PROP_RC_RESIZE_DOWN_THRESH:
-      g_value_set_int (value, gst_vp8_enc->cfg.rc_resize_down_thresh);
-      break;
-    case PROP_RC_UNDERSHOOT_PCT:
-      g_value_set_int (value, gst_vp8_enc->cfg.rc_undershoot_pct);
-      break;
-    case PROP_RC_OVERSHOOT_PCT:
-      g_value_set_int (value, gst_vp8_enc->cfg.rc_overshoot_pct);
-      break;
-    case PROP_RC_BUF_SZ:
-      g_value_set_int (value, gst_vp8_enc->cfg.rc_buf_sz);
-      break;
-    case PROP_RC_BUF_INITIAL_SZ:
-      g_value_set_int (value, gst_vp8_enc->cfg.rc_buf_initial_sz);
-      break;
-    case PROP_RC_BUF_OPTIMAL_SZ:
-      g_value_set_int (value, gst_vp8_enc->cfg.rc_buf_optimal_sz);
-      break;
-    case PROP_RC_2PASS_VBR_BIAS_PCT:
-      g_value_set_int (value, gst_vp8_enc->cfg.rc_2pass_vbr_bias_pct);
-      break;
-    case PROP_RC_2PASS_VBR_MINSECTION_PCT:
-      g_value_set_int (value, gst_vp8_enc->cfg.rc_2pass_vbr_minsection_pct);
-      break;
-    case PROP_RC_2PASS_VBR_MAXSECTION_PCT:
-      g_value_set_int (value, gst_vp8_enc->cfg.rc_2pass_vbr_maxsection_pct);
-      break;
-    case PROP_KF_MODE:
-      g_value_set_enum (value, gst_vp8_enc->cfg.kf_mode);
-      break;
-    case PROP_KF_MAX_DIST:
-      g_value_set_int (value, gst_vp8_enc->cfg.kf_max_dist);
-      break;
-    case PROP_MULTIPASS_MODE:
-      g_value_set_enum (value, gst_vp8_enc->cfg.g_pass);
-      break;
-    case PROP_MULTIPASS_CACHE_FILE:
-      g_value_set_string (value, gst_vp8_enc->multipass_cache_prefix);
-      break;
-    case PROP_TS_NUMBER_LAYERS:
-      g_value_set_int (value, gst_vp8_enc->cfg.ts_number_layers);
-      break;
-    case PROP_TS_TARGET_BITRATE:{
-      GValueArray *va;
-
-      if (gst_vp8_enc->n_ts_target_bitrate == 0) {
-        g_value_set_boxed (value, NULL);
-      } else {
-        gint i;
-
-        va = g_value_array_new (gst_vp8_enc->n_ts_target_bitrate);
-        for (i = 0; i < gst_vp8_enc->n_ts_target_bitrate; i++) {
-          GValue v = { 0, };
-
-          g_value_init (&v, G_TYPE_INT);
-          g_value_set_int (&v, gst_vp8_enc->cfg.ts_target_bitrate[i]);
-          g_value_array_append (va, &v);
-          g_value_unset (&v);
-        }
-        g_value_set_boxed (value, va);
-        g_value_array_free (va);
-      }
-      break;
-    }
-    case PROP_TS_RATE_DECIMATOR:{
-      GValueArray *va;
-
-      if (gst_vp8_enc->n_ts_rate_decimator == 0) {
-        g_value_set_boxed (value, NULL);
-      } else {
-        gint i;
-
-        va = g_value_array_new (gst_vp8_enc->n_ts_rate_decimator);
-        for (i = 0; i < gst_vp8_enc->n_ts_rate_decimator; i++) {
-          GValue v = { 0, };
-
-          g_value_init (&v, G_TYPE_INT);
-          g_value_set_int (&v, gst_vp8_enc->cfg.ts_rate_decimator[i]);
-          g_value_array_append (va, &v);
-          g_value_unset (&v);
-        }
-        g_value_set_boxed (value, va);
-        g_value_array_free (va);
-      }
-      break;
-    }
-    case PROP_TS_PERIODICITY:
-      g_value_set_int (value, gst_vp8_enc->cfg.ts_periodicity);
-      break;
-    case PROP_TS_LAYER_ID:{
-      GValueArray *va;
-
-      if (gst_vp8_enc->n_ts_layer_id == 0) {
-        g_value_set_boxed (value, NULL);
-      } else {
-        gint i;
-
-        va = g_value_array_new (gst_vp8_enc->n_ts_layer_id);
-        for (i = 0; i < gst_vp8_enc->n_ts_layer_id; i++) {
-          GValue v = { 0, };
-
-          g_value_init (&v, G_TYPE_INT);
-          g_value_set_int (&v, gst_vp8_enc->cfg.ts_layer_id[i]);
-          g_value_array_append (va, &v);
-          g_value_unset (&v);
-        }
-        g_value_set_boxed (value, va);
-        g_value_array_free (va);
-      }
-      break;
-    }
-    case PROP_ERROR_RESILIENT:
-      g_value_set_flags (value, gst_vp8_enc->cfg.g_error_resilient);
-      break;
-    case PROP_LAG_IN_FRAMES:
-      g_value_set_int (value, gst_vp8_enc->cfg.g_lag_in_frames);
-      break;
-    case PROP_THREADS:
-      g_value_set_int (value, gst_vp8_enc->cfg.g_threads);
-      break;
-    case PROP_DEADLINE:
-      g_value_set_int64 (value, gst_vp8_enc->deadline);
-      break;
-    case PROP_H_SCALING_MODE:
-      g_value_set_enum (value, gst_vp8_enc->h_scaling_mode);
-      break;
-    case PROP_V_SCALING_MODE:
-      g_value_set_enum (value, gst_vp8_enc->v_scaling_mode);
-      break;
-    case PROP_CPU_USED:
-      g_value_set_int (value, gst_vp8_enc->cpu_used);
-      break;
-    case PROP_ENABLE_AUTO_ALT_REF:
-      g_value_set_boolean (value, gst_vp8_enc->enable_auto_alt_ref);
-      break;
-    case PROP_NOISE_SENSITIVITY:
-      g_value_set_int (value, gst_vp8_enc->noise_sensitivity);
-      break;
-    case PROP_SHARPNESS:
-      g_value_set_int (value, gst_vp8_enc->sharpness);
-      break;
-    case PROP_STATIC_THRESHOLD:
-      g_value_set_int (value, gst_vp8_enc->static_threshold);
-      break;
-    case PROP_TOKEN_PARTITIONS:
-      g_value_set_enum (value, gst_vp8_enc->token_partitions);
-      break;
-    case PROP_ARNR_MAXFRAMES:
-      g_value_set_int (value, gst_vp8_enc->arnr_maxframes);
-      break;
-    case PROP_ARNR_STRENGTH:
-      g_value_set_int (value, gst_vp8_enc->arnr_strength);
-      break;
-    case PROP_ARNR_TYPE:
-      g_value_set_int (value, gst_vp8_enc->arnr_type);
-      break;
-    case PROP_TUNING:
-      g_value_set_enum (value, gst_vp8_enc->tuning);
-      break;
-    case PROP_CQ_LEVEL:
-      g_value_set_int (value, gst_vp8_enc->cq_level);
-      break;
-    case PROP_MAX_INTRA_BITRATE_PCT:
-      g_value_set_int (value, gst_vp8_enc->max_intra_bitrate_pct);
-      break;
-    case PROP_TIMEBASE:
-      gst_value_set_fraction (value, gst_vp8_enc->timebase_n,
-          gst_vp8_enc->timebase_d);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-
-  g_mutex_unlock (&gst_vp8_enc->encoder_lock);
+  return &vpx_codec_vp8_cx_algo;
 }
 
 static gboolean
-gst_vp8_enc_start (GstVideoEncoder * video_encoder)
+gst_vp8_enc_enable_scaling (GstVPXEnc * enc)
 {
-  GstVP8Enc *encoder = GST_VP8_ENC (video_encoder);
-
-  GST_DEBUG_OBJECT (video_encoder, "start");
-
-  if (!encoder->have_default_config) {
-    GST_ELEMENT_ERROR (encoder, LIBRARY, INIT,
-        ("Failed to get default encoder configuration"), (NULL));
-    return FALSE;
-  }
-
   return TRUE;
 }
 
 static void
-gst_vp8_enc_destroy_encoder (GstVP8Enc * encoder)
+gst_vp8_enc_set_image_format (GstVPXEnc * enc, vpx_image_t * image)
 {
-  g_mutex_lock (&encoder->encoder_lock);
-  if (encoder->inited) {
-    vpx_codec_destroy (&encoder->encoder);
-    encoder->inited = FALSE;
-  }
-
-  if (encoder->first_pass_cache_content) {
-    g_byte_array_free (encoder->first_pass_cache_content, TRUE);
-    encoder->first_pass_cache_content = NULL;
-  }
-
-  if (encoder->cfg.rc_twopass_stats_in.buf) {
-    g_free (encoder->cfg.rc_twopass_stats_in.buf);
-    encoder->cfg.rc_twopass_stats_in.buf = NULL;
-    encoder->cfg.rc_twopass_stats_in.sz = 0;
-  }
-  g_mutex_unlock (&encoder->encoder_lock);
-}
-
-static gboolean
-gst_vp8_enc_stop (GstVideoEncoder * video_encoder)
-{
-  GstVP8Enc *encoder;
-
-  GST_DEBUG_OBJECT (video_encoder, "stop");
-
-  encoder = GST_VP8_ENC (video_encoder);
-
-  gst_vp8_enc_destroy_encoder (encoder);
-
-  gst_tag_setter_reset_tags (GST_TAG_SETTER (encoder));
-
-  g_free (encoder->multipass_cache_file);
-  encoder->multipass_cache_file = NULL;
-  encoder->multipass_cache_idx = 0;
-
-  return TRUE;
-}
-
-static gint
-gst_vp8_enc_get_downstream_profile (GstVP8Enc * encoder)
-{
-  GstCaps *allowed;
-  GstStructure *s;
-  gint profile = DEFAULT_PROFILE;
-
-  allowed = gst_pad_get_allowed_caps (GST_VIDEO_ENCODER_SRC_PAD (encoder));
-  if (allowed) {
-    allowed = gst_caps_truncate (allowed);
-    s = gst_caps_get_structure (allowed, 0);
-    if (gst_structure_has_field (s, "profile")) {
-      const GValue *v = gst_structure_get_value (s, "profile");
-      const gchar *profile_str = NULL;
-
-      if (GST_VALUE_HOLDS_LIST (v) && gst_value_list_get_size (v) > 0) {
-        profile_str = g_value_get_string (gst_value_list_get_value (v, 0));
-      } else if (G_VALUE_HOLDS_STRING (v)) {
-        profile_str = g_value_get_string (v);
-      }
-
-      if (profile_str) {
-        gchar *endptr = NULL;
-
-        profile = g_ascii_strtoull (profile_str, &endptr, 10);
-        if (*endptr != '\0' || profile < 0 || profile > 3) {
-          GST_ERROR_OBJECT (encoder, "Invalid profile '%s'", profile_str);
-          profile = DEFAULT_PROFILE;
-        }
-      }
-    }
-    gst_caps_unref (allowed);
-  }
-
-  GST_DEBUG_OBJECT (encoder, "Using profile %d", profile);
-
-  return profile;
-}
-
-static gboolean
-gst_vp8_enc_set_format (GstVideoEncoder * video_encoder,
-    GstVideoCodecState * state)
-{
-  GstVP8Enc *encoder;
-  vpx_codec_err_t status;
-  vpx_image_t *image;
-  guint8 *data = NULL;
-  GstCaps *caps;
-  gboolean ret = TRUE;
-  GstVideoInfo *info = &state->info;
-  GstVideoCodecState *output_state;
-  gchar *profile_str;
-  GstClockTime latency;
-
-  encoder = GST_VP8_ENC (video_encoder);
-  GST_DEBUG_OBJECT (video_encoder, "set_format");
-
-  if (encoder->inited) {
-    gst_vp8_enc_drain (video_encoder);
-    g_mutex_lock (&encoder->encoder_lock);
-    vpx_codec_destroy (&encoder->encoder);
-    encoder->inited = FALSE;
-    encoder->multipass_cache_idx++;
-  } else {
-    g_mutex_lock (&encoder->encoder_lock);
-  }
-
-  encoder->cfg.g_profile = gst_vp8_enc_get_downstream_profile (encoder);
-
-  /* Scale default bitrate to our size */
-  if (!encoder->rc_target_bitrate_set)
-    encoder->cfg.rc_target_bitrate =
-        gst_util_uint64_scale (DEFAULT_RC_TARGET_BITRATE,
-        GST_VIDEO_INFO_WIDTH (info) * GST_VIDEO_INFO_HEIGHT (info),
-        320 * 240 * 1000);
-
-  encoder->cfg.g_w = GST_VIDEO_INFO_WIDTH (info);
-  encoder->cfg.g_h = GST_VIDEO_INFO_HEIGHT (info);
-
-  if (encoder->timebase_n != 0 && encoder->timebase_d != 0) {
-    GST_DEBUG_OBJECT (video_encoder, "Using timebase configuration");
-    encoder->cfg.g_timebase.num = encoder->timebase_n;
-    encoder->cfg.g_timebase.den = encoder->timebase_d;
-  } else {
-    /* Zero framerate and max-framerate but still need to setup the timebase to avoid
-     * a divide by zero error. Presuming the lowest common denominator will be RTP -
-     * VP8 payload draft states clock rate of 90000 which should work for anyone where
-     * FPS < 90000 (shouldn't be too many cases where it's higher) though wouldn't be optimal. RTP specification
-     * http://tools.ietf.org/html/draft-ietf-payload-vp8-01 section 6.3.1 */
-    encoder->cfg.g_timebase.num = 1;
-    encoder->cfg.g_timebase.den = 90000;
-  }
-
-  if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS ||
-      encoder->cfg.g_pass == VPX_RC_LAST_PASS) {
-    if (!encoder->multipass_cache_prefix) {
-      GST_ELEMENT_ERROR (encoder, RESOURCE, OPEN_READ,
-          ("No multipass cache file provided"), (NULL));
-      g_mutex_unlock (&encoder->encoder_lock);
-      return FALSE;
-    }
-
-    g_free (encoder->multipass_cache_file);
-
-    if (encoder->multipass_cache_idx > 0)
-      encoder->multipass_cache_file = g_strdup_printf ("%s.%u",
-          encoder->multipass_cache_prefix, encoder->multipass_cache_idx);
-    else
-      encoder->multipass_cache_file =
-          g_strdup (encoder->multipass_cache_prefix);
-  }
-
-  if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS) {
-    if (encoder->first_pass_cache_content != NULL)
-      g_byte_array_free (encoder->first_pass_cache_content, TRUE);
-
-    encoder->first_pass_cache_content = g_byte_array_sized_new (4096);
-
-  } else if (encoder->cfg.g_pass == VPX_RC_LAST_PASS) {
-    GError *err = NULL;
-
-    if (encoder->cfg.rc_twopass_stats_in.buf != NULL) {
-      g_free (encoder->cfg.rc_twopass_stats_in.buf);
-      encoder->cfg.rc_twopass_stats_in.buf = NULL;
-      encoder->cfg.rc_twopass_stats_in.sz = 0;
-    }
-
-    if (!g_file_get_contents (encoder->multipass_cache_file,
-            (gchar **) & encoder->cfg.rc_twopass_stats_in.buf,
-            &encoder->cfg.rc_twopass_stats_in.sz, &err)) {
-      GST_ELEMENT_ERROR (encoder, RESOURCE, OPEN_READ,
-          ("Failed to read multipass cache file provided"), ("%s",
-              err->message));
-      g_error_free (err);
-      g_mutex_unlock (&encoder->encoder_lock);
-      return FALSE;
-    }
-  }
-
-  status = vpx_codec_enc_init (&encoder->encoder, &vpx_codec_vp8_cx_algo,
-      &encoder->cfg, 0);
-  if (status != VPX_CODEC_OK) {
-    GST_ELEMENT_ERROR (encoder, LIBRARY, INIT,
-        ("Failed to initialize encoder"), ("%s", gst_vpx_error_name (status)));
-    g_mutex_unlock (&encoder->encoder_lock);
-    return FALSE;
-  }
-
-  {
-    vpx_scaling_mode_t sm;
-
-    sm.h_scaling_mode = encoder->h_scaling_mode;
-    sm.v_scaling_mode = encoder->v_scaling_mode;
-
-    status = vpx_codec_control (&encoder->encoder, VP8E_SET_SCALEMODE, &sm);
-    if (status != VPX_CODEC_OK) {
-      GST_WARNING_OBJECT (encoder, "Failed to set VP8E_SET_SCALEMODE: %s",
-          gst_vpx_error_name (status));
-    }
-  }
-
-  status =
-      vpx_codec_control (&encoder->encoder, VP8E_SET_CPUUSED,
-      encoder->cpu_used);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder, "Failed to set VP8E_SET_CPUUSED: %s",
-        gst_vpx_error_name (status));
-  }
-
-  status =
-      vpx_codec_control (&encoder->encoder, VP8E_SET_ENABLEAUTOALTREF,
-      (encoder->enable_auto_alt_ref ? 1 : 0));
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_ENABLEAUTOALTREF: %s",
-        gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_NOISE_SENSITIVITY,
-      encoder->noise_sensitivity);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_NOISE_SENSITIVITY: %s",
-        gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_SHARPNESS,
-      encoder->sharpness);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_SHARPNESS: %s", gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_STATIC_THRESHOLD,
-      encoder->static_threshold);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_STATIC_THRESHOLD: %s",
-        gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_TOKEN_PARTITIONS,
-      encoder->token_partitions);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_TOKEN_PARTIONS: %s",
-        gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_ARNR_MAXFRAMES,
-      encoder->arnr_maxframes);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_ARNR_MAXFRAMES: %s",
-        gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_ARNR_STRENGTH,
-      encoder->arnr_strength);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_ARNR_STRENGTH: %s",
-        gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_TUNING,
-      encoder->tuning);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_TUNING: %s", gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_CQ_LEVEL,
-      encoder->cq_level);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_CQ_LEVEL: %s", gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_MAX_INTRA_BITRATE_PCT,
-      encoder->max_intra_bitrate_pct);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_MAX_INTRA_BITRATE_PCT: %s",
-        gst_vpx_error_name (status));
-  }
-
-  if (GST_VIDEO_INFO_FPS_D (info) == 0 || GST_VIDEO_INFO_FPS_N (info) == 0) {
-    /* FIXME: Assume 25fps for unknown framerates. Better than reporting
-     * that we introduce no latency while we actually do
-     */
-    latency = gst_util_uint64_scale (encoder->cfg.g_lag_in_frames,
-        1 * GST_SECOND, 25);
-  } else {
-    latency = gst_util_uint64_scale (encoder->cfg.g_lag_in_frames,
-        GST_VIDEO_INFO_FPS_D (info) * GST_SECOND, GST_VIDEO_INFO_FPS_N (info));
-  }
-  gst_video_encoder_set_latency (video_encoder, latency, latency);
-  encoder->inited = TRUE;
-
-  /* Store input state */
-  if (encoder->input_state)
-    gst_video_codec_state_unref (encoder->input_state);
-  encoder->input_state = gst_video_codec_state_ref (state);
-
-  /* prepare cached image buffer setup */
-  image = &encoder->image;
-  memset (image, 0, sizeof (*image));
-
   image->fmt = VPX_IMG_FMT_I420;
   image->bps = 12;
   image->x_chroma_shift = image->y_chroma_shift = 1;
-  image->w = image->d_w = GST_VIDEO_INFO_WIDTH (info);
-  image->h = image->d_h = GST_VIDEO_INFO_HEIGHT (info);
+}
 
-  image->stride[VPX_PLANE_Y] = GST_VIDEO_INFO_COMP_STRIDE (info, 0);
-  image->stride[VPX_PLANE_U] = GST_VIDEO_INFO_COMP_STRIDE (info, 1);
-  image->stride[VPX_PLANE_V] = GST_VIDEO_INFO_COMP_STRIDE (info, 2);
-
-  profile_str = g_strdup_printf ("%d", encoder->cfg.g_profile);
+static GstCaps *
+gst_vp8_enc_get_new_simple_caps (GstVPXEnc * enc)
+{
+  GstCaps *caps;
+  gchar *profile_str = g_strdup_printf ("%d", enc->cfg.g_profile);
   caps = gst_caps_new_simple ("video/x-vp8",
       "profile", G_TYPE_STRING, profile_str, NULL);
   g_free (profile_str);
+  return caps;
+}
 
-  {
-    GstStructure *s;
-    GstBuffer *stream_hdr, *vorbiscomment;
-    const GstTagList *iface_tags;
-    GValue array = { 0, };
-    GValue value = { 0, };
-    GstMapInfo map;
+static void
+gst_vp8_enc_set_stream_info (GstVPXEnc * enc, GstCaps * caps,
+    GstVideoInfo * info)
+{
+  GstStructure *s;
+  GstVideoEncoder *video_encoder;
+  GstBuffer *stream_hdr, *vorbiscomment;
+  const GstTagList *iface_tags;
+  GValue array = { 0, };
+  GValue value = { 0, };
+  guint8 *data = NULL;
+  GstMapInfo map;
 
-    s = gst_caps_get_structure (caps, 0);
+  video_encoder = GST_VIDEO_ENCODER (enc);
+  s = gst_caps_get_structure (caps, 0);
 
-    /* put buffers in a fixed list */
-    g_value_init (&array, GST_TYPE_ARRAY);
+  /* put buffers in a fixed list */
+  g_value_init (&array, GST_TYPE_ARRAY);
+  g_value_init (&value, GST_TYPE_BUFFER);
+
+  /* Create Ogg stream-info */
+  stream_hdr = gst_buffer_new_and_alloc (26);
+  gst_buffer_map (stream_hdr, &map, GST_MAP_WRITE);
+  data = map.data;
+
+  GST_WRITE_UINT8 (data, 0x4F);
+  GST_WRITE_UINT32_BE (data + 1, 0x56503830);   /* "VP80" */
+  GST_WRITE_UINT8 (data + 5, 0x01);     /* stream info header */
+  GST_WRITE_UINT8 (data + 6, 1);        /* Major version 1 */
+  GST_WRITE_UINT8 (data + 7, 0);        /* Minor version 0 */
+  GST_WRITE_UINT16_BE (data + 8, GST_VIDEO_INFO_WIDTH (info));
+  GST_WRITE_UINT16_BE (data + 10, GST_VIDEO_INFO_HEIGHT (info));
+  GST_WRITE_UINT24_BE (data + 12, GST_VIDEO_INFO_PAR_N (info));
+  GST_WRITE_UINT24_BE (data + 15, GST_VIDEO_INFO_PAR_D (info));
+  GST_WRITE_UINT32_BE (data + 18, GST_VIDEO_INFO_FPS_N (info));
+  GST_WRITE_UINT32_BE (data + 22, GST_VIDEO_INFO_FPS_D (info));
+
+  gst_buffer_unmap (stream_hdr, &map);
+
+  GST_BUFFER_FLAG_SET (stream_hdr, GST_BUFFER_FLAG_HEADER);
+  gst_value_set_buffer (&value, stream_hdr);
+  gst_value_array_append_value (&array, &value);
+  g_value_unset (&value);
+  gst_buffer_unref (stream_hdr);
+
+  iface_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (video_encoder));
+  if (iface_tags) {
+    vorbiscomment =
+        gst_tag_list_to_vorbiscomment_buffer (iface_tags,
+        (const guint8 *) "OVP80\2 ", 7,
+        "Encoded with GStreamer vp8enc " PACKAGE_VERSION);
+
+    GST_BUFFER_FLAG_SET (vorbiscomment, GST_BUFFER_FLAG_HEADER);
+
     g_value_init (&value, GST_TYPE_BUFFER);
-
-    /* Create Ogg stream-info */
-    stream_hdr = gst_buffer_new_and_alloc (26);
-    gst_buffer_map (stream_hdr, &map, GST_MAP_WRITE);
-    data = map.data;
-
-    GST_WRITE_UINT8 (data, 0x4F);
-    GST_WRITE_UINT32_BE (data + 1, 0x56503830); /* "VP80" */
-    GST_WRITE_UINT8 (data + 5, 0x01);   /* stream info header */
-    GST_WRITE_UINT8 (data + 6, 1);      /* Major version 1 */
-    GST_WRITE_UINT8 (data + 7, 0);      /* Minor version 0 */
-    GST_WRITE_UINT16_BE (data + 8, GST_VIDEO_INFO_WIDTH (info));
-    GST_WRITE_UINT16_BE (data + 10, GST_VIDEO_INFO_HEIGHT (info));
-    GST_WRITE_UINT24_BE (data + 12, GST_VIDEO_INFO_PAR_N (info));
-    GST_WRITE_UINT24_BE (data + 15, GST_VIDEO_INFO_PAR_D (info));
-    GST_WRITE_UINT32_BE (data + 18, GST_VIDEO_INFO_FPS_N (info));
-    GST_WRITE_UINT32_BE (data + 22, GST_VIDEO_INFO_FPS_D (info));
-
-    gst_buffer_unmap (stream_hdr, &map);
-
-    GST_BUFFER_FLAG_SET (stream_hdr, GST_BUFFER_FLAG_HEADER);
-    gst_value_set_buffer (&value, stream_hdr);
+    gst_value_set_buffer (&value, vorbiscomment);
     gst_value_array_append_value (&array, &value);
     g_value_unset (&value);
-    gst_buffer_unref (stream_hdr);
-
-    iface_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (video_encoder));
-    if (iface_tags) {
-      vorbiscomment =
-          gst_tag_list_to_vorbiscomment_buffer (iface_tags,
-          (const guint8 *) "OVP80\2 ", 7,
-          "Encoded with GStreamer vp8enc " PACKAGE_VERSION);
-
-      GST_BUFFER_FLAG_SET (vorbiscomment, GST_BUFFER_FLAG_HEADER);
-
-      g_value_init (&value, GST_TYPE_BUFFER);
-      gst_value_set_buffer (&value, vorbiscomment);
-      gst_value_array_append_value (&array, &value);
-      g_value_unset (&value);
-      gst_buffer_unref (vorbiscomment);
-    }
-
-    gst_structure_set_value (s, "streamheader", &array);
-    g_value_unset (&array);
+    gst_buffer_unref (vorbiscomment);
   }
-  g_mutex_unlock (&encoder->encoder_lock);
 
-  output_state =
-      gst_video_encoder_set_output_state (video_encoder, caps, state);
-  gst_video_codec_state_unref (output_state);
+  gst_structure_set_value (s, "streamheader", &array);
+  g_value_unset (&array);
 
-  gst_video_encoder_negotiate (GST_VIDEO_ENCODER (encoder));
-
-  return ret;
 }
 
-static GstFlowReturn
-gst_vp8_enc_process (GstVP8Enc * encoder)
+static void *
+gst_vp8_enc_process_frame_user_data (GstVPXEnc * enc,
+    GstVideoCodecFrame * frame)
 {
-  vpx_codec_iter_t iter = NULL;
-  const vpx_codec_cx_pkt_t *pkt;
-  GstVideoEncoder *video_encoder;
   GstVP8EncUserData *user_data;
-  GstVideoCodecFrame *frame;
-  GstFlowReturn ret = GST_FLOW_OK;
-
-  video_encoder = GST_VIDEO_ENCODER (encoder);
-
-  g_mutex_lock (&encoder->encoder_lock);
-  pkt = vpx_codec_get_cx_data (&encoder->encoder, &iter);
-  while (pkt != NULL) {
-    GstBuffer *buffer;
-    gboolean invisible;
-
-    GST_DEBUG_OBJECT (encoder, "packet %u type %d", (guint) pkt->data.frame.sz,
-        pkt->kind);
-
-    if (pkt->kind == VPX_CODEC_STATS_PKT
-        && encoder->cfg.g_pass == VPX_RC_FIRST_PASS) {
-      GST_LOG_OBJECT (encoder, "handling STATS packet");
-
-      g_byte_array_append (encoder->first_pass_cache_content,
-          pkt->data.twopass_stats.buf, pkt->data.twopass_stats.sz);
-
-      frame = gst_video_encoder_get_oldest_frame (video_encoder);
-      if (frame != NULL) {
-        buffer = gst_buffer_new ();
-        GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_LIVE);
-        frame->output_buffer = buffer;
-        g_mutex_unlock (&encoder->encoder_lock);
-        ret = gst_video_encoder_finish_frame (video_encoder, frame);
-        g_mutex_lock (&encoder->encoder_lock);
-      }
-
-      pkt = vpx_codec_get_cx_data (&encoder->encoder, &iter);
-      continue;
-    } else if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) {
-      GST_LOG_OBJECT (encoder, "non frame pkt: %d", pkt->kind);
-      pkt = vpx_codec_get_cx_data (&encoder->encoder, &iter);
-      continue;
-    }
-
-    invisible = (pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE) != 0;
-    frame = gst_video_encoder_get_oldest_frame (video_encoder);
-    g_assert (frame != NULL);
-    if ((pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0)
-      GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
-    else
-      GST_VIDEO_CODEC_FRAME_UNSET_SYNC_POINT (frame);
-
-    user_data = gst_video_codec_frame_get_user_data (frame);
-
-    /* FIXME : It would be nice to avoid the memory copy ... */
-    buffer =
-        gst_buffer_new_wrapped (g_memdup (pkt->data.frame.buf,
-            pkt->data.frame.sz), pkt->data.frame.sz);
-
-    if (user_data->image)
-      g_slice_free (vpx_image_t, user_data->image);
-    user_data->image = NULL;
-
-    if (invisible) {
-      user_data->invisible = g_list_append (user_data->invisible, buffer);
-      gst_video_codec_frame_unref (frame);
-    } else {
-      frame->output_buffer = buffer;
-      g_mutex_unlock (&encoder->encoder_lock);
-      ret = gst_video_encoder_finish_frame (video_encoder, frame);
-      g_mutex_lock (&encoder->encoder_lock);
-    }
-
-    pkt = vpx_codec_get_cx_data (&encoder->encoder, &iter);
-  }
-  g_mutex_unlock (&encoder->encoder_lock);
-
-  return ret;
+  user_data = gst_video_codec_frame_get_user_data (frame);
+  if (user_data->image)
+    g_slice_free (vpx_image_t, user_data->image);
+  user_data->image = NULL;
+  return user_data;
 }
 
-/* This function should be called holding then stream lock*/
 static GstFlowReturn
-gst_vp8_enc_drain (GstVideoEncoder * video_encoder)
+gst_vp8_enc_handle_invisible_frame_buffer (GstVPXEnc * enc, void *user_data,
+    GstBuffer * buffer)
 {
-  GstVP8Enc *encoder;
-  int flags = 0;
-  vpx_codec_err_t status;
-  gint64 deadline;
-  vpx_codec_pts_t pts;
-
-  encoder = GST_VP8_ENC (video_encoder);
-
-  g_mutex_lock (&encoder->encoder_lock);
-  deadline = encoder->deadline;
-
-  pts =
-      gst_util_uint64_scale (encoder->last_pts,
-      encoder->cfg.g_timebase.den,
-      encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND);
-
-  status = vpx_codec_encode (&encoder->encoder, NULL, pts, 0, flags, deadline);
-  g_mutex_unlock (&encoder->encoder_lock);
-
-  if (status != 0) {
-    GST_ERROR_OBJECT (encoder, "encode returned %d %s", status,
-        gst_vpx_error_name (status));
-    return GST_FLOW_ERROR;
-  }
-
-  /* dispatch remaining frames */
-  gst_vp8_enc_process (encoder);
-
-  g_mutex_lock (&encoder->encoder_lock);
-  if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS && encoder->multipass_cache_file) {
-    GError *err = NULL;
-
-    if (!g_file_set_contents (encoder->multipass_cache_file,
-            (const gchar *) encoder->first_pass_cache_content->data,
-            encoder->first_pass_cache_content->len, &err)) {
-      GST_ELEMENT_ERROR (encoder, RESOURCE, WRITE, (NULL),
-          ("Failed to write multipass cache file: %s", err->message));
-      g_error_free (err);
-    }
-  }
-  g_mutex_unlock (&encoder->encoder_lock);
-
+  GstVP8EncUserData *vp8_user_data = (GstVP8EncUserData *) user_data;
+  vp8_user_data->invisible = g_list_append (vp8_user_data->invisible, buffer);
   return GST_FLOW_OK;
 }
 
-static gboolean
-gst_vp8_enc_flush (GstVideoEncoder * video_encoder)
+static void
+gst_vp8_enc_set_frame_user_data (GstVPXEnc * enc, GstVideoCodecFrame * frame,
+    vpx_image_t * image)
 {
-  GstVP8Enc *encoder;
-
-  GST_DEBUG_OBJECT (video_encoder, "flush");
-
-  encoder = GST_VP8_ENC (video_encoder);
-
-  gst_vp8_enc_destroy_encoder (encoder);
-  if (encoder->input_state) {
-    gst_video_codec_state_ref (encoder->input_state);
-    gst_vp8_enc_set_format (video_encoder, encoder->input_state);
-    gst_video_codec_state_unref (encoder->input_state);
-  }
-
-  return TRUE;
-}
-
-static GstFlowReturn
-gst_vp8_enc_finish (GstVideoEncoder * video_encoder)
-{
-  GstVP8Enc *encoder;
-  GstFlowReturn ret;
-
-  GST_DEBUG_OBJECT (video_encoder, "finish");
-
-  encoder = GST_VP8_ENC (video_encoder);
-
-  if (encoder->inited) {
-    ret = gst_vp8_enc_drain (video_encoder);
-  } else {
-    ret = GST_FLOW_OK;
-  }
-
-  return ret;
-}
-
-static vpx_image_t *
-gst_vp8_enc_buffer_to_image (GstVP8Enc * enc, GstVideoFrame * frame)
-{
-  vpx_image_t *image = g_slice_new (vpx_image_t);
-
-  memcpy (image, &enc->image, sizeof (*image));
-
-  image->planes[VPX_PLANE_Y] = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
-  image->planes[VPX_PLANE_U] = GST_VIDEO_FRAME_COMP_DATA (frame, 1);
-  image->planes[VPX_PLANE_V] = GST_VIDEO_FRAME_COMP_DATA (frame, 2);
-
-  image->stride[VPX_PLANE_Y] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
-  image->stride[VPX_PLANE_U] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 1);
-  image->stride[VPX_PLANE_V] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 2);
-
-  return image;
-}
-
-static GstFlowReturn
-gst_vp8_enc_handle_frame (GstVideoEncoder * video_encoder,
-    GstVideoCodecFrame * frame)
-{
-  GstVP8Enc *encoder;
-  vpx_codec_err_t status;
-  int flags = 0;
-  vpx_image_t *image;
   GstVP8EncUserData *user_data;
-  GstVideoFrame vframe;
-  vpx_codec_pts_t pts;
-  unsigned long duration;
-
-  GST_DEBUG_OBJECT (video_encoder, "handle_frame");
-
-  encoder = GST_VP8_ENC (video_encoder);
-
-  GST_DEBUG_OBJECT (video_encoder, "size %d %d",
-      GST_VIDEO_INFO_WIDTH (&encoder->input_state->info),
-      GST_VIDEO_INFO_HEIGHT (&encoder->input_state->info));
-
-  gst_video_frame_map (&vframe, &encoder->input_state->info,
-      frame->input_buffer, GST_MAP_READ);
-  image = gst_vp8_enc_buffer_to_image (encoder, &vframe);
-
   user_data = g_slice_new0 (GstVP8EncUserData);
   user_data->image = image;
   gst_video_codec_frame_set_user_data (frame, user_data,
       (GDestroyNotify) gst_vp8_enc_user_data_free);
-
-  if (GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame)) {
-    flags |= VPX_EFLAG_FORCE_KF;
-  }
-
-  g_mutex_lock (&encoder->encoder_lock);
-  pts =
-      gst_util_uint64_scale (frame->pts,
-      encoder->cfg.g_timebase.den,
-      encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND);
-  encoder->last_pts = frame->pts;
-
-  if (frame->duration != GST_CLOCK_TIME_NONE) {
-    duration =
-        gst_util_uint64_scale (frame->duration, encoder->cfg.g_timebase.den,
-        encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND);
-    encoder->last_pts += frame->duration;
-  } else {
-    duration = 1;
-  }
-
-  status = vpx_codec_encode (&encoder->encoder, image,
-      pts, duration, flags, encoder->deadline);
-
-  g_mutex_unlock (&encoder->encoder_lock);
-  gst_video_frame_unmap (&vframe);
-
-  if (status != 0) {
-    GST_ELEMENT_ERROR (encoder, LIBRARY, ENCODE,
-        ("Failed to encode frame"), ("%s", gst_vpx_error_name (status)));
-    gst_video_codec_frame_set_user_data (frame, NULL, NULL);
-    return FALSE;
-  }
-  gst_video_codec_frame_unref (frame);
-  return gst_vp8_enc_process (encoder);
+  return;
 }
 
 static guint64
@@ -2083,6 +334,7 @@
     GstVideoCodecFrame * frame)
 {
   GstVP8Enc *encoder;
+  GstVPXEnc *vpx_enc;
   GstBuffer *buf;
   GstFlowReturn ret = GST_FLOW_OK;
   GstVP8EncUserData *user_data = gst_video_codec_frame_get_user_data (frame);
@@ -2093,8 +345,9 @@
   GST_DEBUG_OBJECT (video_encoder, "pre_push");
 
   encoder = GST_VP8_ENC (video_encoder);
+  vpx_enc = GST_VPX_ENC (encoder);
 
-  info = &encoder->input_state->info;
+  info = &vpx_enc->input_state->info;
 
   g_assert (user_data != NULL);
 
@@ -2166,33 +419,4 @@
   return ret;
 }
 
-static gboolean
-gst_vp8_enc_sink_event (GstVideoEncoder * benc, GstEvent * event)
-{
-  GstVP8Enc *enc = GST_VP8_ENC (benc);
-
-  /* FIXME : Move this to base encoder class */
-
-  if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) {
-    GstTagList *list;
-    GstTagSetter *setter = GST_TAG_SETTER (enc);
-    const GstTagMergeMode mode = gst_tag_setter_get_tag_merge_mode (setter);
-
-    gst_event_parse_tag (event, &list);
-    gst_tag_setter_merge_tags (setter, list, mode);
-  }
-
-  /* just peeked, baseclass handles the rest */
-  return GST_VIDEO_ENCODER_CLASS (parent_class)->sink_event (benc, event);
-}
-
-static gboolean
-gst_vp8_enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query)
-{
-  gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
-
-  return GST_VIDEO_ENCODER_CLASS (parent_class)->propose_allocation (encoder,
-      query);
-}
-
 #endif /* HAVE_VP8_ENCODER */
diff --git a/ext/vpx/gstvp8enc.h b/ext/vpx/gstvp8enc.h
index 3f04646..47319e2 100644
--- a/ext/vpx/gstvp8enc.h
+++ b/ext/vpx/gstvp8enc.h
@@ -28,8 +28,7 @@
 
 #ifdef HAVE_VP8_ENCODER
 
-#include <gst/gst.h>
-#include <gst/video/gstvideoencoder.h>
+#include <gstvpxenc.h>
 
 /* FIXME: Undef HAVE_CONFIG_H because vpx_codec.h uses it,
  * which causes compilation failures */
@@ -37,9 +36,6 @@
 #undef HAVE_CONFIG_H
 #endif
 
-#include <vpx/vpx_encoder.h>
-#include <vpx/vp8cx.h>
-
 G_BEGIN_DECLS
 
 #define GST_TYPE_VP8_ENC \
@@ -58,61 +54,14 @@
 
 struct _GstVP8Enc
 {
-  GstVideoEncoder base_video_encoder;
+  GstVPXEnc base_vpx_encoder;
 
-  /* < private > */
-  vpx_codec_ctx_t encoder;
-  GMutex encoder_lock;
-
-  /* properties */
-  vpx_codec_enc_cfg_t cfg;
-  gboolean have_default_config;
-  gboolean rc_target_bitrate_set;
-  gint n_ts_target_bitrate;
-  gint n_ts_rate_decimator;
-  gint n_ts_layer_id;
-  /* Global two-pass options */
-  gchar *multipass_cache_file;
-  gchar *multipass_cache_prefix;
-  guint multipass_cache_idx;
-  GByteArray *first_pass_cache_content;
-
-  /* Encode parameter */
-  gint64 deadline;
-
-  /* Controls */
-  VPX_SCALING_MODE h_scaling_mode;
-  VPX_SCALING_MODE v_scaling_mode;
-  int cpu_used;
-  gboolean enable_auto_alt_ref;
-  unsigned int noise_sensitivity;
-  unsigned int sharpness;
-  unsigned int static_threshold;
-  vp8e_token_partitions token_partitions;
-  unsigned int arnr_maxframes;
-  unsigned int arnr_strength;
-  unsigned int arnr_type;
-  vp8e_tuning tuning;
-  unsigned int cq_level;
-  unsigned int max_intra_bitrate_pct;
-  /* Timebase - a value of 0 will use the framerate */
-  unsigned int timebase_n;
-  unsigned int timebase_d;
-
-  /* state */
-  gboolean inited;
-
-  vpx_image_t image;
-
-  GstClockTime last_pts;
   int keyframe_distance;
-
-  GstVideoCodecState *input_state;
 };
 
 struct _GstVP8EncClass
 {
-  GstVideoEncoderClass base_video_encoder_class;
+  GstVPXEncClass  base_vpxenc_class;
 };
 
 GType gst_vp8_enc_get_type (void);
diff --git a/ext/vpx/gstvp9dec.c b/ext/vpx/gstvp9dec.c
index 3de5a64..d08a2f7 100644
--- a/ext/vpx/gstvp9dec.c
+++ b/ext/vpx/gstvp9dec.c
@@ -54,63 +54,14 @@
 GST_DEBUG_CATEGORY_STATIC (gst_vp9dec_debug);
 #define GST_CAT_DEFAULT gst_vp9dec_debug
 
-#define DEFAULT_POST_PROCESSING FALSE
-#define DEFAULT_POST_PROCESSING_FLAGS (VP8_DEBLOCK | VP8_DEMACROBLOCK)
-#define DEFAULT_DEBLOCKING_LEVEL 4
-#define DEFAULT_NOISE_LEVEL 0
-#define DEFAULT_THREADS 1
+#define VP9_DECODER_VIDEO_TAG "VP9 video"
 
-enum
-{
-  PROP_0,
-  PROP_POST_PROCESSING,
-  PROP_POST_PROCESSING_FLAGS,
-  PROP_DEBLOCKING_LEVEL,
-  PROP_NOISE_LEVEL,
-  PROP_THREADS
-};
-
-#define C_FLAGS(v) ((guint) v)
-#define GST_VP9_DEC_TYPE_POST_PROCESSING_FLAGS (gst_vp9_dec_post_processing_flags_get_type())
-static GType
-gst_vp9_dec_post_processing_flags_get_type (void)
-{
-  static const GFlagsValue values[] = {
-    {C_FLAGS (VP8_DEBLOCK), "Deblock", "deblock"},
-    {C_FLAGS (VP8_DEMACROBLOCK), "Demacroblock", "demacroblock"},
-    {C_FLAGS (VP8_ADDNOISE), "Add noise", "addnoise"},
-    {C_FLAGS (VP8_MFQE), "Multi-frame quality enhancement", "mfqe"},
-    {0, NULL, NULL}
-  };
-  static volatile GType id = 0;
-
-  if (g_once_init_enter ((gsize *) & id)) {
-    GType _id;
-
-    _id = g_flags_register_static ("GstVP9DecPostProcessingFlags", values);
-
-    g_once_init_leave ((gsize *) & id, _id);
-  }
-
-  return id;
-}
-
-#undef C_FLAGS
-
-static void gst_vp9_dec_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-static void gst_vp9_dec_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-
-static gboolean gst_vp9_dec_start (GstVideoDecoder * decoder);
-static gboolean gst_vp9_dec_stop (GstVideoDecoder * decoder);
-static gboolean gst_vp9_dec_set_format (GstVideoDecoder * decoder,
-    GstVideoCodecState * state);
-static gboolean gst_vp9_dec_flush (GstVideoDecoder * decoder);
-static GstFlowReturn gst_vp9_dec_handle_frame (GstVideoDecoder * decoder,
-    GstVideoCodecFrame * frame);
-static gboolean gst_vp9_dec_decide_allocation (GstVideoDecoder * decoder,
-    GstQuery * query);
+static void gst_vp9_dec_set_stream_info (GstVPXDec * dec,
+    vpx_codec_stream_info_t * stream_info);
+static gboolean gst_vp9_dec_get_valid_format (GstVPXDec * dec,
+    vpx_image_t * img, GstVideoFormat * fmt);
+static void gst_vp9_dec_handle_resolution_change (GstVPXDec * dec,
+    vpx_image_t * img, GstVideoFormat fmt);
 
 static GstStaticPadTemplate gst_vp9_dec_sink_template =
 GST_STATIC_PAD_TEMPLATE ("sink",
@@ -127,49 +78,16 @@
     );
 
 #define parent_class gst_vp9_dec_parent_class
-G_DEFINE_TYPE (GstVP9Dec, gst_vp9_dec, GST_TYPE_VIDEO_DECODER);
+G_DEFINE_TYPE (GstVP9Dec, gst_vp9_dec, GST_TYPE_VPX_DEC);
 
 static void
 gst_vp9_dec_class_init (GstVP9DecClass * klass)
 {
-  GObjectClass *gobject_class;
   GstElementClass *element_class;
-  GstVideoDecoderClass *base_video_decoder_class;
+  GstVPXDecClass *vpx_class;
 
-  gobject_class = G_OBJECT_CLASS (klass);
   element_class = GST_ELEMENT_CLASS (klass);
-  base_video_decoder_class = GST_VIDEO_DECODER_CLASS (klass);
-
-  gobject_class->set_property = gst_vp9_dec_set_property;
-  gobject_class->get_property = gst_vp9_dec_get_property;
-
-  g_object_class_install_property (gobject_class, PROP_POST_PROCESSING,
-      g_param_spec_boolean ("post-processing", "Post Processing",
-          "Enable post processing", DEFAULT_POST_PROCESSING,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_POST_PROCESSING_FLAGS,
-      g_param_spec_flags ("post-processing-flags", "Post Processing Flags",
-          "Flags to control post processing",
-          GST_VP9_DEC_TYPE_POST_PROCESSING_FLAGS, DEFAULT_POST_PROCESSING_FLAGS,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_DEBLOCKING_LEVEL,
-      g_param_spec_uint ("deblocking-level", "Deblocking Level",
-          "Deblocking level",
-          0, 16, DEFAULT_DEBLOCKING_LEVEL,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_NOISE_LEVEL,
-      g_param_spec_uint ("noise-level", "Noise Level",
-          "Noise level",
-          0, 16, DEFAULT_NOISE_LEVEL,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_THREADS,
-      g_param_spec_uint ("threads", "Max Threads",
-          "Maximum number of decoding threads",
-          1, 16, DEFAULT_THREADS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  vpx_class = GST_VPX_DEC_CLASS (klass);
 
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&gst_vp9_dec_src_template));
@@ -182,14 +100,13 @@
       "Decode VP9 video streams", "David Schleef <ds@entropywave.com>, "
       "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
 
-  base_video_decoder_class->start = GST_DEBUG_FUNCPTR (gst_vp9_dec_start);
-  base_video_decoder_class->stop = GST_DEBUG_FUNCPTR (gst_vp9_dec_stop);
-  base_video_decoder_class->flush = GST_DEBUG_FUNCPTR (gst_vp9_dec_flush);
-  base_video_decoder_class->set_format =
-      GST_DEBUG_FUNCPTR (gst_vp9_dec_set_format);
-  base_video_decoder_class->handle_frame =
-      GST_DEBUG_FUNCPTR (gst_vp9_dec_handle_frame);
-  base_video_decoder_class->decide_allocation = gst_vp9_dec_decide_allocation;
+  vpx_class->video_codec_tag = VP9_DECODER_VIDEO_TAG;
+  vpx_class->codec_algo = &vpx_codec_vp9_dx_algo;
+  vpx_class->set_stream_info = GST_DEBUG_FUNCPTR (gst_vp9_dec_set_stream_info);
+  vpx_class->get_frame_format =
+      GST_DEBUG_FUNCPTR (gst_vp9_dec_get_valid_format);
+  vpx_class->handle_resolution_change =
+      GST_DEBUG_FUNCPTR (gst_vp9_dec_handle_resolution_change);
 
   GST_DEBUG_CATEGORY_INIT (gst_vp9dec_debug, "vp9dec", 0, "VP9 Decoder");
 }
@@ -197,442 +114,67 @@
 static void
 gst_vp9_dec_init (GstVP9Dec * gst_vp9_dec)
 {
-  GstVideoDecoder *decoder = (GstVideoDecoder *) gst_vp9_dec;
-
   GST_DEBUG_OBJECT (gst_vp9_dec, "gst_vp9_dec_init");
-  gst_video_decoder_set_packetized (decoder, TRUE);
-  gst_vp9_dec->post_processing = DEFAULT_POST_PROCESSING;
-  gst_vp9_dec->post_processing_flags = DEFAULT_POST_PROCESSING_FLAGS;
-  gst_vp9_dec->deblocking_level = DEFAULT_DEBLOCKING_LEVEL;
-  gst_vp9_dec->noise_level = DEFAULT_NOISE_LEVEL;
-
-  gst_video_decoder_set_needs_format (decoder, TRUE);
-  gst_video_decoder_set_use_default_pad_acceptcaps (decoder, TRUE);
-  GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_DECODER_SINK_PAD (decoder));
 }
 
 static void
-gst_vp9_dec_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
+gst_vp9_dec_set_stream_info (GstVPXDec * dec,
+    vpx_codec_stream_info_t * stream_info)
 {
-  GstVP9Dec *dec;
-
-  g_return_if_fail (GST_IS_VP9_DEC (object));
-  dec = GST_VP9_DEC (object);
-
-  GST_DEBUG_OBJECT (object, "gst_vp9_dec_set_property");
-  switch (prop_id) {
-    case PROP_POST_PROCESSING:
-      dec->post_processing = g_value_get_boolean (value);
-      break;
-    case PROP_POST_PROCESSING_FLAGS:
-      dec->post_processing_flags = g_value_get_flags (value);
-      break;
-    case PROP_DEBLOCKING_LEVEL:
-      dec->deblocking_level = g_value_get_uint (value);
-      break;
-    case PROP_NOISE_LEVEL:
-      dec->noise_level = g_value_get_uint (value);
-      break;
-    case PROP_THREADS:
-      dec->threads = g_value_get_uint (value);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_vp9_dec_get_property (GObject * object, guint prop_id, GValue * value,
-    GParamSpec * pspec)
-{
-  GstVP9Dec *dec;
-
-  g_return_if_fail (GST_IS_VP9_DEC (object));
-  dec = GST_VP9_DEC (object);
-
-  switch (prop_id) {
-    case PROP_POST_PROCESSING:
-      g_value_set_boolean (value, dec->post_processing);
-      break;
-    case PROP_POST_PROCESSING_FLAGS:
-      g_value_set_flags (value, dec->post_processing_flags);
-      break;
-    case PROP_DEBLOCKING_LEVEL:
-      g_value_set_uint (value, dec->deblocking_level);
-      break;
-    case PROP_NOISE_LEVEL:
-      g_value_set_uint (value, dec->noise_level);
-      break;
-    case PROP_THREADS:
-      g_value_set_uint (value, dec->threads);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static gboolean
-gst_vp9_dec_start (GstVideoDecoder * decoder)
-{
-  GstVP9Dec *gst_vp9_dec = GST_VP9_DEC (decoder);
-
-  GST_DEBUG_OBJECT (gst_vp9_dec, "start");
-  gst_vp9_dec->decoder_inited = FALSE;
-
-  return TRUE;
-}
-
-static gboolean
-gst_vp9_dec_stop (GstVideoDecoder * base_video_decoder)
-{
-  GstVP9Dec *gst_vp9_dec = GST_VP9_DEC (base_video_decoder);
-
-  GST_DEBUG_OBJECT (gst_vp9_dec, "stop");
-
-  if (gst_vp9_dec->output_state) {
-    gst_video_codec_state_unref (gst_vp9_dec->output_state);
-    gst_vp9_dec->output_state = NULL;
-  }
-
-  if (gst_vp9_dec->input_state) {
-    gst_video_codec_state_unref (gst_vp9_dec->input_state);
-    gst_vp9_dec->input_state = NULL;
-  }
-
-  if (gst_vp9_dec->decoder_inited)
-    vpx_codec_destroy (&gst_vp9_dec->decoder);
-  gst_vp9_dec->decoder_inited = FALSE;
-
-  return TRUE;
-}
-
-static gboolean
-gst_vp9_dec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
-{
-  GstVP9Dec *gst_vp9_dec = GST_VP9_DEC (decoder);
-
-  GST_DEBUG_OBJECT (gst_vp9_dec, "set_format");
-
-  if (gst_vp9_dec->decoder_inited)
-    vpx_codec_destroy (&gst_vp9_dec->decoder);
-  gst_vp9_dec->decoder_inited = FALSE;
-
-  if (gst_vp9_dec->output_state) {
-    gst_video_codec_state_unref (gst_vp9_dec->output_state);
-    gst_vp9_dec->output_state = NULL;
-  }
-
-  if (gst_vp9_dec->input_state)
-    gst_video_codec_state_unref (gst_vp9_dec->input_state);
-  gst_vp9_dec->input_state = gst_video_codec_state_ref (state);
-
-  return TRUE;
-}
-
-static gboolean
-gst_vp9_dec_flush (GstVideoDecoder * base_video_decoder)
-{
-  GstVP9Dec *decoder;
-
-  GST_DEBUG_OBJECT (base_video_decoder, "flush");
-
-  decoder = GST_VP9_DEC (base_video_decoder);
-
-  if (decoder->output_state) {
-    gst_video_codec_state_unref (decoder->output_state);
-    decoder->output_state = NULL;
-  }
-
-  if (decoder->decoder_inited)
-    vpx_codec_destroy (&decoder->decoder);
-  decoder->decoder_inited = FALSE;
-
-  return TRUE;
-}
-
-static void
-gst_vp9_dec_send_tags (GstVP9Dec * dec)
-{
-  GstTagList *list;
-
-  list = gst_tag_list_new_empty ();
-  gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
-      GST_TAG_VIDEO_CODEC, "VP9 video", NULL);
-
-  gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (dec),
-      gst_event_new_tag (list));
-}
-
-static void
-gst_vp9_dec_image_to_buffer (GstVP9Dec * dec, const vpx_image_t * img,
-    GstBuffer * buffer)
-{
-  int deststride, srcstride, height, width, line, comp;
-  guint8 *dest, *src;
-  GstVideoFrame frame;
-  GstVideoInfo *info = &dec->output_state->info;
-
-  if (!gst_video_frame_map (&frame, info, buffer, GST_MAP_WRITE)) {
-    GST_ERROR_OBJECT (dec, "Could not map video buffer");
-    return;
-  }
-
-  for (comp = 0; comp < 3; comp++) {
-    dest = GST_VIDEO_FRAME_COMP_DATA (&frame, comp);
-    src = img->planes[comp];
-    width = GST_VIDEO_FRAME_COMP_WIDTH (&frame, comp)
-        * GST_VIDEO_FRAME_COMP_PSTRIDE (&frame, comp);
-    height = GST_VIDEO_FRAME_COMP_HEIGHT (&frame, comp);
-    deststride = GST_VIDEO_FRAME_COMP_STRIDE (&frame, comp);
-    srcstride = img->stride[comp];
-
-    if (srcstride == deststride) {
-      GST_TRACE_OBJECT (dec, "Stride matches. Comp %d: %d, copying full plane",
-          comp, srcstride);
-      memcpy (dest, src, srcstride * height);
-    } else {
-      GST_TRACE_OBJECT (dec, "Stride mismatch. Comp %d: %d != %d, copying "
-          "line by line.", comp, srcstride, deststride);
-      for (line = 0; line < height; line++) {
-        memcpy (dest, src, width);
-        dest += deststride;
-        src += srcstride;
-      }
-    }
-  }
-
-  gst_video_frame_unmap (&frame);
-}
-
-static GstFlowReturn
-open_codec (GstVP9Dec * dec, GstVideoCodecFrame * frame)
-{
-  int flags = 0;
-  vpx_codec_stream_info_t stream_info;
-  vpx_codec_caps_t caps;
-  vpx_codec_dec_cfg_t cfg;
-  vpx_codec_err_t status;
-  GstMapInfo minfo;
-
-  memset (&stream_info, 0, sizeof (stream_info));
-  memset (&cfg, 0, sizeof (cfg));
-  stream_info.sz = sizeof (stream_info);
-
-  if (!gst_buffer_map (frame->input_buffer, &minfo, GST_MAP_READ)) {
-    GST_ERROR_OBJECT (dec, "Failed to map input buffer");
-    return GST_FLOW_ERROR;
-  }
-
-  status = vpx_codec_peek_stream_info (&vpx_codec_vp9_dx_algo,
-      minfo.data, minfo.size, &stream_info);
-
-  gst_buffer_unmap (frame->input_buffer, &minfo);
-
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (dec, "VPX preprocessing error: %s",
-        gst_vpx_error_name (status));
-    gst_video_decoder_drop_frame (GST_VIDEO_DECODER (dec), frame);
-    return GST_FLOW_CUSTOM_SUCCESS_1;
-  }
-  if (!stream_info.is_kf) {
-    GST_WARNING_OBJECT (dec, "No keyframe, skipping");
-    gst_video_decoder_drop_frame (GST_VIDEO_DECODER (dec), frame);
-    return GST_FLOW_CUSTOM_SUCCESS_1;
-  }
-
   /* FIXME: peek_stream_info() does not return valid values, take input caps */
-  stream_info.w = dec->input_state->info.width;
-  stream_info.h = dec->input_state->info.height;
-
-  cfg.w = stream_info.w;
-  cfg.h = stream_info.h;
-  cfg.threads = dec->threads;
-
-  caps = vpx_codec_get_caps (&vpx_codec_vp9_dx_algo);
-
-  if (dec->post_processing) {
-    if (!(caps & VPX_CODEC_CAP_POSTPROC)) {
-      GST_WARNING_OBJECT (dec, "Decoder does not support post processing");
-    } else {
-      flags |= VPX_CODEC_USE_POSTPROC;
-    }
-  }
-
-  status =
-      vpx_codec_dec_init (&dec->decoder, &vpx_codec_vp9_dx_algo, &cfg, flags);
-  if (status != VPX_CODEC_OK) {
-    GST_ELEMENT_ERROR (dec, LIBRARY, INIT,
-        ("Failed to initialize VP9 decoder"), ("%s",
-            gst_vpx_error_name (status)));
-    return GST_FLOW_ERROR;
-  }
-
-  if ((caps & VPX_CODEC_CAP_POSTPROC) && dec->post_processing) {
-    vp8_postproc_cfg_t pp_cfg = { 0, };
-
-    pp_cfg.post_proc_flag = dec->post_processing_flags;
-    pp_cfg.deblocking_level = dec->deblocking_level;
-    pp_cfg.noise_level = dec->noise_level;
-
-    status = vpx_codec_control (&dec->decoder, VP8_SET_POSTPROC, &pp_cfg);
-    if (status != VPX_CODEC_OK) {
-      GST_WARNING_OBJECT (dec, "Couldn't set postprocessing settings: %s",
-          gst_vpx_error_name (status));
-    }
-  }
-
-  dec->decoder_inited = TRUE;
-
-  return GST_FLOW_OK;
-}
-
-static GstFlowReturn
-gst_vp9_dec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
-{
-  GstVP9Dec *dec;
-  GstFlowReturn ret = GST_FLOW_OK;
-  vpx_codec_err_t status;
-  vpx_codec_iter_t iter = NULL;
-  vpx_image_t *img;
-  long decoder_deadline = 0;
-  GstClockTimeDiff deadline;
-  GstMapInfo minfo;
-
-  GST_DEBUG_OBJECT (decoder, "handle_frame");
-
-  dec = GST_VP9_DEC (decoder);
-
-  if (!dec->decoder_inited) {
-    ret = open_codec (dec, frame);
-    if (ret == GST_FLOW_CUSTOM_SUCCESS_1)
-      return GST_FLOW_OK;
-    else if (ret != GST_FLOW_OK)
-      return ret;
-  }
-
-  deadline = gst_video_decoder_get_max_decode_time (decoder, frame);
-  if (deadline < 0) {
-    decoder_deadline = 1;
-  } else if (deadline == G_MAXINT64) {
-    decoder_deadline = 0;
-  } else {
-    decoder_deadline = MAX (1, deadline / GST_MSECOND);
-  }
-
-  if (!gst_buffer_map (frame->input_buffer, &minfo, GST_MAP_READ)) {
-    GST_ERROR_OBJECT (dec, "Failed to map input buffer");
-    return GST_FLOW_ERROR;
-  }
-
-  status = vpx_codec_decode (&dec->decoder,
-      minfo.data, minfo.size, NULL, decoder_deadline);
-
-  gst_buffer_unmap (frame->input_buffer, &minfo);
-
-  if (status) {
-    GST_VIDEO_DECODER_ERROR (decoder, 1, LIBRARY, ENCODE,
-        ("Failed to decode frame"), ("%s", gst_vpx_error_name (status)), ret);
-    return ret;
-  }
-
-  img = vpx_codec_get_frame (&dec->decoder, &iter);
-  if (img) {
-    GstVideoFormat fmt;
-
-    switch (img->fmt) {
-      case VPX_IMG_FMT_I420:
-        fmt = GST_VIDEO_FORMAT_I420;
-        break;
-      case VPX_IMG_FMT_YV12:
-        fmt = GST_VIDEO_FORMAT_YV12;
-        break;
-      case VPX_IMG_FMT_I422:
-        fmt = GST_VIDEO_FORMAT_Y42B;
-        break;
-      case VPX_IMG_FMT_I444:
-        fmt = GST_VIDEO_FORMAT_Y444;
-        break;
-      default:
-        vpx_img_free (img);
-        GST_ELEMENT_ERROR (decoder, LIBRARY, ENCODE,
-            ("Failed to decode frame"), ("Unsupported color format %d",
-                img->fmt));
-        return GST_FLOW_ERROR;
-        break;
-    }
-
-    if (!dec->output_state || dec->output_state->info.finfo->format != fmt ||
-        dec->output_state->info.width != img->d_w ||
-        dec->output_state->info.height != img->d_h) {
-      gboolean send_tags = !dec->output_state;
-
-      if (dec->output_state)
-        gst_video_codec_state_unref (dec->output_state);
-
-      dec->output_state =
-          gst_video_decoder_set_output_state (GST_VIDEO_DECODER (dec),
-          fmt, img->d_w, img->d_h, dec->input_state);
-      gst_video_decoder_negotiate (GST_VIDEO_DECODER (dec));
-
-      if (send_tags)
-        gst_vp9_dec_send_tags (dec);
-    }
-
-    if (deadline < 0) {
-      GST_LOG_OBJECT (dec, "Skipping late frame (%f s past deadline)",
-          (double) -deadline / GST_SECOND);
-      gst_video_decoder_drop_frame (decoder, frame);
-    } else {
-      ret = gst_video_decoder_allocate_output_frame (decoder, frame);
-
-      if (ret == GST_FLOW_OK) {
-        gst_vp9_dec_image_to_buffer (dec, img, frame->output_buffer);
-        ret = gst_video_decoder_finish_frame (decoder, frame);
-      } else {
-        gst_video_decoder_drop_frame (decoder, frame);
-      }
-    }
-
-    vpx_img_free (img);
-
-    while ((img = vpx_codec_get_frame (&dec->decoder, &iter))) {
-      GST_WARNING_OBJECT (decoder, "Multiple decoded frames... dropping");
-      vpx_img_free (img);
-    }
-  } else {
-    /* Invisible frame */
-    GST_VIDEO_CODEC_FRAME_SET_DECODE_ONLY (frame);
-    gst_video_decoder_finish_frame (decoder, frame);
-  }
-
-  return ret;
+  stream_info->w = dec->input_state->info.width;
+  stream_info->h = dec->input_state->info.height;
+  return;
 }
 
 static gboolean
-gst_vp9_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query)
+gst_vp9_dec_get_valid_format (GstVPXDec * dec, vpx_image_t * img,
+    GstVideoFormat * fmt)
 {
-  GstBufferPool *pool;
-  GstStructure *config;
+  switch (img->fmt) {
+    case VPX_IMG_FMT_I420:
+      *fmt = GST_VIDEO_FORMAT_I420;
+      return TRUE;
 
-  if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (bdec, query))
-    return FALSE;
+    case VPX_IMG_FMT_YV12:
+      *fmt = GST_VIDEO_FORMAT_YV12;
+      return TRUE;
 
-  g_assert (gst_query_get_n_allocation_pools (query) > 0);
-  gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL);
-  g_assert (pool != NULL);
+    case VPX_IMG_FMT_I422:
+      *fmt = GST_VIDEO_FORMAT_Y42B;
+      return TRUE;
 
-  config = gst_buffer_pool_get_config (pool);
-  if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) {
-    gst_buffer_pool_config_add_option (config,
-        GST_BUFFER_POOL_OPTION_VIDEO_META);
+    case VPX_IMG_FMT_I444:
+      *fmt = GST_VIDEO_FORMAT_Y444;
+      return TRUE;
+
+    default:
+      return FALSE;
   }
-  gst_buffer_pool_set_config (pool, config);
-  gst_object_unref (pool);
+}
 
-  return TRUE;
+static void
+gst_vp9_dec_handle_resolution_change (GstVPXDec * dec, vpx_image_t * img,
+    GstVideoFormat fmt)
+{
+  GstVPXDecClass *vpxclass = GST_VPX_DEC_GET_CLASS (dec);
+
+  if (!dec->output_state || dec->output_state->info.finfo->format != fmt ||
+      dec->output_state->info.width != img->d_w ||
+      dec->output_state->info.height != img->d_h) {
+    gboolean send_tags = !dec->output_state;
+
+    if (dec->output_state)
+      gst_video_codec_state_unref (dec->output_state);
+
+    dec->output_state =
+        gst_video_decoder_set_output_state (GST_VIDEO_DECODER (dec),
+        fmt, img->d_w, img->d_h, dec->input_state);
+    gst_video_decoder_negotiate (GST_VIDEO_DECODER (dec));
+
+    if (send_tags)
+      vpxclass->send_tags (dec);
+  }
 }
 
 #endif /* HAVE_VP9_DECODER */
diff --git a/ext/vpx/gstvp9dec.h b/ext/vpx/gstvp9dec.h
index 8cd69ba..41332f3 100644
--- a/ext/vpx/gstvp9dec.h
+++ b/ext/vpx/gstvp9dec.h
@@ -31,6 +31,7 @@
 
 #include <gst/gst.h>
 #include <gst/video/gstvideodecoder.h>
+#include <gstvpxdec.h>
 
 /* FIXME: Undef HAVE_CONFIG_H because vpx_codec.h uses it,
  * which causes compilation failures */
@@ -59,28 +60,12 @@
 
 struct _GstVP9Dec
 {
-  GstVideoDecoder base_video_decoder;
-
-  /* < private > */
-  vpx_codec_ctx_t decoder;
-
-  /* state */
-  gboolean decoder_inited;
-
-  /* properties */
-  gboolean post_processing;
-  enum vp8_postproc_level post_processing_flags;
-  gint deblocking_level;
-  gint noise_level;
-  gint threads;
-
-  GstVideoCodecState *input_state;
-  GstVideoCodecState *output_state;
+  GstVPXDec base_vpx_decoder;
 };
 
 struct _GstVP9DecClass
 {
-  GstVideoDecoderClass base_video_decoder_class;
+  GstVPXDecClass base_vpx_class;
 };
 
 GType gst_vp9_dec_get_type (void);
diff --git a/ext/vpx/gstvp9enc.c b/ext/vpx/gstvp9enc.c
index e8e347f..b8256ae 100644
--- a/ext/vpx/gstvp9enc.c
+++ b/ext/vpx/gstvp9enc.c
@@ -69,291 +69,6 @@
 GST_DEBUG_CATEGORY_STATIC (gst_vp9enc_debug);
 #define GST_CAT_DEFAULT gst_vp9enc_debug
 
-/* From vp9/vp9_cx_iface.c */
-#define DEFAULT_PROFILE 0
-
-#define DEFAULT_RC_END_USAGE VPX_VBR
-#define DEFAULT_RC_TARGET_BITRATE 256000
-#define DEFAULT_RC_MIN_QUANTIZER 4
-#define DEFAULT_RC_MAX_QUANTIZER 63
-
-#define DEFAULT_RC_DROPFRAME_THRESH 0
-#define DEFAULT_RC_RESIZE_ALLOWED 0
-#define DEFAULT_RC_RESIZE_UP_THRESH 30
-#define DEFAULT_RC_RESIZE_DOWN_THRESH 60
-#define DEFAULT_RC_UNDERSHOOT_PCT 100
-#define DEFAULT_RC_OVERSHOOT_PCT 100
-#define DEFAULT_RC_BUF_SZ 6000
-#define DEFAULT_RC_BUF_INITIAL_SZ 4000
-#define DEFAULT_RC_BUF_OPTIMAL_SZ 5000
-#define DEFAULT_RC_2PASS_VBR_BIAS_PCT 50
-#define DEFAULT_RC_2PASS_VBR_MINSECTION_PCT 0
-#define DEFAULT_RC_2PASS_VBR_MAXSECTION_PCT 400
-
-#define DEFAULT_KF_MODE VPX_KF_AUTO
-#define DEFAULT_KF_MAX_DIST 128
-
-#define DEFAULT_MULTIPASS_MODE VPX_RC_ONE_PASS
-#define DEFAULT_MULTIPASS_CACHE_FILE "multipass.cache"
-
-#define DEFAULT_TS_NUMBER_LAYERS 1
-#define DEFAULT_TS_TARGET_BITRATE NULL
-#define DEFAULT_TS_RATE_DECIMATOR NULL
-#define DEFAULT_TS_PERIODICITY 0
-#define DEFAULT_TS_LAYER_ID NULL
-
-#define DEFAULT_ERROR_RESILIENT 0
-#define DEFAULT_LAG_IN_FRAMES 0
-
-#define DEFAULT_THREADS 0
-
-#define DEFAULT_H_SCALING_MODE VP8E_NORMAL
-#define DEFAULT_V_SCALING_MODE VP8E_NORMAL
-#define DEFAULT_CPU_USED 0
-#define DEFAULT_ENABLE_AUTO_ALT_REF FALSE
-#define DEFAULT_DEADLINE VPX_DL_BEST_QUALITY
-#define DEFAULT_NOISE_SENSITIVITY 0
-#define DEFAULT_SHARPNESS 0
-#define DEFAULT_STATIC_THRESHOLD 0
-#define DEFAULT_TOKEN_PARTITIONS 0
-#define DEFAULT_ARNR_MAXFRAMES 0
-#define DEFAULT_ARNR_STRENGTH 3
-#define DEFAULT_ARNR_TYPE 3
-#define DEFAULT_TUNING VP8_TUNE_PSNR
-#define DEFAULT_CQ_LEVEL 10
-#define DEFAULT_MAX_INTRA_BITRATE_PCT 0
-#define DEFAULT_TIMEBASE_N 0
-#define DEFAULT_TIMEBASE_D 1
-
-enum
-{
-  PROP_0,
-  PROP_RC_END_USAGE,
-  PROP_RC_TARGET_BITRATE,
-  PROP_RC_MIN_QUANTIZER,
-  PROP_RC_MAX_QUANTIZER,
-  PROP_RC_DROPFRAME_THRESH,
-  PROP_RC_RESIZE_ALLOWED,
-  PROP_RC_RESIZE_UP_THRESH,
-  PROP_RC_RESIZE_DOWN_THRESH,
-  PROP_RC_UNDERSHOOT_PCT,
-  PROP_RC_OVERSHOOT_PCT,
-  PROP_RC_BUF_SZ,
-  PROP_RC_BUF_INITIAL_SZ,
-  PROP_RC_BUF_OPTIMAL_SZ,
-  PROP_RC_2PASS_VBR_BIAS_PCT,
-  PROP_RC_2PASS_VBR_MINSECTION_PCT,
-  PROP_RC_2PASS_VBR_MAXSECTION_PCT,
-  PROP_KF_MODE,
-  PROP_KF_MAX_DIST,
-  PROP_TS_NUMBER_LAYERS,
-  PROP_TS_TARGET_BITRATE,
-  PROP_TS_RATE_DECIMATOR,
-  PROP_TS_PERIODICITY,
-  PROP_TS_LAYER_ID,
-  PROP_MULTIPASS_MODE,
-  PROP_MULTIPASS_CACHE_FILE,
-  PROP_ERROR_RESILIENT,
-  PROP_LAG_IN_FRAMES,
-  PROP_THREADS,
-  PROP_DEADLINE,
-  PROP_H_SCALING_MODE,
-  PROP_V_SCALING_MODE,
-  PROP_CPU_USED,
-  PROP_ENABLE_AUTO_ALT_REF,
-  PROP_NOISE_SENSITIVITY,
-  PROP_SHARPNESS,
-  PROP_STATIC_THRESHOLD,
-  PROP_TOKEN_PARTITIONS,
-  PROP_ARNR_MAXFRAMES,
-  PROP_ARNR_STRENGTH,
-  PROP_ARNR_TYPE,
-  PROP_TUNING,
-  PROP_CQ_LEVEL,
-  PROP_MAX_INTRA_BITRATE_PCT,
-  PROP_TIMEBASE
-};
-
-#define GST_VP9_ENC_END_USAGE_TYPE (gst_vp9_enc_end_usage_get_type())
-static GType
-gst_vp9_enc_end_usage_get_type (void)
-{
-  static const GEnumValue values[] = {
-    {VPX_VBR, "Variable Bit Rate (VBR) mode", "vbr"},
-    {VPX_CBR, "Constant Bit Rate (CBR) mode", "cbr"},
-    {VPX_CQ, "Constant Quality Mode (CQ) mode", "cq"},
-    {0, NULL, NULL}
-  };
-  static volatile GType id = 0;
-
-  if (g_once_init_enter ((gsize *) & id)) {
-    GType _id;
-
-    _id = g_enum_register_static ("GstVP9EncEndUsage", values);
-
-    g_once_init_leave ((gsize *) & id, _id);
-  }
-
-  return id;
-}
-
-#define GST_VP9_ENC_MULTIPASS_MODE_TYPE (gst_vp9_enc_multipass_mode_get_type())
-static GType
-gst_vp9_enc_multipass_mode_get_type (void)
-{
-  static const GEnumValue values[] = {
-    {VPX_RC_ONE_PASS, "One pass encoding (default)", "one-pass"},
-    {VPX_RC_FIRST_PASS, "First pass of multipass encoding", "first-pass"},
-    {VPX_RC_LAST_PASS, "Last pass of multipass encoding", "last-pass"},
-    {0, NULL, NULL}
-  };
-  static volatile GType id = 0;
-
-  if (g_once_init_enter ((gsize *) & id)) {
-    GType _id;
-
-    _id = g_enum_register_static ("GstVP9EncMultipassMode", values);
-
-    g_once_init_leave ((gsize *) & id, _id);
-  }
-
-  return id;
-}
-
-#define GST_VP9_ENC_KF_MODE_TYPE (gst_vp9_enc_kf_mode_get_type())
-static GType
-gst_vp9_enc_kf_mode_get_type (void)
-{
-  static const GEnumValue values[] = {
-    {VPX_KF_AUTO, "Determine optimal placement automatically", "auto"},
-    {VPX_KF_DISABLED, "Don't automatically place keyframes", "disabled"},
-    {0, NULL, NULL}
-  };
-  static volatile GType id = 0;
-
-  if (g_once_init_enter ((gsize *) & id)) {
-    GType _id;
-
-    _id = g_enum_register_static ("GstVP9EncKfMode", values);
-
-    g_once_init_leave ((gsize *) & id, _id);
-  }
-
-  return id;
-}
-
-#define GST_VP9_ENC_TUNING_TYPE (gst_vp9_enc_tuning_get_type())
-static GType
-gst_vp9_enc_tuning_get_type (void)
-{
-  static const GEnumValue values[] = {
-    {VP8_TUNE_PSNR, "Tune for PSNR", "psnr"},
-    {VP8_TUNE_SSIM, "Tune for SSIM", "ssim"},
-    {0, NULL, NULL}
-  };
-  static volatile GType id = 0;
-
-  if (g_once_init_enter ((gsize *) & id)) {
-    GType _id;
-
-    _id = g_enum_register_static ("GstVP9EncTuning", values);
-
-    g_once_init_leave ((gsize *) & id, _id);
-  }
-
-  return id;
-}
-
-#define GST_VP9_ENC_SCALING_MODE_TYPE (gst_vp9_enc_scaling_mode_get_type())
-static GType
-gst_vp9_enc_scaling_mode_get_type (void)
-{
-  static const GEnumValue values[] = {
-    {VP8E_NORMAL, "Normal", "normal"},
-    {VP8E_FOURFIVE, "4:5", "4:5"},
-    {VP8E_THREEFIVE, "3:5", "3:5"},
-    {VP8E_ONETWO, "1:2", "1:2"},
-    {0, NULL, NULL}
-  };
-  static volatile GType id = 0;
-
-  if (g_once_init_enter ((gsize *) & id)) {
-    GType _id;
-
-    _id = g_enum_register_static ("GstVP9EncScalingMode", values);
-
-    g_once_init_leave ((gsize *) & id, _id);
-  }
-
-  return id;
-}
-
-#define GST_VP9_ENC_TOKEN_PARTITIONS_TYPE (gst_vp9_enc_token_partitions_get_type())
-static GType
-gst_vp9_enc_token_partitions_get_type (void)
-{
-  static const GEnumValue values[] = {
-    {VP8_ONE_TOKENPARTITION, "One token partition", "1"},
-    {VP8_TWO_TOKENPARTITION, "Two token partitions", "2"},
-    {VP8_FOUR_TOKENPARTITION, "Four token partitions", "4"},
-    {VP8_EIGHT_TOKENPARTITION, "Eight token partitions", "8"},
-    {0, NULL, NULL}
-  };
-  static volatile GType id = 0;
-
-  if (g_once_init_enter ((gsize *) & id)) {
-    GType _id;
-
-    _id = g_enum_register_static ("GstVP9EncTokenPartitions", values);
-
-    g_once_init_leave ((gsize *) & id, _id);
-  }
-
-  return id;
-}
-
-#define GST_VP9_ENC_ER_FLAGS_TYPE (gst_vp9_enc_er_flags_get_type())
-static GType
-gst_vp9_enc_er_flags_get_type (void)
-{
-  static const GFlagsValue values[] = {
-    {VPX_ERROR_RESILIENT_DEFAULT, "Default error resilience", "default"},
-    {VPX_ERROR_RESILIENT_PARTITIONS,
-        "Allow partitions to be decoded independently", "partitions"},
-    {0, NULL, NULL}
-  };
-  static volatile GType id = 0;
-
-  if (g_once_init_enter ((gsize *) & id)) {
-    GType _id;
-
-    _id = g_flags_register_static ("GstVP9EncErFlags", values);
-
-    g_once_init_leave ((gsize *) & id, _id);
-  }
-
-  return id;
-}
-
-static void gst_vp9_enc_finalize (GObject * object);
-static void gst_vp9_enc_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-static void gst_vp9_enc_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-
-static gboolean gst_vp9_enc_start (GstVideoEncoder * encoder);
-static gboolean gst_vp9_enc_stop (GstVideoEncoder * encoder);
-static gboolean gst_vp9_enc_set_format (GstVideoEncoder *
-    video_encoder, GstVideoCodecState * state);
-static GstFlowReturn gst_vp9_enc_finish (GstVideoEncoder * video_encoder);
-static gboolean gst_vp9_enc_flush (GstVideoEncoder * video_encoder);
-static GstFlowReturn gst_vp9_enc_drain (GstVideoEncoder * video_encoder);
-static GstFlowReturn gst_vp9_enc_handle_frame (GstVideoEncoder *
-    video_encoder, GstVideoCodecFrame * frame);
-static gboolean gst_vp9_enc_sink_event (GstVideoEncoder *
-    video_encoder, GstEvent * event);
-static gboolean gst_vp9_enc_propose_allocation (GstVideoEncoder * encoder,
-    GstQuery * query);
 
 /* FIXME: Y42B and Y444 do not work yet it seems */
 static GstStaticPadTemplate gst_vp9_enc_sink_template =
@@ -372,24 +87,29 @@
     );
 
 #define parent_class gst_vp9_enc_parent_class
-G_DEFINE_TYPE_WITH_CODE (GstVP9Enc, gst_vp9_enc, GST_TYPE_VIDEO_ENCODER,
-    G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL);
-    G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL););
+G_DEFINE_TYPE (GstVP9Enc, gst_vp9_enc, GST_TYPE_VPX_ENC);
+
+static vpx_codec_iface_t *gst_vp9_enc_get_algo (GstVPXEnc * enc);
+static gboolean gst_vp9_enc_enable_scaling (GstVPXEnc * enc);
+static void gst_vp9_enc_set_image_format (GstVPXEnc * enc, vpx_image_t * image);
+static GstCaps *gst_vp9_enc_get_new_simple_caps (GstVPXEnc * enc);
+static void gst_vp9_enc_set_stream_info (GstVPXEnc * enc, GstCaps * caps,
+    GstVideoInfo * info);
+static void *gst_vp9_enc_process_frame_user_data (GstVPXEnc * enc,
+    GstVideoCodecFrame * frame);
+static GstFlowReturn gst_vp9_enc_handle_invisible_frame_buffer (GstVPXEnc * enc,
+    void *user_data, GstBuffer * buffer);
+static void gst_vp9_enc_set_frame_user_data (GstVPXEnc * enc,
+    GstVideoCodecFrame * frame, vpx_image_t * image);
 
 static void
 gst_vp9_enc_class_init (GstVP9EncClass * klass)
 {
-  GObjectClass *gobject_class;
   GstElementClass *element_class;
-  GstVideoEncoderClass *video_encoder_class;
+  GstVPXEncClass *vpx_encoder_class;
 
-  gobject_class = G_OBJECT_CLASS (klass);
   element_class = GST_ELEMENT_CLASS (klass);
-  video_encoder_class = GST_VIDEO_ENCODER_CLASS (klass);
-
-  gobject_class->set_property = gst_vp9_enc_set_property;
-  gobject_class->get_property = gst_vp9_enc_get_property;
-  gobject_class->finalize = gst_vp9_enc_finalize;
+  vpx_encoder_class = GST_VPX_ENC_CLASS (klass);
 
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&gst_vp9_enc_src_template));
@@ -402,292 +122,16 @@
       "Encode VP9 video streams", "David Schleef <ds@entropywave.com>, "
       "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
 
-  video_encoder_class->start = gst_vp9_enc_start;
-  video_encoder_class->stop = gst_vp9_enc_stop;
-  video_encoder_class->handle_frame = gst_vp9_enc_handle_frame;
-  video_encoder_class->set_format = gst_vp9_enc_set_format;
-  video_encoder_class->flush = gst_vp9_enc_flush;
-  video_encoder_class->finish = gst_vp9_enc_finish;
-  video_encoder_class->sink_event = gst_vp9_enc_sink_event;
-  video_encoder_class->propose_allocation = gst_vp9_enc_propose_allocation;
-
-  g_object_class_install_property (gobject_class, PROP_RC_END_USAGE,
-      g_param_spec_enum ("end-usage", "Rate control mode",
-          "Rate control mode",
-          GST_VP9_ENC_END_USAGE_TYPE, DEFAULT_RC_END_USAGE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_TARGET_BITRATE,
-      g_param_spec_int ("target-bitrate", "Target bitrate",
-          "Target bitrate (in bits/sec)",
-          0, G_MAXINT, DEFAULT_RC_TARGET_BITRATE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_MIN_QUANTIZER,
-      g_param_spec_int ("min-quantizer", "Minimum Quantizer",
-          "Minimum Quantizer (best)",
-          0, 63, DEFAULT_RC_MIN_QUANTIZER,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_MAX_QUANTIZER,
-      g_param_spec_int ("max-quantizer", "Maximum Quantizer",
-          "Maximum Quantizer (worst)",
-          0, 63, DEFAULT_RC_MAX_QUANTIZER,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_DROPFRAME_THRESH,
-      g_param_spec_int ("dropframe-threshold", "Drop Frame Threshold",
-          "Temporal resampling threshold (buf %)",
-          0, 100, DEFAULT_RC_DROPFRAME_THRESH,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_RESIZE_ALLOWED,
-      g_param_spec_boolean ("resize-allowed", "Resize Allowed",
-          "Allow spatial resampling",
-          DEFAULT_RC_RESIZE_ALLOWED,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_RESIZE_UP_THRESH,
-      g_param_spec_int ("resize-up-threshold", "Resize Up Threshold",
-          "Upscale threshold (buf %)",
-          0, 100, DEFAULT_RC_RESIZE_UP_THRESH,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_RESIZE_DOWN_THRESH,
-      g_param_spec_int ("resize-down-threshold", "Resize Down Threshold",
-          "Downscale threshold (buf %)",
-          0, 100, DEFAULT_RC_RESIZE_DOWN_THRESH,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_UNDERSHOOT_PCT,
-      g_param_spec_int ("undershoot", "Undershoot PCT",
-          "Datarate undershoot (min) target (%)",
-          0, 1000, DEFAULT_RC_UNDERSHOOT_PCT,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_OVERSHOOT_PCT,
-      g_param_spec_int ("overshoot", "Overshoot PCT",
-          "Datarate overshoot (max) target (%)",
-          0, 1000, DEFAULT_RC_OVERSHOOT_PCT,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_BUF_SZ,
-      g_param_spec_int ("buffer-size", "Buffer size",
-          "Client buffer size (ms)",
-          0, G_MAXINT, DEFAULT_RC_BUF_SZ,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_BUF_INITIAL_SZ,
-      g_param_spec_int ("buffer-initial-size", "Buffer initial size",
-          "Initial client buffer size (ms)",
-          0, G_MAXINT, DEFAULT_RC_BUF_INITIAL_SZ,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_BUF_OPTIMAL_SZ,
-      g_param_spec_int ("buffer-optimal-size", "Buffer optimal size",
-          "Optimal client buffer size (ms)",
-          0, G_MAXINT, DEFAULT_RC_BUF_OPTIMAL_SZ,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_RC_2PASS_VBR_BIAS_PCT,
-      g_param_spec_int ("twopass-vbr-bias", "2-pass VBR bias",
-          "CBR/VBR bias (0=CBR, 100=VBR)",
-          0, 100, DEFAULT_RC_2PASS_VBR_BIAS_PCT,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class,
-      PROP_RC_2PASS_VBR_MINSECTION_PCT,
-      g_param_spec_int ("twopass-vbr-minsection", "2-pass GOP min bitrate",
-          "GOP minimum bitrate (% target)", 0, G_MAXINT,
-          DEFAULT_RC_2PASS_VBR_MINSECTION_PCT,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class,
-      PROP_RC_2PASS_VBR_MAXSECTION_PCT,
-      g_param_spec_int ("twopass-vbr-maxsection", "2-pass GOP max bitrate",
-          "GOP maximum bitrate (% target)", 0, G_MAXINT,
-          DEFAULT_RC_2PASS_VBR_MINSECTION_PCT,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_KF_MODE,
-      g_param_spec_enum ("keyframe-mode", "Keyframe Mode",
-          "Keyframe placement",
-          GST_VP9_ENC_KF_MODE_TYPE, DEFAULT_KF_MODE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_KF_MAX_DIST,
-      g_param_spec_int ("keyframe-max-dist", "Keyframe max distance",
-          "Maximum distance between keyframes (number of frames)",
-          0, G_MAXINT, DEFAULT_KF_MAX_DIST,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_MULTIPASS_MODE,
-      g_param_spec_enum ("multipass-mode", "Multipass Mode",
-          "Multipass encode mode",
-          GST_VP9_ENC_MULTIPASS_MODE_TYPE, DEFAULT_MULTIPASS_MODE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_MULTIPASS_CACHE_FILE,
-      g_param_spec_string ("multipass-cache-file", "Multipass Cache File",
-          "Multipass cache file. "
-          "If stream caps reinited, multiple files will be created: "
-          "file, file.1, file.2, ... and so on.",
-          DEFAULT_MULTIPASS_CACHE_FILE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_TS_NUMBER_LAYERS,
-      g_param_spec_int ("temporal-scalability-number-layers",
-          "Number of coding layers", "Number of coding layers to use", 1, 5,
-          DEFAULT_TS_NUMBER_LAYERS,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_TS_TARGET_BITRATE,
-      g_param_spec_value_array ("temporal-scalability-target-bitrate",
-          "Coding layer target bitrates",
-          "Target bitrates for coding layers (one per layer, decreasing)",
-          g_param_spec_int ("target-bitrate", "Target bitrate",
-              "Target bitrate", 0, G_MAXINT, DEFAULT_RC_TARGET_BITRATE,
-              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_TS_RATE_DECIMATOR,
-      g_param_spec_value_array ("temporal-scalability-rate-decimator",
-          "Coding layer rate decimator",
-          "Rate decimation factors for each layer",
-          g_param_spec_int ("rate-decimator", "Rate decimator",
-              "Rate decimator", 0, 1000000000, 0,
-              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_TS_PERIODICITY,
-      g_param_spec_int ("temporal-scalability-periodicity",
-          "Coding layer periodicity",
-          "Length of sequence that defines layer membership periodicity", 0, 16,
-          DEFAULT_TS_PERIODICITY,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_TS_LAYER_ID,
-      g_param_spec_value_array ("temporal-scalability-layer-id",
-          "Coding layer identification",
-          "Sequence defining coding layer membership",
-          g_param_spec_int ("layer-id", "Layer ID", "Layer ID", 0, 4, 0,
-              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  g_object_class_install_property (gobject_class, PROP_LAG_IN_FRAMES,
-      g_param_spec_int ("lag-in-frames", "Lag in frames",
-          "Maximum number of frames to lag",
-          0, 25, DEFAULT_LAG_IN_FRAMES,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_ERROR_RESILIENT,
-      g_param_spec_flags ("error-resilient", "Error resilient",
-          "Error resilience flags",
-          GST_VP9_ENC_ER_FLAGS_TYPE, DEFAULT_ERROR_RESILIENT,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_THREADS,
-      g_param_spec_int ("threads", "Threads",
-          "Number of threads to use",
-          0, 64, DEFAULT_THREADS,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_DEADLINE,
-      g_param_spec_int64 ("deadline", "Deadline",
-          "Deadline per frame (usec, 0=disabled)",
-          0, G_MAXINT64, DEFAULT_DEADLINE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_H_SCALING_MODE,
-      g_param_spec_enum ("horizontal-scaling-mode", "Horizontal scaling mode",
-          "Horizontal scaling mode",
-          GST_VP9_ENC_SCALING_MODE_TYPE, DEFAULT_H_SCALING_MODE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_V_SCALING_MODE,
-      g_param_spec_enum ("vertical-scaling-mode", "Vertical scaling mode",
-          "Vertical scaling mode",
-          GST_VP9_ENC_SCALING_MODE_TYPE, DEFAULT_V_SCALING_MODE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_CPU_USED,
-      g_param_spec_int ("cpu-used", "CPU used",
-          "CPU used",
-          -16, 16, DEFAULT_CPU_USED,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_ENABLE_AUTO_ALT_REF,
-      g_param_spec_boolean ("auto-alt-ref", "Auto alt reference frames",
-          "Automatically generate AltRef frames",
-          DEFAULT_ENABLE_AUTO_ALT_REF,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_NOISE_SENSITIVITY,
-      g_param_spec_int ("noise-sensitivity", "Noise sensitivity",
-          "Noise sensisivity (frames to blur)",
-          0, 6, DEFAULT_NOISE_SENSITIVITY,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_SHARPNESS,
-      g_param_spec_int ("sharpness", "Sharpness",
-          "Filter sharpness",
-          0, 7, DEFAULT_SHARPNESS,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_STATIC_THRESHOLD,
-      g_param_spec_int ("static-threshold", "Static Threshold",
-          "Motion detection threshold",
-          0, G_MAXINT, DEFAULT_STATIC_THRESHOLD,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_TOKEN_PARTITIONS,
-      g_param_spec_enum ("token-partitions", "Token partitions",
-          "Number of token partitions",
-          GST_VP9_ENC_TOKEN_PARTITIONS_TYPE, DEFAULT_TOKEN_PARTITIONS,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_ARNR_MAXFRAMES,
-      g_param_spec_int ("arnr-maxframes", "AltRef max frames",
-          "AltRef maximum number of frames",
-          0, 15, DEFAULT_ARNR_MAXFRAMES,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_ARNR_STRENGTH,
-      g_param_spec_int ("arnr-strength", "AltRef strength",
-          "AltRef strength",
-          0, 6, DEFAULT_ARNR_STRENGTH,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_ARNR_TYPE,
-      g_param_spec_int ("arnr-type", "AltRef type",
-          "AltRef type",
-          1, 3, DEFAULT_ARNR_TYPE,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
-              G_PARAM_DEPRECATED)));
-
-  g_object_class_install_property (gobject_class, PROP_TUNING,
-      g_param_spec_enum ("tuning", "Tuning",
-          "Tuning",
-          GST_VP9_ENC_TUNING_TYPE, DEFAULT_TUNING,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_CQ_LEVEL,
-      g_param_spec_int ("cq-level", "Constrained quality level",
-          "Constrained quality level",
-          0, 63, DEFAULT_CQ_LEVEL,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_MAX_INTRA_BITRATE_PCT,
-      g_param_spec_int ("max-intra-bitrate", "Max Intra bitrate",
-          "Maximum Intra frame bitrate",
-          0, G_MAXINT, DEFAULT_MAX_INTRA_BITRATE_PCT,
-          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-
-  g_object_class_install_property (gobject_class, PROP_TIMEBASE,
-      gst_param_spec_fraction ("timebase", "Shortest interframe time",
-          "Fraction of one second that is the shortest interframe time - normally left as zero which will default to the framerate",
-          0, 1, G_MAXINT, 1, DEFAULT_TIMEBASE_N, DEFAULT_TIMEBASE_D,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  vpx_encoder_class->get_algo = gst_vp9_enc_get_algo;
+  vpx_encoder_class->enable_scaling = gst_vp9_enc_enable_scaling;
+  vpx_encoder_class->set_image_format = gst_vp9_enc_set_image_format;
+  vpx_encoder_class->get_new_vpx_caps = gst_vp9_enc_get_new_simple_caps;
+  vpx_encoder_class->set_stream_info = gst_vp9_enc_set_stream_info;
+  vpx_encoder_class->process_frame_user_data =
+      gst_vp9_enc_process_frame_user_data;
+  vpx_encoder_class->handle_invisible_frame_buffer =
+      gst_vp9_enc_handle_invisible_frame_buffer;
+  vpx_encoder_class->set_frame_user_data = gst_vp9_enc_set_frame_user_data;
 
   GST_DEBUG_CATEGORY_INIT (gst_vp9enc_debug, "vp9enc", 0, "VP9 Encoder");
 }
@@ -696,1015 +140,37 @@
 gst_vp9_enc_init (GstVP9Enc * gst_vp9_enc)
 {
   vpx_codec_err_t status;
-
-  GST_DEBUG_OBJECT (gst_vp9_enc, "init");
-  GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_ENCODER_SINK_PAD (gst_vp9_enc));
-
+  GstVPXEnc *gst_vpx_enc = GST_VPX_ENC (gst_vp9_enc);
+  GST_DEBUG_OBJECT (gst_vp9_enc, "gst_vp9_enc_init");
   status =
-      vpx_codec_enc_config_default (&vpx_codec_vp9_cx_algo, &gst_vp9_enc->cfg,
-      0);
+      vpx_codec_enc_config_default (gst_vp9_enc_get_algo (gst_vpx_enc),
+      &gst_vpx_enc->cfg, 0);
   if (status != VPX_CODEC_OK) {
-    GST_ERROR_OBJECT (gst_vp9_enc,
+    GST_ERROR_OBJECT (gst_vpx_enc,
         "Failed to get default encoder configuration: %s",
         gst_vpx_error_name (status));
-    gst_vp9_enc->have_default_config = FALSE;
+    gst_vpx_enc->have_default_config = FALSE;
   } else {
-    gst_vp9_enc->have_default_config = TRUE;
-  }
-
-  gst_vp9_enc->cfg.rc_end_usage = DEFAULT_RC_END_USAGE;
-  gst_vp9_enc->cfg.rc_target_bitrate = DEFAULT_RC_TARGET_BITRATE / 1000;
-  gst_vp9_enc->rc_target_bitrate_set = FALSE;
-  gst_vp9_enc->cfg.rc_min_quantizer = DEFAULT_RC_MIN_QUANTIZER;
-  gst_vp9_enc->cfg.rc_max_quantizer = DEFAULT_RC_MAX_QUANTIZER;
-  gst_vp9_enc->cfg.rc_dropframe_thresh = DEFAULT_RC_DROPFRAME_THRESH;
-  gst_vp9_enc->cfg.rc_resize_allowed = DEFAULT_RC_RESIZE_ALLOWED;
-  gst_vp9_enc->cfg.rc_resize_up_thresh = DEFAULT_RC_RESIZE_UP_THRESH;
-  gst_vp9_enc->cfg.rc_resize_down_thresh = DEFAULT_RC_RESIZE_DOWN_THRESH;
-  gst_vp9_enc->cfg.rc_undershoot_pct = DEFAULT_RC_UNDERSHOOT_PCT;
-  gst_vp9_enc->cfg.rc_overshoot_pct = DEFAULT_RC_OVERSHOOT_PCT;
-  gst_vp9_enc->cfg.rc_buf_sz = DEFAULT_RC_BUF_SZ;
-  gst_vp9_enc->cfg.rc_buf_initial_sz = DEFAULT_RC_BUF_INITIAL_SZ;
-  gst_vp9_enc->cfg.rc_buf_optimal_sz = DEFAULT_RC_BUF_OPTIMAL_SZ;
-  gst_vp9_enc->cfg.rc_2pass_vbr_bias_pct = DEFAULT_RC_2PASS_VBR_BIAS_PCT;
-  gst_vp9_enc->cfg.rc_2pass_vbr_minsection_pct =
-      DEFAULT_RC_2PASS_VBR_MINSECTION_PCT;
-  gst_vp9_enc->cfg.rc_2pass_vbr_maxsection_pct =
-      DEFAULT_RC_2PASS_VBR_MAXSECTION_PCT;
-  gst_vp9_enc->cfg.kf_mode = DEFAULT_KF_MODE;
-  gst_vp9_enc->cfg.kf_max_dist = DEFAULT_KF_MAX_DIST;
-  gst_vp9_enc->cfg.g_pass = DEFAULT_MULTIPASS_MODE;
-  gst_vp9_enc->multipass_cache_prefix = g_strdup (DEFAULT_MULTIPASS_CACHE_FILE);
-  gst_vp9_enc->multipass_cache_file = NULL;
-  gst_vp9_enc->multipass_cache_idx = 0;
-  gst_vp9_enc->cfg.ts_number_layers = DEFAULT_TS_NUMBER_LAYERS;
-  gst_vp9_enc->n_ts_target_bitrate = 0;
-  gst_vp9_enc->n_ts_rate_decimator = 0;
-  gst_vp9_enc->cfg.ts_periodicity = DEFAULT_TS_PERIODICITY;
-  gst_vp9_enc->n_ts_layer_id = 0;
-  gst_vp9_enc->cfg.g_error_resilient = DEFAULT_ERROR_RESILIENT;
-  gst_vp9_enc->cfg.g_lag_in_frames = DEFAULT_LAG_IN_FRAMES;
-  gst_vp9_enc->cfg.g_threads = DEFAULT_THREADS;
-  gst_vp9_enc->deadline = DEFAULT_DEADLINE;
-  gst_vp9_enc->h_scaling_mode = DEFAULT_H_SCALING_MODE;
-  gst_vp9_enc->v_scaling_mode = DEFAULT_V_SCALING_MODE;
-  gst_vp9_enc->cpu_used = DEFAULT_CPU_USED;
-  gst_vp9_enc->enable_auto_alt_ref = DEFAULT_ENABLE_AUTO_ALT_REF;
-  gst_vp9_enc->noise_sensitivity = DEFAULT_NOISE_SENSITIVITY;
-  gst_vp9_enc->sharpness = DEFAULT_SHARPNESS;
-  gst_vp9_enc->static_threshold = DEFAULT_STATIC_THRESHOLD;
-  gst_vp9_enc->token_partitions = DEFAULT_TOKEN_PARTITIONS;
-  gst_vp9_enc->arnr_maxframes = DEFAULT_ARNR_MAXFRAMES;
-  gst_vp9_enc->arnr_strength = DEFAULT_ARNR_STRENGTH;
-  gst_vp9_enc->arnr_type = DEFAULT_ARNR_TYPE;
-  gst_vp9_enc->tuning = DEFAULT_TUNING;
-  gst_vp9_enc->cq_level = DEFAULT_CQ_LEVEL;
-  gst_vp9_enc->max_intra_bitrate_pct = DEFAULT_MAX_INTRA_BITRATE_PCT;
-  gst_vp9_enc->timebase_n = DEFAULT_TIMEBASE_N;
-  gst_vp9_enc->timebase_d = DEFAULT_TIMEBASE_D;
-
-  gst_vp9_enc->cfg.g_profile = DEFAULT_PROFILE;
-
-  g_mutex_init (&gst_vp9_enc->encoder_lock);
-}
-
-static void
-gst_vp9_enc_finalize (GObject * object)
-{
-  GstVP9Enc *gst_vp9_enc;
-
-  GST_DEBUG_OBJECT (object, "finalize");
-
-  g_return_if_fail (GST_IS_VP9_ENC (object));
-  gst_vp9_enc = GST_VP9_ENC (object);
-
-  g_free (gst_vp9_enc->multipass_cache_prefix);
-  g_free (gst_vp9_enc->multipass_cache_file);
-  gst_vp9_enc->multipass_cache_idx = 0;
-
-  if (gst_vp9_enc->input_state)
-    gst_video_codec_state_unref (gst_vp9_enc->input_state);
-
-  g_mutex_clear (&gst_vp9_enc->encoder_lock);
-
-  G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_vp9_enc_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstVP9Enc *gst_vp9_enc;
-  gboolean global = FALSE;
-  vpx_codec_err_t status;
-
-  g_return_if_fail (GST_IS_VP9_ENC (object));
-  gst_vp9_enc = GST_VP9_ENC (object);
-
-  GST_DEBUG_OBJECT (object, "gst_vp9_enc_set_property");
-  g_mutex_lock (&gst_vp9_enc->encoder_lock);
-  switch (prop_id) {
-    case PROP_RC_END_USAGE:
-      gst_vp9_enc->cfg.rc_end_usage = g_value_get_enum (value);
-      global = TRUE;
-      break;
-    case PROP_RC_TARGET_BITRATE:
-      gst_vp9_enc->cfg.rc_target_bitrate = g_value_get_int (value) / 1000;
-      gst_vp9_enc->rc_target_bitrate_set = TRUE;
-      global = TRUE;
-      break;
-    case PROP_RC_MIN_QUANTIZER:
-      gst_vp9_enc->cfg.rc_min_quantizer = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_MAX_QUANTIZER:
-      gst_vp9_enc->cfg.rc_max_quantizer = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_DROPFRAME_THRESH:
-      gst_vp9_enc->cfg.rc_dropframe_thresh = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_RESIZE_ALLOWED:
-      gst_vp9_enc->cfg.rc_resize_allowed = g_value_get_boolean (value);
-      global = TRUE;
-      break;
-    case PROP_RC_RESIZE_UP_THRESH:
-      gst_vp9_enc->cfg.rc_resize_up_thresh = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_RESIZE_DOWN_THRESH:
-      gst_vp9_enc->cfg.rc_resize_down_thresh = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_UNDERSHOOT_PCT:
-      gst_vp9_enc->cfg.rc_undershoot_pct = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_OVERSHOOT_PCT:
-      gst_vp9_enc->cfg.rc_overshoot_pct = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_BUF_SZ:
-      gst_vp9_enc->cfg.rc_buf_sz = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_BUF_INITIAL_SZ:
-      gst_vp9_enc->cfg.rc_buf_initial_sz = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_BUF_OPTIMAL_SZ:
-      gst_vp9_enc->cfg.rc_buf_optimal_sz = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_2PASS_VBR_BIAS_PCT:
-      gst_vp9_enc->cfg.rc_2pass_vbr_bias_pct = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_2PASS_VBR_MINSECTION_PCT:
-      gst_vp9_enc->cfg.rc_2pass_vbr_minsection_pct = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_RC_2PASS_VBR_MAXSECTION_PCT:
-      gst_vp9_enc->cfg.rc_2pass_vbr_maxsection_pct = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_KF_MODE:
-      gst_vp9_enc->cfg.kf_mode = g_value_get_enum (value);
-      global = TRUE;
-      break;
-    case PROP_KF_MAX_DIST:
-      gst_vp9_enc->cfg.kf_max_dist = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_MULTIPASS_MODE:
-      gst_vp9_enc->cfg.g_pass = g_value_get_enum (value);
-      global = TRUE;
-      break;
-    case PROP_MULTIPASS_CACHE_FILE:
-      if (gst_vp9_enc->multipass_cache_prefix)
-        g_free (gst_vp9_enc->multipass_cache_prefix);
-      gst_vp9_enc->multipass_cache_prefix = g_value_dup_string (value);
-      break;
-    case PROP_TS_NUMBER_LAYERS:
-      gst_vp9_enc->cfg.ts_number_layers = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_TS_TARGET_BITRATE:{
-      GValueArray *va = g_value_get_boxed (value);
-
-      memset (&gst_vp9_enc->cfg.ts_target_bitrate, 0,
-          sizeof (gst_vp9_enc->cfg.ts_target_bitrate));
-      if (va == NULL) {
-        gst_vp9_enc->n_ts_target_bitrate = 0;
-      } else {
-        if (va->n_values > VPX_TS_MAX_LAYERS) {
-          g_warning ("%s: Only %d layers allowed at maximum",
-              GST_ELEMENT_NAME (gst_vp9_enc), VPX_TS_MAX_LAYERS);
-        } else {
-          gint i;
-
-          for (i = 0; i < va->n_values; i++)
-            gst_vp9_enc->cfg.ts_target_bitrate[i] =
-                g_value_get_int (g_value_array_get_nth (va, i));
-          gst_vp9_enc->n_ts_target_bitrate = va->n_values;
-        }
-      }
-      global = TRUE;
-      break;
-    }
-    case PROP_TS_RATE_DECIMATOR:{
-      GValueArray *va = g_value_get_boxed (value);
-
-      memset (&gst_vp9_enc->cfg.ts_rate_decimator, 0,
-          sizeof (gst_vp9_enc->cfg.ts_rate_decimator));
-      if (va == NULL) {
-        gst_vp9_enc->n_ts_rate_decimator = 0;
-      } else if (va->n_values > VPX_TS_MAX_LAYERS) {
-        g_warning ("%s: Only %d layers allowed at maximum",
-            GST_ELEMENT_NAME (gst_vp9_enc), VPX_TS_MAX_LAYERS);
-      } else {
-        gint i;
-
-        for (i = 0; i < va->n_values; i++)
-          gst_vp9_enc->cfg.ts_rate_decimator[i] =
-              g_value_get_int (g_value_array_get_nth (va, i));
-        gst_vp9_enc->n_ts_rate_decimator = va->n_values;
-      }
-      global = TRUE;
-      break;
-    }
-    case PROP_TS_PERIODICITY:
-      gst_vp9_enc->cfg.ts_periodicity = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_TS_LAYER_ID:{
-      GValueArray *va = g_value_get_boxed (value);
-
-      memset (&gst_vp9_enc->cfg.ts_layer_id, 0,
-          sizeof (gst_vp9_enc->cfg.ts_layer_id));
-      if (va && va->n_values > VPX_TS_MAX_PERIODICITY) {
-        g_warning ("%s: Only %d sized layer sequences allowed at maximum",
-            GST_ELEMENT_NAME (gst_vp9_enc), VPX_TS_MAX_PERIODICITY);
-      } else if (va) {
-        gint i;
-
-        for (i = 0; i < va->n_values; i++)
-          gst_vp9_enc->cfg.ts_layer_id[i] =
-              g_value_get_int (g_value_array_get_nth (va, i));
-        gst_vp9_enc->n_ts_layer_id = va->n_values;
-      } else {
-        gst_vp9_enc->n_ts_layer_id = 0;
-      }
-      global = TRUE;
-      break;
-    }
-    case PROP_ERROR_RESILIENT:
-      gst_vp9_enc->cfg.g_error_resilient = g_value_get_flags (value);
-      global = TRUE;
-      break;
-    case PROP_LAG_IN_FRAMES:
-      gst_vp9_enc->cfg.g_lag_in_frames = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_THREADS:
-      gst_vp9_enc->cfg.g_threads = g_value_get_int (value);
-      global = TRUE;
-      break;
-    case PROP_DEADLINE:
-      gst_vp9_enc->deadline = g_value_get_int64 (value);
-      break;
-    case PROP_H_SCALING_MODE:
-      gst_vp9_enc->h_scaling_mode = g_value_get_enum (value);
-      if (gst_vp9_enc->inited) {
-        vpx_scaling_mode_t sm;
-
-        sm.h_scaling_mode = gst_vp9_enc->h_scaling_mode;
-        sm.v_scaling_mode = gst_vp9_enc->v_scaling_mode;
-
-        status =
-            vpx_codec_control (&gst_vp9_enc->encoder, VP8E_SET_SCALEMODE, &sm);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp9_enc,
-              "Failed to set VP8E_SET_SCALEMODE: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_V_SCALING_MODE:
-      gst_vp9_enc->v_scaling_mode = g_value_get_enum (value);
-      if (gst_vp9_enc->inited) {
-        vpx_scaling_mode_t sm;
-
-        sm.h_scaling_mode = gst_vp9_enc->h_scaling_mode;
-        sm.v_scaling_mode = gst_vp9_enc->v_scaling_mode;
-
-        status =
-            vpx_codec_control (&gst_vp9_enc->encoder, VP8E_SET_SCALEMODE, &sm);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp9_enc,
-              "Failed to set VP8E_SET_SCALEMODE: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_CPU_USED:
-      gst_vp9_enc->cpu_used = g_value_get_int (value);
-      if (gst_vp9_enc->inited) {
-        status =
-            vpx_codec_control (&gst_vp9_enc->encoder, VP8E_SET_CPUUSED,
-            gst_vp9_enc->cpu_used);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp9_enc, "Failed to set VP8E_SET_CPUUSED: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_ENABLE_AUTO_ALT_REF:
-      gst_vp9_enc->enable_auto_alt_ref = g_value_get_boolean (value);
-      if (gst_vp9_enc->inited) {
-        status =
-            vpx_codec_control (&gst_vp9_enc->encoder, VP8E_SET_ENABLEAUTOALTREF,
-            (gst_vp9_enc->enable_auto_alt_ref ? 1 : 0));
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp9_enc,
-              "Failed to set VP8E_SET_ENABLEAUTOALTREF: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_NOISE_SENSITIVITY:
-      gst_vp9_enc->noise_sensitivity = g_value_get_int (value);
-      if (gst_vp9_enc->inited) {
-        status =
-            vpx_codec_control (&gst_vp9_enc->encoder,
-            VP8E_SET_NOISE_SENSITIVITY, gst_vp9_enc->noise_sensitivity);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp9_enc,
-              "Failed to set VP8E_SET_NOISE_SENSITIVITY: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_SHARPNESS:
-      gst_vp9_enc->sharpness = g_value_get_int (value);
-      if (gst_vp9_enc->inited) {
-        status = vpx_codec_control (&gst_vp9_enc->encoder, VP8E_SET_SHARPNESS,
-            gst_vp9_enc->sharpness);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp9_enc,
-              "Failed to set VP8E_SET_SHARPNESS: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_STATIC_THRESHOLD:
-      gst_vp9_enc->static_threshold = g_value_get_int (value);
-      if (gst_vp9_enc->inited) {
-        status =
-            vpx_codec_control (&gst_vp9_enc->encoder, VP8E_SET_STATIC_THRESHOLD,
-            gst_vp9_enc->static_threshold);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp9_enc,
-              "Failed to set VP8E_SET_STATIC_THRESHOLD: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_TOKEN_PARTITIONS:
-      gst_vp9_enc->token_partitions = g_value_get_enum (value);
-      if (gst_vp9_enc->inited) {
-        status =
-            vpx_codec_control (&gst_vp9_enc->encoder, VP8E_SET_TOKEN_PARTITIONS,
-            gst_vp9_enc->token_partitions);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp9_enc,
-              "Failed to set VP8E_SET_TOKEN_PARTIONS: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_ARNR_MAXFRAMES:
-      gst_vp9_enc->arnr_maxframes = g_value_get_int (value);
-      if (gst_vp9_enc->inited) {
-        status =
-            vpx_codec_control (&gst_vp9_enc->encoder, VP8E_SET_ARNR_MAXFRAMES,
-            gst_vp9_enc->arnr_maxframes);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp9_enc,
-              "Failed to set VP8E_SET_ARNR_MAXFRAMES: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_ARNR_STRENGTH:
-      gst_vp9_enc->arnr_strength = g_value_get_int (value);
-      if (gst_vp9_enc->inited) {
-        status =
-            vpx_codec_control (&gst_vp9_enc->encoder, VP8E_SET_ARNR_STRENGTH,
-            gst_vp9_enc->arnr_strength);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp9_enc,
-              "Failed to set VP8E_SET_ARNR_STRENGTH: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_ARNR_TYPE:
-      gst_vp9_enc->arnr_type = g_value_get_int (value);
-      g_warning ("arnr-type is a no-op since control has been deprecated "
-          "in libvpx");
-      break;
-    case PROP_TUNING:
-      gst_vp9_enc->tuning = g_value_get_enum (value);
-      if (gst_vp9_enc->inited) {
-        status = vpx_codec_control (&gst_vp9_enc->encoder, VP8E_SET_TUNING,
-            gst_vp9_enc->tuning);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp9_enc,
-              "Failed to set VP8E_SET_TUNING: %s", gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_CQ_LEVEL:
-      gst_vp9_enc->cq_level = g_value_get_int (value);
-      if (gst_vp9_enc->inited) {
-        status = vpx_codec_control (&gst_vp9_enc->encoder, VP8E_SET_CQ_LEVEL,
-            gst_vp9_enc->cq_level);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp9_enc,
-              "Failed to set VP8E_SET_CQ_LEVEL: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_MAX_INTRA_BITRATE_PCT:
-      gst_vp9_enc->max_intra_bitrate_pct = g_value_get_int (value);
-      if (gst_vp9_enc->inited) {
-        status =
-            vpx_codec_control (&gst_vp9_enc->encoder,
-            VP8E_SET_MAX_INTRA_BITRATE_PCT, gst_vp9_enc->max_intra_bitrate_pct);
-        if (status != VPX_CODEC_OK) {
-          GST_WARNING_OBJECT (gst_vp9_enc,
-              "Failed to set VP8E_SET_MAX_INTRA_BITRATE_PCT: %s",
-              gst_vpx_error_name (status));
-        }
-      }
-      break;
-    case PROP_TIMEBASE:
-      gst_vp9_enc->timebase_n = gst_value_get_fraction_numerator (value);
-      gst_vp9_enc->timebase_d = gst_value_get_fraction_denominator (value);
-      break;
-    default:
-      break;
-  }
-
-  if (global &&gst_vp9_enc->inited) {
-    status =
-        vpx_codec_enc_config_set (&gst_vp9_enc->encoder, &gst_vp9_enc->cfg);
-    if (status != VPX_CODEC_OK) {
-      g_mutex_unlock (&gst_vp9_enc->encoder_lock);
-      GST_ELEMENT_ERROR (gst_vp9_enc, LIBRARY, INIT,
-          ("Failed to set encoder configuration"), ("%s",
-              gst_vpx_error_name (status)));
-    } else {
-      g_mutex_unlock (&gst_vp9_enc->encoder_lock);
-    }
-  } else {
-    g_mutex_unlock (&gst_vp9_enc->encoder_lock);
+    gst_vpx_enc->have_default_config = TRUE;
   }
 }
 
-static void
-gst_vp9_enc_get_property (GObject * object, guint prop_id, GValue * value,
-    GParamSpec * pspec)
+static vpx_codec_iface_t *
+gst_vp9_enc_get_algo (GstVPXEnc * enc)
 {
-  GstVP9Enc *gst_vp9_enc;
-
-  g_return_if_fail (GST_IS_VP9_ENC (object));
-  gst_vp9_enc = GST_VP9_ENC (object);
-
-  g_mutex_lock (&gst_vp9_enc->encoder_lock);
-  switch (prop_id) {
-    case PROP_RC_END_USAGE:
-      g_value_set_enum (value, gst_vp9_enc->cfg.rc_end_usage);
-      break;
-    case PROP_RC_TARGET_BITRATE:
-      g_value_set_int (value, gst_vp9_enc->cfg.rc_target_bitrate * 1000);
-      break;
-    case PROP_RC_MIN_QUANTIZER:
-      g_value_set_int (value, gst_vp9_enc->cfg.rc_min_quantizer);
-      break;
-    case PROP_RC_MAX_QUANTIZER:
-      g_value_set_int (value, gst_vp9_enc->cfg.rc_max_quantizer);
-      break;
-    case PROP_RC_DROPFRAME_THRESH:
-      g_value_set_int (value, gst_vp9_enc->cfg.rc_dropframe_thresh);
-      break;
-    case PROP_RC_RESIZE_ALLOWED:
-      g_value_set_boolean (value, gst_vp9_enc->cfg.rc_resize_allowed);
-      break;
-    case PROP_RC_RESIZE_UP_THRESH:
-      g_value_set_int (value, gst_vp9_enc->cfg.rc_resize_up_thresh);
-      break;
-    case PROP_RC_RESIZE_DOWN_THRESH:
-      g_value_set_int (value, gst_vp9_enc->cfg.rc_resize_down_thresh);
-      break;
-    case PROP_RC_UNDERSHOOT_PCT:
-      g_value_set_int (value, gst_vp9_enc->cfg.rc_undershoot_pct);
-      break;
-    case PROP_RC_OVERSHOOT_PCT:
-      g_value_set_int (value, gst_vp9_enc->cfg.rc_overshoot_pct);
-      break;
-    case PROP_RC_BUF_SZ:
-      g_value_set_int (value, gst_vp9_enc->cfg.rc_buf_sz);
-      break;
-    case PROP_RC_BUF_INITIAL_SZ:
-      g_value_set_int (value, gst_vp9_enc->cfg.rc_buf_initial_sz);
-      break;
-    case PROP_RC_BUF_OPTIMAL_SZ:
-      g_value_set_int (value, gst_vp9_enc->cfg.rc_buf_optimal_sz);
-      break;
-    case PROP_RC_2PASS_VBR_BIAS_PCT:
-      g_value_set_int (value, gst_vp9_enc->cfg.rc_2pass_vbr_bias_pct);
-      break;
-    case PROP_RC_2PASS_VBR_MINSECTION_PCT:
-      g_value_set_int (value, gst_vp9_enc->cfg.rc_2pass_vbr_minsection_pct);
-      break;
-    case PROP_RC_2PASS_VBR_MAXSECTION_PCT:
-      g_value_set_int (value, gst_vp9_enc->cfg.rc_2pass_vbr_maxsection_pct);
-      break;
-    case PROP_KF_MODE:
-      g_value_set_enum (value, gst_vp9_enc->cfg.kf_mode);
-      break;
-    case PROP_KF_MAX_DIST:
-      g_value_set_int (value, gst_vp9_enc->cfg.kf_max_dist);
-      break;
-    case PROP_MULTIPASS_MODE:
-      g_value_set_enum (value, gst_vp9_enc->cfg.g_pass);
-      break;
-    case PROP_MULTIPASS_CACHE_FILE:
-      g_value_set_string (value, gst_vp9_enc->multipass_cache_prefix);
-      break;
-    case PROP_TS_NUMBER_LAYERS:
-      g_value_set_int (value, gst_vp9_enc->cfg.ts_number_layers);
-      break;
-    case PROP_TS_TARGET_BITRATE:{
-      GValueArray *va;
-
-      if (gst_vp9_enc->n_ts_target_bitrate == 0) {
-        g_value_set_boxed (value, NULL);
-      } else {
-        gint i;
-
-        va = g_value_array_new (gst_vp9_enc->n_ts_target_bitrate);
-        for (i = 0; i < gst_vp9_enc->n_ts_target_bitrate; i++) {
-          GValue v = { 0, };
-
-          g_value_init (&v, G_TYPE_INT);
-          g_value_set_int (&v, gst_vp9_enc->cfg.ts_target_bitrate[i]);
-          g_value_array_append (va, &v);
-          g_value_unset (&v);
-        }
-        g_value_set_boxed (value, va);
-        g_value_array_free (va);
-      }
-      break;
-    }
-    case PROP_TS_RATE_DECIMATOR:{
-      GValueArray *va;
-
-      if (gst_vp9_enc->n_ts_rate_decimator == 0) {
-        g_value_set_boxed (value, NULL);
-      } else {
-        gint i;
-
-        va = g_value_array_new (gst_vp9_enc->n_ts_rate_decimator);
-        for (i = 0; i < gst_vp9_enc->n_ts_rate_decimator; i++) {
-          GValue v = { 0, };
-
-          g_value_init (&v, G_TYPE_INT);
-          g_value_set_int (&v, gst_vp9_enc->cfg.ts_rate_decimator[i]);
-          g_value_array_append (va, &v);
-          g_value_unset (&v);
-        }
-        g_value_set_boxed (value, va);
-        g_value_array_free (va);
-      }
-      break;
-    }
-    case PROP_TS_PERIODICITY:
-      g_value_set_int (value, gst_vp9_enc->cfg.ts_periodicity);
-      break;
-    case PROP_TS_LAYER_ID:{
-      GValueArray *va;
-
-      if (gst_vp9_enc->n_ts_layer_id == 0) {
-        g_value_set_boxed (value, NULL);
-      } else {
-        gint i;
-
-        va = g_value_array_new (gst_vp9_enc->n_ts_layer_id);
-        for (i = 0; i < gst_vp9_enc->n_ts_layer_id; i++) {
-          GValue v = { 0, };
-
-          g_value_init (&v, G_TYPE_INT);
-          g_value_set_int (&v, gst_vp9_enc->cfg.ts_layer_id[i]);
-          g_value_array_append (va, &v);
-          g_value_unset (&v);
-        }
-        g_value_set_boxed (value, va);
-        g_value_array_free (va);
-      }
-      break;
-    }
-    case PROP_ERROR_RESILIENT:
-      g_value_set_flags (value, gst_vp9_enc->cfg.g_error_resilient);
-      break;
-    case PROP_LAG_IN_FRAMES:
-      g_value_set_int (value, gst_vp9_enc->cfg.g_lag_in_frames);
-      break;
-    case PROP_THREADS:
-      g_value_set_int (value, gst_vp9_enc->cfg.g_threads);
-      break;
-    case PROP_DEADLINE:
-      g_value_set_int64 (value, gst_vp9_enc->deadline);
-      break;
-    case PROP_H_SCALING_MODE:
-      g_value_set_enum (value, gst_vp9_enc->h_scaling_mode);
-      break;
-    case PROP_V_SCALING_MODE:
-      g_value_set_enum (value, gst_vp9_enc->v_scaling_mode);
-      break;
-    case PROP_CPU_USED:
-      g_value_set_int (value, gst_vp9_enc->cpu_used);
-      break;
-    case PROP_ENABLE_AUTO_ALT_REF:
-      g_value_set_boolean (value, gst_vp9_enc->enable_auto_alt_ref);
-      break;
-    case PROP_NOISE_SENSITIVITY:
-      g_value_set_int (value, gst_vp9_enc->noise_sensitivity);
-      break;
-    case PROP_SHARPNESS:
-      g_value_set_int (value, gst_vp9_enc->sharpness);
-      break;
-    case PROP_STATIC_THRESHOLD:
-      g_value_set_int (value, gst_vp9_enc->static_threshold);
-      break;
-    case PROP_TOKEN_PARTITIONS:
-      g_value_set_enum (value, gst_vp9_enc->token_partitions);
-      break;
-    case PROP_ARNR_MAXFRAMES:
-      g_value_set_int (value, gst_vp9_enc->arnr_maxframes);
-      break;
-    case PROP_ARNR_STRENGTH:
-      g_value_set_int (value, gst_vp9_enc->arnr_strength);
-      break;
-    case PROP_ARNR_TYPE:
-      g_value_set_int (value, gst_vp9_enc->arnr_type);
-      break;
-    case PROP_TUNING:
-      g_value_set_enum (value, gst_vp9_enc->tuning);
-      break;
-    case PROP_CQ_LEVEL:
-      g_value_set_int (value, gst_vp9_enc->cq_level);
-      break;
-    case PROP_MAX_INTRA_BITRATE_PCT:
-      g_value_set_int (value, gst_vp9_enc->max_intra_bitrate_pct);
-      break;
-    case PROP_TIMEBASE:
-      gst_value_set_fraction (value, gst_vp9_enc->timebase_n,
-          gst_vp9_enc->timebase_d);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-
-  g_mutex_unlock (&gst_vp9_enc->encoder_lock);
+  return &vpx_codec_vp9_cx_algo;
 }
 
 static gboolean
-gst_vp9_enc_start (GstVideoEncoder * video_encoder)
+gst_vp9_enc_enable_scaling (GstVPXEnc * enc)
 {
-  GstVP9Enc *encoder = GST_VP9_ENC (video_encoder);
-
-  GST_DEBUG_OBJECT (video_encoder, "start");
-
-  if (!encoder->have_default_config) {
-    GST_ELEMENT_ERROR (encoder, LIBRARY, INIT,
-        ("Failed to get default encoder configuration"), (NULL));
-    return FALSE;
-  }
-
-  return TRUE;
+  return FALSE;
 }
 
 static void
-gst_vp9_enc_destroy_encoder (GstVP9Enc * encoder)
+gst_vp9_enc_set_image_format (GstVPXEnc * enc, vpx_image_t * image)
 {
-  g_mutex_lock (&encoder->encoder_lock);
-  if (encoder->inited) {
-    vpx_codec_destroy (&encoder->encoder);
-    encoder->inited = FALSE;
-  }
-
-  if (encoder->first_pass_cache_content) {
-    g_byte_array_free (encoder->first_pass_cache_content, TRUE);
-    encoder->first_pass_cache_content = NULL;
-  }
-
-  if (encoder->cfg.rc_twopass_stats_in.buf) {
-    g_free (encoder->cfg.rc_twopass_stats_in.buf);
-    encoder->cfg.rc_twopass_stats_in.buf = NULL;
-    encoder->cfg.rc_twopass_stats_in.sz = 0;
-  }
-  g_mutex_unlock (&encoder->encoder_lock);
-}
-
-static gboolean
-gst_vp9_enc_stop (GstVideoEncoder * video_encoder)
-{
-  GstVP9Enc *encoder;
-
-  GST_DEBUG_OBJECT (video_encoder, "stop");
-
-  encoder = GST_VP9_ENC (video_encoder);
-
-  gst_vp9_enc_destroy_encoder (encoder);
-
-  gst_tag_setter_reset_tags (GST_TAG_SETTER (encoder));
-
-  g_free (encoder->multipass_cache_file);
-  encoder->multipass_cache_file = NULL;
-  encoder->multipass_cache_idx = 0;
-
-  return TRUE;
-}
-
-static gint
-gst_vp9_enc_get_downstream_profile (GstVP9Enc * encoder)
-{
-  GstCaps *allowed;
-  GstStructure *s;
-  gint profile = DEFAULT_PROFILE;
-
-  allowed = gst_pad_get_allowed_caps (GST_VIDEO_ENCODER_SRC_PAD (encoder));
-  if (allowed) {
-    allowed = gst_caps_truncate (allowed);
-    s = gst_caps_get_structure (allowed, 0);
-    if (gst_structure_has_field (s, "profile")) {
-      const GValue *v = gst_structure_get_value (s, "profile");
-      const gchar *profile_str = NULL;
-
-      if (GST_VALUE_HOLDS_LIST (v) && gst_value_list_get_size (v) > 0) {
-        profile_str = g_value_get_string (gst_value_list_get_value (v, 0));
-      } else if (G_VALUE_HOLDS_STRING (v)) {
-        profile_str = g_value_get_string (v);
-      }
-
-      if (profile_str) {
-        gchar *endptr = NULL;
-
-        profile = g_ascii_strtoull (profile_str, &endptr, 10);
-        if (*endptr != '\0' || profile < 0 || profile > 3) {
-          GST_ERROR_OBJECT (encoder, "Invalid profile '%s'", profile_str);
-          profile = DEFAULT_PROFILE;
-        }
-      }
-    }
-    gst_caps_unref (allowed);
-  }
-
-  GST_DEBUG_OBJECT (encoder, "Using profile %d", profile);
-
-  return profile;
-}
-
-static gboolean
-gst_vp9_enc_set_format (GstVideoEncoder * video_encoder,
-    GstVideoCodecState * state)
-{
-  GstVP9Enc *encoder;
-  vpx_codec_err_t status;
-  vpx_image_t *image;
-  GstCaps *caps;
-  gboolean ret = TRUE;
-  GstVideoInfo *info = &state->info;
-  GstVideoCodecState *output_state;
-  gchar *profile_str;
-  GstClockTime latency;
-
-  encoder = GST_VP9_ENC (video_encoder);
-  GST_DEBUG_OBJECT (video_encoder, "set_format");
-
-  if (encoder->inited) {
-    gst_vp9_enc_drain (video_encoder);
-    g_mutex_lock (&encoder->encoder_lock);
-    vpx_codec_destroy (&encoder->encoder);
-    encoder->inited = FALSE;
-    encoder->multipass_cache_idx++;
-  } else {
-    g_mutex_lock (&encoder->encoder_lock);
-  }
-
-  encoder->cfg.g_profile = gst_vp9_enc_get_downstream_profile (encoder);
-
-  /* Scale default bitrate to our size */
-  if (!encoder->rc_target_bitrate_set)
-    encoder->cfg.rc_target_bitrate =
-        gst_util_uint64_scale (DEFAULT_RC_TARGET_BITRATE,
-        GST_VIDEO_INFO_WIDTH (info) * GST_VIDEO_INFO_HEIGHT (info),
-        320 * 240 * 1000);
-
-  encoder->cfg.g_w = GST_VIDEO_INFO_WIDTH (info);
-  encoder->cfg.g_h = GST_VIDEO_INFO_HEIGHT (info);
-
-  if (encoder->timebase_n != 0 && encoder->timebase_d != 0) {
-    GST_DEBUG_OBJECT (video_encoder, "Using timebase configuration");
-    encoder->cfg.g_timebase.num = encoder->timebase_n;
-    encoder->cfg.g_timebase.den = encoder->timebase_d;
-  } else {
-    /* Zero framerate and max-framerate but still need to setup the timebase to avoid
-     * a divide by zero error. Presuming the lowest common denominator will be RTP -
-     * VP9 payload draft states clock rate of 90000 which should work for anyone where
-     * FPS < 90000 (shouldn't be too many cases where it's higher) though wouldn't be optimal. RTP specification
-     * http://tools.ietf.org/html/draft-ietf-payload-vp9-01 section 6.3.1 */
-    encoder->cfg.g_timebase.num = 1;
-    encoder->cfg.g_timebase.den = 90000;
-  }
-
-  if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS ||
-      encoder->cfg.g_pass == VPX_RC_LAST_PASS) {
-    if (!encoder->multipass_cache_prefix) {
-      GST_ELEMENT_ERROR (encoder, RESOURCE, OPEN_READ,
-          ("No multipass cache file provided"), (NULL));
-      g_mutex_unlock (&encoder->encoder_lock);
-      return FALSE;
-    }
-
-    g_free (encoder->multipass_cache_file);
-
-    if (encoder->multipass_cache_idx > 0)
-      encoder->multipass_cache_file = g_strdup_printf ("%s.%u",
-          encoder->multipass_cache_prefix, encoder->multipass_cache_idx);
-    else
-      encoder->multipass_cache_file =
-          g_strdup (encoder->multipass_cache_prefix);
-  }
-
-  if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS) {
-    if (encoder->first_pass_cache_content != NULL)
-      g_byte_array_free (encoder->first_pass_cache_content, TRUE);
-
-    encoder->first_pass_cache_content = g_byte_array_sized_new (4096);
-
-  } else if (encoder->cfg.g_pass == VPX_RC_LAST_PASS) {
-    GError *err = NULL;
-
-    if (encoder->cfg.rc_twopass_stats_in.buf != NULL) {
-      g_free (encoder->cfg.rc_twopass_stats_in.buf);
-      encoder->cfg.rc_twopass_stats_in.buf = NULL;
-      encoder->cfg.rc_twopass_stats_in.sz = 0;
-    }
-
-    if (!g_file_get_contents (encoder->multipass_cache_file,
-            (gchar **) & encoder->cfg.rc_twopass_stats_in.buf,
-            &encoder->cfg.rc_twopass_stats_in.sz, &err)) {
-      GST_ELEMENT_ERROR (encoder, RESOURCE, OPEN_READ,
-          ("Failed to read multipass cache file provided"), ("%s",
-              err->message));
-      g_error_free (err);
-      g_mutex_unlock (&encoder->encoder_lock);
-      return FALSE;
-    }
-  }
-
-  status = vpx_codec_enc_init (&encoder->encoder, &vpx_codec_vp9_cx_algo,
-      &encoder->cfg, 0);
-  if (status != VPX_CODEC_OK) {
-    GST_ELEMENT_ERROR (encoder, LIBRARY, INIT,
-        ("Failed to initialize encoder"), ("%s", gst_vpx_error_name (status)));
-    g_mutex_unlock (&encoder->encoder_lock);
-    return FALSE;
-  }
-
-  /* FIXME: Disabled for now, does not work with VP9 */
-#if 0
-  {
-    vpx_scaling_mode_t sm;
-
-    sm.h_scaling_mode = encoder->h_scaling_mode;
-    sm.v_scaling_mode = encoder->v_scaling_mode;
-
-    status = vpx_codec_control (&encoder->encoder, VP8E_SET_SCALEMODE, &sm);
-    if (status != VPX_CODEC_OK) {
-      GST_WARNING_OBJECT (encoder, "Failed to set VP8E_SET_SCALEMODE: %s",
-          gst_vpx_error_name (status));
-    }
-  }
-#endif
-
-  status =
-      vpx_codec_control (&encoder->encoder, VP8E_SET_CPUUSED,
-      encoder->cpu_used);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder, "Failed to set VP8E_SET_CPUUSED: %s",
-        gst_vpx_error_name (status));
-  }
-
-  status =
-      vpx_codec_control (&encoder->encoder, VP8E_SET_ENABLEAUTOALTREF,
-      (encoder->enable_auto_alt_ref ? 1 : 0));
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_ENABLEAUTOALTREF: %s",
-        gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_NOISE_SENSITIVITY,
-      encoder->noise_sensitivity);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_NOISE_SENSITIVITY: %s",
-        gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_SHARPNESS,
-      encoder->sharpness);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_SHARPNESS: %s", gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_STATIC_THRESHOLD,
-      encoder->static_threshold);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_STATIC_THRESHOLD: %s",
-        gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_TOKEN_PARTITIONS,
-      encoder->token_partitions);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_TOKEN_PARTIONS: %s",
-        gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_ARNR_MAXFRAMES,
-      encoder->arnr_maxframes);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_ARNR_MAXFRAMES: %s",
-        gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_ARNR_STRENGTH,
-      encoder->arnr_strength);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_ARNR_STRENGTH: %s",
-        gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_TUNING,
-      encoder->tuning);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_TUNING: %s", gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_CQ_LEVEL,
-      encoder->cq_level);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_CQ_LEVEL: %s", gst_vpx_error_name (status));
-  }
-  status = vpx_codec_control (&encoder->encoder, VP8E_SET_MAX_INTRA_BITRATE_PCT,
-      encoder->max_intra_bitrate_pct);
-  if (status != VPX_CODEC_OK) {
-    GST_WARNING_OBJECT (encoder,
-        "Failed to set VP8E_SET_MAX_INTRA_BITRATE_PCT: %s",
-        gst_vpx_error_name (status));
-  }
-
-  if (GST_VIDEO_INFO_FPS_D (info) == 0 || GST_VIDEO_INFO_FPS_N (info) == 0) {
-    /* FIXME: Assume 25fps for unknown framerates. Better than reporting
-     * that we introduce no latency while we actually do
-     */
-    latency = gst_util_uint64_scale (encoder->cfg.g_lag_in_frames,
-        1 * GST_SECOND, 25);
-  } else {
-    latency = gst_util_uint64_scale (encoder->cfg.g_lag_in_frames,
-        GST_VIDEO_INFO_FPS_D (info) * GST_SECOND, GST_VIDEO_INFO_FPS_N (info));
-  }
-  gst_video_encoder_set_latency (video_encoder, latency, latency);
-  encoder->inited = TRUE;
-
-  /* Store input state */
-  if (encoder->input_state)
-    gst_video_codec_state_unref (encoder->input_state);
-  encoder->input_state = gst_video_codec_state_ref (state);
-
-  /* prepare cached image buffer setup */
-  image = &encoder->image;
-  memset (image, 0, sizeof (*image));
-
-  switch (encoder->input_state->info.finfo->format) {
+  switch (enc->input_state->info.finfo->format) {
     case GST_VIDEO_FORMAT_I420:
       image->fmt = VPX_IMG_FMT_I420;
       image->bps = 12;
@@ -1730,297 +196,49 @@
       g_assert_not_reached ();
       break;
   }
-  image->w = image->d_w = GST_VIDEO_INFO_WIDTH (info);
-  image->h = image->d_h = GST_VIDEO_INFO_HEIGHT (info);
+}
 
-  image->stride[VPX_PLANE_Y] = GST_VIDEO_INFO_COMP_STRIDE (info, 0);
-  image->stride[VPX_PLANE_U] = GST_VIDEO_INFO_COMP_STRIDE (info, 1);
-  image->stride[VPX_PLANE_V] = GST_VIDEO_INFO_COMP_STRIDE (info, 2);
-
-  profile_str = g_strdup_printf ("%d", encoder->cfg.g_profile);
+static GstCaps *
+gst_vp9_enc_get_new_simple_caps (GstVPXEnc * enc)
+{
+  GstCaps *caps;
+  gchar *profile_str = g_strdup_printf ("%d", enc->cfg.g_profile);
   caps = gst_caps_new_simple ("video/x-vp9",
       "profile", G_TYPE_STRING, profile_str, NULL);
   g_free (profile_str);
-
-  g_mutex_unlock (&encoder->encoder_lock);
-
-  output_state =
-      gst_video_encoder_set_output_state (video_encoder, caps, state);
-  gst_video_codec_state_unref (output_state);
-
-  gst_video_encoder_negotiate (GST_VIDEO_ENCODER (encoder));
-
-  return ret;
+  return caps;
 }
 
-static GstFlowReturn
-gst_vp9_enc_process (GstVP9Enc * encoder)
+static void
+gst_vp9_enc_set_stream_info (GstVPXEnc * enc, GstCaps * caps,
+    GstVideoInfo * info)
 {
-  vpx_codec_iter_t iter = NULL;
-  const vpx_codec_cx_pkt_t *pkt;
-  GstVideoEncoder *video_encoder;
-  GstVideoCodecFrame *frame;
-  GstFlowReturn ret = GST_FLOW_OK;
-
-  video_encoder = GST_VIDEO_ENCODER (encoder);
-
-  g_mutex_lock (&encoder->encoder_lock);
-  pkt = vpx_codec_get_cx_data (&encoder->encoder, &iter);
-  while (pkt != NULL) {
-    GstBuffer *buffer;
-    gboolean invisible;
-
-    GST_DEBUG_OBJECT (encoder, "packet %u type %d", (guint) pkt->data.frame.sz,
-        pkt->kind);
-
-    if (pkt->kind == VPX_CODEC_STATS_PKT
-        && encoder->cfg.g_pass == VPX_RC_FIRST_PASS) {
-      GST_LOG_OBJECT (encoder, "handling STATS packet");
-
-      g_byte_array_append (encoder->first_pass_cache_content,
-          pkt->data.twopass_stats.buf, pkt->data.twopass_stats.sz);
-
-      frame = gst_video_encoder_get_oldest_frame (video_encoder);
-      if (frame != NULL) {
-        buffer = gst_buffer_new ();
-        GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_LIVE);
-        frame->output_buffer = buffer;
-        g_mutex_unlock (&encoder->encoder_lock);
-        ret = gst_video_encoder_finish_frame (video_encoder, frame);
-        g_mutex_lock (&encoder->encoder_lock);
-      }
-
-      pkt = vpx_codec_get_cx_data (&encoder->encoder, &iter);
-      continue;
-    } else if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) {
-      GST_LOG_OBJECT (encoder, "non frame pkt: %d", pkt->kind);
-      pkt = vpx_codec_get_cx_data (&encoder->encoder, &iter);
-      continue;
-    }
-
-    invisible = (pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE) != 0;
-    frame = gst_video_encoder_get_oldest_frame (video_encoder);
-    g_assert (frame != NULL);
-    if ((pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0)
-      GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
-    else
-      GST_VIDEO_CODEC_FRAME_UNSET_SYNC_POINT (frame);
-
-    /* FIXME : It would be nice to avoid the memory copy ... */
-    buffer =
-        gst_buffer_new_wrapped (g_memdup (pkt->data.frame.buf,
-            pkt->data.frame.sz), pkt->data.frame.sz);
-
-    if (invisible) {
-      g_mutex_unlock (&encoder->encoder_lock);
-      ret = gst_pad_push (GST_VIDEO_ENCODER_SRC_PAD (encoder), buffer);
-      g_mutex_lock (&encoder->encoder_lock);
-      gst_video_codec_frame_unref (frame);
-    } else {
-      frame->output_buffer = buffer;
-      g_mutex_unlock (&encoder->encoder_lock);
-      ret = gst_video_encoder_finish_frame (video_encoder, frame);
-      g_mutex_lock (&encoder->encoder_lock);
-    }
-
-    pkt = vpx_codec_get_cx_data (&encoder->encoder, &iter);
-  }
-  g_mutex_unlock (&encoder->encoder_lock);
-
-  return ret;
+  return;
 }
 
-/* This function should be called holding then stream lock*/
-static GstFlowReturn
-gst_vp9_enc_drain (GstVideoEncoder * video_encoder)
-{
-  GstVP9Enc *encoder;
-  int flags = 0;
-  vpx_codec_err_t status;
-  gint64 deadline;
-  vpx_codec_pts_t pts;
-
-  encoder = GST_VP9_ENC (video_encoder);
-
-  g_mutex_lock (&encoder->encoder_lock);
-  deadline = encoder->deadline;
-
-  pts =
-      gst_util_uint64_scale (encoder->last_pts,
-      encoder->cfg.g_timebase.den,
-      encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND);
-
-  status = vpx_codec_encode (&encoder->encoder, NULL, pts, 0, flags, deadline);
-  g_mutex_unlock (&encoder->encoder_lock);
-
-  if (status != 0) {
-    GST_ERROR_OBJECT (encoder, "encode returned %d %s", status,
-        gst_vpx_error_name (status));
-    return GST_FLOW_ERROR;
-  }
-
-  /* dispatch remaining frames */
-  gst_vp9_enc_process (encoder);
-
-  g_mutex_lock (&encoder->encoder_lock);
-  if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS && encoder->multipass_cache_file) {
-    GError *err = NULL;
-
-    if (!g_file_set_contents (encoder->multipass_cache_file,
-            (const gchar *) encoder->first_pass_cache_content->data,
-            encoder->first_pass_cache_content->len, &err)) {
-      GST_ELEMENT_ERROR (encoder, RESOURCE, WRITE, (NULL),
-          ("Failed to write multipass cache file: %s", err->message));
-      g_error_free (err);
-    }
-  }
-  g_mutex_unlock (&encoder->encoder_lock);
-
-  return GST_FLOW_OK;
-}
-
-static gboolean
-gst_vp9_enc_flush (GstVideoEncoder * video_encoder)
-{
-  GstVP9Enc *encoder;
-
-  GST_DEBUG_OBJECT (video_encoder, "flush");
-
-  encoder = GST_VP9_ENC (video_encoder);
-
-  gst_vp9_enc_destroy_encoder (encoder);
-  if (encoder->input_state) {
-    gst_video_codec_state_ref (encoder->input_state);
-    gst_vp9_enc_set_format (video_encoder, encoder->input_state);
-    gst_video_codec_state_unref (encoder->input_state);
-  }
-
-  return TRUE;
-}
-
-static GstFlowReturn
-gst_vp9_enc_finish (GstVideoEncoder * video_encoder)
-{
-  GstVP9Enc *encoder;
-  GstFlowReturn ret;
-
-  GST_DEBUG_OBJECT (video_encoder, "finish");
-
-  encoder = GST_VP9_ENC (video_encoder);
-
-  if (encoder->inited) {
-    ret = gst_vp9_enc_drain (video_encoder);
-  } else {
-    ret = GST_FLOW_OK;
-  }
-
-  return ret;
-}
-
-static vpx_image_t *
-gst_vp9_enc_buffer_to_image (GstVP9Enc * enc, GstVideoFrame * frame)
-{
-  vpx_image_t *image = g_slice_new (vpx_image_t);
-
-  memcpy (image, &enc->image, sizeof (*image));
-
-  image->planes[VPX_PLANE_Y] = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
-  image->planes[VPX_PLANE_U] = GST_VIDEO_FRAME_COMP_DATA (frame, 1);
-  image->planes[VPX_PLANE_V] = GST_VIDEO_FRAME_COMP_DATA (frame, 2);
-
-  image->stride[VPX_PLANE_Y] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
-  image->stride[VPX_PLANE_U] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 1);
-  image->stride[VPX_PLANE_V] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 2);
-
-  return image;
-}
-
-static GstFlowReturn
-gst_vp9_enc_handle_frame (GstVideoEncoder * video_encoder,
+static void *
+gst_vp9_enc_process_frame_user_data (GstVPXEnc * enc,
     GstVideoCodecFrame * frame)
 {
-  GstVP9Enc *encoder;
-  vpx_codec_err_t status;
-  int flags = 0;
-  vpx_image_t *image;
-  GstVideoFrame vframe;
-  vpx_codec_pts_t pts;
-  unsigned long duration;
-
-  GST_DEBUG_OBJECT (video_encoder, "handle_frame");
-
-  encoder = GST_VP9_ENC (video_encoder);
-
-  GST_DEBUG_OBJECT (video_encoder, "size %d %d",
-      GST_VIDEO_INFO_WIDTH (&encoder->input_state->info),
-      GST_VIDEO_INFO_HEIGHT (&encoder->input_state->info));
-
-  gst_video_frame_map (&vframe, &encoder->input_state->info,
-      frame->input_buffer, GST_MAP_READ);
-  image = gst_vp9_enc_buffer_to_image (encoder, &vframe);
-
-  if (GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame)) {
-    flags |= VPX_EFLAG_FORCE_KF;
-  }
-
-  g_mutex_lock (&encoder->encoder_lock);
-  pts =
-      gst_util_uint64_scale (frame->pts,
-      encoder->cfg.g_timebase.den,
-      encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND);
-  encoder->last_pts = frame->pts;
-
-  if (frame->duration != GST_CLOCK_TIME_NONE) {
-    duration =
-        gst_util_uint64_scale (frame->duration, encoder->cfg.g_timebase.den,
-        encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND);
-    encoder->last_pts += frame->duration;
-  } else {
-    duration = 1;
-  }
-
-  status = vpx_codec_encode (&encoder->encoder, image,
-      pts, duration, flags, encoder->deadline);
-
-  g_mutex_unlock (&encoder->encoder_lock);
-  gst_video_frame_unmap (&vframe);
-
-  if (status != 0) {
-    GST_ELEMENT_ERROR (encoder, LIBRARY, ENCODE,
-        ("Failed to encode frame"), ("%s", gst_vpx_error_name (status)));
-    return FALSE;
-  }
-  gst_video_codec_frame_unref (frame);
-  return gst_vp9_enc_process (encoder);
+  return NULL;
 }
 
-static gboolean
-gst_vp9_enc_sink_event (GstVideoEncoder * benc, GstEvent * event)
+static GstFlowReturn
+gst_vp9_enc_handle_invisible_frame_buffer (GstVPXEnc * enc, void *user_data,
+    GstBuffer * buffer)
 {
-  GstVP9Enc *enc = GST_VP9_ENC (benc);
-
-  /* FIXME : Move this to base encoder class */
-
-  if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) {
-    GstTagList *list;
-    GstTagSetter *setter = GST_TAG_SETTER (enc);
-    const GstTagMergeMode mode = gst_tag_setter_get_tag_merge_mode (setter);
-
-    gst_event_parse_tag (event, &list);
-    gst_tag_setter_merge_tags (setter, list, mode);
-  }
-
-  /* just peeked, baseclass handles the rest */
-  return GST_VIDEO_ENCODER_CLASS (parent_class)->sink_event (benc, event);
+  GstFlowReturn ret;
+  g_mutex_unlock (&enc->encoder_lock);
+  ret = gst_pad_push (GST_VIDEO_ENCODER_SRC_PAD (enc), buffer);
+  g_mutex_lock (&enc->encoder_lock);
+  return ret;
 }
 
-static gboolean
-gst_vp9_enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query)
+static void
+gst_vp9_enc_set_frame_user_data (GstVPXEnc * enc, GstVideoCodecFrame * frame,
+    vpx_image_t * image)
 {
-  gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
-
-  return GST_VIDEO_ENCODER_CLASS (parent_class)->propose_allocation (encoder,
-      query);
+  return;
 }
 
 #endif /* HAVE_VP9_ENCODER */
diff --git a/ext/vpx/gstvp9enc.h b/ext/vpx/gstvp9enc.h
index e85a802..843372b 100644
--- a/ext/vpx/gstvp9enc.h
+++ b/ext/vpx/gstvp9enc.h
@@ -28,8 +28,7 @@
 
 #ifdef HAVE_VP9_ENCODER
 
-#include <gst/gst.h>
-#include <gst/video/gstvideoencoder.h>
+#include <gstvpxenc.h>
 
 /* FIXME: Undef HAVE_CONFIG_H because vpx_codec.h uses it,
  * which causes compilation failures */
@@ -37,9 +36,6 @@
 #undef HAVE_CONFIG_H
 #endif
 
-#include <vpx/vpx_encoder.h>
-#include <vpx/vp8cx.h>
-
 G_BEGIN_DECLS
 
 #define GST_TYPE_VP9_ENC \
@@ -58,59 +54,12 @@
 
 struct _GstVP9Enc
 {
-  GstVideoEncoder base_video_encoder;
-
-  /* < private > */
-  vpx_codec_ctx_t encoder;
-  GMutex encoder_lock;
-
-  /* properties */
-  vpx_codec_enc_cfg_t cfg;
-  gboolean have_default_config;
-  gboolean rc_target_bitrate_set;
-  gint n_ts_target_bitrate;
-  gint n_ts_rate_decimator;
-  gint n_ts_layer_id;
-  /* Global two-pass options */
-  gchar *multipass_cache_file;
-  gchar *multipass_cache_prefix;
-  guint multipass_cache_idx;
-  GByteArray *first_pass_cache_content;
-
-  /* Encode parameter */
-  gint64 deadline;
-
-  /* Controls */
-  VPX_SCALING_MODE h_scaling_mode;
-  VPX_SCALING_MODE v_scaling_mode;
-  int cpu_used;
-  gboolean enable_auto_alt_ref;
-  unsigned int noise_sensitivity;
-  unsigned int sharpness;
-  unsigned int static_threshold;
-  vp8e_token_partitions token_partitions;
-  unsigned int arnr_maxframes;
-  unsigned int arnr_strength;
-  unsigned int arnr_type;
-  vp8e_tuning tuning;
-  unsigned int cq_level;
-  unsigned int max_intra_bitrate_pct;
-  /* Timebase - a value of 0 will use the framerate */
-  unsigned int timebase_n;
-  unsigned int timebase_d;
-
-  /* state */
-  gboolean inited;
-
-  vpx_image_t image;
-
-  GstClockTime last_pts;
-  GstVideoCodecState *input_state;
+	GstVPXEnc base_vpx_encoder;
 };
 
 struct _GstVP9EncClass
 {
-  GstVideoEncoderClass base_video_encoder_class;
+  GstVPXEncClass  base_vpxenc_class;
 };
 
 GType gst_vp9_enc_get_type (void);
diff --git a/ext/vpx/gstvpxdec.c b/ext/vpx/gstvpxdec.c
new file mode 100644
index 0000000..fc75a7b
--- /dev/null
+++ b/ext/vpx/gstvpxdec.c
@@ -0,0 +1,796 @@
+/* VPX
+ * Copyright (C) 2006 David Schleef <ds@schleef.org>
+ * Copyright (C) 2008,2009,2010 Entropy Wave Inc
+ * Copyright (C) 2010-2012 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if defined(HAVE_VP8_DECODER) || defined(HAVE_VP9_DECODER)
+
+#include <string.h>
+
+#include "gstvpxdec.h"
+#include "gstvp8utils.h"
+
+#include <gst/video/gstvideometa.h>
+#include <gst/video/gstvideopool.h>
+
+GST_DEBUG_CATEGORY_STATIC (gst_vpxdec_debug);
+#define GST_CAT_DEFAULT gst_vpxdec_debug
+
+#define DEFAULT_POST_PROCESSING FALSE
+#define DEFAULT_POST_PROCESSING_FLAGS (VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE)
+#define DEFAULT_DEBLOCKING_LEVEL 4
+#define DEFAULT_NOISE_LEVEL 0
+#define DEFAULT_THREADS 0
+#define DEFAULT_VIDEO_CODEC_TAG NULL
+#define DEFAULT_CODEC_ALGO NULL
+
+enum
+{
+  PROP_0,
+  PROP_POST_PROCESSING,
+  PROP_POST_PROCESSING_FLAGS,
+  PROP_DEBLOCKING_LEVEL,
+  PROP_NOISE_LEVEL,
+  PROP_THREADS
+};
+
+#define C_FLAGS(v) ((guint) v)
+#define GST_VPX_DEC_TYPE_POST_PROCESSING_FLAGS (gst_vpx_dec_post_processing_flags_get_type())
+static GType
+gst_vpx_dec_post_processing_flags_get_type (void)
+{
+  static const GFlagsValue values[] = {
+    {C_FLAGS (VP8_DEBLOCK), "Deblock", "deblock"},
+    {C_FLAGS (VP8_DEMACROBLOCK), "Demacroblock", "demacroblock"},
+    {C_FLAGS (VP8_ADDNOISE), "Add noise", "addnoise"},
+    {C_FLAGS (VP8_MFQE), "Multi-frame quality enhancement", "mfqe"},
+    {0, NULL, NULL}
+  };
+  static volatile GType id = 0;
+
+  if (g_once_init_enter ((gsize *) & id)) {
+    GType _id;
+
+    _id = g_flags_register_static ("GstVPXDecPostProcessingFlags", values);
+
+    g_once_init_leave ((gsize *) & id, _id);
+  }
+
+  return id;
+}
+
+#undef C_FLAGS
+
+static void gst_vpx_dec_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_vpx_dec_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+static gboolean gst_vpx_dec_start (GstVideoDecoder * decoder);
+static gboolean gst_vpx_dec_stop (GstVideoDecoder * decoder);
+static gboolean gst_vpx_dec_set_format (GstVideoDecoder * decoder,
+    GstVideoCodecState * state);
+static gboolean gst_vpx_dec_flush (GstVideoDecoder * decoder);
+static GstFlowReturn
+gst_vpx_dec_handle_frame (GstVideoDecoder * decoder,
+    GstVideoCodecFrame * frame);
+static gboolean gst_vpx_dec_decide_allocation (GstVideoDecoder * decoder,
+    GstQuery * query);
+
+static void gst_vpx_dec_image_to_buffer (GstVPXDec * dec,
+    const vpx_image_t * img, GstBuffer * buffer);
+static GstFlowReturn gst_vpx_dec_open_codec (GstVPXDec * dec,
+    GstVideoCodecFrame * frame);
+static void gst_vpx_dec_default_send_tags (GstVPXDec * dec);
+static void gst_vpx_dec_set_stream_info (GstVPXDec * dec,
+    vpx_codec_stream_info_t * stream_info);
+static void gst_vpx_dec_set_default_format (GstVPXDec * dec, GstVideoFormat fmt,
+    int width, int height);
+static gboolean gst_vpx_dec_default_frame_format (GstVPXDec * dec,
+    vpx_image_t * img, GstVideoFormat * fmt);
+static void gst_vpx_dec_handle_resolution_change (GstVPXDec * dec,
+    vpx_image_t * img, GstVideoFormat fmt);
+
+#define parent_class gst_vpx_dec_parent_class
+G_DEFINE_TYPE (GstVPXDec, gst_vpx_dec, GST_TYPE_VIDEO_DECODER);
+
+static void
+gst_vpx_dec_class_init (GstVPXDecClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstVideoDecoderClass *base_video_decoder_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  base_video_decoder_class = GST_VIDEO_DECODER_CLASS (klass);
+
+  gobject_class->set_property = gst_vpx_dec_set_property;
+  gobject_class->get_property = gst_vpx_dec_get_property;
+
+  g_object_class_install_property (gobject_class, PROP_POST_PROCESSING,
+      g_param_spec_boolean ("post-processing", "Post Processing",
+          "Enable post processing", DEFAULT_POST_PROCESSING,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_POST_PROCESSING_FLAGS,
+      g_param_spec_flags ("post-processing-flags", "Post Processing Flags",
+          "Flags to control post processing",
+          GST_VPX_DEC_TYPE_POST_PROCESSING_FLAGS, DEFAULT_POST_PROCESSING_FLAGS,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_DEBLOCKING_LEVEL,
+      g_param_spec_uint ("deblocking-level", "Deblocking Level",
+          "Deblocking level",
+          0, 16, DEFAULT_DEBLOCKING_LEVEL,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_NOISE_LEVEL,
+      g_param_spec_uint ("noise-level", "Noise Level",
+          "Noise level",
+          0, 16, DEFAULT_NOISE_LEVEL,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_THREADS,
+      g_param_spec_uint ("threads", "Max Threads",
+          "Maximum number of decoding threads",
+          0, 16, DEFAULT_THREADS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  base_video_decoder_class->start = GST_DEBUG_FUNCPTR (gst_vpx_dec_start);
+  base_video_decoder_class->stop = GST_DEBUG_FUNCPTR (gst_vpx_dec_stop);
+  base_video_decoder_class->flush = GST_DEBUG_FUNCPTR (gst_vpx_dec_flush);
+  base_video_decoder_class->set_format =
+      GST_DEBUG_FUNCPTR (gst_vpx_dec_set_format);
+  base_video_decoder_class->handle_frame =
+      GST_DEBUG_FUNCPTR (gst_vpx_dec_handle_frame);;
+  base_video_decoder_class->decide_allocation =
+      GST_DEBUG_FUNCPTR (gst_vpx_dec_decide_allocation);
+
+  klass->video_codec_tag = DEFAULT_VIDEO_CODEC_TAG;
+  klass->codec_algo = DEFAULT_CODEC_ALGO;
+  klass->open_codec = GST_DEBUG_FUNCPTR (gst_vpx_dec_open_codec);
+  klass->send_tags = GST_DEBUG_FUNCPTR (gst_vpx_dec_default_send_tags);
+  klass->set_stream_info = NULL;
+  klass->set_default_format = NULL;
+  klass->handle_resolution_change = NULL;
+  klass->get_frame_format =
+      GST_DEBUG_FUNCPTR (gst_vpx_dec_default_frame_format);
+
+  GST_DEBUG_CATEGORY_INIT (gst_vpxdec_debug, "vpxdec", 0, "VPX Decoder");
+}
+
+static void
+gst_vpx_dec_init (GstVPXDec * gst_vpx_dec)
+{
+  GstVideoDecoder *decoder = (GstVideoDecoder *) gst_vpx_dec;
+
+  GST_DEBUG_OBJECT (gst_vpx_dec, "gst_vpx_dec_init");
+  gst_video_decoder_set_packetized (decoder, TRUE);
+  gst_vpx_dec->post_processing = DEFAULT_POST_PROCESSING;
+  gst_vpx_dec->post_processing_flags = DEFAULT_POST_PROCESSING_FLAGS;
+  gst_vpx_dec->deblocking_level = DEFAULT_DEBLOCKING_LEVEL;
+  gst_vpx_dec->noise_level = DEFAULT_NOISE_LEVEL;
+
+  gst_video_decoder_set_needs_format (decoder, TRUE);
+  gst_video_decoder_set_use_default_pad_acceptcaps (decoder, TRUE);
+  GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_DECODER_SINK_PAD (decoder));
+}
+
+static void
+gst_vpx_dec_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstVPXDec *dec;
+
+  g_return_if_fail (GST_IS_VPX_DEC (object));
+  dec = GST_VPX_DEC (object);
+
+  GST_DEBUG_OBJECT (object, "gst_vpx_dec_set_property");
+  switch (prop_id) {
+    case PROP_POST_PROCESSING:
+      dec->post_processing = g_value_get_boolean (value);
+      break;
+    case PROP_POST_PROCESSING_FLAGS:
+      dec->post_processing_flags = g_value_get_flags (value);
+      break;
+    case PROP_DEBLOCKING_LEVEL:
+      dec->deblocking_level = g_value_get_uint (value);
+      break;
+    case PROP_NOISE_LEVEL:
+      dec->noise_level = g_value_get_uint (value);
+      break;
+    case PROP_THREADS:
+      dec->threads = g_value_get_uint (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_vpx_dec_get_property (GObject * object, guint prop_id, GValue * value,
+    GParamSpec * pspec)
+{
+  GstVPXDec *dec;
+
+  g_return_if_fail (GST_IS_VPX_DEC (object));
+  dec = GST_VPX_DEC (object);
+
+  switch (prop_id) {
+    case PROP_POST_PROCESSING:
+      g_value_set_boolean (value, dec->post_processing);
+      break;
+    case PROP_POST_PROCESSING_FLAGS:
+      g_value_set_flags (value, dec->post_processing_flags);
+      break;
+    case PROP_DEBLOCKING_LEVEL:
+      g_value_set_uint (value, dec->deblocking_level);
+      break;
+    case PROP_NOISE_LEVEL:
+      g_value_set_uint (value, dec->noise_level);
+      break;
+    case PROP_THREADS:
+      g_value_set_uint (value, dec->threads);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static gboolean
+gst_vpx_dec_start (GstVideoDecoder * decoder)
+{
+  GstVPXDec *gst_vpx_dec = GST_VPX_DEC (decoder);
+
+  GST_DEBUG_OBJECT (gst_vpx_dec, "start");
+  gst_vpx_dec->decoder_inited = FALSE;
+
+  return TRUE;
+}
+
+static gboolean
+gst_vpx_dec_stop (GstVideoDecoder * base_video_decoder)
+{
+  GstVPXDec *gst_vpx_dec = GST_VPX_DEC (base_video_decoder);
+
+  GST_DEBUG_OBJECT (gst_vpx_dec, "stop");
+
+  if (gst_vpx_dec->output_state) {
+    gst_video_codec_state_unref (gst_vpx_dec->output_state);
+    gst_vpx_dec->output_state = NULL;
+  }
+
+  if (gst_vpx_dec->input_state) {
+    gst_video_codec_state_unref (gst_vpx_dec->input_state);
+    gst_vpx_dec->input_state = NULL;
+  }
+
+  if (gst_vpx_dec->decoder_inited)
+    vpx_codec_destroy (&gst_vpx_dec->decoder);
+  gst_vpx_dec->decoder_inited = FALSE;
+
+  if (gst_vpx_dec->pool) {
+    gst_buffer_pool_set_active (gst_vpx_dec->pool, FALSE);
+    gst_object_unref (gst_vpx_dec->pool);
+    gst_vpx_dec->pool = NULL;
+    gst_vpx_dec->buf_size = 0;
+  }
+
+  return TRUE;
+}
+
+static gboolean
+gst_vpx_dec_set_format (GstVideoDecoder * decoder, GstVideoCodecState * state)
+{
+  GstVPXDec *gst_vpx_dec = GST_VPX_DEC (decoder);
+
+  GST_DEBUG_OBJECT (gst_vpx_dec, "set_format");
+
+  if (gst_vpx_dec->decoder_inited)
+    vpx_codec_destroy (&gst_vpx_dec->decoder);
+  gst_vpx_dec->decoder_inited = FALSE;
+
+  if (gst_vpx_dec->output_state) {
+    gst_video_codec_state_unref (gst_vpx_dec->output_state);
+    gst_vpx_dec->output_state = NULL;
+  }
+
+  if (gst_vpx_dec->input_state) {
+    gst_video_codec_state_unref (gst_vpx_dec->input_state);
+  }
+
+  gst_vpx_dec->input_state = gst_video_codec_state_ref (state);
+
+  return TRUE;
+}
+
+static gboolean
+gst_vpx_dec_flush (GstVideoDecoder * base_video_decoder)
+{
+  GstVPXDec *decoder;
+
+  GST_DEBUG_OBJECT (base_video_decoder, "flush");
+
+  decoder = GST_VPX_DEC (base_video_decoder);
+
+  if (decoder->output_state) {
+    gst_video_codec_state_unref (decoder->output_state);
+    decoder->output_state = NULL;
+  }
+
+  if (decoder->decoder_inited)
+    vpx_codec_destroy (&decoder->decoder);
+  decoder->decoder_inited = FALSE;
+
+  return TRUE;
+}
+
+static void
+gst_vpx_dec_default_send_tags (GstVPXDec * dec)
+{
+  GstTagList *list;
+  GstVPXDecClass *vpxclass = GST_VPX_DEC_GET_CLASS (dec);
+
+  if (vpxclass->video_codec_tag == NULL)
+    return;
+
+  list = gst_tag_list_new_empty ();
+  gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
+      GST_TAG_VIDEO_CODEC, vpxclass->video_codec_tag, NULL);
+
+  gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (dec),
+      gst_event_new_tag (list));
+}
+
+#ifdef HAVE_VPX_1_4
+struct Frame
+{
+  GstMapInfo info;
+  GstBuffer *buffer;
+};
+
+static GstBuffer *
+gst_vpx_dec_prepare_image (GstVPXDec * dec, const vpx_image_t * img)
+{
+  gint comp;
+  GstVideoMeta *vmeta;
+  GstBuffer *buffer;
+  struct Frame *frame = img->fb_priv;
+  GstVideoInfo *info = &dec->output_state->info;
+
+  buffer = gst_buffer_ref (frame->buffer);
+
+  vmeta = gst_buffer_get_video_meta (buffer);
+  vmeta->format = GST_VIDEO_INFO_FORMAT (info);
+  vmeta->width = GST_VIDEO_INFO_WIDTH (info);
+  vmeta->height = GST_VIDEO_INFO_HEIGHT (info);
+  vmeta->n_planes = GST_VIDEO_INFO_N_PLANES (info);
+
+  for (comp = 0; comp < 4; comp++) {
+    vmeta->stride[comp] = img->stride[comp];
+    vmeta->offset[comp] =
+        img->planes[comp] ? img->planes[comp] - frame->info.data : 0;
+  }
+
+  /* FIXME This is a READ/WRITE mapped buffer see bug #754826 */
+
+  return buffer;
+}
+
+static int
+gst_vpx_dec_get_buffer_cb (gpointer priv, gsize min_size,
+    vpx_codec_frame_buffer_t * fb)
+{
+  GstVPXDec *dec = priv;
+  GstBuffer *buffer;
+  struct Frame *frame;
+  GstFlowReturn ret;
+
+  if (!dec->pool || dec->buf_size != min_size) {
+    GstBufferPool *pool;
+    GstStructure *config;
+    GstCaps *caps;
+    GstAllocator *allocator;
+    GstAllocationParams params;
+
+    if (dec->pool) {
+      gst_buffer_pool_set_active (dec->pool, FALSE);
+      gst_object_unref (dec->pool);
+      dec->pool = NULL;
+      dec->buf_size = 0;
+    }
+
+    gst_video_decoder_get_allocator (GST_VIDEO_DECODER (dec), &allocator,
+        &params);
+
+    if (allocator &&
+        GST_OBJECT_FLAG_IS_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC)) {
+      gst_object_unref (allocator);
+      allocator = NULL;
+    }
+
+    pool = gst_buffer_pool_new ();
+    config = gst_buffer_pool_get_config (pool);
+    gst_buffer_pool_config_set_allocator (config, allocator, &params);
+    caps = gst_caps_from_string ("video/internal");
+    gst_buffer_pool_config_set_params (config, caps, min_size, 2, 0);
+    gst_caps_unref (caps);
+    gst_buffer_pool_set_config (pool, config);
+
+    if (allocator)
+      gst_object_unref (allocator);
+
+    if (!gst_buffer_pool_set_active (pool, TRUE)) {
+      GST_WARNING ("Failed to create internal pool");
+      gst_object_unref (pool);
+      return -1;
+    }
+
+    dec->pool = pool;
+    dec->buf_size = min_size;
+  }
+
+  ret = gst_buffer_pool_acquire_buffer (dec->pool, &buffer, NULL);
+  if (ret != GST_FLOW_OK) {
+    GST_WARNING ("Failed to acquire buffer from internal pool.");
+    return -1;
+  }
+
+  /* Add it now, while the buffer is writable */
+  gst_buffer_add_video_meta (buffer, GST_VIDEO_FRAME_FLAG_NONE,
+      GST_VIDEO_FORMAT_ENCODED, 0, 0);
+
+  frame = g_new0 (struct Frame, 1);
+  if (!gst_buffer_map (buffer, &frame->info, GST_MAP_READWRITE)) {
+    gst_buffer_unref (buffer);
+    g_free (frame);
+    GST_WARNING ("Failed to map buffer from internal pool.");
+    return -1;
+  }
+
+  fb->size = frame->info.size;
+  fb->data = frame->info.data;
+  frame->buffer = buffer;
+  fb->priv = frame;
+
+  GST_TRACE_OBJECT (priv, "Allocated buffer %p", frame->buffer);
+
+  return 0;
+}
+
+static int
+gst_vpx_dec_release_buffer_cb (gpointer priv, vpx_codec_frame_buffer_t * fb)
+{
+  struct Frame *frame = fb->priv;
+
+  GST_TRACE_OBJECT (priv, "Release buffer %p", frame->buffer);
+
+  g_assert (frame);
+  gst_buffer_unmap (frame->buffer, &frame->info);
+  gst_buffer_unref (frame->buffer);
+  g_free (frame);
+
+  return 0;
+}
+#endif
+
+static void
+gst_vpx_dec_image_to_buffer (GstVPXDec * dec, const vpx_image_t * img,
+    GstBuffer * buffer)
+{
+  int deststride, srcstride, height, width, line, comp;
+  guint8 *dest, *src;
+  GstVideoFrame frame;
+  GstVideoInfo *info = &dec->output_state->info;
+
+  if (!gst_video_frame_map (&frame, info, buffer, GST_MAP_WRITE)) {
+    GST_ERROR_OBJECT (dec, "Could not map video buffer");
+    return;
+  }
+
+  for (comp = 0; comp < 3; comp++) {
+    dest = GST_VIDEO_FRAME_COMP_DATA (&frame, comp);
+    src = img->planes[comp];
+    width = GST_VIDEO_FRAME_COMP_WIDTH (&frame, comp)
+        * GST_VIDEO_FRAME_COMP_PSTRIDE (&frame, comp);
+    height = GST_VIDEO_FRAME_COMP_HEIGHT (&frame, comp);
+    deststride = GST_VIDEO_FRAME_COMP_STRIDE (&frame, comp);
+    srcstride = img->stride[comp];
+
+    if (srcstride == deststride) {
+      GST_TRACE_OBJECT (dec, "Stride matches. Comp %d: %d, copying full plane",
+          comp, srcstride);
+      memcpy (dest, src, srcstride * height);
+    } else {
+      GST_TRACE_OBJECT (dec, "Stride mismatch. Comp %d: %d != %d, copying "
+          "line by line.", comp, srcstride, deststride);
+      for (line = 0; line < height; line++) {
+        memcpy (dest, src, width);
+        dest += deststride;
+        src += srcstride;
+      }
+    }
+  }
+
+  gst_video_frame_unmap (&frame);
+}
+
+static GstFlowReturn
+gst_vpx_dec_open_codec (GstVPXDec * dec, GstVideoCodecFrame * frame)
+{
+  int flags = 0;
+  vpx_codec_stream_info_t stream_info;
+  vpx_codec_caps_t caps;
+  vpx_codec_dec_cfg_t cfg;
+  vpx_codec_err_t status;
+  GstMapInfo minfo;
+  GstVPXDecClass *vpxclass = GST_VPX_DEC_GET_CLASS (dec);
+
+  g_return_val_if_fail (vpxclass->codec_algo != NULL, GST_FLOW_ERROR);
+
+  memset (&stream_info, 0, sizeof (stream_info));
+  memset (&cfg, 0, sizeof (cfg));
+  stream_info.sz = sizeof (stream_info);
+
+  if (!gst_buffer_map (frame->input_buffer, &minfo, GST_MAP_READ)) {
+    GST_ERROR_OBJECT (dec, "Failed to map input buffer");
+    return GST_FLOW_ERROR;
+  }
+
+  status = vpx_codec_peek_stream_info (vpxclass->codec_algo,
+      minfo.data, minfo.size, &stream_info);
+
+  gst_buffer_unmap (frame->input_buffer, &minfo);
+
+  if (status != VPX_CODEC_OK) {
+    GST_WARNING_OBJECT (dec, "VPX preprocessing error: %s",
+        gst_vpx_error_name (status));
+    gst_video_decoder_drop_frame (GST_VIDEO_DECODER (dec), frame);
+    return GST_FLOW_CUSTOM_SUCCESS_1;
+  }
+  if (!stream_info.is_kf) {
+    GST_WARNING_OBJECT (dec, "No keyframe, skipping");
+    gst_video_decoder_drop_frame (GST_VIDEO_DECODER (dec), frame);
+    return GST_FLOW_CUSTOM_SUCCESS_1;
+  }
+
+  gst_vpx_dec_set_stream_info (dec, &stream_info);
+  gst_vpx_dec_set_default_format (dec, GST_VIDEO_FORMAT_I420, stream_info.w,
+      stream_info.h);
+
+  cfg.w = stream_info.w;
+  cfg.h = stream_info.h;
+  cfg.threads = dec->threads;
+
+  caps = vpx_codec_get_caps (vpxclass->codec_algo);
+
+  if (dec->post_processing) {
+    if (!(caps & VPX_CODEC_CAP_POSTPROC)) {
+      GST_WARNING_OBJECT (dec, "Decoder does not support post processing");
+    } else {
+      flags |= VPX_CODEC_USE_POSTPROC;
+    }
+  }
+
+  status =
+      vpx_codec_dec_init (&dec->decoder, vpxclass->codec_algo, &cfg, flags);
+  if (status != VPX_CODEC_OK) {
+    GST_ELEMENT_ERROR (dec, LIBRARY, INIT,
+        ("Failed to initialize VP8 decoder"), ("%s",
+            gst_vpx_error_name (status)));
+    return GST_FLOW_ERROR;
+  }
+
+  if ((caps & VPX_CODEC_CAP_POSTPROC) && dec->post_processing) {
+    vp8_postproc_cfg_t pp_cfg = { 0, };
+
+    pp_cfg.post_proc_flag = dec->post_processing_flags;
+    pp_cfg.deblocking_level = dec->deblocking_level;
+    pp_cfg.noise_level = dec->noise_level;
+
+    status = vpx_codec_control (&dec->decoder, VP8_SET_POSTPROC, &pp_cfg);
+    if (status != VPX_CODEC_OK) {
+      GST_WARNING_OBJECT (dec, "Couldn't set postprocessing settings: %s",
+          gst_vpx_error_name (status));
+    }
+  }
+#ifdef HAVE_VPX_1_4
+  vpx_codec_set_frame_buffer_functions (&dec->decoder,
+      gst_vpx_dec_get_buffer_cb, gst_vpx_dec_release_buffer_cb, dec);
+#endif
+
+  dec->decoder_inited = TRUE;
+
+  return GST_FLOW_OK;
+}
+
+static GstFlowReturn
+gst_vpx_dec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
+{
+  GstVPXDec *dec;
+  GstFlowReturn ret = GST_FLOW_OK;
+  vpx_codec_err_t status;
+  vpx_codec_iter_t iter = NULL;
+  vpx_image_t *img;
+  long decoder_deadline = 0;
+  GstClockTimeDiff deadline;
+  GstMapInfo minfo;
+  GstVPXDecClass *vpxclass;
+  GstVideoFormat fmt;
+
+  GST_LOG_OBJECT (decoder, "handle_frame");
+
+  dec = GST_VPX_DEC (decoder);
+  vpxclass = GST_VPX_DEC_GET_CLASS (dec);
+
+  if (!dec->decoder_inited) {
+    ret = vpxclass->open_codec (dec, frame);
+    if (ret == GST_FLOW_CUSTOM_SUCCESS_1)
+      return GST_FLOW_OK;
+    else if (ret != GST_FLOW_OK)
+      return ret;
+  }
+
+  deadline = gst_video_decoder_get_max_decode_time (decoder, frame);
+  if (deadline < 0) {
+    decoder_deadline = 1;
+  } else if (deadline == G_MAXINT64) {
+    decoder_deadline = 0;
+  } else {
+    decoder_deadline = MAX (1, deadline / GST_MSECOND);
+  }
+
+  if (!gst_buffer_map (frame->input_buffer, &minfo, GST_MAP_READ)) {
+    GST_ERROR_OBJECT (dec, "Failed to map input buffer");
+    return GST_FLOW_ERROR;
+  }
+
+  status = vpx_codec_decode (&dec->decoder,
+      minfo.data, minfo.size, NULL, decoder_deadline);
+
+  gst_buffer_unmap (frame->input_buffer, &minfo);
+
+  if (status) {
+    GST_VIDEO_DECODER_ERROR (decoder, 1, LIBRARY, ENCODE,
+        ("Failed to decode frame"), ("%s", gst_vpx_error_name (status)), ret);
+    return ret;
+  }
+
+  img = vpx_codec_get_frame (&dec->decoder, &iter);
+  if (img) {
+    if (vpxclass->get_frame_format (dec, img, &fmt) == FALSE) {
+      vpx_img_free (img);
+      GST_ELEMENT_ERROR (decoder, LIBRARY, ENCODE,
+          ("Failed to decode frame"), ("Unsupported color format %d",
+              img->fmt));
+      return GST_FLOW_ERROR;
+    }
+
+    if (deadline < 0) {
+      GST_LOG_OBJECT (dec, "Skipping late frame (%f s past deadline)",
+          (double) -deadline / GST_SECOND);
+      gst_video_decoder_drop_frame (decoder, frame);
+    } else {
+      gst_vpx_dec_handle_resolution_change (dec, img, fmt);
+#ifdef HAVE_VPX_1_4
+      if (img->fb_priv && dec->have_video_meta) {
+        frame->output_buffer = gst_vpx_dec_prepare_image (dec, img);
+        ret = gst_video_decoder_finish_frame (decoder, frame);
+      } else
+#endif
+      {
+        ret = gst_video_decoder_allocate_output_frame (decoder, frame);
+
+        if (ret == GST_FLOW_OK) {
+          gst_vpx_dec_image_to_buffer (dec, img, frame->output_buffer);
+          ret = gst_video_decoder_finish_frame (decoder, frame);
+        } else {
+          gst_video_decoder_drop_frame (decoder, frame);
+        }
+      }
+    }
+
+    vpx_img_free (img);
+
+    while ((img = vpx_codec_get_frame (&dec->decoder, &iter))) {
+      GST_WARNING_OBJECT (decoder, "Multiple decoded frames... dropping");
+      vpx_img_free (img);
+    }
+  } else {
+    /* Invisible frame */
+    GST_VIDEO_CODEC_FRAME_SET_DECODE_ONLY (frame);
+    gst_video_decoder_finish_frame (decoder, frame);
+  }
+
+  return ret;
+}
+
+static gboolean
+gst_vpx_dec_decide_allocation (GstVideoDecoder * bdec, GstQuery * query)
+{
+  GstVPXDec *dec = GST_VPX_DEC (bdec);
+  GstBufferPool *pool;
+  GstStructure *config;
+
+  if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (bdec, query))
+    return FALSE;
+
+  g_assert (gst_query_get_n_allocation_pools (query) > 0);
+  gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL);
+  g_assert (pool != NULL);
+
+  config = gst_buffer_pool_get_config (pool);
+  if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) {
+    gst_buffer_pool_config_add_option (config,
+        GST_BUFFER_POOL_OPTION_VIDEO_META);
+    dec->have_video_meta = TRUE;
+  }
+  gst_buffer_pool_set_config (pool, config);
+  gst_object_unref (pool);
+
+  return TRUE;
+}
+
+static void
+gst_vpx_dec_set_stream_info (GstVPXDec * dec,
+    vpx_codec_stream_info_t * stream_info)
+{
+  GstVPXDecClass *vpxclass = GST_VPX_DEC_GET_CLASS (dec);
+  if (vpxclass->set_stream_info != NULL) {
+    vpxclass->set_stream_info (dec, stream_info);
+  }
+}
+
+static void
+gst_vpx_dec_set_default_format (GstVPXDec * dec, GstVideoFormat fmt, int width,
+    int height)
+{
+  GstVPXDecClass *vpxclass = GST_VPX_DEC_GET_CLASS (dec);
+  if (vpxclass->set_default_format != NULL) {
+    vpxclass->set_default_format (dec, fmt, width, height);
+  }
+}
+
+static gboolean
+gst_vpx_dec_default_frame_format (GstVPXDec * dec, vpx_image_t * img,
+    GstVideoFormat * fmt)
+{
+  if (img->fmt == VPX_IMG_FMT_I420) {
+    *fmt = GST_VIDEO_FORMAT_I420;
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+
+}
+
+static void
+gst_vpx_dec_handle_resolution_change (GstVPXDec * dec, vpx_image_t * img,
+    GstVideoFormat fmt)
+{
+  GstVPXDecClass *vpxclass = GST_VPX_DEC_GET_CLASS (dec);
+  if (vpxclass->handle_resolution_change != NULL) {
+    vpxclass->handle_resolution_change (dec, img, fmt);
+  }
+}
+
+#endif /* HAVE_VP8_DECODER ||  HAVE_VP9_DECODER */
diff --git a/ext/vpx/gstvpxdec.h b/ext/vpx/gstvpxdec.h
new file mode 100644
index 0000000..6852f86
--- /dev/null
+++ b/ext/vpx/gstvpxdec.h
@@ -0,0 +1,113 @@
+/* VPX
+ * Copyright (C) 2006 David Schleef <ds@schleef.org>
+ * Copyright (C) 2008,2009,2010 Entropy Wave Inc
+ * Copyright (C) 2010 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef __GST_VPX_DEC_H__
+#define __GST_VPX_DEC_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if defined(HAVE_VP8_DECODER) || defined(HAVE_VP9_DECODER)
+
+#include <gst/gst.h>
+#include <gst/video/gstvideodecoder.h>
+
+/* FIXME: Undef HAVE_CONFIG_H because vpx_codec.h uses it,
+ * which causes compilation failures */
+#ifdef HAVE_CONFIG_H
+#undef HAVE_CONFIG_H
+#endif
+
+#include <vpx/vpx_decoder.h>
+#include <vpx/vp8dx.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_VPX_DEC \
+  (gst_vpx_dec_get_type())
+#define GST_VPX_DEC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VPX_DEC,GstVPXDec))
+#define GST_VPX_DEC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VPX_DEC,GstVPXDecClass))
+#define GST_IS_VPX_DEC(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VPX_DEC))
+#define GST_IS_VPX_DEC_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VPX_DEC))
+#define GST_VPX_DEC_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VPX_DEC, GstVPXDecClass))
+
+typedef struct _GstVPXDec GstVPXDec;
+typedef struct _GstVPXDecClass GstVPXDecClass;
+
+struct _GstVPXDec
+{
+  GstVideoDecoder base_video_decoder;
+
+  /* < private > */
+  vpx_codec_ctx_t decoder;
+
+  /* state */
+  gboolean decoder_inited;
+
+  /* properties */
+  gboolean post_processing;
+  enum vp8_postproc_level post_processing_flags;
+  gint deblocking_level;
+  gint noise_level;
+  gint threads;
+
+  GstVideoCodecState *input_state;
+  GstVideoCodecState *output_state;
+
+  /* allocation */
+  gboolean have_video_meta;
+  GstBufferPool *pool;
+  gsize buf_size;
+};
+
+struct _GstVPXDecClass
+{
+  GstVideoDecoderClass base_video_decoder_class;
+  const char* video_codec_tag;
+  /*supported vpx algo*/
+  vpx_codec_iface_t* codec_algo;
+  /*virtual function to open_codec*/
+  GstFlowReturn (*open_codec) (GstVPXDec * dec, GstVideoCodecFrame * frame);
+  /*virtual function to send tags*/
+  void (*send_tags) (GstVPXDec* dec);
+  /*virtual function to set/correct the stream info*/
+  void (*set_stream_info) (GstVPXDec *dec, vpx_codec_stream_info_t *stream_info);
+  /*virtual function to set default format while opening codec*/
+  void (*set_default_format) (GstVPXDec *dec, GstVideoFormat fmt, int width, int height);
+  /*virtual function to negotiate format while handling frame*/
+  void (*handle_resolution_change) (GstVPXDec *dec, vpx_image_t *img, GstVideoFormat fmt);
+  /*virtual function to check valid format*/
+  gboolean (*get_frame_format)(GstVPXDec *dec, vpx_image_t *img, GstVideoFormat* fmt);
+};
+
+GType gst_vpx_dec_get_type (void);
+
+G_END_DECLS
+
+#endif
+
+#endif /* __GST_VP8_DEC_H__ */
diff --git a/ext/vpx/gstvpxenc.c b/ext/vpx/gstvpxenc.c
new file mode 100644
index 0000000..e56b766
--- /dev/null
+++ b/ext/vpx/gstvpxenc.c
@@ -0,0 +1,1941 @@
+/* VPX
+ * Copyright (C) 2006 David Schleef <ds@schleef.org>
+ * Copyright (C) 2010 Entropy Wave Inc
+ * Copyright (C) 2010-2012 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if defined(HAVE_VP8_ENCODER) || defined(HAVE_VP9_ENCODER)
+
+/* glib decided in 2.32 it would be a great idea to deprecated GValueArray without
+ * providing an alternative
+ *
+ * See https://bugzilla.gnome.org/show_bug.cgi?id=667228
+ * */
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
+#include <gst/tag/tag.h>
+#include <gst/video/video.h>
+#include <string.h>
+
+#include "gstvp8utils.h"
+#include "gstvpxenc.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_vpxenc_debug);
+#define GST_CAT_DEFAULT gst_vpxenc_debug
+
+/* From vp8/vp8_cx_iface.c and vp9/vp9_cx_iface.c */
+#define DEFAULT_PROFILE 0
+
+#define DEFAULT_RC_END_USAGE VPX_VBR
+#define DEFAULT_RC_TARGET_BITRATE 256000
+#define DEFAULT_RC_MIN_QUANTIZER 4
+#define DEFAULT_RC_MAX_QUANTIZER 63
+
+#define DEFAULT_RC_DROPFRAME_THRESH 0
+#define DEFAULT_RC_RESIZE_ALLOWED 0
+#define DEFAULT_RC_RESIZE_UP_THRESH 30
+#define DEFAULT_RC_RESIZE_DOWN_THRESH 60
+#define DEFAULT_RC_UNDERSHOOT_PCT 100
+#define DEFAULT_RC_OVERSHOOT_PCT 100
+#define DEFAULT_RC_BUF_SZ 6000
+#define DEFAULT_RC_BUF_INITIAL_SZ 4000
+#define DEFAULT_RC_BUF_OPTIMAL_SZ 5000
+#define DEFAULT_RC_2PASS_VBR_BIAS_PCT 50
+#define DEFAULT_RC_2PASS_VBR_MINSECTION_PCT 0
+#define DEFAULT_RC_2PASS_VBR_MAXSECTION_PCT 400
+
+#define DEFAULT_KF_MODE VPX_KF_AUTO
+#define DEFAULT_KF_MAX_DIST 128
+
+#define DEFAULT_MULTIPASS_MODE VPX_RC_ONE_PASS
+#define DEFAULT_MULTIPASS_CACHE_FILE "multipass.cache"
+
+#define DEFAULT_TS_NUMBER_LAYERS 1
+#define DEFAULT_TS_TARGET_BITRATE NULL
+#define DEFAULT_TS_RATE_DECIMATOR NULL
+#define DEFAULT_TS_PERIODICITY 0
+#define DEFAULT_TS_LAYER_ID NULL
+
+#define DEFAULT_ERROR_RESILIENT 0
+#define DEFAULT_LAG_IN_FRAMES 0
+
+#define DEFAULT_THREADS 0
+
+#define DEFAULT_H_SCALING_MODE VP8E_NORMAL
+#define DEFAULT_V_SCALING_MODE VP8E_NORMAL
+#define DEFAULT_CPU_USED 0
+#define DEFAULT_ENABLE_AUTO_ALT_REF FALSE
+#define DEFAULT_DEADLINE VPX_DL_BEST_QUALITY
+#define DEFAULT_NOISE_SENSITIVITY 0
+#define DEFAULT_SHARPNESS 0
+#define DEFAULT_STATIC_THRESHOLD 0
+#define DEFAULT_TOKEN_PARTITIONS 0
+#define DEFAULT_ARNR_MAXFRAMES 0
+#define DEFAULT_ARNR_STRENGTH 3
+#define DEFAULT_ARNR_TYPE 3
+#define DEFAULT_TUNING VP8_TUNE_PSNR
+#define DEFAULT_CQ_LEVEL 10
+#define DEFAULT_MAX_INTRA_BITRATE_PCT 0
+#define DEFAULT_TIMEBASE_N 0
+#define DEFAULT_TIMEBASE_D 1
+
+enum
+{
+  PROP_0,
+  PROP_RC_END_USAGE,
+  PROP_RC_TARGET_BITRATE,
+  PROP_RC_MIN_QUANTIZER,
+  PROP_RC_MAX_QUANTIZER,
+  PROP_RC_DROPFRAME_THRESH,
+  PROP_RC_RESIZE_ALLOWED,
+  PROP_RC_RESIZE_UP_THRESH,
+  PROP_RC_RESIZE_DOWN_THRESH,
+  PROP_RC_UNDERSHOOT_PCT,
+  PROP_RC_OVERSHOOT_PCT,
+  PROP_RC_BUF_SZ,
+  PROP_RC_BUF_INITIAL_SZ,
+  PROP_RC_BUF_OPTIMAL_SZ,
+  PROP_RC_2PASS_VBR_BIAS_PCT,
+  PROP_RC_2PASS_VBR_MINSECTION_PCT,
+  PROP_RC_2PASS_VBR_MAXSECTION_PCT,
+  PROP_KF_MODE,
+  PROP_KF_MAX_DIST,
+  PROP_TS_NUMBER_LAYERS,
+  PROP_TS_TARGET_BITRATE,
+  PROP_TS_RATE_DECIMATOR,
+  PROP_TS_PERIODICITY,
+  PROP_TS_LAYER_ID,
+  PROP_MULTIPASS_MODE,
+  PROP_MULTIPASS_CACHE_FILE,
+  PROP_ERROR_RESILIENT,
+  PROP_LAG_IN_FRAMES,
+  PROP_THREADS,
+  PROP_DEADLINE,
+  PROP_H_SCALING_MODE,
+  PROP_V_SCALING_MODE,
+  PROP_CPU_USED,
+  PROP_ENABLE_AUTO_ALT_REF,
+  PROP_NOISE_SENSITIVITY,
+  PROP_SHARPNESS,
+  PROP_STATIC_THRESHOLD,
+  PROP_TOKEN_PARTITIONS,
+  PROP_ARNR_MAXFRAMES,
+  PROP_ARNR_STRENGTH,
+  PROP_ARNR_TYPE,
+  PROP_TUNING,
+  PROP_CQ_LEVEL,
+  PROP_MAX_INTRA_BITRATE_PCT,
+  PROP_TIMEBASE
+};
+
+
+#define GST_VPX_ENC_END_USAGE_TYPE (gst_vpx_enc_end_usage_get_type())
+static GType
+gst_vpx_enc_end_usage_get_type (void)
+{
+  static const GEnumValue values[] = {
+    {VPX_VBR, "Variable Bit Rate (VBR) mode", "vbr"},
+    {VPX_CBR, "Constant Bit Rate (CBR) mode", "cbr"},
+    {VPX_CQ, "Constant Quality Mode (CQ) mode", "cq"},
+    {0, NULL, NULL}
+  };
+  static volatile GType id = 0;
+
+  if (g_once_init_enter ((gsize *) & id)) {
+    GType _id;
+
+    _id = g_enum_register_static ("GstVPXEncEndUsage", values);
+
+    g_once_init_leave ((gsize *) & id, _id);
+  }
+
+  return id;
+}
+
+#define GST_VPX_ENC_MULTIPASS_MODE_TYPE (gst_vpx_enc_multipass_mode_get_type())
+static GType
+gst_vpx_enc_multipass_mode_get_type (void)
+{
+  static const GEnumValue values[] = {
+    {VPX_RC_ONE_PASS, "One pass encoding (default)", "one-pass"},
+    {VPX_RC_FIRST_PASS, "First pass of multipass encoding", "first-pass"},
+    {VPX_RC_LAST_PASS, "Last pass of multipass encoding", "last-pass"},
+    {0, NULL, NULL}
+  };
+  static volatile GType id = 0;
+
+  if (g_once_init_enter ((gsize *) & id)) {
+    GType _id;
+
+    _id = g_enum_register_static ("GstVPXEncMultipassMode", values);
+
+    g_once_init_leave ((gsize *) & id, _id);
+  }
+
+  return id;
+}
+
+#define GST_VPX_ENC_KF_MODE_TYPE (gst_vpx_enc_kf_mode_get_type())
+static GType
+gst_vpx_enc_kf_mode_get_type (void)
+{
+  static const GEnumValue values[] = {
+    {VPX_KF_AUTO, "Determine optimal placement automatically", "auto"},
+    {VPX_KF_DISABLED, "Don't automatically place keyframes", "disabled"},
+    {0, NULL, NULL}
+  };
+  static volatile GType id = 0;
+
+  if (g_once_init_enter ((gsize *) & id)) {
+    GType _id;
+
+    _id = g_enum_register_static ("GstVPXEncKfMode", values);
+
+    g_once_init_leave ((gsize *) & id, _id);
+  }
+
+  return id;
+}
+
+#define GST_VPX_ENC_TUNING_TYPE (gst_vpx_enc_tuning_get_type())
+static GType
+gst_vpx_enc_tuning_get_type (void)
+{
+  static const GEnumValue values[] = {
+    {VP8_TUNE_PSNR, "Tune for PSNR", "psnr"},
+    {VP8_TUNE_SSIM, "Tune for SSIM", "ssim"},
+    {0, NULL, NULL}
+  };
+  static volatile GType id = 0;
+
+  if (g_once_init_enter ((gsize *) & id)) {
+    GType _id;
+
+    _id = g_enum_register_static ("GstVPXEncTuning", values);
+
+    g_once_init_leave ((gsize *) & id, _id);
+  }
+
+  return id;
+}
+
+#define GST_VPX_ENC_SCALING_MODE_TYPE (gst_vpx_enc_scaling_mode_get_type())
+static GType
+gst_vpx_enc_scaling_mode_get_type (void)
+{
+  static const GEnumValue values[] = {
+    {VP8E_NORMAL, "Normal", "normal"},
+    {VP8E_FOURFIVE, "4:5", "4:5"},
+    {VP8E_THREEFIVE, "3:5", "3:5"},
+    {VP8E_ONETWO, "1:2", "1:2"},
+    {0, NULL, NULL}
+  };
+  static volatile GType id = 0;
+
+  if (g_once_init_enter ((gsize *) & id)) {
+    GType _id;
+
+    _id = g_enum_register_static ("GstVPXEncScalingMode", values);
+
+    g_once_init_leave ((gsize *) & id, _id);
+  }
+
+  return id;
+}
+
+#define GST_VPX_ENC_TOKEN_PARTITIONS_TYPE (gst_vpx_enc_token_partitions_get_type())
+static GType
+gst_vpx_enc_token_partitions_get_type (void)
+{
+  static const GEnumValue values[] = {
+    {VP8_ONE_TOKENPARTITION, "One token partition", "1"},
+    {VP8_TWO_TOKENPARTITION, "Two token partitions", "2"},
+    {VP8_FOUR_TOKENPARTITION, "Four token partitions", "4"},
+    {VP8_EIGHT_TOKENPARTITION, "Eight token partitions", "8"},
+    {0, NULL, NULL}
+  };
+  static volatile GType id = 0;
+
+  if (g_once_init_enter ((gsize *) & id)) {
+    GType _id;
+
+    _id = g_enum_register_static ("GstVPXEncTokenPartitions", values);
+
+    g_once_init_leave ((gsize *) & id, _id);
+  }
+
+  return id;
+}
+
+#define GST_VPX_ENC_ER_FLAGS_TYPE (gst_vpx_enc_er_flags_get_type())
+static GType
+gst_vpx_enc_er_flags_get_type (void)
+{
+  static const GFlagsValue values[] = {
+    {VPX_ERROR_RESILIENT_DEFAULT, "Default error resilience", "default"},
+    {VPX_ERROR_RESILIENT_PARTITIONS,
+        "Allow partitions to be decoded independently", "partitions"},
+    {0, NULL, NULL}
+  };
+  static volatile GType id = 0;
+
+  if (g_once_init_enter ((gsize *) & id)) {
+    GType _id;
+
+    _id = g_flags_register_static ("GstVPXEncErFlags", values);
+
+    g_once_init_leave ((gsize *) & id, _id);
+  }
+
+  return id;
+}
+
+static void gst_vpx_enc_finalize (GObject * object);
+static void gst_vpx_enc_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_vpx_enc_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+static gboolean gst_vpx_enc_start (GstVideoEncoder * encoder);
+static gboolean gst_vpx_enc_stop (GstVideoEncoder * encoder);
+static gboolean gst_vpx_enc_set_format (GstVideoEncoder *
+    video_encoder, GstVideoCodecState * state);
+static GstFlowReturn gst_vpx_enc_finish (GstVideoEncoder * video_encoder);
+static gboolean gst_vpx_enc_flush (GstVideoEncoder * video_encoder);
+static GstFlowReturn gst_vpx_enc_drain (GstVideoEncoder * video_encoder);
+static GstFlowReturn gst_vpx_enc_handle_frame (GstVideoEncoder *
+    video_encoder, GstVideoCodecFrame * frame);
+static gboolean gst_vpx_enc_sink_event (GstVideoEncoder *
+    video_encoder, GstEvent * event);
+static gboolean gst_vpx_enc_propose_allocation (GstVideoEncoder * encoder,
+    GstQuery * query);
+
+#define parent_class gst_vpx_enc_parent_class
+G_DEFINE_TYPE_WITH_CODE (GstVPXEnc, gst_vpx_enc, GST_TYPE_VIDEO_ENCODER,
+    G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL);
+    G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL););
+
+static void
+gst_vpx_enc_class_init (GstVPXEncClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstVideoEncoderClass *video_encoder_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  video_encoder_class = GST_VIDEO_ENCODER_CLASS (klass);
+
+  gobject_class->set_property = gst_vpx_enc_set_property;
+  gobject_class->get_property = gst_vpx_enc_get_property;
+  gobject_class->finalize = gst_vpx_enc_finalize;
+
+  video_encoder_class->start = gst_vpx_enc_start;
+  video_encoder_class->stop = gst_vpx_enc_stop;
+  video_encoder_class->handle_frame = gst_vpx_enc_handle_frame;
+  video_encoder_class->set_format = gst_vpx_enc_set_format;
+  video_encoder_class->flush = gst_vpx_enc_flush;
+  video_encoder_class->finish = gst_vpx_enc_finish;
+  video_encoder_class->sink_event = gst_vpx_enc_sink_event;
+  video_encoder_class->propose_allocation = gst_vpx_enc_propose_allocation;
+
+  g_object_class_install_property (gobject_class, PROP_RC_END_USAGE,
+      g_param_spec_enum ("end-usage", "Rate control mode",
+          "Rate control mode",
+          GST_VPX_ENC_END_USAGE_TYPE, DEFAULT_RC_END_USAGE,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_RC_TARGET_BITRATE,
+      g_param_spec_int ("target-bitrate", "Target bitrate",
+          "Target bitrate (in bits/sec)",
+          0, G_MAXINT, DEFAULT_RC_TARGET_BITRATE,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_RC_MIN_QUANTIZER,
+      g_param_spec_int ("min-quantizer", "Minimum Quantizer",
+          "Minimum Quantizer (best)",
+          0, 63, DEFAULT_RC_MIN_QUANTIZER,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_RC_MAX_QUANTIZER,
+      g_param_spec_int ("max-quantizer", "Maximum Quantizer",
+          "Maximum Quantizer (worst)",
+          0, 63, DEFAULT_RC_MAX_QUANTIZER,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_RC_DROPFRAME_THRESH,
+      g_param_spec_int ("dropframe-threshold", "Drop Frame Threshold",
+          "Temporal resampling threshold (buf %)",
+          0, 100, DEFAULT_RC_DROPFRAME_THRESH,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_RC_RESIZE_ALLOWED,
+      g_param_spec_boolean ("resize-allowed", "Resize Allowed",
+          "Allow spatial resampling",
+          DEFAULT_RC_RESIZE_ALLOWED,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_RC_RESIZE_UP_THRESH,
+      g_param_spec_int ("resize-up-threshold", "Resize Up Threshold",
+          "Upscale threshold (buf %)",
+          0, 100, DEFAULT_RC_RESIZE_UP_THRESH,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_RC_RESIZE_DOWN_THRESH,
+      g_param_spec_int ("resize-down-threshold", "Resize Down Threshold",
+          "Downscale threshold (buf %)",
+          0, 100, DEFAULT_RC_RESIZE_DOWN_THRESH,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_RC_UNDERSHOOT_PCT,
+      g_param_spec_int ("undershoot", "Undershoot PCT",
+          "Datarate undershoot (min) target (%)",
+          0, 1000, DEFAULT_RC_UNDERSHOOT_PCT,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_RC_OVERSHOOT_PCT,
+      g_param_spec_int ("overshoot", "Overshoot PCT",
+          "Datarate overshoot (max) target (%)",
+          0, 1000, DEFAULT_RC_OVERSHOOT_PCT,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_RC_BUF_SZ,
+      g_param_spec_int ("buffer-size", "Buffer size",
+          "Client buffer size (ms)",
+          0, G_MAXINT, DEFAULT_RC_BUF_SZ,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_RC_BUF_INITIAL_SZ,
+      g_param_spec_int ("buffer-initial-size", "Buffer initial size",
+          "Initial client buffer size (ms)",
+          0, G_MAXINT, DEFAULT_RC_BUF_INITIAL_SZ,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_RC_BUF_OPTIMAL_SZ,
+      g_param_spec_int ("buffer-optimal-size", "Buffer optimal size",
+          "Optimal client buffer size (ms)",
+          0, G_MAXINT, DEFAULT_RC_BUF_OPTIMAL_SZ,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_RC_2PASS_VBR_BIAS_PCT,
+      g_param_spec_int ("twopass-vbr-bias", "2-pass VBR bias",
+          "CBR/VBR bias (0=CBR, 100=VBR)",
+          0, 100, DEFAULT_RC_2PASS_VBR_BIAS_PCT,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class,
+      PROP_RC_2PASS_VBR_MINSECTION_PCT,
+      g_param_spec_int ("twopass-vbr-minsection", "2-pass GOP min bitrate",
+          "GOP minimum bitrate (% target)", 0, G_MAXINT,
+          DEFAULT_RC_2PASS_VBR_MINSECTION_PCT,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class,
+      PROP_RC_2PASS_VBR_MAXSECTION_PCT,
+      g_param_spec_int ("twopass-vbr-maxsection", "2-pass GOP max bitrate",
+          "GOP maximum bitrate (% target)", 0, G_MAXINT,
+          DEFAULT_RC_2PASS_VBR_MINSECTION_PCT,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_KF_MODE,
+      g_param_spec_enum ("keyframe-mode", "Keyframe Mode",
+          "Keyframe placement",
+          GST_VPX_ENC_KF_MODE_TYPE, DEFAULT_KF_MODE,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_KF_MAX_DIST,
+      g_param_spec_int ("keyframe-max-dist", "Keyframe max distance",
+          "Maximum distance between keyframes (number of frames)",
+          0, G_MAXINT, DEFAULT_KF_MAX_DIST,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_MULTIPASS_MODE,
+      g_param_spec_enum ("multipass-mode", "Multipass Mode",
+          "Multipass encode mode",
+          GST_VPX_ENC_MULTIPASS_MODE_TYPE, DEFAULT_MULTIPASS_MODE,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_MULTIPASS_CACHE_FILE,
+      g_param_spec_string ("multipass-cache-file", "Multipass Cache File",
+          "Multipass cache file. "
+          "If stream caps reinited, multiple files will be created: "
+          "file, file.1, file.2, ... and so on.",
+          DEFAULT_MULTIPASS_CACHE_FILE,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_TS_NUMBER_LAYERS,
+      g_param_spec_int ("temporal-scalability-number-layers",
+          "Number of coding layers", "Number of coding layers to use", 1, 5,
+          DEFAULT_TS_NUMBER_LAYERS,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_TS_TARGET_BITRATE,
+      g_param_spec_value_array ("temporal-scalability-target-bitrate",
+          "Coding layer target bitrates",
+          "Target bitrates for coding layers (one per layer, decreasing)",
+          g_param_spec_int ("target-bitrate", "Target bitrate",
+              "Target bitrate", 0, G_MAXINT, DEFAULT_RC_TARGET_BITRATE,
+              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_TS_RATE_DECIMATOR,
+      g_param_spec_value_array ("temporal-scalability-rate-decimator",
+          "Coding layer rate decimator",
+          "Rate decimation factors for each layer",
+          g_param_spec_int ("rate-decimator", "Rate decimator",
+              "Rate decimator", 0, 1000000000, 0,
+              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_TS_PERIODICITY,
+      g_param_spec_int ("temporal-scalability-periodicity",
+          "Coding layer periodicity",
+          "Length of sequence that defines layer membership periodicity", 0, 16,
+          DEFAULT_TS_PERIODICITY,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_TS_LAYER_ID,
+      g_param_spec_value_array ("temporal-scalability-layer-id",
+          "Coding layer identification",
+          "Sequence defining coding layer membership",
+          g_param_spec_int ("layer-id", "Layer ID", "Layer ID", 0, 4, 0,
+              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_LAG_IN_FRAMES,
+      g_param_spec_int ("lag-in-frames", "Lag in frames",
+          "Maximum number of frames to lag",
+          0, 25, DEFAULT_LAG_IN_FRAMES,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_ERROR_RESILIENT,
+      g_param_spec_flags ("error-resilient", "Error resilient",
+          "Error resilience flags",
+          GST_VPX_ENC_ER_FLAGS_TYPE, DEFAULT_ERROR_RESILIENT,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_THREADS,
+      g_param_spec_int ("threads", "Threads",
+          "Number of threads to use",
+          0, 64, DEFAULT_THREADS,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_DEADLINE,
+      g_param_spec_int64 ("deadline", "Deadline",
+          "Deadline per frame (usec, 0=disabled)",
+          0, G_MAXINT64, DEFAULT_DEADLINE,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_H_SCALING_MODE,
+      g_param_spec_enum ("horizontal-scaling-mode", "Horizontal scaling mode",
+          "Horizontal scaling mode",
+          GST_VPX_ENC_SCALING_MODE_TYPE, DEFAULT_H_SCALING_MODE,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_V_SCALING_MODE,
+      g_param_spec_enum ("vertical-scaling-mode", "Vertical scaling mode",
+          "Vertical scaling mode",
+          GST_VPX_ENC_SCALING_MODE_TYPE, DEFAULT_V_SCALING_MODE,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_CPU_USED,
+      g_param_spec_int ("cpu-used", "CPU used",
+          "CPU used",
+          -16, 16, DEFAULT_CPU_USED,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_ENABLE_AUTO_ALT_REF,
+      g_param_spec_boolean ("auto-alt-ref", "Auto alt reference frames",
+          "Automatically generate AltRef frames",
+          DEFAULT_ENABLE_AUTO_ALT_REF,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_NOISE_SENSITIVITY,
+      g_param_spec_int ("noise-sensitivity", "Noise sensitivity",
+          "Noise sensisivity (frames to blur)",
+          0, 6, DEFAULT_NOISE_SENSITIVITY,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_SHARPNESS,
+      g_param_spec_int ("sharpness", "Sharpness",
+          "Filter sharpness",
+          0, 7, DEFAULT_SHARPNESS,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_STATIC_THRESHOLD,
+      g_param_spec_int ("static-threshold", "Static Threshold",
+          "Motion detection threshold",
+          0, G_MAXINT, DEFAULT_STATIC_THRESHOLD,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_TOKEN_PARTITIONS,
+      g_param_spec_enum ("token-partitions", "Token partitions",
+          "Number of token partitions",
+          GST_VPX_ENC_TOKEN_PARTITIONS_TYPE, DEFAULT_TOKEN_PARTITIONS,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_ARNR_MAXFRAMES,
+      g_param_spec_int ("arnr-maxframes", "AltRef max frames",
+          "AltRef maximum number of frames",
+          0, 15, DEFAULT_ARNR_MAXFRAMES,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_ARNR_STRENGTH,
+      g_param_spec_int ("arnr-strength", "AltRef strength",
+          "AltRef strength",
+          0, 6, DEFAULT_ARNR_STRENGTH,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_ARNR_TYPE,
+      g_param_spec_int ("arnr-type", "AltRef type",
+          "AltRef type",
+          1, 3, DEFAULT_ARNR_TYPE,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+              G_PARAM_DEPRECATED)));
+
+  g_object_class_install_property (gobject_class, PROP_TUNING,
+      g_param_spec_enum ("tuning", "Tuning",
+          "Tuning",
+          GST_VPX_ENC_TUNING_TYPE, DEFAULT_TUNING,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_CQ_LEVEL,
+      g_param_spec_int ("cq-level", "Constrained quality level",
+          "Constrained quality level",
+          0, 63, DEFAULT_CQ_LEVEL,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_MAX_INTRA_BITRATE_PCT,
+      g_param_spec_int ("max-intra-bitrate", "Max Intra bitrate",
+          "Maximum Intra frame bitrate",
+          0, G_MAXINT, DEFAULT_MAX_INTRA_BITRATE_PCT,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (gobject_class, PROP_TIMEBASE,
+      gst_param_spec_fraction ("timebase", "Shortest interframe time",
+          "Fraction of one second that is the shortest interframe time - normally left as zero which will default to the framerate",
+          0, 1, G_MAXINT, 1, DEFAULT_TIMEBASE_N, DEFAULT_TIMEBASE_D,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  GST_DEBUG_CATEGORY_INIT (gst_vpxenc_debug, "vpxenc", 0, "VPX Encoder");
+}
+
+static void
+gst_vpx_enc_init (GstVPXEnc * gst_vpx_enc)
+{
+  GST_DEBUG_OBJECT (gst_vpx_enc, "init");
+  GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_ENCODER_SINK_PAD (gst_vpx_enc));
+
+  gst_vpx_enc->cfg.rc_end_usage = DEFAULT_RC_END_USAGE;
+  gst_vpx_enc->cfg.rc_target_bitrate = DEFAULT_RC_TARGET_BITRATE / 1000;
+  gst_vpx_enc->rc_target_bitrate_set = FALSE;
+  gst_vpx_enc->cfg.rc_min_quantizer = DEFAULT_RC_MIN_QUANTIZER;
+  gst_vpx_enc->cfg.rc_max_quantizer = DEFAULT_RC_MAX_QUANTIZER;
+  gst_vpx_enc->cfg.rc_dropframe_thresh = DEFAULT_RC_DROPFRAME_THRESH;
+  gst_vpx_enc->cfg.rc_resize_allowed = DEFAULT_RC_RESIZE_ALLOWED;
+  gst_vpx_enc->cfg.rc_resize_up_thresh = DEFAULT_RC_RESIZE_UP_THRESH;
+  gst_vpx_enc->cfg.rc_resize_down_thresh = DEFAULT_RC_RESIZE_DOWN_THRESH;
+  gst_vpx_enc->cfg.rc_undershoot_pct = DEFAULT_RC_UNDERSHOOT_PCT;
+  gst_vpx_enc->cfg.rc_overshoot_pct = DEFAULT_RC_OVERSHOOT_PCT;
+  gst_vpx_enc->cfg.rc_buf_sz = DEFAULT_RC_BUF_SZ;
+  gst_vpx_enc->cfg.rc_buf_initial_sz = DEFAULT_RC_BUF_INITIAL_SZ;
+  gst_vpx_enc->cfg.rc_buf_optimal_sz = DEFAULT_RC_BUF_OPTIMAL_SZ;
+  gst_vpx_enc->cfg.rc_2pass_vbr_bias_pct = DEFAULT_RC_2PASS_VBR_BIAS_PCT;
+  gst_vpx_enc->cfg.rc_2pass_vbr_minsection_pct =
+      DEFAULT_RC_2PASS_VBR_MINSECTION_PCT;
+  gst_vpx_enc->cfg.rc_2pass_vbr_maxsection_pct =
+      DEFAULT_RC_2PASS_VBR_MAXSECTION_PCT;
+  gst_vpx_enc->cfg.kf_mode = DEFAULT_KF_MODE;
+  gst_vpx_enc->cfg.kf_max_dist = DEFAULT_KF_MAX_DIST;
+  gst_vpx_enc->cfg.g_pass = DEFAULT_MULTIPASS_MODE;
+  gst_vpx_enc->multipass_cache_prefix = g_strdup (DEFAULT_MULTIPASS_CACHE_FILE);
+  gst_vpx_enc->multipass_cache_file = NULL;
+  gst_vpx_enc->multipass_cache_idx = 0;
+  gst_vpx_enc->cfg.ts_number_layers = DEFAULT_TS_NUMBER_LAYERS;
+  gst_vpx_enc->n_ts_target_bitrate = 0;
+  gst_vpx_enc->n_ts_rate_decimator = 0;
+  gst_vpx_enc->cfg.ts_periodicity = DEFAULT_TS_PERIODICITY;
+  gst_vpx_enc->n_ts_layer_id = 0;
+  gst_vpx_enc->cfg.g_error_resilient = DEFAULT_ERROR_RESILIENT;
+  gst_vpx_enc->cfg.g_lag_in_frames = DEFAULT_LAG_IN_FRAMES;
+  gst_vpx_enc->cfg.g_threads = DEFAULT_THREADS;
+  gst_vpx_enc->deadline = DEFAULT_DEADLINE;
+  gst_vpx_enc->h_scaling_mode = DEFAULT_H_SCALING_MODE;
+  gst_vpx_enc->v_scaling_mode = DEFAULT_V_SCALING_MODE;
+  gst_vpx_enc->cpu_used = DEFAULT_CPU_USED;
+  gst_vpx_enc->enable_auto_alt_ref = DEFAULT_ENABLE_AUTO_ALT_REF;
+  gst_vpx_enc->noise_sensitivity = DEFAULT_NOISE_SENSITIVITY;
+  gst_vpx_enc->sharpness = DEFAULT_SHARPNESS;
+  gst_vpx_enc->static_threshold = DEFAULT_STATIC_THRESHOLD;
+  gst_vpx_enc->token_partitions = DEFAULT_TOKEN_PARTITIONS;
+  gst_vpx_enc->arnr_maxframes = DEFAULT_ARNR_MAXFRAMES;
+  gst_vpx_enc->arnr_strength = DEFAULT_ARNR_STRENGTH;
+  gst_vpx_enc->arnr_type = DEFAULT_ARNR_TYPE;
+  gst_vpx_enc->tuning = DEFAULT_TUNING;
+  gst_vpx_enc->cq_level = DEFAULT_CQ_LEVEL;
+  gst_vpx_enc->max_intra_bitrate_pct = DEFAULT_MAX_INTRA_BITRATE_PCT;
+  gst_vpx_enc->timebase_n = DEFAULT_TIMEBASE_N;
+  gst_vpx_enc->timebase_d = DEFAULT_TIMEBASE_D;
+
+  gst_vpx_enc->cfg.g_profile = DEFAULT_PROFILE;
+
+  g_mutex_init (&gst_vpx_enc->encoder_lock);
+}
+
+static void
+gst_vpx_enc_finalize (GObject * object)
+{
+  GstVPXEnc *gst_vpx_enc;
+
+  GST_DEBUG_OBJECT (object, "finalize");
+
+  g_return_if_fail (GST_IS_VPX_ENC (object));
+  gst_vpx_enc = GST_VPX_ENC (object);
+
+  g_free (gst_vpx_enc->multipass_cache_prefix);
+  g_free (gst_vpx_enc->multipass_cache_file);
+  gst_vpx_enc->multipass_cache_idx = 0;
+
+
+  if (gst_vpx_enc->input_state)
+    gst_video_codec_state_unref (gst_vpx_enc->input_state);
+
+  g_mutex_clear (&gst_vpx_enc->encoder_lock);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_vpx_enc_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstVPXEnc *gst_vpx_enc;
+  gboolean global = FALSE;
+  vpx_codec_err_t status;
+
+  g_return_if_fail (GST_IS_VPX_ENC (object));
+  gst_vpx_enc = GST_VPX_ENC (object);
+
+  GST_DEBUG_OBJECT (object, "gst_vpx_enc_set_property");
+  g_mutex_lock (&gst_vpx_enc->encoder_lock);
+  switch (prop_id) {
+    case PROP_RC_END_USAGE:
+      gst_vpx_enc->cfg.rc_end_usage = g_value_get_enum (value);
+      global = TRUE;
+      break;
+    case PROP_RC_TARGET_BITRATE:
+      gst_vpx_enc->cfg.rc_target_bitrate = g_value_get_int (value) / 1000;
+      gst_vpx_enc->rc_target_bitrate_set = TRUE;
+      global = TRUE;
+      break;
+    case PROP_RC_MIN_QUANTIZER:
+      gst_vpx_enc->cfg.rc_min_quantizer = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_RC_MAX_QUANTIZER:
+      gst_vpx_enc->cfg.rc_max_quantizer = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_RC_DROPFRAME_THRESH:
+      gst_vpx_enc->cfg.rc_dropframe_thresh = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_RC_RESIZE_ALLOWED:
+      gst_vpx_enc->cfg.rc_resize_allowed = g_value_get_boolean (value);
+      global = TRUE;
+      break;
+    case PROP_RC_RESIZE_UP_THRESH:
+      gst_vpx_enc->cfg.rc_resize_up_thresh = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_RC_RESIZE_DOWN_THRESH:
+      gst_vpx_enc->cfg.rc_resize_down_thresh = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_RC_UNDERSHOOT_PCT:
+      gst_vpx_enc->cfg.rc_undershoot_pct = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_RC_OVERSHOOT_PCT:
+      gst_vpx_enc->cfg.rc_overshoot_pct = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_RC_BUF_SZ:
+      gst_vpx_enc->cfg.rc_buf_sz = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_RC_BUF_INITIAL_SZ:
+      gst_vpx_enc->cfg.rc_buf_initial_sz = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_RC_BUF_OPTIMAL_SZ:
+      gst_vpx_enc->cfg.rc_buf_optimal_sz = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_RC_2PASS_VBR_BIAS_PCT:
+      gst_vpx_enc->cfg.rc_2pass_vbr_bias_pct = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_RC_2PASS_VBR_MINSECTION_PCT:
+      gst_vpx_enc->cfg.rc_2pass_vbr_minsection_pct = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_RC_2PASS_VBR_MAXSECTION_PCT:
+      gst_vpx_enc->cfg.rc_2pass_vbr_maxsection_pct = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_KF_MODE:
+      gst_vpx_enc->cfg.kf_mode = g_value_get_enum (value);
+      global = TRUE;
+      break;
+    case PROP_KF_MAX_DIST:
+      gst_vpx_enc->cfg.kf_max_dist = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_MULTIPASS_MODE:
+      gst_vpx_enc->cfg.g_pass = g_value_get_enum (value);
+      global = TRUE;
+      break;
+    case PROP_MULTIPASS_CACHE_FILE:
+      if (gst_vpx_enc->multipass_cache_prefix)
+        g_free (gst_vpx_enc->multipass_cache_prefix);
+      gst_vpx_enc->multipass_cache_prefix = g_value_dup_string (value);
+      break;
+    case PROP_TS_NUMBER_LAYERS:
+      gst_vpx_enc->cfg.ts_number_layers = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_TS_TARGET_BITRATE:{
+      GValueArray *va = g_value_get_boxed (value);
+
+      memset (&gst_vpx_enc->cfg.ts_target_bitrate, 0,
+          sizeof (gst_vpx_enc->cfg.ts_target_bitrate));
+      if (va == NULL) {
+        gst_vpx_enc->n_ts_target_bitrate = 0;
+      } else if (va->n_values > VPX_TS_MAX_LAYERS) {
+        g_warning ("%s: Only %d layers allowed at maximum",
+            GST_ELEMENT_NAME (gst_vpx_enc), VPX_TS_MAX_LAYERS);
+      } else {
+        gint i;
+
+        for (i = 0; i < va->n_values; i++)
+          gst_vpx_enc->cfg.ts_target_bitrate[i] =
+              g_value_get_int (g_value_array_get_nth (va, i));
+        gst_vpx_enc->n_ts_target_bitrate = va->n_values;
+      }
+      global = TRUE;
+      break;
+    }
+    case PROP_TS_RATE_DECIMATOR:{
+      GValueArray *va = g_value_get_boxed (value);
+
+      memset (&gst_vpx_enc->cfg.ts_rate_decimator, 0,
+          sizeof (gst_vpx_enc->cfg.ts_rate_decimator));
+      if (va == NULL) {
+        gst_vpx_enc->n_ts_rate_decimator = 0;
+      } else if (va->n_values > VPX_TS_MAX_LAYERS) {
+        g_warning ("%s: Only %d layers allowed at maximum",
+            GST_ELEMENT_NAME (gst_vpx_enc), VPX_TS_MAX_LAYERS);
+      } else {
+        gint i;
+
+        for (i = 0; i < va->n_values; i++)
+          gst_vpx_enc->cfg.ts_rate_decimator[i] =
+              g_value_get_int (g_value_array_get_nth (va, i));
+        gst_vpx_enc->n_ts_rate_decimator = va->n_values;
+      }
+      global = TRUE;
+      break;
+    }
+    case PROP_TS_PERIODICITY:
+      gst_vpx_enc->cfg.ts_periodicity = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_TS_LAYER_ID:{
+      GValueArray *va = g_value_get_boxed (value);
+
+      memset (&gst_vpx_enc->cfg.ts_layer_id, 0,
+          sizeof (gst_vpx_enc->cfg.ts_layer_id));
+      if (va && va->n_values > VPX_TS_MAX_PERIODICITY) {
+        g_warning ("%s: Only %d sized layer sequences allowed at maximum",
+            GST_ELEMENT_NAME (gst_vpx_enc), VPX_TS_MAX_PERIODICITY);
+      } else if (va) {
+        gint i;
+
+        for (i = 0; i < va->n_values; i++)
+          gst_vpx_enc->cfg.ts_layer_id[i] =
+              g_value_get_int (g_value_array_get_nth (va, i));
+        gst_vpx_enc->n_ts_layer_id = va->n_values;
+      } else {
+        gst_vpx_enc->n_ts_layer_id = 0;
+      }
+      global = TRUE;
+      break;
+    }
+    case PROP_ERROR_RESILIENT:
+      gst_vpx_enc->cfg.g_error_resilient = g_value_get_flags (value);
+      global = TRUE;
+      break;
+    case PROP_LAG_IN_FRAMES:
+      gst_vpx_enc->cfg.g_lag_in_frames = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_THREADS:
+      gst_vpx_enc->cfg.g_threads = g_value_get_int (value);
+      global = TRUE;
+      break;
+    case PROP_DEADLINE:
+      gst_vpx_enc->deadline = g_value_get_int64 (value);
+      break;
+    case PROP_H_SCALING_MODE:
+      gst_vpx_enc->h_scaling_mode = g_value_get_enum (value);
+      if (gst_vpx_enc->inited) {
+        vpx_scaling_mode_t sm;
+
+        sm.h_scaling_mode = gst_vpx_enc->h_scaling_mode;
+        sm.v_scaling_mode = gst_vpx_enc->v_scaling_mode;
+
+        status =
+            vpx_codec_control (&gst_vpx_enc->encoder, VP8E_SET_SCALEMODE, &sm);
+        if (status != VPX_CODEC_OK) {
+          GST_WARNING_OBJECT (gst_vpx_enc,
+              "Failed to set VP8E_SET_SCALEMODE: %s",
+              gst_vpx_error_name (status));
+        }
+      }
+      break;
+    case PROP_V_SCALING_MODE:
+      gst_vpx_enc->v_scaling_mode = g_value_get_enum (value);
+      if (gst_vpx_enc->inited) {
+        vpx_scaling_mode_t sm;
+
+        sm.h_scaling_mode = gst_vpx_enc->h_scaling_mode;
+        sm.v_scaling_mode = gst_vpx_enc->v_scaling_mode;
+
+        status =
+            vpx_codec_control (&gst_vpx_enc->encoder, VP8E_SET_SCALEMODE, &sm);
+        if (status != VPX_CODEC_OK) {
+          GST_WARNING_OBJECT (gst_vpx_enc,
+              "Failed to set VP8E_SET_SCALEMODE: %s",
+              gst_vpx_error_name (status));
+        }
+      }
+      break;
+    case PROP_CPU_USED:
+      gst_vpx_enc->cpu_used = g_value_get_int (value);
+      if (gst_vpx_enc->inited) {
+        status =
+            vpx_codec_control (&gst_vpx_enc->encoder, VP8E_SET_CPUUSED,
+            gst_vpx_enc->cpu_used);
+        if (status != VPX_CODEC_OK) {
+          GST_WARNING_OBJECT (gst_vpx_enc, "Failed to set VP8E_SET_CPUUSED: %s",
+              gst_vpx_error_name (status));
+        }
+      }
+      break;
+    case PROP_ENABLE_AUTO_ALT_REF:
+      gst_vpx_enc->enable_auto_alt_ref = g_value_get_boolean (value);
+      if (gst_vpx_enc->inited) {
+        status =
+            vpx_codec_control (&gst_vpx_enc->encoder, VP8E_SET_ENABLEAUTOALTREF,
+            (gst_vpx_enc->enable_auto_alt_ref ? 1 : 0));
+        if (status != VPX_CODEC_OK) {
+          GST_WARNING_OBJECT (gst_vpx_enc,
+              "Failed to set VP8E_SET_ENABLEAUTOALTREF: %s",
+              gst_vpx_error_name (status));
+        }
+      }
+      break;
+    case PROP_NOISE_SENSITIVITY:
+      gst_vpx_enc->noise_sensitivity = g_value_get_int (value);
+      if (gst_vpx_enc->inited) {
+        status =
+            vpx_codec_control (&gst_vpx_enc->encoder,
+            VP8E_SET_NOISE_SENSITIVITY, gst_vpx_enc->noise_sensitivity);
+        if (status != VPX_CODEC_OK) {
+          GST_WARNING_OBJECT (gst_vpx_enc,
+              "Failed to set VP8E_SET_NOISE_SENSITIVITY: %s",
+              gst_vpx_error_name (status));
+        }
+      }
+      break;
+    case PROP_SHARPNESS:
+      gst_vpx_enc->sharpness = g_value_get_int (value);
+      if (gst_vpx_enc->inited) {
+        status = vpx_codec_control (&gst_vpx_enc->encoder, VP8E_SET_SHARPNESS,
+            gst_vpx_enc->sharpness);
+        if (status != VPX_CODEC_OK) {
+          GST_WARNING_OBJECT (gst_vpx_enc,
+              "Failed to set VP8E_SET_SHARPNESS: %s",
+              gst_vpx_error_name (status));
+        }
+      }
+      break;
+    case PROP_STATIC_THRESHOLD:
+      gst_vpx_enc->static_threshold = g_value_get_int (value);
+      if (gst_vpx_enc->inited) {
+        status =
+            vpx_codec_control (&gst_vpx_enc->encoder, VP8E_SET_STATIC_THRESHOLD,
+            gst_vpx_enc->static_threshold);
+        if (status != VPX_CODEC_OK) {
+          GST_WARNING_OBJECT (gst_vpx_enc,
+              "Failed to set VP8E_SET_STATIC_THRESHOLD: %s",
+              gst_vpx_error_name (status));
+        }
+      }
+      break;
+    case PROP_TOKEN_PARTITIONS:
+      gst_vpx_enc->token_partitions = g_value_get_enum (value);
+      if (gst_vpx_enc->inited) {
+        status =
+            vpx_codec_control (&gst_vpx_enc->encoder, VP8E_SET_TOKEN_PARTITIONS,
+            gst_vpx_enc->token_partitions);
+        if (status != VPX_CODEC_OK) {
+          GST_WARNING_OBJECT (gst_vpx_enc,
+              "Failed to set VP8E_SET_TOKEN_PARTIONS: %s",
+              gst_vpx_error_name (status));
+        }
+      }
+      break;
+    case PROP_ARNR_MAXFRAMES:
+      gst_vpx_enc->arnr_maxframes = g_value_get_int (value);
+      if (gst_vpx_enc->inited) {
+        status =
+            vpx_codec_control (&gst_vpx_enc->encoder, VP8E_SET_ARNR_MAXFRAMES,
+            gst_vpx_enc->arnr_maxframes);
+        if (status != VPX_CODEC_OK) {
+          GST_WARNING_OBJECT (gst_vpx_enc,
+              "Failed to set VP8E_SET_ARNR_MAXFRAMES: %s",
+              gst_vpx_error_name (status));
+        }
+      }
+      break;
+    case PROP_ARNR_STRENGTH:
+      gst_vpx_enc->arnr_strength = g_value_get_int (value);
+      if (gst_vpx_enc->inited) {
+        status =
+            vpx_codec_control (&gst_vpx_enc->encoder, VP8E_SET_ARNR_STRENGTH,
+            gst_vpx_enc->arnr_strength);
+        if (status != VPX_CODEC_OK) {
+          GST_WARNING_OBJECT (gst_vpx_enc,
+              "Failed to set VP8E_SET_ARNR_STRENGTH: %s",
+              gst_vpx_error_name (status));
+        }
+      }
+      break;
+    case PROP_ARNR_TYPE:
+      gst_vpx_enc->arnr_type = g_value_get_int (value);
+      g_warning ("arnr-type is a no-op since control has been deprecated "
+          "in libvpx");
+      break;
+    case PROP_TUNING:
+      gst_vpx_enc->tuning = g_value_get_enum (value);
+      if (gst_vpx_enc->inited) {
+        status = vpx_codec_control (&gst_vpx_enc->encoder, VP8E_SET_TUNING,
+            gst_vpx_enc->tuning);
+        if (status != VPX_CODEC_OK) {
+          GST_WARNING_OBJECT (gst_vpx_enc,
+              "Failed to set VP8E_SET_TUNING: %s", gst_vpx_error_name (status));
+        }
+      }
+      break;
+    case PROP_CQ_LEVEL:
+      gst_vpx_enc->cq_level = g_value_get_int (value);
+      if (gst_vpx_enc->inited) {
+        status = vpx_codec_control (&gst_vpx_enc->encoder, VP8E_SET_CQ_LEVEL,
+            gst_vpx_enc->cq_level);
+        if (status != VPX_CODEC_OK) {
+          GST_WARNING_OBJECT (gst_vpx_enc,
+              "Failed to set VP8E_SET_CQ_LEVEL: %s",
+              gst_vpx_error_name (status));
+        }
+      }
+      break;
+    case PROP_MAX_INTRA_BITRATE_PCT:
+      gst_vpx_enc->max_intra_bitrate_pct = g_value_get_int (value);
+      if (gst_vpx_enc->inited) {
+        status =
+            vpx_codec_control (&gst_vpx_enc->encoder,
+            VP8E_SET_MAX_INTRA_BITRATE_PCT, gst_vpx_enc->max_intra_bitrate_pct);
+        if (status != VPX_CODEC_OK) {
+          GST_WARNING_OBJECT (gst_vpx_enc,
+              "Failed to set VP8E_SET_MAX_INTRA_BITRATE_PCT: %s",
+              gst_vpx_error_name (status));
+        }
+      }
+      break;
+    case PROP_TIMEBASE:
+      gst_vpx_enc->timebase_n = gst_value_get_fraction_numerator (value);
+      gst_vpx_enc->timebase_d = gst_value_get_fraction_denominator (value);
+      break;
+    default:
+      break;
+  }
+
+  if (global &&gst_vpx_enc->inited) {
+    status =
+        vpx_codec_enc_config_set (&gst_vpx_enc->encoder, &gst_vpx_enc->cfg);
+    if (status != VPX_CODEC_OK) {
+      g_mutex_unlock (&gst_vpx_enc->encoder_lock);
+      GST_ELEMENT_ERROR (gst_vpx_enc, LIBRARY, INIT,
+          ("Failed to set encoder configuration"), ("%s",
+              gst_vpx_error_name (status)));
+    } else {
+      g_mutex_unlock (&gst_vpx_enc->encoder_lock);
+    }
+  } else {
+    g_mutex_unlock (&gst_vpx_enc->encoder_lock);
+  }
+}
+
+static void
+gst_vpx_enc_get_property (GObject * object, guint prop_id, GValue * value,
+    GParamSpec * pspec)
+{
+  GstVPXEnc *gst_vpx_enc;
+
+  g_return_if_fail (GST_IS_VPX_ENC (object));
+  gst_vpx_enc = GST_VPX_ENC (object);
+
+  g_mutex_lock (&gst_vpx_enc->encoder_lock);
+  switch (prop_id) {
+    case PROP_RC_END_USAGE:
+      g_value_set_enum (value, gst_vpx_enc->cfg.rc_end_usage);
+      break;
+    case PROP_RC_TARGET_BITRATE:
+      g_value_set_int (value, gst_vpx_enc->cfg.rc_target_bitrate * 1000);
+      break;
+    case PROP_RC_MIN_QUANTIZER:
+      g_value_set_int (value, gst_vpx_enc->cfg.rc_min_quantizer);
+      break;
+    case PROP_RC_MAX_QUANTIZER:
+      g_value_set_int (value, gst_vpx_enc->cfg.rc_max_quantizer);
+      break;
+    case PROP_RC_DROPFRAME_THRESH:
+      g_value_set_int (value, gst_vpx_enc->cfg.rc_dropframe_thresh);
+      break;
+    case PROP_RC_RESIZE_ALLOWED:
+      g_value_set_boolean (value, gst_vpx_enc->cfg.rc_resize_allowed);
+      break;
+    case PROP_RC_RESIZE_UP_THRESH:
+      g_value_set_int (value, gst_vpx_enc->cfg.rc_resize_up_thresh);
+      break;
+    case PROP_RC_RESIZE_DOWN_THRESH:
+      g_value_set_int (value, gst_vpx_enc->cfg.rc_resize_down_thresh);
+      break;
+    case PROP_RC_UNDERSHOOT_PCT:
+      g_value_set_int (value, gst_vpx_enc->cfg.rc_undershoot_pct);
+      break;
+    case PROP_RC_OVERSHOOT_PCT:
+      g_value_set_int (value, gst_vpx_enc->cfg.rc_overshoot_pct);
+      break;
+    case PROP_RC_BUF_SZ:
+      g_value_set_int (value, gst_vpx_enc->cfg.rc_buf_sz);
+      break;
+    case PROP_RC_BUF_INITIAL_SZ:
+      g_value_set_int (value, gst_vpx_enc->cfg.rc_buf_initial_sz);
+      break;
+    case PROP_RC_BUF_OPTIMAL_SZ:
+      g_value_set_int (value, gst_vpx_enc->cfg.rc_buf_optimal_sz);
+      break;
+    case PROP_RC_2PASS_VBR_BIAS_PCT:
+      g_value_set_int (value, gst_vpx_enc->cfg.rc_2pass_vbr_bias_pct);
+      break;
+    case PROP_RC_2PASS_VBR_MINSECTION_PCT:
+      g_value_set_int (value, gst_vpx_enc->cfg.rc_2pass_vbr_minsection_pct);
+      break;
+    case PROP_RC_2PASS_VBR_MAXSECTION_PCT:
+      g_value_set_int (value, gst_vpx_enc->cfg.rc_2pass_vbr_maxsection_pct);
+      break;
+    case PROP_KF_MODE:
+      g_value_set_enum (value, gst_vpx_enc->cfg.kf_mode);
+      break;
+    case PROP_KF_MAX_DIST:
+      g_value_set_int (value, gst_vpx_enc->cfg.kf_max_dist);
+      break;
+    case PROP_MULTIPASS_MODE:
+      g_value_set_enum (value, gst_vpx_enc->cfg.g_pass);
+      break;
+    case PROP_MULTIPASS_CACHE_FILE:
+      g_value_set_string (value, gst_vpx_enc->multipass_cache_prefix);
+      break;
+    case PROP_TS_NUMBER_LAYERS:
+      g_value_set_int (value, gst_vpx_enc->cfg.ts_number_layers);
+      break;
+    case PROP_TS_TARGET_BITRATE:{
+      GValueArray *va;
+
+      if (gst_vpx_enc->n_ts_target_bitrate == 0) {
+        g_value_set_boxed (value, NULL);
+      } else {
+        gint i;
+
+        va = g_value_array_new (gst_vpx_enc->n_ts_target_bitrate);
+        for (i = 0; i < gst_vpx_enc->n_ts_target_bitrate; i++) {
+          GValue v = { 0, };
+
+          g_value_init (&v, G_TYPE_INT);
+          g_value_set_int (&v, gst_vpx_enc->cfg.ts_target_bitrate[i]);
+          g_value_array_append (va, &v);
+          g_value_unset (&v);
+        }
+        g_value_set_boxed (value, va);
+        g_value_array_free (va);
+      }
+      break;
+    }
+    case PROP_TS_RATE_DECIMATOR:{
+      GValueArray *va;
+
+      if (gst_vpx_enc->n_ts_rate_decimator == 0) {
+        g_value_set_boxed (value, NULL);
+      } else {
+        gint i;
+
+        va = g_value_array_new (gst_vpx_enc->n_ts_rate_decimator);
+        for (i = 0; i < gst_vpx_enc->n_ts_rate_decimator; i++) {
+          GValue v = { 0, };
+
+          g_value_init (&v, G_TYPE_INT);
+          g_value_set_int (&v, gst_vpx_enc->cfg.ts_rate_decimator[i]);
+          g_value_array_append (va, &v);
+          g_value_unset (&v);
+        }
+        g_value_set_boxed (value, va);
+        g_value_array_free (va);
+      }
+      break;
+    }
+    case PROP_TS_PERIODICITY:
+      g_value_set_int (value, gst_vpx_enc->cfg.ts_periodicity);
+      break;
+    case PROP_TS_LAYER_ID:{
+      GValueArray *va;
+
+      if (gst_vpx_enc->n_ts_layer_id == 0) {
+        g_value_set_boxed (value, NULL);
+      } else {
+        gint i;
+
+        va = g_value_array_new (gst_vpx_enc->n_ts_layer_id);
+        for (i = 0; i < gst_vpx_enc->n_ts_layer_id; i++) {
+          GValue v = { 0, };
+
+          g_value_init (&v, G_TYPE_INT);
+          g_value_set_int (&v, gst_vpx_enc->cfg.ts_layer_id[i]);
+          g_value_array_append (va, &v);
+          g_value_unset (&v);
+        }
+        g_value_set_boxed (value, va);
+        g_value_array_free (va);
+      }
+      break;
+    }
+    case PROP_ERROR_RESILIENT:
+      g_value_set_flags (value, gst_vpx_enc->cfg.g_error_resilient);
+      break;
+    case PROP_LAG_IN_FRAMES:
+      g_value_set_int (value, gst_vpx_enc->cfg.g_lag_in_frames);
+      break;
+    case PROP_THREADS:
+      g_value_set_int (value, gst_vpx_enc->cfg.g_threads);
+      break;
+    case PROP_DEADLINE:
+      g_value_set_int64 (value, gst_vpx_enc->deadline);
+      break;
+    case PROP_H_SCALING_MODE:
+      g_value_set_enum (value, gst_vpx_enc->h_scaling_mode);
+      break;
+    case PROP_V_SCALING_MODE:
+      g_value_set_enum (value, gst_vpx_enc->v_scaling_mode);
+      break;
+    case PROP_CPU_USED:
+      g_value_set_int (value, gst_vpx_enc->cpu_used);
+      break;
+    case PROP_ENABLE_AUTO_ALT_REF:
+      g_value_set_boolean (value, gst_vpx_enc->enable_auto_alt_ref);
+      break;
+    case PROP_NOISE_SENSITIVITY:
+      g_value_set_int (value, gst_vpx_enc->noise_sensitivity);
+      break;
+    case PROP_SHARPNESS:
+      g_value_set_int (value, gst_vpx_enc->sharpness);
+      break;
+    case PROP_STATIC_THRESHOLD:
+      g_value_set_int (value, gst_vpx_enc->static_threshold);
+      break;
+    case PROP_TOKEN_PARTITIONS:
+      g_value_set_enum (value, gst_vpx_enc->token_partitions);
+      break;
+    case PROP_ARNR_MAXFRAMES:
+      g_value_set_int (value, gst_vpx_enc->arnr_maxframes);
+      break;
+    case PROP_ARNR_STRENGTH:
+      g_value_set_int (value, gst_vpx_enc->arnr_strength);
+      break;
+    case PROP_ARNR_TYPE:
+      g_value_set_int (value, gst_vpx_enc->arnr_type);
+      break;
+    case PROP_TUNING:
+      g_value_set_enum (value, gst_vpx_enc->tuning);
+      break;
+    case PROP_CQ_LEVEL:
+      g_value_set_int (value, gst_vpx_enc->cq_level);
+      break;
+    case PROP_MAX_INTRA_BITRATE_PCT:
+      g_value_set_int (value, gst_vpx_enc->max_intra_bitrate_pct);
+      break;
+    case PROP_TIMEBASE:
+      gst_value_set_fraction (value, gst_vpx_enc->timebase_n,
+          gst_vpx_enc->timebase_d);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+
+  g_mutex_unlock (&gst_vpx_enc->encoder_lock);
+}
+
+static gboolean
+gst_vpx_enc_start (GstVideoEncoder * video_encoder)
+{
+  GstVPXEnc *encoder = GST_VPX_ENC (video_encoder);
+
+  GST_DEBUG_OBJECT (video_encoder, "start");
+
+  if (!encoder->have_default_config) {
+    GST_ELEMENT_ERROR (encoder, LIBRARY, INIT,
+        ("Failed to get default encoder configuration"), (NULL));
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+static void
+gst_vpx_enc_destroy_encoder (GstVPXEnc * encoder)
+{
+  g_mutex_lock (&encoder->encoder_lock);
+  if (encoder->inited) {
+    vpx_codec_destroy (&encoder->encoder);
+    encoder->inited = FALSE;
+  }
+
+  if (encoder->first_pass_cache_content) {
+    g_byte_array_free (encoder->first_pass_cache_content, TRUE);
+    encoder->first_pass_cache_content = NULL;
+  }
+
+  if (encoder->cfg.rc_twopass_stats_in.buf) {
+    g_free (encoder->cfg.rc_twopass_stats_in.buf);
+    encoder->cfg.rc_twopass_stats_in.buf = NULL;
+    encoder->cfg.rc_twopass_stats_in.sz = 0;
+  }
+  g_mutex_unlock (&encoder->encoder_lock);
+}
+
+static gboolean
+gst_vpx_enc_stop (GstVideoEncoder * video_encoder)
+{
+  GstVPXEnc *encoder;
+
+  GST_DEBUG_OBJECT (video_encoder, "stop");
+
+  encoder = GST_VPX_ENC (video_encoder);
+
+  gst_vpx_enc_destroy_encoder (encoder);
+
+  gst_tag_setter_reset_tags (GST_TAG_SETTER (encoder));
+
+  g_free (encoder->multipass_cache_file);
+  encoder->multipass_cache_file = NULL;
+  encoder->multipass_cache_idx = 0;
+
+  return TRUE;
+}
+
+static gint
+gst_vpx_enc_get_downstream_profile (GstVPXEnc * encoder)
+{
+  GstCaps *allowed;
+  GstStructure *s;
+  gint profile = DEFAULT_PROFILE;
+
+  allowed = gst_pad_get_allowed_caps (GST_VIDEO_ENCODER_SRC_PAD (encoder));
+  if (allowed) {
+    allowed = gst_caps_truncate (allowed);
+    s = gst_caps_get_structure (allowed, 0);
+    if (gst_structure_has_field (s, "profile")) {
+      const GValue *v = gst_structure_get_value (s, "profile");
+      const gchar *profile_str = NULL;
+
+      if (GST_VALUE_HOLDS_LIST (v) && gst_value_list_get_size (v) > 0) {
+        profile_str = g_value_get_string (gst_value_list_get_value (v, 0));
+      } else if (G_VALUE_HOLDS_STRING (v)) {
+        profile_str = g_value_get_string (v);
+      }
+
+      if (profile_str) {
+        gchar *endptr = NULL;
+
+        profile = g_ascii_strtoull (profile_str, &endptr, 10);
+        if (*endptr != '\0' || profile < 0 || profile > 3) {
+          GST_ERROR_OBJECT (encoder, "Invalid profile '%s'", profile_str);
+          profile = DEFAULT_PROFILE;
+        }
+      }
+    }
+    gst_caps_unref (allowed);
+  }
+
+  GST_DEBUG_OBJECT (encoder, "Using profile %d", profile);
+
+  return profile;
+}
+
+static gboolean
+gst_vpx_enc_set_format (GstVideoEncoder * video_encoder,
+    GstVideoCodecState * state)
+{
+  GstVPXEnc *encoder;
+  vpx_codec_err_t status;
+  vpx_image_t *image;
+  GstCaps *caps;
+  gboolean ret = TRUE;
+  GstVideoInfo *info = &state->info;
+  GstVideoCodecState *output_state;
+  GstClockTime latency;
+  GstVPXEncClass *vpx_enc_class;
+
+  encoder = GST_VPX_ENC (video_encoder);
+  vpx_enc_class = GST_VPX_ENC_GET_CLASS (encoder);
+  GST_DEBUG_OBJECT (video_encoder, "set_format");
+
+  if (encoder->inited) {
+    gst_vpx_enc_drain (video_encoder);
+    g_mutex_lock (&encoder->encoder_lock);
+    vpx_codec_destroy (&encoder->encoder);
+    encoder->inited = FALSE;
+    encoder->multipass_cache_idx++;
+  } else {
+    g_mutex_lock (&encoder->encoder_lock);
+  }
+
+  encoder->cfg.g_profile = gst_vpx_enc_get_downstream_profile (encoder);
+
+  /* Scale default bitrate to our size */
+  if (!encoder->rc_target_bitrate_set)
+    encoder->cfg.rc_target_bitrate =
+        gst_util_uint64_scale (DEFAULT_RC_TARGET_BITRATE,
+        GST_VIDEO_INFO_WIDTH (info) * GST_VIDEO_INFO_HEIGHT (info),
+        320 * 240 * 1000);
+
+  encoder->cfg.g_w = GST_VIDEO_INFO_WIDTH (info);
+  encoder->cfg.g_h = GST_VIDEO_INFO_HEIGHT (info);
+
+  if (encoder->timebase_n != 0 && encoder->timebase_d != 0) {
+    GST_DEBUG_OBJECT (video_encoder, "Using timebase configuration");
+    encoder->cfg.g_timebase.num = encoder->timebase_n;
+    encoder->cfg.g_timebase.den = encoder->timebase_d;
+  } else {
+    /* Zero framerate and max-framerate but still need to setup the timebase to avoid
+     * a divide by zero error. Presuming the lowest common denominator will be RTP -
+     * VP8 payload draft states clock rate of 90000 which should work for anyone where
+     * FPS < 90000 (shouldn't be too many cases where it's higher) though wouldn't be optimal. RTP specification
+     * http://tools.ietf.org/html/draft-ietf-payload-vp8-01 section 6.3.1 */
+    encoder->cfg.g_timebase.num = 1;
+    encoder->cfg.g_timebase.den = 90000;
+  }
+
+  if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS ||
+      encoder->cfg.g_pass == VPX_RC_LAST_PASS) {
+    if (!encoder->multipass_cache_prefix) {
+      GST_ELEMENT_ERROR (encoder, RESOURCE, OPEN_READ,
+          ("No multipass cache file provided"), (NULL));
+      g_mutex_unlock (&encoder->encoder_lock);
+      return FALSE;
+    }
+
+    g_free (encoder->multipass_cache_file);
+
+    if (encoder->multipass_cache_idx > 0)
+      encoder->multipass_cache_file = g_strdup_printf ("%s.%u",
+          encoder->multipass_cache_prefix, encoder->multipass_cache_idx);
+    else
+      encoder->multipass_cache_file =
+          g_strdup (encoder->multipass_cache_prefix);
+  }
+
+  if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS) {
+    if (encoder->first_pass_cache_content != NULL)
+      g_byte_array_free (encoder->first_pass_cache_content, TRUE);
+
+    encoder->first_pass_cache_content = g_byte_array_sized_new (4096);
+
+  } else if (encoder->cfg.g_pass == VPX_RC_LAST_PASS) {
+    GError *err = NULL;
+
+    if (encoder->cfg.rc_twopass_stats_in.buf != NULL) {
+      g_free (encoder->cfg.rc_twopass_stats_in.buf);
+      encoder->cfg.rc_twopass_stats_in.buf = NULL;
+      encoder->cfg.rc_twopass_stats_in.sz = 0;
+    }
+
+    if (!g_file_get_contents (encoder->multipass_cache_file,
+            (gchar **) & encoder->cfg.rc_twopass_stats_in.buf,
+            &encoder->cfg.rc_twopass_stats_in.sz, &err)) {
+      GST_ELEMENT_ERROR (encoder, RESOURCE, OPEN_READ,
+          ("Failed to read multipass cache file provided"), ("%s",
+              err->message));
+      g_error_free (err);
+      g_mutex_unlock (&encoder->encoder_lock);
+      return FALSE;
+    }
+  }
+
+  status =
+      vpx_codec_enc_init (&encoder->encoder, vpx_enc_class->get_algo (encoder),
+      &encoder->cfg, 0);
+  if (status != VPX_CODEC_OK) {
+    GST_ELEMENT_ERROR (encoder, LIBRARY, INIT,
+        ("Failed to initialize encoder"), ("%s", gst_vpx_error_name (status)));
+    g_mutex_unlock (&encoder->encoder_lock);
+    return FALSE;
+  }
+
+  if (vpx_enc_class->enable_scaling (encoder)) {
+    vpx_scaling_mode_t sm;
+
+    sm.h_scaling_mode = encoder->h_scaling_mode;
+    sm.v_scaling_mode = encoder->v_scaling_mode;
+
+    status = vpx_codec_control (&encoder->encoder, VP8E_SET_SCALEMODE, &sm);
+    if (status != VPX_CODEC_OK) {
+      GST_WARNING_OBJECT (encoder, "Failed to set VP8E_SET_SCALEMODE: %s",
+          gst_vpx_error_name (status));
+    }
+  }
+
+  status =
+      vpx_codec_control (&encoder->encoder, VP8E_SET_CPUUSED,
+      encoder->cpu_used);
+  if (status != VPX_CODEC_OK) {
+    GST_WARNING_OBJECT (encoder, "Failed to set VP8E_SET_CPUUSED: %s",
+        gst_vpx_error_name (status));
+  }
+
+  status =
+      vpx_codec_control (&encoder->encoder, VP8E_SET_ENABLEAUTOALTREF,
+      (encoder->enable_auto_alt_ref ? 1 : 0));
+  if (status != VPX_CODEC_OK) {
+    GST_WARNING_OBJECT (encoder,
+        "Failed to set VP8E_SET_ENABLEAUTOALTREF: %s",
+        gst_vpx_error_name (status));
+  }
+  status = vpx_codec_control (&encoder->encoder, VP8E_SET_NOISE_SENSITIVITY,
+      encoder->noise_sensitivity);
+  if (status != VPX_CODEC_OK) {
+    GST_WARNING_OBJECT (encoder,
+        "Failed to set VP8E_SET_NOISE_SENSITIVITY: %s",
+        gst_vpx_error_name (status));
+  }
+  status = vpx_codec_control (&encoder->encoder, VP8E_SET_SHARPNESS,
+      encoder->sharpness);
+  if (status != VPX_CODEC_OK) {
+    GST_WARNING_OBJECT (encoder,
+        "Failed to set VP8E_SET_SHARPNESS: %s", gst_vpx_error_name (status));
+  }
+  status = vpx_codec_control (&encoder->encoder, VP8E_SET_STATIC_THRESHOLD,
+      encoder->static_threshold);
+  if (status != VPX_CODEC_OK) {
+    GST_WARNING_OBJECT (encoder,
+        "Failed to set VP8E_SET_STATIC_THRESHOLD: %s",
+        gst_vpx_error_name (status));
+  }
+  status = vpx_codec_control (&encoder->encoder, VP8E_SET_TOKEN_PARTITIONS,
+      encoder->token_partitions);
+  if (status != VPX_CODEC_OK) {
+    GST_WARNING_OBJECT (encoder,
+        "Failed to set VP8E_SET_TOKEN_PARTIONS: %s",
+        gst_vpx_error_name (status));
+  }
+  status = vpx_codec_control (&encoder->encoder, VP8E_SET_ARNR_MAXFRAMES,
+      encoder->arnr_maxframes);
+  if (status != VPX_CODEC_OK) {
+    GST_WARNING_OBJECT (encoder,
+        "Failed to set VP8E_SET_ARNR_MAXFRAMES: %s",
+        gst_vpx_error_name (status));
+  }
+  status = vpx_codec_control (&encoder->encoder, VP8E_SET_ARNR_STRENGTH,
+      encoder->arnr_strength);
+  if (status != VPX_CODEC_OK) {
+    GST_WARNING_OBJECT (encoder,
+        "Failed to set VP8E_SET_ARNR_STRENGTH: %s",
+        gst_vpx_error_name (status));
+  }
+  status = vpx_codec_control (&encoder->encoder, VP8E_SET_TUNING,
+      encoder->tuning);
+  if (status != VPX_CODEC_OK) {
+    GST_WARNING_OBJECT (encoder,
+        "Failed to set VP8E_SET_TUNING: %s", gst_vpx_error_name (status));
+  }
+  status = vpx_codec_control (&encoder->encoder, VP8E_SET_CQ_LEVEL,
+      encoder->cq_level);
+  if (status != VPX_CODEC_OK) {
+    GST_WARNING_OBJECT (encoder,
+        "Failed to set VP8E_SET_CQ_LEVEL: %s", gst_vpx_error_name (status));
+  }
+  status = vpx_codec_control (&encoder->encoder, VP8E_SET_MAX_INTRA_BITRATE_PCT,
+      encoder->max_intra_bitrate_pct);
+  if (status != VPX_CODEC_OK) {
+    GST_WARNING_OBJECT (encoder,
+        "Failed to set VP8E_SET_MAX_INTRA_BITRATE_PCT: %s",
+        gst_vpx_error_name (status));
+  }
+
+  if (GST_VIDEO_INFO_FPS_D (info) == 0 || GST_VIDEO_INFO_FPS_N (info) == 0) {
+    /* FIXME: Assume 25fps for unknown framerates. Better than reporting
+     * that we introduce no latency while we actually do
+     */
+    latency = gst_util_uint64_scale (encoder->cfg.g_lag_in_frames,
+        1 * GST_SECOND, 25);
+  } else {
+    latency = gst_util_uint64_scale (encoder->cfg.g_lag_in_frames,
+        GST_VIDEO_INFO_FPS_D (info) * GST_SECOND, GST_VIDEO_INFO_FPS_N (info));
+  }
+  gst_video_encoder_set_latency (video_encoder, latency, latency);
+  encoder->inited = TRUE;
+
+  /* Store input state */
+  if (encoder->input_state)
+    gst_video_codec_state_unref (encoder->input_state);
+  encoder->input_state = gst_video_codec_state_ref (state);
+
+  /* prepare cached image buffer setup */
+  image = &encoder->image;
+  memset (image, 0, sizeof (*image));
+
+  vpx_enc_class->set_image_format (encoder, image);
+
+  image->w = image->d_w = GST_VIDEO_INFO_WIDTH (info);
+  image->h = image->d_h = GST_VIDEO_INFO_HEIGHT (info);
+
+  image->stride[VPX_PLANE_Y] = GST_VIDEO_INFO_COMP_STRIDE (info, 0);
+  image->stride[VPX_PLANE_U] = GST_VIDEO_INFO_COMP_STRIDE (info, 1);
+  image->stride[VPX_PLANE_V] = GST_VIDEO_INFO_COMP_STRIDE (info, 2);
+
+  caps = vpx_enc_class->get_new_vpx_caps (encoder);
+
+  vpx_enc_class->set_stream_info (encoder, caps, info);
+
+  g_mutex_unlock (&encoder->encoder_lock);
+
+  output_state =
+      gst_video_encoder_set_output_state (video_encoder, caps, state);
+  gst_video_codec_state_unref (output_state);
+
+  gst_video_encoder_negotiate (GST_VIDEO_ENCODER (encoder));
+
+  return ret;
+}
+
+static GstFlowReturn
+gst_vpx_enc_process (GstVPXEnc * encoder)
+{
+  vpx_codec_iter_t iter = NULL;
+  const vpx_codec_cx_pkt_t *pkt;
+  GstVideoEncoder *video_encoder;
+  void *user_data;
+  GstVideoCodecFrame *frame;
+  GstFlowReturn ret = GST_FLOW_OK;
+  GstVPXEncClass *vpx_enc_class;
+
+  video_encoder = GST_VIDEO_ENCODER (encoder);
+  vpx_enc_class = GST_VPX_ENC_GET_CLASS (encoder);
+
+  g_mutex_lock (&encoder->encoder_lock);
+  pkt = vpx_codec_get_cx_data (&encoder->encoder, &iter);
+  while (pkt != NULL) {
+    GstBuffer *buffer;
+    gboolean invisible;
+
+    GST_DEBUG_OBJECT (encoder, "packet %u type %d", (guint) pkt->data.frame.sz,
+        pkt->kind);
+
+    if (pkt->kind == VPX_CODEC_STATS_PKT
+        && encoder->cfg.g_pass == VPX_RC_FIRST_PASS) {
+      GST_LOG_OBJECT (encoder, "handling STATS packet");
+
+      g_byte_array_append (encoder->first_pass_cache_content,
+          pkt->data.twopass_stats.buf, pkt->data.twopass_stats.sz);
+
+      frame = gst_video_encoder_get_oldest_frame (video_encoder);
+      if (frame != NULL) {
+        buffer = gst_buffer_new ();
+        GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_LIVE);
+        frame->output_buffer = buffer;
+        g_mutex_unlock (&encoder->encoder_lock);
+        ret = gst_video_encoder_finish_frame (video_encoder, frame);
+        g_mutex_lock (&encoder->encoder_lock);
+      }
+
+      pkt = vpx_codec_get_cx_data (&encoder->encoder, &iter);
+      continue;
+    } else if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) {
+      GST_LOG_OBJECT (encoder, "non frame pkt: %d", pkt->kind);
+      pkt = vpx_codec_get_cx_data (&encoder->encoder, &iter);
+      continue;
+    }
+
+    invisible = (pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE) != 0;
+    frame = gst_video_encoder_get_oldest_frame (video_encoder);
+    g_assert (frame != NULL);
+    if ((pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0)
+      GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
+    else
+      GST_VIDEO_CODEC_FRAME_UNSET_SYNC_POINT (frame);
+
+    /* FIXME : It would be nice to avoid the memory copy ... */
+    buffer =
+        gst_buffer_new_wrapped (g_memdup (pkt->data.frame.buf,
+            pkt->data.frame.sz), pkt->data.frame.sz);
+
+    user_data = vpx_enc_class->process_frame_user_data (encoder, frame);
+
+    if (invisible) {
+      ret =
+          vpx_enc_class->handle_invisible_frame_buffer (encoder, user_data,
+          buffer);
+      gst_video_codec_frame_unref (frame);
+    } else {
+      frame->output_buffer = buffer;
+      g_mutex_unlock (&encoder->encoder_lock);
+      ret = gst_video_encoder_finish_frame (video_encoder, frame);
+      g_mutex_lock (&encoder->encoder_lock);
+    }
+
+    pkt = vpx_codec_get_cx_data (&encoder->encoder, &iter);
+  }
+  g_mutex_unlock (&encoder->encoder_lock);
+
+  return ret;
+}
+
+/* This function should be called holding then stream lock*/
+static GstFlowReturn
+gst_vpx_enc_drain (GstVideoEncoder * video_encoder)
+{
+  GstVPXEnc *encoder;
+  int flags = 0;
+  vpx_codec_err_t status;
+  gint64 deadline;
+  vpx_codec_pts_t pts;
+
+  encoder = GST_VPX_ENC (video_encoder);
+
+  g_mutex_lock (&encoder->encoder_lock);
+  deadline = encoder->deadline;
+
+  pts =
+      gst_util_uint64_scale (encoder->last_pts,
+      encoder->cfg.g_timebase.den,
+      encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND);
+
+  status = vpx_codec_encode (&encoder->encoder, NULL, pts, 0, flags, deadline);
+  g_mutex_unlock (&encoder->encoder_lock);
+
+  if (status != 0) {
+    GST_ERROR_OBJECT (encoder, "encode returned %d %s", status,
+        gst_vpx_error_name (status));
+    return GST_FLOW_ERROR;
+  }
+
+  /* dispatch remaining frames */
+  gst_vpx_enc_process (encoder);
+
+  g_mutex_lock (&encoder->encoder_lock);
+  if (encoder->cfg.g_pass == VPX_RC_FIRST_PASS && encoder->multipass_cache_file) {
+    GError *err = NULL;
+
+    if (!g_file_set_contents (encoder->multipass_cache_file,
+            (const gchar *) encoder->first_pass_cache_content->data,
+            encoder->first_pass_cache_content->len, &err)) {
+      GST_ELEMENT_ERROR (encoder, RESOURCE, WRITE, (NULL),
+          ("Failed to write multipass cache file: %s", err->message));
+      g_error_free (err);
+    }
+  }
+  g_mutex_unlock (&encoder->encoder_lock);
+
+  return GST_FLOW_OK;
+}
+
+static gboolean
+gst_vpx_enc_flush (GstVideoEncoder * video_encoder)
+{
+  GstVPXEnc *encoder;
+
+  GST_DEBUG_OBJECT (video_encoder, "flush");
+
+  encoder = GST_VPX_ENC (video_encoder);
+
+  gst_vpx_enc_destroy_encoder (encoder);
+  if (encoder->input_state) {
+    gst_video_codec_state_ref (encoder->input_state);
+    gst_vpx_enc_set_format (video_encoder, encoder->input_state);
+    gst_video_codec_state_unref (encoder->input_state);
+  }
+
+  return TRUE;
+}
+
+static GstFlowReturn
+gst_vpx_enc_finish (GstVideoEncoder * video_encoder)
+{
+  GstVPXEnc *encoder;
+  GstFlowReturn ret;
+
+  GST_DEBUG_OBJECT (video_encoder, "finish");
+
+  encoder = GST_VPX_ENC (video_encoder);
+
+  if (encoder->inited) {
+    ret = gst_vpx_enc_drain (video_encoder);
+  } else {
+    ret = GST_FLOW_OK;
+  }
+
+  return ret;
+}
+
+static vpx_image_t *
+gst_vpx_enc_buffer_to_image (GstVPXEnc * enc, GstVideoFrame * frame)
+{
+  vpx_image_t *image = g_slice_new (vpx_image_t);
+
+  memcpy (image, &enc->image, sizeof (*image));
+
+  image->planes[VPX_PLANE_Y] = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
+  image->planes[VPX_PLANE_U] = GST_VIDEO_FRAME_COMP_DATA (frame, 1);
+  image->planes[VPX_PLANE_V] = GST_VIDEO_FRAME_COMP_DATA (frame, 2);
+
+  image->stride[VPX_PLANE_Y] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
+  image->stride[VPX_PLANE_U] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 1);
+  image->stride[VPX_PLANE_V] = GST_VIDEO_FRAME_COMP_STRIDE (frame, 2);
+
+  return image;
+}
+
+static GstFlowReturn
+gst_vpx_enc_handle_frame (GstVideoEncoder * video_encoder,
+    GstVideoCodecFrame * frame)
+{
+  GstVPXEnc *encoder;
+  vpx_codec_err_t status;
+  int flags = 0;
+  vpx_image_t *image;
+  GstVideoFrame vframe;
+  vpx_codec_pts_t pts;
+  unsigned long duration;
+  GstVPXEncClass *vpx_enc_class;
+
+  GST_DEBUG_OBJECT (video_encoder, "handle_frame");
+
+  encoder = GST_VPX_ENC (video_encoder);
+  vpx_enc_class = GST_VPX_ENC_GET_CLASS (encoder);
+
+  GST_DEBUG_OBJECT (video_encoder, "size %d %d",
+      GST_VIDEO_INFO_WIDTH (&encoder->input_state->info),
+      GST_VIDEO_INFO_HEIGHT (&encoder->input_state->info));
+
+  gst_video_frame_map (&vframe, &encoder->input_state->info,
+      frame->input_buffer, GST_MAP_READ);
+  image = gst_vpx_enc_buffer_to_image (encoder, &vframe);
+
+  vpx_enc_class->set_frame_user_data (encoder, frame, image);
+
+  if (GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame)) {
+    flags |= VPX_EFLAG_FORCE_KF;
+  }
+
+  g_mutex_lock (&encoder->encoder_lock);
+  pts =
+      gst_util_uint64_scale (frame->pts,
+      encoder->cfg.g_timebase.den,
+      encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND);
+  encoder->last_pts = frame->pts;
+
+  if (frame->duration != GST_CLOCK_TIME_NONE) {
+    duration =
+        gst_util_uint64_scale (frame->duration, encoder->cfg.g_timebase.den,
+        encoder->cfg.g_timebase.num * (GstClockTime) GST_SECOND);
+    encoder->last_pts += frame->duration;
+  } else {
+    duration = 1;
+  }
+
+  status = vpx_codec_encode (&encoder->encoder, image,
+      pts, duration, flags, encoder->deadline);
+
+  g_mutex_unlock (&encoder->encoder_lock);
+  gst_video_frame_unmap (&vframe);
+
+  if (status != 0) {
+    GST_ELEMENT_ERROR (encoder, LIBRARY, ENCODE,
+        ("Failed to encode frame"), ("%s", gst_vpx_error_name (status)));
+    gst_video_codec_frame_set_user_data (frame, NULL, NULL);
+    return FALSE;
+  }
+  gst_video_codec_frame_unref (frame);
+  return gst_vpx_enc_process (encoder);
+}
+
+static gboolean
+gst_vpx_enc_sink_event (GstVideoEncoder * benc, GstEvent * event)
+{
+  GstVPXEnc *enc = GST_VPX_ENC (benc);
+
+  /* FIXME : Move this to base encoder class */
+
+  if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) {
+    GstTagList *list;
+    GstTagSetter *setter = GST_TAG_SETTER (enc);
+    const GstTagMergeMode mode = gst_tag_setter_get_tag_merge_mode (setter);
+
+    gst_event_parse_tag (event, &list);
+    gst_tag_setter_merge_tags (setter, list, mode);
+  }
+
+  /* just peeked, baseclass handles the rest */
+  return GST_VIDEO_ENCODER_CLASS (parent_class)->sink_event (benc, event);
+}
+
+static gboolean
+gst_vpx_enc_propose_allocation (GstVideoEncoder * encoder, GstQuery * query)
+{
+  gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
+
+  return GST_VIDEO_ENCODER_CLASS (parent_class)->propose_allocation (encoder,
+      query);
+}
+
+#endif /* HAVE_VP8_ENCODER || HAVE_VP9_ENCODER */
diff --git a/ext/vpx/gstvpxenc.h b/ext/vpx/gstvpxenc.h
new file mode 100644
index 0000000..fb01927
--- /dev/null
+++ b/ext/vpx/gstvpxenc.h
@@ -0,0 +1,140 @@
+/* VP8
+ * Copyright (C) 2006 David Schleef <ds@schleef.org>
+ * Copyright (C) 2010 Entropy Wave Inc
+ * Copyright (C) 2010 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+#ifndef __GST_VPX_ENC_H__
+#define __GST_VPX_ENC_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if defined(HAVE_VP8_ENCODER) || defined(HAVE_VP9_ENCODER)
+
+#include <gst/gst.h>
+#include <gst/video/gstvideoencoder.h>
+
+/* FIXME: Undef HAVE_CONFIG_H because vpx_codec.h uses it,
+ * which causes compilation failures */
+#ifdef HAVE_CONFIG_H
+#undef HAVE_CONFIG_H
+#endif
+
+#include <vpx/vpx_encoder.h>
+#include <vpx/vp8cx.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_VPX_ENC \
+  (gst_vpx_enc_get_type())
+#define GST_VPX_ENC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VPX_ENC,GstVPXEnc))
+#define GST_VPX_ENC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VPX_ENC,GstVPXEncClass))
+#define GST_IS_VPX_ENC(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VPX_ENC))
+#define GST_IS_VPX_ENC_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VPX_ENC))
+#define GST_VPX_ENC_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VPX_ENC, GstVPXEncClass))
+
+typedef struct _GstVPXEnc GstVPXEnc;
+typedef struct _GstVPXEncClass GstVPXEncClass;
+
+struct _GstVPXEnc
+{
+  GstVideoEncoder base_video_encoder;
+
+  /* < private > */
+  vpx_codec_ctx_t encoder;
+  GMutex encoder_lock;
+
+  /* properties */
+  vpx_codec_enc_cfg_t cfg;
+  gboolean have_default_config;
+  gboolean rc_target_bitrate_set;
+  gint n_ts_target_bitrate;
+  gint n_ts_rate_decimator;
+  gint n_ts_layer_id;
+  /* Global two-pass options */
+  gchar *multipass_cache_file;
+  gchar *multipass_cache_prefix;
+  guint multipass_cache_idx;
+  GByteArray *first_pass_cache_content;
+
+  /* Encode parameter */
+  gint64 deadline;
+
+  /* Controls */
+  VPX_SCALING_MODE h_scaling_mode;
+  VPX_SCALING_MODE v_scaling_mode;
+  int cpu_used;
+  gboolean enable_auto_alt_ref;
+  unsigned int noise_sensitivity;
+  unsigned int sharpness;
+  unsigned int static_threshold;
+  vp8e_token_partitions token_partitions;
+  unsigned int arnr_maxframes;
+  unsigned int arnr_strength;
+  unsigned int arnr_type;
+  vp8e_tuning tuning;
+  unsigned int cq_level;
+  unsigned int max_intra_bitrate_pct;
+  /* Timebase - a value of 0 will use the framerate */
+  unsigned int timebase_n;
+  unsigned int timebase_d;
+
+  /* state */
+  gboolean inited;
+
+  vpx_image_t image;
+
+  GstClockTime last_pts;
+
+  GstVideoCodecState *input_state;
+};
+
+struct _GstVPXEncClass
+{
+  GstVideoEncoderClass base_video_encoder_class;
+  /*virtual function to get supported algo*/
+  vpx_codec_iface_t* (*get_algo) (GstVPXEnc *enc);
+  /*enabled scaling*/
+  gboolean (*enable_scaling) (GstVPXEnc *enc);
+  /*set image format info*/
+  void (*set_image_format) (GstVPXEnc *enc, vpx_image_t *image);
+  /*get new simple caps*/
+  GstCaps* (*get_new_vpx_caps) (GstVPXEnc *enc);
+  /*set stream info*/
+  void (*set_stream_info) (GstVPXEnc *enc, GstCaps *caps, GstVideoInfo *info);
+  /*process user data*/
+  void* (*process_frame_user_data) (GstVPXEnc *enc, GstVideoCodecFrame* frame);
+  /*set frame user data*/
+  void (*set_frame_user_data) (GstVPXEnc *enc, GstVideoCodecFrame* frame, vpx_image_t *image);
+  /*Handle invisible frame*/
+  GstFlowReturn (*handle_invisible_frame_buffer) (GstVPXEnc *enc, void* user_data, GstBuffer* buffer);
+};
+
+GType gst_vpx_enc_get_type (void);
+
+G_END_DECLS
+
+#endif
+
+#endif /* __GST_VPX_ENC_H__ */
diff --git a/ext/wavpack/Makefile.in b/ext/wavpack/Makefile.in
index f8271d1..00aafd9 100644
--- a/ext/wavpack/Makefile.in
+++ b/ext/wavpack/Makefile.in
@@ -481,6 +481,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst-plugins-good.doap b/gst-plugins-good.doap
index 9f313ae..a0f605e 100644
--- a/gst-plugins-good.doap
+++ b/gst-plugins-good.doap
@@ -34,6 +34,16 @@
 
  <release>
   <Version>
+   <revision>1.7.1</revision>
+   <branch>master</branch>
+   <name></name>
+   <created>2015-12-24</created>
+   <file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-plugins-good/gst-plugins-good-1.7.1.tar.xz" />
+  </Version>
+ </release>
+
+ <release>
+  <Version>
    <revision>1.6.2</revision>
    <branch>1.6</branch>
    <name></name>
diff --git a/gst-plugins-good.spec b/gst-plugins-good.spec
index de398d3..9daa75d 100644
--- a/gst-plugins-good.spec
+++ b/gst-plugins-good.spec
@@ -4,7 +4,7 @@
 %define gst_minver   0.11.0
 
 Name: 		%{gstreamer}-plugins-good
-Version: 	1.6.2
+Version: 	1.7.1
 Release: 	1.gst
 Summary: 	GStreamer plug-ins with good code and licensing
 
diff --git a/gst/Makefile.in b/gst/Makefile.in
index 50a8d8c..7998d2e 100644
--- a/gst/Makefile.in
+++ b/gst/Makefile.in
@@ -455,6 +455,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/alpha/Makefile.in b/gst/alpha/Makefile.in
index 1049b81..714bf23 100644
--- a/gst/alpha/Makefile.in
+++ b/gst/alpha/Makefile.in
@@ -486,6 +486,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/apetag/Makefile.in b/gst/apetag/Makefile.in
index fb65f06..525265d 100644
--- a/gst/apetag/Makefile.in
+++ b/gst/apetag/Makefile.in
@@ -476,6 +476,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/audiofx/Makefile.in b/gst/audiofx/Makefile.in
index 393e06b..a8e19d9 100644
--- a/gst/audiofx/Makefile.in
+++ b/gst/audiofx/Makefile.in
@@ -523,6 +523,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/audiofx/audiochebband.c b/gst/audiofx/audiochebband.c
index d295009..78febe9 100644
--- a/gst/audiofx/audiochebband.c
+++ b/gst/audiofx/audiochebband.c
@@ -59,7 +59,7 @@
  * <refsect2>
  * <title>Example launch line</title>
  * |[
- * gst-launch-1.0 audiotestsrc freq=1500 ! audioconvert ! audiochebband mode=band-pass lower-frequency=1000 upper-frequenc=6000 poles=4 ! audioconvert ! alsasink
+ * gst-launch-1.0 audiotestsrc freq=1500 ! audioconvert ! audiochebband mode=band-pass lower-frequency=1000 upper-frequency=6000 poles=4 ! audioconvert ! alsasink
  * gst-launch-1.0 filesrc location="melo1.ogg" ! oggdemux ! vorbisdec ! audioconvert ! audiochebband mode=band-reject lower-frequency=1000 upper-frequency=4000 ripple=0.2 ! audioconvert ! alsasink
  * gst-launch-1.0 audiotestsrc wave=white-noise ! audioconvert ! audiochebband mode=band-pass lower-frequency=1000 upper-frequency=4000 type=2 ! audioconvert ! alsasink
  * ]|
diff --git a/gst/audiofx/audiodynamic.h b/gst/audiofx/audiodynamic.h
index 09f3bc6..ff1e4fb 100644
--- a/gst/audiofx/audiodynamic.h
+++ b/gst/audiofx/audiodynamic.h
@@ -43,8 +43,6 @@
 {
   GstAudioFilter audiofilter;
 
-  gfloat degree;
-
   /* < private > */
   GstAudioDynamicProcessFunc process;
   gint characteristics;
diff --git a/gst/audiofx/audiofxbaseiirfilter.h b/gst/audiofx/audiofxbaseiirfilter.h
index d0e8b8b..f78ae31 100644
--- a/gst/audiofx/audiofxbaseiirfilter.h
+++ b/gst/audiofx/audiofxbaseiirfilter.h
@@ -54,7 +54,6 @@
   /* < private > */
   GstAudioFXBaseIIRFilterProcessFunc process;
 
-  gboolean have_coeffs;
   gdouble *a;
   guint na;
   gdouble *b;
diff --git a/gst/audiofx/gstscaletempo.c b/gst/audiofx/gstscaletempo.c
index d1f2f53..2601bf4 100644
--- a/gst/audiofx/gstscaletempo.c
+++ b/gst/audiofx/gstscaletempo.c
@@ -94,6 +94,7 @@
 #define SUPPORTED_CAPS \
 GST_STATIC_CAPS ( \
     GST_AUDIO_CAPS_MAKE (GST_AUDIO_NE (F32)) "; " \
+    GST_AUDIO_CAPS_MAKE (GST_AUDIO_NE (F64)) "; " \
     GST_AUDIO_CAPS_MAKE (GST_AUDIO_NE (S16)) \
 )
 
@@ -113,40 +114,44 @@
 G_DEFINE_TYPE_WITH_CODE (GstScaletempo, gst_scaletempo,
     GST_TYPE_BASE_TRANSFORM, DEBUG_INIT (0));
 
-static guint
-best_overlap_offset_float (GstScaletempo * st)
-{
-  gfloat *pw, *po, *ppc, *search_start;
-  gfloat best_corr = G_MININT;
-  guint best_off = 0;
-  gint i, off;
-
-  pw = st->table_window;
-  po = st->buf_overlap;
-  po += st->samples_per_frame;
-  ppc = st->buf_pre_corr;
-  for (i = st->samples_per_frame; i < st->samples_overlap; i++) {
-    *ppc++ = *pw++ * *po++;
-  }
-
-  search_start = (gfloat *) st->buf_queue + st->samples_per_frame;
-  for (off = 0; off < st->frames_search; off++) {
-    gfloat corr = 0;
-    gfloat *ps = search_start;
-    ppc = st->buf_pre_corr;
-    for (i = st->samples_per_frame; i < st->samples_overlap; i++) {
-      corr += *ppc++ * *ps++;
-    }
-    if (corr > best_corr) {
-      best_corr = corr;
-      best_off = off;
-    }
-    search_start += st->samples_per_frame;
-  }
-
-  return best_off * st->bytes_per_frame;
+#define CREATE_BEST_OVERLAP_OFFSET_FLOAT_FUNC(type) \
+static guint \
+best_overlap_offset_##type (GstScaletempo * st) \
+{ \
+  g##type *pw, *po, *ppc, *search_start; \
+  g##type best_corr = G_MININT; \
+  guint best_off = 0; \
+  gint i, off; \
+  \
+  pw = st->table_window; \
+  po = st->buf_overlap; \
+  po += st->samples_per_frame; \
+  ppc = st->buf_pre_corr; \
+  for (i = st->samples_per_frame; i < st->samples_overlap; i++) { \
+    *ppc++ = *pw++ * *po++; \
+  } \
+  \
+  search_start = (g##type *) st->buf_queue + st->samples_per_frame; \
+  for (off = 0; off < st->frames_search; off++) { \
+    g##type corr = 0; \
+    g##type *ps = search_start; \
+    ppc = st->buf_pre_corr; \
+    for (i = st->samples_per_frame; i < st->samples_overlap; i++) { \
+      corr += *ppc++ * *ps++; \
+    } \
+    if (corr > best_corr) { \
+      best_corr = corr; \
+      best_off = off; \
+    } \
+    search_start += st->samples_per_frame; \
+  } \
+  \
+  return best_off * st->bytes_per_frame; \
 }
 
+CREATE_BEST_OVERLAP_OFFSET_FLOAT_FUNC (float);
+CREATE_BEST_OVERLAP_OFFSET_FLOAT_FUNC (double);
+
 /* buffer padding for loop optimization: sizeof(gint32) * (loop_size - 1) */
 #define UNROLL_PADDING (4*3)
 static guint
@@ -192,20 +197,24 @@
   return best_off * st->bytes_per_frame;
 }
 
-static void
-output_overlap_float (GstScaletempo * st, gpointer buf_out, guint bytes_off)
-{
-  gfloat *pout = buf_out;
-  gfloat *pb = st->table_blend;
-  gfloat *po = st->buf_overlap;
-  gfloat *pin = (gfloat *) (st->buf_queue + bytes_off);
-  gint i;
-  for (i = 0; i < st->samples_overlap; i++) {
-    *pout++ = *po - *pb++ * (*po - *pin++);
-    po++;
-  }
+#define CREATE_OUTPUT_OVERLAP_FLOAT_FUNC(type) \
+static void \
+output_overlap_##type (GstScaletempo * st, gpointer buf_out, guint bytes_off) \
+{ \
+  g##type *pout = buf_out; \
+  g##type *pb = st->table_blend; \
+  g##type *po = st->buf_overlap; \
+  g##type *pin = (g##type *) (st->buf_queue + bytes_off); \
+  gint i; \
+  for (i = 0; i < st->samples_overlap; i++) { \
+    *pout++ = *po - *pb++ * (*po - *pin++); \
+    po++; \
+  } \
 }
 
+CREATE_OUTPUT_OVERLAP_FLOAT_FUNC (float);
+CREATE_OUTPUT_OVERLAP_FLOAT_FUNC (double);
+
 static void
 output_overlap_s16 (GstScaletempo * st, gpointer buf_out, guint bytes_off)
 {
@@ -283,12 +292,13 @@
     st->bytes_standing = st->bytes_stride - st->bytes_overlap;
     st->samples_standing = st->bytes_standing / st->bytes_per_sample;
     st->buf_overlap = g_realloc (st->buf_overlap, st->bytes_overlap);
-    st->table_blend = g_realloc (st->table_blend, st->samples_overlap * 4);     /* sizeof (gint32|gfloat) */
+    st->table_blend =
+        g_realloc (st->table_blend, st->samples_overlap * st->bytes_per_sample);
     if (st->bytes_overlap > prev_overlap) {
       memset ((guint8 *) st->buf_overlap + prev_overlap, 0,
           st->bytes_overlap - prev_overlap);
     }
-    if (st->use_int) {
+    if (st->format == GST_AUDIO_FORMAT_S16) {
       gint32 *pb = st->table_blend;
       gint64 blend = 0;
       for (i = 0; i < frames_overlap; i++) {
@@ -299,7 +309,7 @@
         blend += 65535;         /* 2^16 */
       }
       st->output_overlap = output_overlap_s16;
-    } else {
+    } else if (st->format == GST_AUDIO_FORMAT_F32) {
       gfloat *pb = st->table_blend;
       gfloat t = (gfloat) frames_overlap;
       for (i = 0; i < frames_overlap; i++) {
@@ -309,6 +319,16 @@
         }
       }
       st->output_overlap = output_overlap_float;
+    } else {
+      gdouble *pb = st->table_blend;
+      gdouble t = (gdouble) frames_overlap;
+      for (i = 0; i < frames_overlap; i++) {
+        gdouble v = i / t;
+        for (j = 0; j < st->samples_per_frame; j++) {
+          *pb++ = v;
+        }
+      }
+      st->output_overlap = output_overlap_double;
     }
   }
 
@@ -318,11 +338,12 @@
   if (st->frames_search < 1) {  /* if no search */
     st->best_overlap_offset = NULL;
   } else {
-    guint bytes_pre_corr = (st->samples_overlap - st->samples_per_frame) * 4;   /* sizeof (gint32|gfloat) */
+    guint bytes_pre_corr =
+        (st->samples_overlap - st->samples_per_frame) * st->bytes_per_sample;
     st->buf_pre_corr =
         g_realloc (st->buf_pre_corr, bytes_pre_corr + UNROLL_PADDING);
     st->table_window = g_realloc (st->table_window, bytes_pre_corr);
-    if (st->use_int) {
+    if (st->format == GST_AUDIO_FORMAT_S16) {
       gint64 t = frames_overlap;
       gint32 n = 8589934588LL / (t * t);        /* 4 * (2^31 - 1) / t^2 */
       gint32 *pw;
@@ -336,7 +357,7 @@
         }
       }
       st->best_overlap_offset = best_overlap_offset_s16;
-    } else {
+    } else if (st->format == GST_AUDIO_FORMAT_F32) {
       gfloat *pw = st->table_window;
       for (i = 1; i < frames_overlap; i++) {
         gfloat v = i * (frames_overlap - i);
@@ -345,6 +366,15 @@
         }
       }
       st->best_overlap_offset = best_overlap_offset_float;
+    } else {
+      gdouble *pw = st->table_window;
+      for (i = 1; i < frames_overlap; i++) {
+        gdouble v = i * (frames_overlap - i);
+        for (j = 0; j < st->samples_per_frame; j++) {
+          *pw++ = v;
+        }
+      }
+      st->best_overlap_offset = best_overlap_offset_double;
     }
   }
 
@@ -386,7 +416,7 @@
       (gint) (st->bytes_standing / st->bytes_per_frame),
       (gint) (st->bytes_overlap / st->bytes_per_frame), st->frames_search,
       (gint) (st->bytes_queue_max / st->bytes_per_frame),
-      (st->use_int ? "s16" : "float"));
+      gst_audio_format_to_string (st->format));
 
   st->reinit_buffers = FALSE;
 }
@@ -401,7 +431,19 @@
   outbuf = gst_buffer_new_and_alloc (imap.size);
   gst_buffer_map (outbuf, &omap, GST_MAP_WRITE);
 
-  {
+  if (st->format == GST_AUDIO_FORMAT_F64) {
+    const gint64 *ip = (const gint64 *) imap.data;
+    gint64 *op = (gint64 *) (omap.data + omap.size - 8 * st->samples_per_frame);
+    guint i, n = imap.size / (8 * st->samples_per_frame);
+    guint j, c = st->samples_per_frame;
+
+    for (i = 0; i < n; i++) {
+      for (j = 0; j < c; j++)
+        op[j] = ip[j];
+      op -= c;
+      ip += c;
+    }
+  } else {
     const gint32 *ip = (const gint32 *) imap.data;
     gint32 *op = (gint32 *) (omap.data + omap.size - 4 * st->samples_per_frame);
     guint i, n = imap.size / (4 * st->samples_per_frame);
@@ -616,8 +658,8 @@
   GstScaletempo *scaletempo = GST_SCALETEMPO (trans);
 
   gint width, bps, nch, rate;
-  gboolean use_int;
   GstAudioInfo info;
+  GstAudioFormat format;
 
   if (!gst_audio_info_from_caps (&info, incaps))
     return FALSE;
@@ -625,7 +667,7 @@
   nch = GST_AUDIO_INFO_CHANNELS (&info);
   rate = GST_AUDIO_INFO_RATE (&info);
   width = GST_AUDIO_INFO_WIDTH (&info);
-  use_int = GST_AUDIO_INFO_IS_INTEGER (&info);
+  format = GST_AUDIO_INFO_FORMAT (&info);
 
   bps = width / 8;
 
@@ -633,13 +675,12 @@
 
   if (rate != scaletempo->sample_rate
       || nch != scaletempo->samples_per_frame
-      || bps != scaletempo->bytes_per_sample
-      || use_int != scaletempo->use_int) {
+      || bps != scaletempo->bytes_per_sample || format != scaletempo->format) {
     scaletempo->sample_rate = rate;
     scaletempo->samples_per_frame = nch;
     scaletempo->bytes_per_sample = bps;
     scaletempo->bytes_per_frame = nch * bps;
-    scaletempo->use_int = use_int;
+    scaletempo->format = format;
     scaletempo->reinit_buffers = TRUE;
   }
 
diff --git a/gst/audiofx/gstscaletempo.h b/gst/audiofx/gstscaletempo.h
index a6065b0..051881d 100644
--- a/gst/audiofx/gstscaletempo.h
+++ b/gst/audiofx/gstscaletempo.h
@@ -49,7 +49,7 @@
   guint ms_search;
 
   /* caps */
-  gboolean use_int;
+  GstAudioFormat format;
   guint samples_per_frame;      /* AKA number of channels */
   guint bytes_per_sample;
   guint bytes_per_frame;
diff --git a/gst/audioparsers/Makefile.in b/gst/audioparsers/Makefile.in
index df9da7b..f6ae877 100644
--- a/gst/audioparsers/Makefile.in
+++ b/gst/audioparsers/Makefile.in
@@ -485,6 +485,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/audioparsers/gstaacparse.c b/gst/audioparsers/gstaacparse.c
index cd75b7f..2be97c0 100644
--- a/gst/audioparsers/gstaacparse.c
+++ b/gst/audioparsers/gstaacparse.c
@@ -1302,7 +1302,10 @@
       /* This is pretty normal when skipping data at the start of
        * random stream (MPEG-TS capture for example) */
       GST_DEBUG_OBJECT (aacparse, "Error reading LOAS config. Skipping.");
-      *skipsize = map.size;
+      /* Since we don't fully parse the LOAS config, we don't know for sure
+       * how much to skip. Just skip 1 to end up to the next marker and
+       * resume parsing from there */
+      *skipsize = 1;
       goto exit;
     }
 
@@ -1367,10 +1370,19 @@
     GstTagList *taglist;
     GstCaps *caps;
 
-    taglist = gst_tag_list_new_empty ();
-
     /* codec tag */
     caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
+    if (caps == NULL) {
+      if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
+        GST_INFO_OBJECT (parse, "Src pad is flushing");
+        return GST_FLOW_FLUSHING;
+      } else {
+        GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
+        return GST_FLOW_NOT_NEGOTIATED;
+      }
+    }
+
+    taglist = gst_tag_list_new_empty ();
     gst_pb_utils_add_codec_description_to_tag_list (taglist,
         GST_TAG_AUDIO_CODEC, caps);
     gst_caps_unref (caps);
diff --git a/gst/audioparsers/gstac3parse.c b/gst/audioparsers/gstac3parse.c
index a7b2475..875f9cb 100644
--- a/gst/audioparsers/gstac3parse.c
+++ b/gst/audioparsers/gstac3parse.c
@@ -786,10 +786,19 @@
     GstTagList *taglist;
     GstCaps *caps;
 
-    taglist = gst_tag_list_new_empty ();
-
     /* codec tag */
     caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
+    if (G_UNLIKELY (caps == NULL)) {
+      if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
+        GST_INFO_OBJECT (parse, "Src pad is flushing");
+        return GST_FLOW_FLUSHING;
+      } else {
+        GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
+        return GST_FLOW_NOT_NEGOTIATED;
+      }
+    }
+
+    taglist = gst_tag_list_new_empty ();
     gst_pb_utils_add_codec_description_to_tag_list (taglist,
         GST_TAG_AUDIO_CODEC, caps);
     gst_caps_unref (caps);
diff --git a/gst/audioparsers/gstamrparse.c b/gst/audioparsers/gstamrparse.c
index b9501d5..557afc9 100644
--- a/gst/audioparsers/gstamrparse.c
+++ b/gst/audioparsers/gstamrparse.c
@@ -426,10 +426,19 @@
     GstTagList *taglist;
     GstCaps *caps;
 
-    taglist = gst_tag_list_new_empty ();
-
     /* codec tag */
     caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
+    if (G_UNLIKELY (caps == NULL)) {
+      if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
+        GST_INFO_OBJECT (parse, "Src pad is flushing");
+        return GST_FLOW_FLUSHING;
+      } else {
+        GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
+        return GST_FLOW_NOT_NEGOTIATED;
+      }
+    }
+
+    taglist = gst_tag_list_new_empty ();
     gst_pb_utils_add_codec_description_to_tag_list (taglist,
         GST_TAG_AUDIO_CODEC, caps);
     gst_caps_unref (caps);
diff --git a/gst/audioparsers/gstdcaparse.c b/gst/audioparsers/gstdcaparse.c
index cfe97e1..3809323 100644
--- a/gst/audioparsers/gstdcaparse.c
+++ b/gst/audioparsers/gstdcaparse.c
@@ -565,10 +565,19 @@
     GstTagList *taglist;
     GstCaps *caps;
 
-    taglist = gst_tag_list_new_empty ();
-
     /* codec tag */
     caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
+    if (G_UNLIKELY (caps == NULL)) {
+      if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
+        GST_INFO_OBJECT (parse, "Src pad is flushing");
+        return GST_FLOW_FLUSHING;
+      } else {
+        GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
+        return GST_FLOW_NOT_NEGOTIATED;
+      }
+    }
+
+    taglist = gst_tag_list_new_empty ();
     gst_pb_utils_add_codec_description_to_tag_list (taglist,
         GST_TAG_AUDIO_CODEC, caps);
     gst_caps_unref (caps);
diff --git a/gst/audioparsers/gstflacparse.c b/gst/audioparsers/gstflacparse.c
index bf598c7..6939604 100644
--- a/gst/audioparsers/gstflacparse.c
+++ b/gst/audioparsers/gstflacparse.c
@@ -1708,6 +1708,15 @@
 
     /* codec tag */
     caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
+    if (G_UNLIKELY (caps == NULL)) {
+      if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
+        GST_INFO_OBJECT (parse, "Src pad is flushing");
+        return GST_FLOW_FLUSHING;
+      } else {
+        GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
+        return GST_FLOW_NOT_NEGOTIATED;
+      }
+    }
     gst_pb_utils_add_codec_description_to_tag_list (flacparse->tags,
         GST_TAG_AUDIO_CODEC, caps);
     gst_caps_unref (caps);
diff --git a/gst/audioparsers/gstmpegaudioparse.c b/gst/audioparsers/gstmpegaudioparse.c
index ba4441d..1a5313a 100644
--- a/gst/audioparsers/gstmpegaudioparse.c
+++ b/gst/audioparsers/gstmpegaudioparse.c
@@ -1361,6 +1361,17 @@
 
     /* codec tag */
     caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
+    if (G_UNLIKELY (caps == NULL)) {
+      gst_tag_list_unref (taglist);
+
+      if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
+        GST_INFO_OBJECT (parse, "Src pad is flushing");
+        return GST_FLOW_FLUSHING;
+      } else {
+        GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
+        return GST_FLOW_NOT_NEGOTIATED;
+      }
+    }
     gst_pb_utils_add_codec_description_to_tag_list (taglist,
         GST_TAG_AUDIO_CODEC, caps);
     gst_caps_unref (caps);
diff --git a/gst/audioparsers/gstsbcparse.c b/gst/audioparsers/gstsbcparse.c
index 4412e2b..5776511 100644
--- a/gst/audioparsers/gstsbcparse.c
+++ b/gst/audioparsers/gstsbcparse.c
@@ -507,10 +507,19 @@
     GstTagList *taglist;
     GstCaps *caps;
 
-    taglist = gst_tag_list_new_empty ();
-
     /* codec tag */
     caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
+    if (G_UNLIKELY (caps == NULL)) {
+      if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
+        GST_INFO_OBJECT (parse, "Src pad is flushing");
+        return GST_FLOW_FLUSHING;
+      } else {
+        GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
+        return GST_FLOW_NOT_NEGOTIATED;
+      }
+    }
+
+    taglist = gst_tag_list_new_empty ();
     gst_pb_utils_add_codec_description_to_tag_list (taglist,
         GST_TAG_AUDIO_CODEC, caps);
     gst_caps_unref (caps);
diff --git a/gst/audioparsers/gstwavpackparse.c b/gst/audioparsers/gstwavpackparse.c
index 3c6e27a..ce85c5b 100644
--- a/gst/audioparsers/gstwavpackparse.c
+++ b/gst/audioparsers/gstwavpackparse.c
@@ -680,10 +680,19 @@
     GstTagList *taglist;
     GstCaps *caps;
 
-    taglist = gst_tag_list_new_empty ();
-
     /* codec tag */
     caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
+    if (G_UNLIKELY (caps == NULL)) {
+      if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
+        GST_INFO_OBJECT (parse, "Src pad is flushing");
+        return GST_FLOW_FLUSHING;
+      } else {
+        GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
+        return GST_FLOW_NOT_NEGOTIATED;
+      }
+    }
+
+    taglist = gst_tag_list_new_empty ();
     gst_pb_utils_add_codec_description_to_tag_list (taglist,
         GST_TAG_AUDIO_CODEC, caps);
     gst_caps_unref (caps);
diff --git a/gst/auparse/Makefile.in b/gst/auparse/Makefile.in
index 99361d2..35870bf 100644
--- a/gst/auparse/Makefile.in
+++ b/gst/auparse/Makefile.in
@@ -476,6 +476,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/autodetect/Makefile.in b/gst/autodetect/Makefile.in
index 470f098..c7a9984 100644
--- a/gst/autodetect/Makefile.in
+++ b/gst/autodetect/Makefile.in
@@ -480,6 +480,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/avi/Makefile.in b/gst/avi/Makefile.in
index 0566395..390cdcb 100644
--- a/gst/avi/Makefile.in
+++ b/gst/avi/Makefile.in
@@ -478,6 +478,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c
index aaac6cb..4a80cd6 100644
--- a/gst/avi/gstavidemux.c
+++ b/gst/avi/gstavidemux.c
@@ -2017,6 +2017,7 @@
   GstEvent *event;
   gchar *stream_id;
   GstMapInfo map;
+  gboolean sparse = FALSE;
 
   element = GST_ELEMENT_CAST (avi);
 
@@ -2284,7 +2285,8 @@
           stream->strf.vids, stream->extradata, stream->initdata, &codec_name);
 
       /* DXSB is XSUB, and it is placed inside a vids */
-      if (!caps || fourcc != GST_MAKE_FOURCC ('D', 'X', 'S', 'B')) {
+      if (!caps || (fourcc != GST_MAKE_FOURCC ('D', 'X', 'S', 'B') &&
+              fourcc != GST_MAKE_FOURCC ('D', 'X', 'S', 'A'))) {
         padname = g_strdup_printf ("video_%u", avi->num_v_streams);
         templ = gst_element_class_get_pad_template (klass, "video_%u");
         if (!caps) {
@@ -2314,6 +2316,7 @@
         templ = gst_element_class_get_pad_template (klass, "subpicture_%u");
         tag_name = NULL;
         avi->num_sp_streams++;
+        sparse = TRUE;
       }
       break;
     }
@@ -2353,6 +2356,7 @@
       caps = gst_caps_new_empty_simple ("application/x-subtitle-avi");
       tag_name = NULL;
       avi->num_t_streams++;
+      sparse = TRUE;
       break;
     }
     default:
@@ -2431,6 +2435,8 @@
   event = gst_event_new_stream_start (stream_id);
   if (avi->have_group_id)
     gst_event_set_group_id (event, avi->group_id);
+  if (sparse)
+    gst_event_set_stream_flags (event, GST_STREAM_FLAG_SPARSE);
 
   gst_pad_push_event (pad, event);
   g_free (stream_id);
@@ -5186,6 +5192,10 @@
           && (timestamp > avi->segment.stop)) {
         goto eos_stop;
       }
+    } else {
+      if (keyframe && GST_CLOCK_TIME_IS_VALID (avi->segment.start)
+          && (timestamp < avi->segment.start))
+        goto eos_stop;
     }
 
     GST_LOG ("reading buffer (size=%" G_GUINT64_FORMAT "), stream %d, pos %"
diff --git a/gst/cutter/Makefile.in b/gst/cutter/Makefile.in
index bf789fa..c0f7da3 100644
--- a/gst/cutter/Makefile.in
+++ b/gst/cutter/Makefile.in
@@ -476,6 +476,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/debugutils/Makefile.in b/gst/debugutils/Makefile.in
index d8b7435..c51a483 100644
--- a/gst/debugutils/Makefile.in
+++ b/gst/debugutils/Makefile.in
@@ -493,6 +493,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/debugutils/progressreport.c b/gst/debugutils/progressreport.c
index 7dd05dc..1426ca8 100644
--- a/gst/debugutils/progressreport.c
+++ b/gst/debugutils/progressreport.c
@@ -252,6 +252,9 @@
       cur = gst_segment_to_stream_time (&base->segment, format,
           GST_BUFFER_TIMESTAMP (buf));
       total = base->segment.duration;
+    } else if (format == GST_FORMAT_BUFFERS) {
+      cur = filter->buffer_count;
+      total = -1;
     } else {
       return FALSE;
     }
@@ -411,6 +414,7 @@
   GST_OBJECT_LOCK (filter);
   need_update =
       ((cur_time.tv_sec - filter->last_report.tv_sec) >= filter->update_freq);
+  filter->buffer_count++;
   GST_OBJECT_UNLOCK (filter);
 
   if (need_update) {
@@ -432,6 +436,7 @@
 
   g_get_current_time (&filter->last_report);
   filter->start_time = filter->last_report;
+  filter->buffer_count = 0;
 
   return TRUE;
 }
diff --git a/gst/debugutils/progressreport.h b/gst/debugutils/progressreport.h
index c46ac09..d990937 100644
--- a/gst/debugutils/progressreport.h
+++ b/gst/debugutils/progressreport.h
@@ -50,6 +50,7 @@
   gboolean do_query;
   GTimeVal start_time;
   GTimeVal last_report;
+  gint64 buffer_count;
 
   /* Format used for querying. Using a string here because the
    * format might not be registered yet when the property is set */
diff --git a/gst/deinterlace/Makefile.in b/gst/deinterlace/Makefile.in
index 493aaf0..22a90c0 100644
--- a/gst/deinterlace/Makefile.in
+++ b/gst/deinterlace/Makefile.in
@@ -517,6 +517,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/deinterlace/gstdeinterlace.c b/gst/deinterlace/gstdeinterlace.c
index 0c46a42..fa0c5f4 100644
--- a/gst/deinterlace/gstdeinterlace.c
+++ b/gst/deinterlace/gstdeinterlace.c
@@ -1191,9 +1191,9 @@
     GstClockTimeDiff diff, GstClockTime timestamp)
 {
   GST_DEBUG_OBJECT (self,
-      "Updating QoS: proportion %lf, diff %s%" GST_TIME_FORMAT ", timestamp %"
-      GST_TIME_FORMAT, proportion, (diff < 0) ? "-" : "",
-      GST_TIME_ARGS (ABS (diff)), GST_TIME_ARGS (timestamp));
+      "Updating QoS: proportion %lf, diff %" GST_STIME_FORMAT ", timestamp %"
+      GST_TIME_FORMAT, proportion, GST_STIME_ARGS (diff),
+      GST_TIME_ARGS (timestamp));
 
   GST_OBJECT_LOCK (self);
   self->proportion = proportion;
@@ -2123,6 +2123,32 @@
   return TRUE;
 }
 
+static gboolean
+gst_deinterlace_acceptcaps (GstDeinterlace * self, GstPad * pad, GstCaps * caps)
+{
+  gboolean ret;
+  GstCaps *ourcaps;
+  GstVideoInterlaceMode interlacing_mode;
+
+  interlacing_mode = GST_VIDEO_INFO_INTERLACE_MODE (&self->vinfo);
+
+  if (self->mode == GST_DEINTERLACE_MODE_INTERLACED ||
+      (self->mode == GST_DEINTERLACE_MODE_AUTO &&
+          interlacing_mode != GST_VIDEO_INTERLACE_MODE_PROGRESSIVE)) {
+    ourcaps = gst_caps_from_string (DEINTERLACE_CAPS);
+  } else {
+    ourcaps = gst_pad_get_pad_template_caps (pad);
+  }
+
+  ret = gst_caps_can_intersect (caps, ourcaps);
+  gst_caps_unref (ourcaps);
+
+  GST_DEBUG_OBJECT (pad, "accept-caps result:%d for caps %" GST_PTR_FORMAT,
+      ret, caps);
+
+  return ret;
+}
+
 static GstCaps *
 gst_deinterlace_getcaps (GstDeinterlace * self, GstPad * pad, GstCaps * filter)
 {
@@ -2156,6 +2182,7 @@
 
       if (!interlace_mode || g_strcmp0 (interlace_mode, "progressive") == 0) {
         filter_interlaced = FALSE;
+        break;
       }
     }
   }
@@ -2675,6 +2702,17 @@
       res = TRUE;
       break;
     }
+    case GST_QUERY_ACCEPT_CAPS:
+    {
+      GstCaps *caps;
+      gboolean ret;
+
+      gst_query_parse_accept_caps (query, &caps);
+      ret = gst_deinterlace_acceptcaps (self, pad, caps);
+      gst_query_set_accept_caps_result (query, ret);
+      res = TRUE;
+      break;
+    }
     case GST_QUERY_ALLOCATION:
       if (self->passthrough)
         res = gst_pad_peer_query (self->srcpad, query);
diff --git a/gst/dtmf/Makefile.in b/gst/dtmf/Makefile.in
index c2abcb5..8da27fa 100644
--- a/gst/dtmf/Makefile.in
+++ b/gst/dtmf/Makefile.in
@@ -479,6 +479,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/effectv/Makefile.in b/gst/effectv/Makefile.in
index f58a7ca..f70dfd8 100644
--- a/gst/effectv/Makefile.in
+++ b/gst/effectv/Makefile.in
@@ -484,6 +484,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/effectv/gstop.c b/gst/effectv/gstop.c
index d91a375..82da702 100644
--- a/gst/effectv/gstop.c
+++ b/gst/effectv/gstop.c
@@ -275,14 +275,12 @@
   height = GST_VIDEO_INFO_HEIGHT (in_info);
 
   for (i = 0; i < 4; i++) {
-    if (filter->opmap[i])
-      g_free (filter->opmap[i]);
+    g_free (filter->opmap[i]);
     filter->opmap[i] = g_new (gint8, width * height);
   }
   setOpmap (filter->opmap, width, height);
 
-  if (filter->diff)
-    g_free (filter->diff);
+  g_free (filter->diff);
   filter->diff = g_new (guint8, width * height);
 
   return TRUE;
@@ -307,14 +305,12 @@
     gint i;
 
     for (i = 0; i < 4; i++) {
-      if (filter->opmap[i])
-        g_free (filter->opmap[i]);
+      g_free (filter->opmap[i]);
       filter->opmap[i] = NULL;
     }
   }
 
-  if (filter->diff)
-    g_free (filter->diff);
+  g_free (filter->diff);
   filter->diff = NULL;
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
diff --git a/gst/effectv/gstradioac.c b/gst/effectv/gstradioac.c
index 244f98f..1af4234 100644
--- a/gst/effectv/gstradioac.c
+++ b/gst/effectv/gstradioac.c
@@ -439,28 +439,22 @@
   filter->buf_margin_right =
       height - filter->buf_width - filter->buf_margin_left;
 
-  if (filter->blurzoombuf)
-    g_free (filter->blurzoombuf);
+  g_free (filter->blurzoombuf);
   filter->blurzoombuf = g_new0 (guint8, filter->buf_area * 2);
 
-  if (filter->blurzoomx)
-    g_free (filter->blurzoomx);
+  g_free (filter->blurzoomx);
   filter->blurzoomx = g_new0 (gint, filter->buf_width);
 
-  if (filter->blurzoomy)
-    g_free (filter->blurzoomy);
+  g_free (filter->blurzoomy);
   filter->blurzoomy = g_new0 (gint, filter->buf_height);
 
-  if (filter->snapframe)
-    g_free (filter->snapframe);
+  g_free (filter->snapframe);
   filter->snapframe = g_new (guint32, width * height);
 
-  if (filter->diff)
-    g_free (filter->diff);
+  g_free (filter->diff);
   filter->diff = g_new (guint8, width * height);
 
-  if (filter->background)
-    g_free (filter->background);
+  g_free (filter->background);
   filter->background = g_new0 (gint16, width * height);
 
   setTable (filter);
@@ -490,28 +484,22 @@
 {
   GstRadioacTV *filter = GST_RADIOACTV (object);
 
-  if (filter->snapframe)
-    g_free (filter->snapframe);
+  g_free (filter->snapframe);
   filter->snapframe = NULL;
 
-  if (filter->blurzoombuf)
-    g_free (filter->blurzoombuf);
+  g_free (filter->blurzoombuf);
   filter->blurzoombuf = NULL;
 
-  if (filter->diff)
-    g_free (filter->diff);
+  g_free (filter->diff);
   filter->diff = NULL;
 
-  if (filter->background)
-    g_free (filter->background);
+  g_free (filter->background);
   filter->background = NULL;
 
-  if (filter->blurzoomx)
-    g_free (filter->blurzoomx);
+  g_free (filter->blurzoomx);
   filter->blurzoomx = NULL;
 
-  if (filter->blurzoomy)
-    g_free (filter->blurzoomy);
+  g_free (filter->blurzoomy);
   filter->blurzoomy = NULL;
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
diff --git a/gst/effectv/gstripple.c b/gst/effectv/gstripple.c
index 71b9796..f81e4d7 100644
--- a/gst/effectv/gstripple.c
+++ b/gst/effectv/gstripple.c
@@ -460,24 +460,20 @@
 
   /* we over allocate the buffers, as the render code does not handle clipping
    * very well */
-  if (filter->map)
-    g_free (filter->map);
+  g_free (filter->map);
   filter->map = g_new0 (gint, (1 + filter->map_h) * filter->map_w * 3);
 
   filter->map1 = filter->map;
   filter->map2 = filter->map + filter->map_w * filter->map_h;
   filter->map3 = filter->map + filter->map_w * filter->map_h * 2;
 
-  if (filter->vtable)
-    g_free (filter->vtable);
+  g_free (filter->vtable);
   filter->vtable = g_new0 (gint8, (1 + filter->map_h) * filter->map_w * 2);
 
-  if (filter->background)
-    g_free (filter->background);
+  g_free (filter->background);
   filter->background = g_new0 (gint16, width * (height + 1));
 
-  if (filter->diff)
-    g_free (filter->diff);
+  g_free (filter->diff);
   filter->diff = g_new0 (guint8, width * (height + 1));
   GST_OBJECT_UNLOCK (filter);
 
@@ -507,20 +503,16 @@
 {
   GstRippleTV *filter = GST_RIPPLETV (object);
 
-  if (filter->map)
-    g_free (filter->map);
+  g_free (filter->map);
   filter->map = NULL;
 
-  if (filter->vtable)
-    g_free (filter->vtable);
+  g_free (filter->vtable);
   filter->vtable = NULL;
 
-  if (filter->background)
-    g_free (filter->background);
+  g_free (filter->background);
   filter->background = NULL;
 
-  if (filter->diff)
-    g_free (filter->diff);
+  g_free (filter->diff);
   filter->diff = NULL;
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
diff --git a/gst/effectv/gstshagadelic.c b/gst/effectv/gstshagadelic.c
index 956e5dd..2564cb3 100644
--- a/gst/effectv/gstshagadelic.c
+++ b/gst/effectv/gstshagadelic.c
@@ -215,12 +215,10 @@
 {
   GstShagadelicTV *filter = GST_SHAGADELICTV (object);
 
-  if (filter->ripple)
-    g_free (filter->ripple);
+  g_free (filter->ripple);
   filter->ripple = NULL;
 
-  if (filter->spiral)
-    g_free (filter->spiral);
+  g_free (filter->spiral);
   filter->spiral = NULL;
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
diff --git a/gst/effectv/gststreak.c b/gst/effectv/gststreak.c
index 6eeb08d..be7149c 100644
--- a/gst/effectv/gststreak.c
+++ b/gst/effectv/gststreak.c
@@ -151,8 +151,7 @@
   width = GST_VIDEO_INFO_WIDTH (in_info);
   height = GST_VIDEO_INFO_HEIGHT (in_info);
 
-  if (filter->planebuffer)
-    g_free (filter->planebuffer);
+  g_free (filter->planebuffer);
 
   filter->planebuffer = g_new0 (guint32, width * height * 4 * PLANES);
 
diff --git a/gst/equalizer/Makefile.in b/gst/equalizer/Makefile.in
index 39cb30d..c8138de 100644
--- a/gst/equalizer/Makefile.in
+++ b/gst/equalizer/Makefile.in
@@ -482,6 +482,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/flv/Makefile.am b/gst/flv/Makefile.am
index b396743..b205999 100644
--- a/gst/flv/Makefile.am
+++ b/gst/flv/Makefile.am
@@ -2,7 +2,7 @@
 
 libgstflv_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
 libgstflv_la_LIBADD = -lgstpbutils-@GST_API_VERSION@ -lgstaudio-@GST_API_VERSION@ \
-        -lgstvideo-@GST_API_VERSION@ \
+        -lgstvideo-@GST_API_VERSION@ -lgsttag-$(GST_API_VERSION) \
 	$(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(GST_LIBS)
 libgstflv_la_LDFLAGS = ${GST_PLUGIN_LDFLAGS}
 libgstflv_la_SOURCES = gstflvdemux.c gstflvmux.c
diff --git a/gst/flv/Makefile.in b/gst/flv/Makefile.in
index 74ed9db..64faf93 100644
--- a/gst/flv/Makefile.in
+++ b/gst/flv/Makefile.in
@@ -477,6 +477,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
@@ -565,7 +567,7 @@
 plugin_LTLIBRARIES = libgstflv.la
 libgstflv_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
 libgstflv_la_LIBADD = -lgstpbutils-@GST_API_VERSION@ -lgstaudio-@GST_API_VERSION@ \
-        -lgstvideo-@GST_API_VERSION@ \
+        -lgstvideo-@GST_API_VERSION@ -lgsttag-$(GST_API_VERSION) \
 	$(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(GST_LIBS)
 
 libgstflv_la_LDFLAGS = ${GST_PLUGIN_LDFLAGS}
diff --git a/gst/flv/gstflvdemux.c b/gst/flv/gstflvdemux.c
index 22bc40b..19765f7 100644
--- a/gst/flv/gstflvdemux.c
+++ b/gst/flv/gstflvdemux.c
@@ -38,12 +38,14 @@
 #include "gstflvmux.h"
 
 #include <string.h>
+#include <stdio.h>
 #include <gst/base/gstbytereader.h>
 #include <gst/base/gstbytewriter.h>
 #include <gst/pbutils/descriptions.h>
 #include <gst/pbutils/pbutils.h>
 #include <gst/audio/audio.h>
 #include <gst/video/video.h>
+#include <gst/tag/tag.h>
 
 /* FIXME: don't rely on own GstIndex */
 #include "gstindex.c"
@@ -242,55 +244,74 @@
   GST_DEBUG_OBJECT (demux, "upstream seekable: %d", demux->upstream_seekable);
 }
 
-static void
-parse_flv_demux_parse_date_string (GDate * date, const gchar * s)
+static GstDateTime *
+parse_flv_demux_parse_date_string (const gchar * s)
 {
-  g_date_set_parse (date, s);
-  if (g_date_valid (date))
-    return;
+  static const gchar months[12][4] = {
+    "Jan", "Feb", "Mar", "Apr",
+    "May", "Jun", "Jul", "Aug",
+    "Sep", "Oct", "Nov", "Dec"
+  };
+  GstDateTime *dt = NULL;
+  gchar **tokens;
+  guint64 d;
+  gchar *endptr;
+  gint i, hh, mm, ss;
+  gint year = -1, month = -1, day = -1;
+  gint hour = -1, minute = -1, seconds = -1;
 
   /* "Fri Oct 15 15:13:16 2004" needs to be parsed */
-  {
-    static const gchar *months[] = {
-      "Jan", "Feb", "Mar", "Apr",
-      "May", "Jun", "Jul", "Aug",
-      "Sep", "Oct", "Nov", "Dec"
-    };
-    gchar **tokens = g_strsplit (s, " ", -1);
-    guint64 d;
-    gchar *endptr;
-    gint i;
+  tokens = g_strsplit (s, " ", -1);
 
-    if (g_strv_length (tokens) != 5)
-      goto out;
+  if (g_strv_length (tokens) != 5)
+    goto out;
 
-    if (strlen (tokens[1]) != 3)
-      goto out;
-    for (i = 0; i < 12; i++) {
-      if (!strcmp (tokens[1], months[i])) {
-        break;
-      }
+  /* year */
+  d = g_ascii_strtoull (tokens[4], &endptr, 10);
+  if (d == 0 && *endptr != '\0')
+    goto out;
+
+  year = d;
+
+  /* month */
+  if (strlen (tokens[1]) != 3)
+    goto out;
+  for (i = 0; i < 12; i++) {
+    if (!strcmp (tokens[1], months[i])) {
+      break;
     }
-    if (i == 12)
-      goto out;
-    g_date_set_month (date, i + 1);
-
-    d = g_ascii_strtoull (tokens[2], &endptr, 10);
-    if (d == 0 && *endptr != '\0')
-      goto out;
-
-    g_date_set_day (date, d);
-
-    d = g_ascii_strtoull (tokens[4], &endptr, 10);
-    if (d == 0 && *endptr != '\0')
-      goto out;
-
-    g_date_set_year (date, d);
-
-  out:
-    if (tokens)
-      g_strfreev (tokens);
   }
+  if (i == 12)
+    goto out;
+
+  month = i + 1;
+
+  /* day */
+  d = g_ascii_strtoull (tokens[2], &endptr, 10);
+  if (d == 0 && *endptr != '\0')
+    goto out;
+
+  day = d;
+
+  /* time */
+  hh = mm = ss = 0;
+  if (sscanf (tokens[3], "%d:%d:%d", &hh, &mm, &ss) < 2)
+    goto out;
+  if (hh >= 0 && hh < 24 && mm >= 0 && mm < 60 && ss >= 0 && ss < 60) {
+    hour = hh;
+    minute = mm;
+    seconds = ss;
+  }
+
+out:
+
+  if (tokens)
+    g_strfreev (tokens);
+
+  if (year > 0)
+    dt = gst_date_time_new (0.0, year, month, day, hour, minute, seconds);
+
+  return dt;
 }
 
 static gboolean
@@ -373,16 +394,16 @@
       GST_DEBUG_OBJECT (demux, "%s => (string) %s", tag_name, s);
 
       if (!strcmp (tag_name, "creationdate")) {
-        GDate *date = g_date_new ();
+        GstDateTime *dt;
 
-        parse_flv_demux_parse_date_string (date, s);
-        if (!g_date_valid (date)) {
-          GST_DEBUG_OBJECT (demux, "Failed to parse string as date");
+        dt = parse_flv_demux_parse_date_string (s);
+        if (dt == NULL) {
+          GST_DEBUG_OBJECT (demux, "Failed to parse '%s' into datetime", s);
         } else {
           gst_tag_list_add (demux->taglist, GST_TAG_MERGE_REPLACE,
-              GST_TAG_DATE, date, NULL);
+              GST_TAG_DATE_TIME, dt, NULL);
         }
-        g_date_free (date);
+        gst_date_time_unref (dt);
       } else if (!strcmp (tag_name, "creator")) {
         gst_tag_list_add (demux->taglist, GST_TAG_MERGE_REPLACE,
             GST_TAG_ARTIST, s, NULL);
@@ -749,6 +770,7 @@
       GstByteWriter w;
       GstStructure *structure;
       GstBuffer *buf;
+      GstTagList *tags;
 
       caps = gst_caps_new_empty_simple ("audio/x-speex");
       structure = gst_caps_get_structure (caps, 0);
@@ -785,7 +807,9 @@
 
       /* comment part */
       g_value_init (&value, GST_TYPE_BUFFER);
-      buf = gst_buffer_new_wrapped (g_memdup ("No comments", 12), 12);
+      tags = gst_tag_list_new_empty ();
+      buf = gst_tag_list_to_vorbiscomment_buffer (tags, NULL, 0, "No comments");
+      gst_tag_list_unref (tags);
       g_value_take_boxed (&value, buf);
       gst_value_array_append_value (&streamheader, &value);
       g_value_unset (&value);
@@ -1012,7 +1036,7 @@
   /* codec tags with special rates */
   if (codec_tag == 5 || codec_tag == 14)
     rate = 8000;
-  else if (codec_tag == 4)
+  else if ((codec_tag == 4) || (codec_tag == 11))
     rate = 16000;
 
   GST_LOG_OBJECT (demux, "audio tag with %d channels, %dHz sampling rate, "
diff --git a/gst/flx/Makefile.in b/gst/flx/Makefile.in
index 410c896..979805e 100644
--- a/gst/flx/Makefile.in
+++ b/gst/flx/Makefile.in
@@ -477,6 +477,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/flx/gstflxdec.c b/gst/flx/gstflxdec.c
index 3df4e9b..71fd880 100644
--- a/gst/flx/gstflxdec.c
+++ b/gst/flx/gstflxdec.c
@@ -596,8 +596,7 @@
           break;
       }
 
-      if (chunk)
-        g_free (chunk);
+      g_free (chunk);
 
       avail = gst_adapter_available (flxdec->adapter);
     }
diff --git a/gst/goom/Makefile.am b/gst/goom/Makefile.am
index 1ffa734..178172f 100644
--- a/gst/goom/Makefile.am
+++ b/gst/goom/Makefile.am
@@ -35,11 +35,10 @@
 	goom.h goom_typedefs.h goom_graphic.h			\
 	goom_config_param.h goom_visual_fx.h goom_filters.h	\
 	goom_tools.h goom_tools.h goom_config.h			\
-	gstaudiovisualizer.c gstaudiovisualizer.h \
 	$(ARCH_FILES)
 
 libgstgoom_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(GOOM_FILTER_CFLAGS) $(ARCH_CFLAGS) $(ORC_CFLAGS)
-libgstgoom_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS) -lgstvideo-$(GST_API_VERSION) -lgstaudio-$(GST_API_VERSION) $(LIBM) $(ORC_LIBS)
+libgstgoom_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstpbutils-$(GST_API_VERSION) $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM) $(ORC_LIBS)
 libgstgoom_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstgoom_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
diff --git a/gst/goom/Makefile.in b/gst/goom/Makefile.in
index c822bc1..ab2c7cf 100644
--- a/gst/goom/Makefile.in
+++ b/gst/goom/Makefile.in
@@ -162,7 +162,7 @@
 am__DEPENDENCIES_1 =
 libgstgoom_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_1)
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 am__libgstgoom_la_SOURCES_DIST = gstgoom.c gstgoom.h drawmethods.c \
 	drawmethods.h sound_tester.c sound_tester.h mathtools.c \
 	mathtools.h lines.c lines.h ifs.c ifs.h surf3d.c surf3d.h \
@@ -171,8 +171,8 @@
 	motif_goom2.h plugin_info.c goom_plugin_info.h goom_tools.c \
 	config_param.c filters.c goom_core.c graphic.c goom.h \
 	goom_typedefs.h goom_graphic.h goom_config_param.h \
-	goom_filters.h goom_tools.h goom_config.h gstaudiovisualizer.c \
-	gstaudiovisualizer.h mmx.c xmmx.c mmx.h xmmx.h
+	goom_filters.h goom_tools.h goom_config.h mmx.c xmmx.c mmx.h \
+	xmmx.h
 am__objects_1 = libgstgoom_la-mmx.lo libgstgoom_la-xmmx.lo
 @HAVE_CPU_I386_TRUE@am__objects_2 = $(am__objects_1)
 am_libgstgoom_la_OBJECTS = libgstgoom_la-gstgoom.lo \
@@ -184,7 +184,7 @@
 	libgstgoom_la-plugin_info.lo libgstgoom_la-goom_tools.lo \
 	libgstgoom_la-config_param.lo libgstgoom_la-filters.lo \
 	libgstgoom_la-goom_core.lo libgstgoom_la-graphic.lo \
-	libgstgoom_la-gstaudiovisualizer.lo $(am__objects_2)
+	$(am__objects_2)
 libgstgoom_la_OBJECTS = $(am_libgstgoom_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -495,6 +495,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
@@ -608,11 +610,10 @@
 	goom.h goom_typedefs.h goom_graphic.h			\
 	goom_config_param.h goom_visual_fx.h goom_filters.h	\
 	goom_tools.h goom_tools.h goom_config.h			\
-	gstaudiovisualizer.c gstaudiovisualizer.h \
 	$(ARCH_FILES)
 
 libgstgoom_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(GOOM_FILTER_CFLAGS) $(ARCH_CFLAGS) $(ORC_CFLAGS)
-libgstgoom_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS) -lgstvideo-$(GST_API_VERSION) -lgstaudio-$(GST_API_VERSION) $(LIBM) $(ORC_LIBS)
+libgstgoom_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstpbutils-$(GST_API_VERSION) $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM) $(ORC_LIBS)
 libgstgoom_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstgoom_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 EXTRA_DIST = $(PPC_FILES) $(MMX_FILES)
@@ -702,7 +703,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstgoom_la-goom_core.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstgoom_la-goom_tools.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstgoom_la-graphic.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstgoom_la-gstaudiovisualizer.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstgoom_la-gstgoom.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstgoom_la-ifs.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstgoom_la-lines.Plo@am__quote@
@@ -858,13 +858,6 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstgoom_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstgoom_la_CFLAGS) $(CFLAGS) -c -o libgstgoom_la-graphic.lo `test -f 'graphic.c' || echo '$(srcdir)/'`graphic.c
 
-libgstgoom_la-gstaudiovisualizer.lo: gstaudiovisualizer.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstgoom_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstgoom_la_CFLAGS) $(CFLAGS) -MT libgstgoom_la-gstaudiovisualizer.lo -MD -MP -MF $(DEPDIR)/libgstgoom_la-gstaudiovisualizer.Tpo -c -o libgstgoom_la-gstaudiovisualizer.lo `test -f 'gstaudiovisualizer.c' || echo '$(srcdir)/'`gstaudiovisualizer.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstgoom_la-gstaudiovisualizer.Tpo $(DEPDIR)/libgstgoom_la-gstaudiovisualizer.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gstaudiovisualizer.c' object='libgstgoom_la-gstaudiovisualizer.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstgoom_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstgoom_la_CFLAGS) $(CFLAGS) -c -o libgstgoom_la-gstaudiovisualizer.lo `test -f 'gstaudiovisualizer.c' || echo '$(srcdir)/'`gstaudiovisualizer.c
-
 libgstgoom_la-mmx.lo: mmx.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstgoom_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstgoom_la_CFLAGS) $(CFLAGS) -MT libgstgoom_la-mmx.lo -MD -MP -MF $(DEPDIR)/libgstgoom_la-mmx.Tpo -c -o libgstgoom_la-mmx.lo `test -f 'mmx.c' || echo '$(srcdir)/'`mmx.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstgoom_la-mmx.Tpo $(DEPDIR)/libgstgoom_la-mmx.Plo
diff --git a/gst/goom/gstaudiovisualizer.c b/gst/goom/gstaudiovisualizer.c
deleted file mode 100644
index e643de4..0000000
--- a/gst/goom/gstaudiovisualizer.c
+++ /dev/null
@@ -1,1455 +0,0 @@
-/* GStreamer
- * Copyright (C) <2011> Stefan Kost <ensonic@users.sf.net>
- * Copyright (C) <2015> Luis de Bethencourt <luis@debethencourt.com>
- *
- * gstaudiovisualizer.c: class for audio visualisation elements
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * SECTION:gstaudiovisualizer
- *
- * A class for scopes (visualizers). It takes care of re-fitting the audio-rate
- * to video-rate and handles renegotiation (downstream video size changes).
- *
- * It also provides several background shading effects. These effects are
- * applied to a previous picture before the render() implementation can draw a
- * new frame.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-#include <gst/video/video.h>
-#include <gst/video/gstvideometa.h>
-#include <gst/video/gstvideopool.h>
-
-#include "gstaudiovisualizer.h"
-
-GST_DEBUG_CATEGORY_STATIC (audio_visualizer_debug);
-#define GST_CAT_DEFAULT (audio_visualizer_debug)
-
-#define DEFAULT_SHADER GST_AUDIO_VISUALIZER_SHADER_FADE
-#define DEFAULT_SHADE_AMOUNT   0x000a0a0a
-
-enum
-{
-  PROP_0,
-  PROP_SHADER,
-  PROP_SHADE_AMOUNT
-};
-
-static GstBaseTransformClass *parent_class = NULL;
-
-static void gst_audio_visualizer_class_init (GstAudioVisualizerClass * klass);
-static void gst_audio_visualizer_init (GstAudioVisualizer * scope,
-    GstAudioVisualizerClass * g_class);
-static void gst_audio_visualizer_set_property (GObject * object,
-    guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_audio_visualizer_get_property (GObject * object,
-    guint prop_id, GValue * value, GParamSpec * pspec);
-static void gst_audio_visualizer_finalize (GObject * object);
-
-static gboolean gst_audio_visualizer_src_negotiate (GstAudioVisualizer * scope);
-static gboolean gst_audio_visualizer_src_setcaps (GstAudioVisualizer *
-    scope, GstCaps * caps);
-static gboolean gst_audio_visualizer_sink_setcaps (GstAudioVisualizer *
-    scope, GstCaps * caps);
-
-static GstFlowReturn gst_audio_visualizer_chain (GstPad * pad,
-    GstObject * parent, GstBuffer * buffer);
-
-static gboolean gst_audio_visualizer_src_event (GstPad * pad,
-    GstObject * parent, GstEvent * event);
-static gboolean gst_audio_visualizer_sink_event (GstPad * pad,
-    GstObject * parent, GstEvent * event);
-
-static gboolean gst_audio_visualizer_src_query (GstPad * pad,
-    GstObject * parent, GstQuery * query);
-
-static GstStateChangeReturn gst_audio_visualizer_change_state (GstElement *
-    element, GstStateChange transition);
-
-static gboolean gst_audio_visualizer_do_bufferpool (GstAudioVisualizer * scope,
-    GstCaps * outcaps);
-
-static gboolean
-default_decide_allocation (GstAudioVisualizer * scope, GstQuery * query);
-
-#define GST_AUDIO_VISUALIZER_GET_PRIVATE(obj)  \
-    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_AUDIO_VISUALIZER, GstAudioVisualizerPrivate))
-
-struct _GstAudioVisualizerPrivate
-{
-  gboolean negotiated;
-
-  GstBufferPool *pool;
-  gboolean pool_active;
-  GstAllocator *allocator;
-  GstAllocationParams params;
-  GstQuery *query;
-
-  /* pads */
-  GstPad *srcpad, *sinkpad;
-
-  GstAudioVisualizerShader shader_type;
-  GstAudioVisualizerShaderFunc shader;
-  guint32 shade_amount;
-
-  GstAdapter *adapter;
-
-  GstBuffer *inbuf;
-  GstBuffer *tempbuf;
-  GstVideoFrame tempframe;
-
-  guint spf;                    /* samples per video frame */
-  guint64 frame_duration;
-
-  /* QoS stuff *//* with LOCK */
-  gdouble proportion;
-  GstClockTime earliest_time;
-
-  guint dropped;                /* frames dropped / not dropped */
-  guint processed;
-
-  /* configuration mutex */
-  GMutex config_lock;
-
-  GstSegment segment;
-};
-
-/* shading functions */
-
-#define GST_TYPE_AUDIO_VISUALIZER_SHADER (gst_audio_visualizer_shader_get_type())
-static GType
-gst_audio_visualizer_shader_get_type (void)
-{
-  static GType shader_type = 0;
-  static const GEnumValue shaders[] = {
-    {GST_AUDIO_VISUALIZER_SHADER_NONE, "None", "none"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE, "Fade", "fade"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_UP, "Fade and move up",
-        "fade-and-move-up"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_DOWN, "Fade and move down",
-        "fade-and-move-down"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_LEFT, "Fade and move left",
-        "fade-and-move-left"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_RIGHT,
-          "Fade and move right",
-        "fade-and-move-right"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_OUT,
-        "Fade and move horizontally out", "fade-and-move-horiz-out"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_IN,
-        "Fade and move horizontally in", "fade-and-move-horiz-in"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_OUT,
-        "Fade and move vertically out", "fade-and-move-vert-out"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_IN,
-        "Fade and move vertically in", "fade-and-move-vert-in"},
-    {0, NULL, NULL},
-  };
-
-  if (G_UNLIKELY (shader_type == 0)) {
-    /* TODO: rename when exporting it as a library */
-    shader_type =
-        g_enum_register_static ("GstAudioVisualizerShader-ExtGoom", shaders);
-  }
-  return shader_type;
-}
-
-/* we're only supporting GST_VIDEO_FORMAT_xRGB right now) */
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-
-#define SHADE(_d, _s, _i, _r, _g, _b)                     \
-G_STMT_START {                                            \
-    _d[_i * 4 + 0] = (_s[_i * 4 + 0] > _b) ? _s[_i * 4 + 0] - _b : 0; \
-    _d[_i * 4 + 1] = (_s[_i * 4 + 1] > _g) ? _s[_i * 4 + 1] - _g : 0; \
-    _d[_i * 4 + 2] = (_s[_i * 4 + 2] > _r) ? _s[_i * 4 + 2] - _r : 0; \
-    _d[_i * 4 + 3] = 0;                                       \
-} G_STMT_END
-
-#else /* G_BYTE_ORDER == G_LITTLE_ENDIAN */
-
-#define SHADE(_d, _s, _i, _r, _g, _b)                     \
-G_STMT_START {                                            \
-    _d[_i * 4 + 0] = 0;                                       \
-    _d[_i * 4 + 1] = (_s[_i * 4 + 1] > _r) ? _s[_i * 4 + 1] - _r : 0; \
-    _d[_i * 4 + 2] = (_s[_i * 4 + 2] > _g) ? _s[_i * 4 + 2] - _g : 0; \
-    _d[_i * 4 + 3] = (_s[_i * 4 + 3] > _b) ? _s[_i * 4 + 3] - _b : 0; \
-} G_STMT_END
-
-#endif
-
-static void
-shader_fade (GstAudioVisualizer * scope, const GstVideoFrame * sframe,
-    GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *d;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  for (j = 0; j < height; j++) {
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    s += ss;
-    d += ds;
-  }
-}
-
-static void
-shader_fade_and_move_up (GstAudioVisualizer * scope,
-    const GstVideoFrame * sframe, GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *d;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  for (j = 1; j < height; j++) {
-    s += ss;
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    d += ds;
-  }
-}
-
-static void
-shader_fade_and_move_down (GstAudioVisualizer * scope,
-    const GstVideoFrame * sframe, GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *d;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  for (j = 1; j < height; j++) {
-    d += ds;
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    s += ss;
-  }
-}
-
-static void
-shader_fade_and_move_left (GstAudioVisualizer * scope,
-    const GstVideoFrame * sframe, GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *d;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  width -= 1;
-  s += 4;
-
-  /* move to the left */
-  for (j = 0; j < height; j++) {
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    d += ds;
-    s += ss;
-  }
-}
-
-static void
-shader_fade_and_move_right (GstAudioVisualizer * scope,
-    const GstVideoFrame * sframe, GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *d;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  width -= 1;
-  d += 4;
-
-  /* move to the right */
-  for (j = 0; j < height; j++) {
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    d += ds;
-    s += ss;
-  }
-}
-
-static void
-shader_fade_and_move_horiz_out (GstAudioVisualizer * scope,
-    const GstVideoFrame * sframe, GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *d;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  /* move upper half up */
-  for (j = 0; j < height / 2; j++) {
-    s += ss;
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    d += ds;
-  }
-  /* move lower half down */
-  for (j = 0; j < height / 2; j++) {
-    d += ds;
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    s += ss;
-  }
-}
-
-static void
-shader_fade_and_move_horiz_in (GstAudioVisualizer * scope,
-    const GstVideoFrame * sframe, GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *d;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  /* move upper half down */
-  for (j = 0; j < height / 2; j++) {
-    d += ds;
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    s += ss;
-  }
-  /* move lower half up */
-  for (j = 0; j < height / 2; j++) {
-    s += ss;
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    d += ds;
-  }
-}
-
-static void
-shader_fade_and_move_vert_out (GstAudioVisualizer * scope,
-    const GstVideoFrame * sframe, GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *s1, *d, *d1;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  for (j = 0; j < height; j++) {
-    /* move left half to the left */
-    s1 = s + 1;
-    for (i = 0; i < width / 2; i++) {
-      SHADE (d, s1, i, r, g, b);
-    }
-    /* move right half to the right */
-    d1 = d + 1;
-    for (; i < width - 1; i++) {
-      SHADE (d1, s, i, r, g, b);
-    }
-    s += ss;
-    d += ds;
-  }
-}
-
-static void
-shader_fade_and_move_vert_in (GstAudioVisualizer * scope,
-    const GstVideoFrame * sframe, GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *s1, *d, *d1;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  for (j = 0; j < height; j++) {
-    /* move left half to the right */
-    d1 = d + 1;
-    for (i = 0; i < width / 2; i++) {
-      SHADE (d1, s, i, r, g, b);
-    }
-    /* move right half to the left */
-    s1 = s + 1;
-    for (; i < width - 1; i++) {
-      SHADE (d, s1, i, r, g, b);
-    }
-    s += ss;
-    d += ds;
-  }
-}
-
-static void
-gst_audio_visualizer_change_shader (GstAudioVisualizer * scope)
-{
-  GstAudioVisualizerShaderFunc shader;
-
-  switch (scope->priv->shader_type) {
-    case GST_AUDIO_VISUALIZER_SHADER_NONE:
-      shader = NULL;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE:
-      shader = shader_fade;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_UP:
-      shader = shader_fade_and_move_up;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_DOWN:
-      shader = shader_fade_and_move_down;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_LEFT:
-      shader = shader_fade_and_move_left;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_RIGHT:
-      shader = shader_fade_and_move_right;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_OUT:
-      shader = shader_fade_and_move_horiz_out;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_IN:
-      shader = shader_fade_and_move_horiz_in;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_OUT:
-      shader = shader_fade_and_move_vert_out;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_IN:
-      shader = shader_fade_and_move_vert_in;
-      break;
-    default:
-      GST_ERROR ("invalid shader function");
-      shader = NULL;
-      break;
-  }
-
-  scope->priv->shader = shader;
-}
-
-/* class */
-
-GType
-goom_gst_audio_visualizer_get_type (void)
-{
-  static volatile gsize audio_visualizer_type = 0;
-
-  if (g_once_init_enter (&audio_visualizer_type)) {
-    static const GTypeInfo audio_visualizer_info = {
-      sizeof (GstAudioVisualizerClass),
-      NULL,
-      NULL,
-      (GClassInitFunc) gst_audio_visualizer_class_init,
-      NULL,
-      NULL,
-      sizeof (GstAudioVisualizer),
-      0,
-      (GInstanceInitFunc) gst_audio_visualizer_init,
-    };
-    GType _type;
-
-    /* TODO: rename when exporting it as a library */
-    _type = g_type_register_static (GST_TYPE_ELEMENT,
-        "GstAudioVisualizer-ExtGoom", &audio_visualizer_info,
-        G_TYPE_FLAG_ABSTRACT);
-    g_once_init_leave (&audio_visualizer_type, _type);
-  }
-  return (GType) audio_visualizer_type;
-}
-
-static void
-gst_audio_visualizer_class_init (GstAudioVisualizerClass * klass)
-{
-  GObjectClass *gobject_class = (GObjectClass *) klass;
-  GstElementClass *element_class = (GstElementClass *) klass;
-
-  g_type_class_add_private (klass, sizeof (GstAudioVisualizerPrivate));
-
-  parent_class = g_type_class_peek_parent (klass);
-
-  GST_DEBUG_CATEGORY_INIT (audio_visualizer_debug,
-      "audiovisualizer-goom", 0, "audio visualisation class");
-
-  gobject_class->set_property = gst_audio_visualizer_set_property;
-  gobject_class->get_property = gst_audio_visualizer_get_property;
-  gobject_class->finalize = gst_audio_visualizer_finalize;
-
-  element_class->change_state =
-      GST_DEBUG_FUNCPTR (gst_audio_visualizer_change_state);
-
-  klass->decide_allocation = GST_DEBUG_FUNCPTR (default_decide_allocation);
-
-  g_object_class_install_property (gobject_class, PROP_SHADER,
-      g_param_spec_enum ("shader", "shader type",
-          "Shader function to apply on each frame",
-          GST_TYPE_AUDIO_VISUALIZER_SHADER, DEFAULT_SHADER,
-          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, PROP_SHADE_AMOUNT,
-      g_param_spec_uint ("shade-amount", "shade amount",
-          "Shading color to use (big-endian ARGB)", 0, G_MAXUINT32,
-          DEFAULT_SHADE_AMOUNT,
-          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-}
-
-static void
-gst_audio_visualizer_init (GstAudioVisualizer * scope,
-    GstAudioVisualizerClass * g_class)
-{
-  GstPadTemplate *pad_template;
-
-  scope->priv = GST_AUDIO_VISUALIZER_GET_PRIVATE (scope);
-
-  /* create the sink and src pads */
-  pad_template =
-      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");
-  g_return_if_fail (pad_template != NULL);
-  scope->priv->sinkpad = gst_pad_new_from_template (pad_template, "sink");
-  gst_pad_set_chain_function (scope->priv->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_audio_visualizer_chain));
-  gst_pad_set_event_function (scope->priv->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_audio_visualizer_sink_event));
-  gst_element_add_pad (GST_ELEMENT (scope), scope->priv->sinkpad);
-
-  pad_template =
-      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
-  g_return_if_fail (pad_template != NULL);
-  scope->priv->srcpad = gst_pad_new_from_template (pad_template, "src");
-  gst_pad_set_event_function (scope->priv->srcpad,
-      GST_DEBUG_FUNCPTR (gst_audio_visualizer_src_event));
-  gst_pad_set_query_function (scope->priv->srcpad,
-      GST_DEBUG_FUNCPTR (gst_audio_visualizer_src_query));
-  gst_element_add_pad (GST_ELEMENT (scope), scope->priv->srcpad);
-
-  scope->priv->adapter = gst_adapter_new ();
-  scope->priv->inbuf = gst_buffer_new ();
-
-  /* properties */
-  scope->priv->shader_type = DEFAULT_SHADER;
-  gst_audio_visualizer_change_shader (scope);
-  scope->priv->shade_amount = DEFAULT_SHADE_AMOUNT;
-
-  /* reset the initial video state */
-  gst_video_info_init (&scope->vinfo);
-  scope->priv->frame_duration = GST_CLOCK_TIME_NONE;
-
-  /* reset the initial state */
-  gst_audio_info_init (&scope->ainfo);
-  gst_video_info_init (&scope->vinfo);
-
-  g_mutex_init (&scope->priv->config_lock);
-}
-
-static void
-gst_audio_visualizer_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstAudioVisualizer *scope = GST_AUDIO_VISUALIZER (object);
-
-  switch (prop_id) {
-    case PROP_SHADER:
-      scope->priv->shader_type = g_value_get_enum (value);
-      gst_audio_visualizer_change_shader (scope);
-      break;
-    case PROP_SHADE_AMOUNT:
-      scope->priv->shade_amount = g_value_get_uint (value);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_audio_visualizer_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstAudioVisualizer *scope = GST_AUDIO_VISUALIZER (object);
-
-  switch (prop_id) {
-    case PROP_SHADER:
-      g_value_set_enum (value, scope->priv->shader_type);
-      break;
-    case PROP_SHADE_AMOUNT:
-      g_value_set_uint (value, scope->priv->shade_amount);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_audio_visualizer_finalize (GObject * object)
-{
-  GstAudioVisualizer *scope = GST_AUDIO_VISUALIZER (object);
-  GstAudioVisualizerPrivate *priv = scope->priv;
-
-  if (priv->adapter) {
-    g_object_unref (priv->adapter);
-    priv->adapter = NULL;
-  }
-  if (priv->inbuf) {
-    gst_buffer_unref (priv->inbuf);
-    priv->inbuf = NULL;
-  }
-  if (priv->tempbuf) {
-    gst_video_frame_unmap (&priv->tempframe);
-    gst_buffer_unref (priv->tempbuf);
-    priv->tempbuf = NULL;
-  }
-
-  g_mutex_clear (&priv->config_lock);
-
-  G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_audio_visualizer_reset (GstAudioVisualizer * scope)
-{
-  GstAudioVisualizerPrivate *priv = scope->priv;
-
-  gst_adapter_clear (priv->adapter);
-  gst_segment_init (&priv->segment, GST_FORMAT_UNDEFINED);
-
-  GST_OBJECT_LOCK (scope);
-  priv->proportion = 1.0;
-  priv->earliest_time = -1;
-  priv->dropped = 0;
-  priv->processed = 0;
-  GST_OBJECT_UNLOCK (scope);
-}
-
-static gboolean
-gst_audio_visualizer_sink_setcaps (GstAudioVisualizer * scope, GstCaps * caps)
-{
-  GstAudioInfo info;
-
-  if (!gst_audio_info_from_caps (&info, caps))
-    goto wrong_caps;
-
-  scope->ainfo = info;
-
-  GST_DEBUG_OBJECT (scope, "audio: channels %d, rate %d",
-      GST_AUDIO_INFO_CHANNELS (&info), GST_AUDIO_INFO_RATE (&info));
-
-  if (!gst_audio_visualizer_src_negotiate (scope)) {
-    goto not_negotiated;
-  }
-
-  return TRUE;
-
-  /* Errors */
-wrong_caps:
-  {
-    GST_WARNING_OBJECT (scope, "could not parse caps");
-    return FALSE;
-  }
-not_negotiated:
-  {
-    GST_WARNING_OBJECT (scope, "failed to negotiate");
-    return FALSE;
-  }
-}
-
-static gboolean
-gst_audio_visualizer_src_setcaps (GstAudioVisualizer * scope, GstCaps * caps)
-{
-  GstVideoInfo info;
-  GstAudioVisualizerClass *klass;
-  GstAudioVisualizerPrivate *priv;
-  gboolean res;
-
-  if (!gst_video_info_from_caps (&info, caps))
-    goto wrong_caps;
-
-  klass = GST_AUDIO_VISUALIZER_CLASS (G_OBJECT_GET_CLASS (scope));
-
-  priv = scope->priv;
-
-  scope->vinfo = info;
-
-  priv->frame_duration = gst_util_uint64_scale_int (GST_SECOND,
-      GST_VIDEO_INFO_FPS_D (&info), GST_VIDEO_INFO_FPS_N (&info));
-  priv->spf = gst_util_uint64_scale_int (GST_AUDIO_INFO_RATE (&scope->ainfo),
-      GST_VIDEO_INFO_FPS_D (&info), GST_VIDEO_INFO_FPS_N (&info));
-  scope->req_spf = priv->spf;
-
-  if (priv->tempbuf) {
-    gst_video_frame_unmap (&priv->tempframe);
-    gst_buffer_unref (priv->tempbuf);
-  }
-  priv->tempbuf = gst_buffer_new_wrapped (g_malloc0 (scope->vinfo.size),
-      scope->vinfo.size);
-  gst_video_frame_map (&priv->tempframe, &scope->vinfo, priv->tempbuf,
-      GST_MAP_READWRITE);
-
-  if (klass->setup && !klass->setup (scope))
-    goto setup_failed;
-
-  GST_DEBUG_OBJECT (scope, "video: dimension %dx%d, framerate %d/%d",
-      GST_VIDEO_INFO_WIDTH (&info), GST_VIDEO_INFO_HEIGHT (&info),
-      GST_VIDEO_INFO_FPS_N (&info), GST_VIDEO_INFO_FPS_D (&info));
-  GST_DEBUG_OBJECT (scope, "blocks: spf %u, req_spf %u", priv->spf,
-      scope->req_spf);
-
-  gst_pad_set_caps (priv->srcpad, caps);
-
-  /* find a pool for the negotiated caps now */
-  res = gst_audio_visualizer_do_bufferpool (scope, caps);
-  gst_caps_unref (caps);
-
-  return res;
-
-  /* ERRORS */
-wrong_caps:
-  {
-    gst_caps_unref (caps);
-    GST_DEBUG_OBJECT (scope, "error parsing caps");
-    return FALSE;
-  }
-
-setup_failed:
-  {
-    GST_WARNING_OBJECT (scope, "failed to set up");
-    return FALSE;
-  }
-}
-
-static gboolean
-gst_audio_visualizer_src_negotiate (GstAudioVisualizer * scope)
-{
-  GstCaps *othercaps, *target;
-  GstStructure *structure;
-  GstCaps *templ;
-  gboolean ret;
-
-  templ = gst_pad_get_pad_template_caps (scope->priv->srcpad);
-
-  GST_DEBUG_OBJECT (scope, "performing negotiation");
-
-  /* see what the peer can do */
-  othercaps = gst_pad_peer_query_caps (scope->priv->srcpad, NULL);
-  if (othercaps) {
-    target = gst_caps_intersect (othercaps, templ);
-    gst_caps_unref (othercaps);
-    gst_caps_unref (templ);
-
-    if (gst_caps_is_empty (target))
-      goto no_format;
-
-    target = gst_caps_truncate (target);
-  } else {
-    target = templ;
-  }
-
-  target = gst_caps_make_writable (target);
-  structure = gst_caps_get_structure (target, 0);
-  gst_structure_fixate_field_nearest_int (structure, "width", 320);
-  gst_structure_fixate_field_nearest_int (structure, "height", 200);
-  gst_structure_fixate_field_nearest_fraction (structure, "framerate", 25, 1);
-
-  target = gst_caps_fixate (target);
-
-  GST_DEBUG_OBJECT (scope, "final caps are %" GST_PTR_FORMAT, target);
-
-  ret = gst_audio_visualizer_src_setcaps (scope, target);
-
-  return ret;
-
-no_format:
-  {
-    gst_caps_unref (target);
-    return FALSE;
-  }
-}
-
-/* takes ownership of the pool, allocator and query */
-static gboolean
-gst_audio_visualizer_set_allocation (GstAudioVisualizer * scope,
-    GstBufferPool * pool, GstAllocator * allocator,
-    GstAllocationParams * params, GstQuery * query)
-{
-  GstAllocator *oldalloc;
-  GstBufferPool *oldpool;
-  GstQuery *oldquery;
-  GstAudioVisualizerPrivate *priv = scope->priv;
-
-  GST_OBJECT_LOCK (scope);
-  oldpool = priv->pool;
-  priv->pool = pool;
-  priv->pool_active = FALSE;
-
-  oldalloc = priv->allocator;
-  priv->allocator = allocator;
-
-  oldquery = priv->query;
-  priv->query = query;
-
-  if (params)
-    priv->params = *params;
-  else
-    gst_allocation_params_init (&priv->params);
-  GST_OBJECT_UNLOCK (scope);
-
-  if (oldpool) {
-    GST_DEBUG_OBJECT (scope, "deactivating old pool %p", oldpool);
-    gst_buffer_pool_set_active (oldpool, FALSE);
-    gst_object_unref (oldpool);
-  }
-  if (oldalloc) {
-    gst_object_unref (oldalloc);
-  }
-  if (oldquery) {
-    gst_query_unref (oldquery);
-  }
-  return TRUE;
-}
-
-static gboolean
-gst_audio_visualizer_do_bufferpool (GstAudioVisualizer * scope,
-    GstCaps * outcaps)
-{
-  GstQuery *query;
-  gboolean result = TRUE;
-  GstBufferPool *pool = NULL;
-  GstAudioVisualizerClass *klass;
-  GstAllocator *allocator;
-  GstAllocationParams params;
-
-  /* not passthrough, we need to allocate */
-  /* find a pool for the negotiated caps now */
-  GST_DEBUG_OBJECT (scope, "doing allocation query");
-  query = gst_query_new_allocation (outcaps, TRUE);
-
-  if (!gst_pad_peer_query (scope->priv->srcpad, query)) {
-    /* not a problem, we use the query defaults */
-    GST_DEBUG_OBJECT (scope, "allocation query failed");
-  }
-
-  klass = GST_AUDIO_VISUALIZER_GET_CLASS (scope);
-
-  GST_DEBUG_OBJECT (scope, "calling decide_allocation");
-  g_assert (klass->decide_allocation != NULL);
-  result = klass->decide_allocation (scope, query);
-
-  GST_DEBUG_OBJECT (scope, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, result,
-      query);
-
-  if (!result)
-    goto no_decide_allocation;
-
-  /* we got configuration from our peer or the decide_allocation method,
-   * parse them */
-  if (gst_query_get_n_allocation_params (query) > 0) {
-    gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
-  } else {
-    allocator = NULL;
-    gst_allocation_params_init (&params);
-  }
-
-  if (gst_query_get_n_allocation_pools (query) > 0)
-    gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL);
-
-  /* now store */
-  result =
-      gst_audio_visualizer_set_allocation (scope, pool, allocator, &params,
-      query);
-
-  return result;
-
-  /* Errors */
-no_decide_allocation:
-  {
-    GST_WARNING_OBJECT (scope, "Subclass failed to decide allocation");
-    gst_query_unref (query);
-
-    return result;
-  }
-}
-
-static gboolean
-default_decide_allocation (GstAudioVisualizer * scope, GstQuery * query)
-{
-  GstCaps *outcaps;
-  GstBufferPool *pool;
-  guint size, min, max;
-  GstAllocator *allocator;
-  GstAllocationParams params;
-  GstStructure *config;
-  gboolean update_allocator;
-  gboolean update_pool;
-
-  gst_query_parse_allocation (query, &outcaps, NULL);
-
-  /* we got configuration from our peer or the decide_allocation method,
-   * parse them */
-  if (gst_query_get_n_allocation_params (query) > 0) {
-    /* try the allocator */
-    gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
-    update_allocator = TRUE;
-  } else {
-    allocator = NULL;
-    gst_allocation_params_init (&params);
-    update_allocator = FALSE;
-  }
-
-  if (gst_query_get_n_allocation_pools (query) > 0) {
-    gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
-    update_pool = TRUE;
-  } else {
-    pool = NULL;
-    size = GST_VIDEO_INFO_SIZE (&scope->vinfo);
-    min = max = 0;
-    update_pool = FALSE;
-  }
-
-  if (pool == NULL) {
-    /* we did not get a pool, make one ourselves then */
-    pool = gst_video_buffer_pool_new ();
-  }
-
-  config = gst_buffer_pool_get_config (pool);
-  gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
-  gst_buffer_pool_config_set_allocator (config, allocator, &params);
-  gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
-  gst_buffer_pool_set_config (pool, config);
-
-  if (update_allocator)
-    gst_query_set_nth_allocation_param (query, 0, allocator, &params);
-  else
-    gst_query_add_allocation_param (query, allocator, &params);
-
-  if (allocator)
-    gst_object_unref (allocator);
-
-  if (update_pool)
-    gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
-  else
-    gst_query_add_allocation_pool (query, pool, size, min, max);
-
-  if (pool)
-    gst_object_unref (pool);
-
-  return TRUE;
-}
-
-static GstFlowReturn
-default_prepare_output_buffer (GstAudioVisualizer * scope, GstBuffer ** outbuf)
-{
-  GstAudioVisualizerPrivate *priv;
-
-  priv = scope->priv;
-
-  g_assert (priv->pool != NULL);
-
-  /* we can't reuse the input buffer */
-  if (!priv->pool_active) {
-    GST_DEBUG_OBJECT (scope, "setting pool %p active", priv->pool);
-    if (!gst_buffer_pool_set_active (priv->pool, TRUE))
-      goto activate_failed;
-    priv->pool_active = TRUE;
-  }
-  GST_DEBUG_OBJECT (scope, "using pool alloc");
-
-  return gst_buffer_pool_acquire_buffer (priv->pool, outbuf, NULL);
-
-  /* ERRORS */
-activate_failed:
-  {
-    GST_ELEMENT_ERROR (scope, RESOURCE, SETTINGS,
-        ("failed to activate bufferpool"), ("failed to activate bufferpool"));
-    return GST_FLOW_ERROR;
-  }
-}
-
-static GstFlowReturn
-gst_audio_visualizer_chain (GstPad * pad, GstObject * parent,
-    GstBuffer * buffer)
-{
-  GstFlowReturn ret = GST_FLOW_OK;
-  GstAudioVisualizer *scope;
-  GstAudioVisualizerPrivate *priv;
-  GstAudioVisualizerClass *klass;
-  GstBuffer *inbuf;
-  guint64 dist, ts;
-  guint avail, sbpf;
-  gpointer adata;
-  gint bps, channels, rate;
-
-  scope = GST_AUDIO_VISUALIZER (parent);
-  priv = scope->priv;
-  klass = GST_AUDIO_VISUALIZER_CLASS (G_OBJECT_GET_CLASS (scope));
-
-  GST_LOG_OBJECT (scope, "chainfunc called");
-
-  /* resync on DISCONT */
-  if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
-    gst_adapter_clear (priv->adapter);
-  }
-
-  /* Make sure have an output format */
-  if (gst_pad_check_reconfigure (priv->srcpad)) {
-    if (!gst_audio_visualizer_src_negotiate (scope)) {
-      gst_pad_mark_reconfigure (priv->srcpad);
-      goto not_negotiated;
-    }
-  }
-
-  channels = GST_AUDIO_INFO_CHANNELS (&scope->ainfo);
-  rate = GST_AUDIO_INFO_RATE (&scope->ainfo);
-  bps = GST_AUDIO_INFO_BPS (&scope->ainfo);
-
-  if (bps == 0) {
-    ret = GST_FLOW_NOT_NEGOTIATED;
-    goto beach;
-  }
-
-  gst_adapter_push (priv->adapter, buffer);
-
-  g_mutex_lock (&priv->config_lock);
-
-  /* this is what we want */
-  sbpf = scope->req_spf * channels * sizeof (gint16);
-
-  inbuf = priv->inbuf;
-  /* FIXME: the timestamp in the adapter would be different */
-  gst_buffer_copy_into (inbuf, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
-
-  /* this is what we have */
-  avail = gst_adapter_available (priv->adapter);
-  GST_LOG_OBJECT (scope, "avail: %u, bpf: %u", avail, sbpf);
-  while (avail >= sbpf) {
-    GstBuffer *outbuf;
-    GstVideoFrame outframe;
-
-    /* get timestamp of the current adapter content */
-    ts = gst_adapter_prev_pts (priv->adapter, &dist);
-    if (GST_CLOCK_TIME_IS_VALID (ts)) {
-      /* convert bytes to time */
-      dist /= bps;
-      ts += gst_util_uint64_scale_int (dist, GST_SECOND, rate);
-    }
-
-    /* check for QoS, don't compute buffers that are known to be late */
-    if (GST_CLOCK_TIME_IS_VALID (ts)) {
-      GstClockTime earliest_time;
-      gdouble proportion;
-      gint64 qostime;
-
-      qostime =
-          gst_segment_to_running_time (&priv->segment, GST_FORMAT_TIME,
-          ts) + priv->frame_duration;
-
-      GST_OBJECT_LOCK (scope);
-      earliest_time = priv->earliest_time;
-      proportion = priv->proportion;
-      GST_OBJECT_UNLOCK (scope);
-
-      if (GST_CLOCK_TIME_IS_VALID (earliest_time) && qostime <= earliest_time) {
-        GstClockTime stream_time, jitter;
-        GstMessage *qos_msg;
-
-        GST_DEBUG_OBJECT (scope,
-            "QoS: skip ts: %" GST_TIME_FORMAT ", earliest: %" GST_TIME_FORMAT,
-            GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));
-
-        ++priv->dropped;
-        stream_time = gst_segment_to_stream_time (&priv->segment,
-            GST_FORMAT_TIME, ts);
-        jitter = GST_CLOCK_DIFF (qostime, earliest_time);
-        qos_msg = gst_message_new_qos (GST_OBJECT (scope), FALSE, qostime,
-            stream_time, ts, GST_BUFFER_DURATION (buffer));
-        gst_message_set_qos_values (qos_msg, jitter, proportion, 1000000);
-        gst_message_set_qos_stats (qos_msg, GST_FORMAT_BUFFERS,
-            priv->processed, priv->dropped);
-        gst_element_post_message (GST_ELEMENT (scope), qos_msg);
-
-        goto skip;
-      }
-    }
-
-    ++priv->processed;
-
-    g_mutex_unlock (&priv->config_lock);
-    ret = default_prepare_output_buffer (scope, &outbuf);
-    g_mutex_lock (&priv->config_lock);
-    /* recheck as the value could have changed */
-    sbpf = scope->req_spf * channels * sizeof (gint16);
-
-    /* no buffer allocated, we don't care why. */
-    if (ret != GST_FLOW_OK)
-      break;
-
-    /* sync controlled properties */
-    if (GST_CLOCK_TIME_IS_VALID (ts))
-      gst_object_sync_values (GST_OBJECT (scope), ts);
-
-    GST_BUFFER_TIMESTAMP (outbuf) = ts;
-    GST_BUFFER_DURATION (outbuf) = priv->frame_duration;
-
-    /* this can fail as the data size we need could have changed */
-    if (!(adata = (gpointer) gst_adapter_map (priv->adapter, sbpf)))
-      break;
-
-    gst_video_frame_map (&outframe, &scope->vinfo, outbuf, GST_MAP_READWRITE);
-
-    if (priv->shader) {
-      gst_video_frame_copy (&outframe, &priv->tempframe);
-    } else {
-      /* gst_video_frame_clear() or is output frame already cleared */
-      gint i;
-
-      for (i = 0; i < scope->vinfo.finfo->n_planes; i++) {
-        memset (outframe.data[i], 0, outframe.map[i].size);
-      }
-    }
-
-    gst_buffer_replace_all_memory (inbuf,
-        gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, adata, sbpf, 0,
-            sbpf, NULL, NULL));
-
-    /* call class->render() vmethod */
-    if (klass->render) {
-      if (!klass->render (scope, inbuf, &outframe)) {
-        ret = GST_FLOW_ERROR;
-        gst_video_frame_unmap (&outframe);
-        goto beach;
-      } else {
-        /* run various post processing (shading and geometric transformation) */
-        /* FIXME: SHADER assumes 32bpp */
-        if (priv->shader && GST_VIDEO_INFO_COMP_PSTRIDE (&scope->vinfo, 0) == 4) {
-          priv->shader (scope, &outframe, &priv->tempframe);
-        }
-      }
-    }
-    gst_video_frame_unmap (&outframe);
-
-    g_mutex_unlock (&priv->config_lock);
-    ret = gst_pad_push (priv->srcpad, outbuf);
-    outbuf = NULL;
-    g_mutex_lock (&priv->config_lock);
-
-  skip:
-    /* recheck as the value could have changed */
-    sbpf = scope->req_spf * channels * sizeof (gint16);
-    GST_LOG_OBJECT (scope, "avail: %u, bpf: %u", avail, sbpf);
-    /* we want to take less or more, depending on spf : req_spf */
-    if (avail - sbpf >= sbpf) {
-      gst_adapter_flush (priv->adapter, sbpf);
-      gst_adapter_unmap (priv->adapter);
-    } else if (avail >= sbpf) {
-      /* just flush a bit and stop */
-      gst_adapter_flush (priv->adapter, (avail - sbpf));
-      gst_adapter_unmap (priv->adapter);
-      break;
-    }
-    avail = gst_adapter_available (priv->adapter);
-
-    if (ret != GST_FLOW_OK)
-      break;
-  }
-
-  g_mutex_unlock (&priv->config_lock);
-
-beach:
-  return ret;
-
-  /* ERRORS */
-not_negotiated:
-  {
-    GST_DEBUG_OBJECT (scope, "Failed to renegotiate");
-    return GST_FLOW_NOT_NEGOTIATED;
-  }
-}
-
-static gboolean
-gst_audio_visualizer_src_event (GstPad * pad, GstObject * parent,
-    GstEvent * event)
-{
-  gboolean res;
-  GstAudioVisualizer *scope;
-  GstAudioVisualizerPrivate *priv;
-
-  scope = GST_AUDIO_VISUALIZER (parent);
-  priv = scope->priv;
-
-  switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_QOS:
-    {
-      gdouble proportion;
-      GstClockTimeDiff diff;
-      GstClockTime timestamp;
-
-      gst_event_parse_qos (event, NULL, &proportion, &diff, &timestamp);
-
-      /* save stuff for the _chain() function */
-      GST_OBJECT_LOCK (scope);
-      priv->proportion = proportion;
-      if (diff >= 0)
-        /* we're late, this is a good estimate for next displayable
-         * frame (see part-qos.txt) */
-        priv->earliest_time = timestamp + 2 * diff + priv->frame_duration;
-      else
-        priv->earliest_time = timestamp + diff;
-      GST_OBJECT_UNLOCK (scope);
-
-      res = gst_pad_push_event (priv->sinkpad, event);
-      break;
-    }
-    case GST_EVENT_RECONFIGURE:
-      /* dont't forward */
-      gst_event_unref (event);
-      res = TRUE;
-      break;
-    default:
-      res = gst_pad_event_default (pad, parent, event);
-      break;
-  }
-
-  return res;
-}
-
-static gboolean
-gst_audio_visualizer_sink_event (GstPad * pad, GstObject * parent,
-    GstEvent * event)
-{
-  gboolean res;
-  GstAudioVisualizer *scope;
-
-  scope = GST_AUDIO_VISUALIZER (parent);
-
-  switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_CAPS:
-    {
-      GstCaps *caps;
-
-      gst_event_parse_caps (event, &caps);
-      res = gst_audio_visualizer_sink_setcaps (scope, caps);
-      gst_event_unref (event);
-      break;
-    }
-    case GST_EVENT_FLUSH_STOP:
-      gst_audio_visualizer_reset (scope);
-      res = gst_pad_push_event (scope->priv->srcpad, event);
-      break;
-    case GST_EVENT_SEGMENT:
-    {
-      /* the newsegment values are used to clip the input samples
-       * and to convert the incomming timestamps to running time so
-       * we can do QoS */
-      gst_event_copy_segment (event, &scope->priv->segment);
-
-      res = gst_pad_push_event (scope->priv->srcpad, event);
-      break;
-    }
-    default:
-      res = gst_pad_event_default (pad, parent, event);
-      break;
-  }
-
-  return res;
-}
-
-static gboolean
-gst_audio_visualizer_src_query (GstPad * pad, GstObject * parent,
-    GstQuery * query)
-{
-  gboolean res = FALSE;
-  GstAudioVisualizer *scope;
-
-  scope = GST_AUDIO_VISUALIZER (parent);
-
-  switch (GST_QUERY_TYPE (query)) {
-    case GST_QUERY_LATENCY:
-    {
-      /* We need to send the query upstream and add the returned latency to our
-       * own */
-      GstClockTime min_latency, max_latency;
-      gboolean us_live;
-      GstClockTime our_latency;
-      guint max_samples;
-      gint rate = GST_AUDIO_INFO_RATE (&scope->ainfo);
-
-      if (rate == 0)
-        break;
-
-      if ((res = gst_pad_peer_query (scope->priv->sinkpad, query))) {
-        gst_query_parse_latency (query, &us_live, &min_latency, &max_latency);
-
-        GST_DEBUG_OBJECT (scope, "Peer latency: min %"
-            GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
-            GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
-
-        /* the max samples we must buffer buffer */
-        max_samples = MAX (scope->req_spf, scope->priv->spf);
-        our_latency = gst_util_uint64_scale_int (max_samples, GST_SECOND, rate);
-
-        GST_DEBUG_OBJECT (scope, "Our latency: %" GST_TIME_FORMAT,
-            GST_TIME_ARGS (our_latency));
-
-        /* we add some latency but only if we need to buffer more than what
-         * upstream gives us */
-        min_latency += our_latency;
-        if (max_latency != -1)
-          max_latency += our_latency;
-
-        GST_DEBUG_OBJECT (scope, "Calculated total latency : min %"
-            GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
-            GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
-
-        gst_query_set_latency (query, TRUE, min_latency, max_latency);
-      }
-      break;
-    }
-    default:
-      res = gst_pad_query_default (pad, parent, query);
-      break;
-  }
-
-  return res;
-}
-
-static GstStateChangeReturn
-gst_audio_visualizer_change_state (GstElement * element,
-    GstStateChange transition)
-{
-  GstStateChangeReturn ret;
-  GstAudioVisualizer *scope;
-
-  scope = GST_AUDIO_VISUALIZER (element);
-
-  switch (transition) {
-    case GST_STATE_CHANGE_READY_TO_PAUSED:
-      gst_audio_visualizer_reset (scope);
-      break;
-    default:
-      break;
-  }
-
-  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
-  switch (transition) {
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-      gst_audio_visualizer_set_allocation (scope, NULL, NULL, NULL, NULL);
-      break;
-    case GST_STATE_CHANGE_READY_TO_NULL:
-      break;
-    default:
-      break;
-  }
-
-  return ret;
-}
diff --git a/gst/goom/gstaudiovisualizer.h b/gst/goom/gstaudiovisualizer.h
deleted file mode 100644
index ea8444b..0000000
--- a/gst/goom/gstaudiovisualizer.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* GStreamer
- * Copyright (C) <2011> Stefan Kost <ensonic@users.sf.net>
- * Copyright (C) <2015> Luis de Bethencourt <luis@debethencourt.com>
- *
- * gstaudiovisualizer.c: base class for audio visualisation elements
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef __GST_AUDIO_VISUALIZER_H__
-#define __GST_AUDIO_VISUALIZER_H__
-
-#include <gst/gst.h>
-#include <gst/base/gstbasetransform.h>
-
-#include <gst/video/video.h>
-#include <gst/audio/audio.h>
-#include <gst/base/gstadapter.h>
-
-G_BEGIN_DECLS
-#define GST_TYPE_AUDIO_VISUALIZER            (goom_gst_audio_visualizer_get_type())
-#define GST_AUDIO_VISUALIZER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_VISUALIZER,GstAudioVisualizer))
-#define GST_AUDIO_VISUALIZER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIO_VISUALIZER,GstAudioVisualizerClass))
-#define GST_AUDIO_VISUALIZER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_AUDIO_VISUALIZER,GstAudioVisualizerClass))
-#define GST_IS_SYNAESTHESIA(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_VISUALIZER))
-#define GST_IS_SYNAESTHESIA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIO_VISUALIZER))
-typedef struct _GstAudioVisualizer GstAudioVisualizer;
-typedef struct _GstAudioVisualizerClass GstAudioVisualizerClass;
-typedef struct _GstAudioVisualizerPrivate GstAudioVisualizerPrivate;
-
-typedef void (*GstAudioVisualizerShaderFunc)(GstAudioVisualizer *scope, const GstVideoFrame *s, GstVideoFrame *d);
-
-/**
- * GstAudioVisualizerShader:
- * @GST_AUDIO_VISUALIZER_SHADER_NONE: no shading
- * @GST_AUDIO_VISUALIZER_SHADER_FADE: plain fading
- * @GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_UP: fade and move up
- * @GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_DOWN: fade and move down
- * @GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_LEFT: fade and move left
- * @GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_RIGHT: fade and move right
- * @GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_OUT: fade and move horizontally out
- * @GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_IN: fade and move horizontally in
- * @GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_OUT: fade and move vertically out
- * @GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_IN: fade and move vertically in
- *
- * Different types of supported background shading functions.
- */
-typedef enum {
-  GST_AUDIO_VISUALIZER_SHADER_NONE,
-  GST_AUDIO_VISUALIZER_SHADER_FADE,
-  GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_UP,
-  GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_DOWN,
-  GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_LEFT,
-  GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_RIGHT,
-  GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_OUT,
-  GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_IN,
-  GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_OUT,
-  GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_IN
-} GstAudioVisualizerShader;
-
-struct _GstAudioVisualizer
-{
-  GstElement parent;
-
-  guint req_spf;                /* min samples per frame wanted by the subclass */
-
-  /* video state */
-  GstVideoInfo vinfo;
-
-  /* audio state */
-  GstAudioInfo ainfo;
-
-  /* <private> */
-  GstAudioVisualizerPrivate *priv;
-};
-
-struct _GstAudioVisualizerClass
-{
-  GstElementClass parent_class;
-
-  /* virtual function, called whenever the format changes */
-  gboolean (*setup) (GstAudioVisualizer * scope);
-
-  /* virtual function for rendering a frame */
-  gboolean (*render) (GstAudioVisualizer * scope, GstBuffer * audio, GstVideoFrame * video);
-
-  gboolean (*decide_allocation)   (GstAudioVisualizer * scope, GstQuery *query);
-};
-
-GType goom_gst_audio_visualizer_get_type (void);
-
-G_END_DECLS
-#endif /* __GST_AUDIO_VISUALIZER_H__ */
diff --git a/gst/goom/gstgoom.h b/gst/goom/gstgoom.h
index f8cb434..25975dd 100644
--- a/gst/goom/gstgoom.h
+++ b/gst/goom/gstgoom.h
@@ -21,7 +21,8 @@
 #ifndef __GST_GOOM_H__
 #define __GST_GOOM_H__
 
-#include "gstaudiovisualizer.h"
+#include <gst/pbutils/gstaudiovisualizer.h>
+
 #include "goom.h"
 
 G_BEGIN_DECLS
diff --git a/gst/goom/plugin_info.c b/gst/goom/plugin_info.c
index 0952dca..96d570c 100644
--- a/gst/goom/plugin_info.c
+++ b/gst/goom/plugin_info.c
@@ -106,8 +106,6 @@
   }
 #endif /* HAVE_CPU_PPC */
 #endif
-
-  cpuFlavour = 0;               /* trick compiler into thinking variable is used */
 }
 
 void
diff --git a/gst/goom2k1/Makefile.am b/gst/goom2k1/Makefile.am
index 3da8ac8..f6eab4a 100644
--- a/gst/goom2k1/Makefile.am
+++ b/gst/goom2k1/Makefile.am
@@ -3,11 +3,10 @@
 GOOM_FILTER_FILES = filters.c
 GOOM_FILTER_CFLAGS = -UMMX -UUSE_ASM
 
-noinst_HEADERS = gstgoom.h filters.h goom_core.h goom_tools.h graphic.h lines.h \
-         gstaudiovisualizer.h
+noinst_HEADERS = gstgoom.h filters.h goom_core.h goom_tools.h graphic.h lines.h
 
 libgstgoom2k1_la_SOURCES = gstgoom.c goom_core.c $(GOOM_FILTER_FILES) graphic.c \
-         lines.c gstaudiovisualizer.c
+         lines.c
 
 libgstgoom2k1_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(GOOM_FILTER_CFLAGS) \
 	-Dgst_goom_get_type=gst_goom2k1_get_type		\
@@ -24,7 +23,7 @@
 	-DzoomFilterDestroy=zoomFilterDestroy2k1		\
 	-DzoomFilterNew=zoomFilterNew2k1
 
-libgstgoom2k1_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM) -lgstvideo-$(GST_API_VERSION) -lgstaudio-$(GST_API_VERSION)
+libgstgoom2k1_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstpbutils-$(GST_API_VERSION) $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM)
 libgstgoom2k1_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstgoom2k1_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
diff --git a/gst/goom2k1/Makefile.in b/gst/goom2k1/Makefile.in
index 3f3586e..dda4cc5 100644
--- a/gst/goom2k1/Makefile.in
+++ b/gst/goom2k1/Makefile.in
@@ -163,12 +163,12 @@
 LTLIBRARIES = $(plugin_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 libgstgoom2k1_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
 am__objects_1 = libgstgoom2k1_la-filters.lo
 am_libgstgoom2k1_la_OBJECTS = libgstgoom2k1_la-gstgoom.lo \
 	libgstgoom2k1_la-goom_core.lo $(am__objects_1) \
-	libgstgoom2k1_la-graphic.lo libgstgoom2k1_la-lines.lo \
-	libgstgoom2k1_la-gstaudiovisualizer.lo
+	libgstgoom2k1_la-graphic.lo libgstgoom2k1_la-lines.lo
 libgstgoom2k1_la_OBJECTS = $(am_libgstgoom2k1_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -480,6 +480,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
@@ -568,11 +570,9 @@
 plugin_LTLIBRARIES = libgstgoom2k1.la
 GOOM_FILTER_FILES = filters.c
 GOOM_FILTER_CFLAGS = -UMMX -UUSE_ASM
-noinst_HEADERS = gstgoom.h filters.h goom_core.h goom_tools.h graphic.h lines.h \
-         gstaudiovisualizer.h
-
+noinst_HEADERS = gstgoom.h filters.h goom_core.h goom_tools.h graphic.h lines.h
 libgstgoom2k1_la_SOURCES = gstgoom.c goom_core.c $(GOOM_FILTER_FILES) graphic.c \
-         lines.c gstaudiovisualizer.c
+         lines.c
 
 libgstgoom2k1_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(GOOM_FILTER_CFLAGS) \
 	-Dgst_goom_get_type=gst_goom2k1_get_type		\
@@ -589,7 +589,7 @@
 	-DzoomFilterDestroy=zoomFilterDestroy2k1		\
 	-DzoomFilterNew=zoomFilterNew2k1
 
-libgstgoom2k1_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM) -lgstvideo-$(GST_API_VERSION) -lgstaudio-$(GST_API_VERSION)
+libgstgoom2k1_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstpbutils-$(GST_API_VERSION) $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM)
 libgstgoom2k1_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstgoom2k1_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 EXTRA_DIST = filters.c
@@ -674,7 +674,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstgoom2k1_la-filters.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstgoom2k1_la-goom_core.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstgoom2k1_la-graphic.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstgoom2k1_la-gstaudiovisualizer.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstgoom2k1_la-gstgoom.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstgoom2k1_la-lines.Plo@am__quote@
 
@@ -737,13 +736,6 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstgoom2k1_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstgoom2k1_la_CFLAGS) $(CFLAGS) -c -o libgstgoom2k1_la-lines.lo `test -f 'lines.c' || echo '$(srcdir)/'`lines.c
 
-libgstgoom2k1_la-gstaudiovisualizer.lo: gstaudiovisualizer.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstgoom2k1_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstgoom2k1_la_CFLAGS) $(CFLAGS) -MT libgstgoom2k1_la-gstaudiovisualizer.lo -MD -MP -MF $(DEPDIR)/libgstgoom2k1_la-gstaudiovisualizer.Tpo -c -o libgstgoom2k1_la-gstaudiovisualizer.lo `test -f 'gstaudiovisualizer.c' || echo '$(srcdir)/'`gstaudiovisualizer.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstgoom2k1_la-gstaudiovisualizer.Tpo $(DEPDIR)/libgstgoom2k1_la-gstaudiovisualizer.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gstaudiovisualizer.c' object='libgstgoom2k1_la-gstaudiovisualizer.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstgoom2k1_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstgoom2k1_la_CFLAGS) $(CFLAGS) -c -o libgstgoom2k1_la-gstaudiovisualizer.lo `test -f 'gstaudiovisualizer.c' || echo '$(srcdir)/'`gstaudiovisualizer.c
-
 mostlyclean-libtool:
 	-rm -f *.lo
 
diff --git a/gst/goom2k1/gstaudiovisualizer.c b/gst/goom2k1/gstaudiovisualizer.c
deleted file mode 100644
index fbd298d..0000000
--- a/gst/goom2k1/gstaudiovisualizer.c
+++ /dev/null
@@ -1,1455 +0,0 @@
-/* GStreamer
- * Copyright (C) <2011> Stefan Kost <ensonic@users.sf.net>
- * Copyright (C) <2015> Luis de Bethencourt <luis@debethencourt.com>
- *
- * gstaudiovisualizer.c: class for audio visualisation elements
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-/**
- * SECTION:gstaudiovisualizer
- *
- * A class for scopes (visualizers). It takes care of re-fitting the audio-rate
- * to video-rate and handles renegotiation (downstream video size changes).
- *
- * It also provides several background shading effects. These effects are
- * applied to a previous picture before the render() implementation can draw a
- * new frame.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-
-#include <gst/video/video.h>
-#include <gst/video/gstvideometa.h>
-#include <gst/video/gstvideopool.h>
-
-#include "gstaudiovisualizer.h"
-
-GST_DEBUG_CATEGORY_STATIC (audio_visualizer_debug);
-#define GST_CAT_DEFAULT (audio_visualizer_debug)
-
-#define DEFAULT_SHADER GST_AUDIO_VISUALIZER_SHADER_FADE
-#define DEFAULT_SHADE_AMOUNT   0x000a0a0a
-
-enum
-{
-  PROP_0,
-  PROP_SHADER,
-  PROP_SHADE_AMOUNT
-};
-
-static GstBaseTransformClass *parent_class = NULL;
-
-static void gst_audio_visualizer_class_init (GstAudioVisualizerClass * klass);
-static void gst_audio_visualizer_init (GstAudioVisualizer * scope,
-    GstAudioVisualizerClass * g_class);
-static void gst_audio_visualizer_set_property (GObject * object,
-    guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_audio_visualizer_get_property (GObject * object,
-    guint prop_id, GValue * value, GParamSpec * pspec);
-static void gst_audio_visualizer_finalize (GObject * object);
-
-static gboolean gst_audio_visualizer_src_negotiate (GstAudioVisualizer * scope);
-static gboolean gst_audio_visualizer_src_setcaps (GstAudioVisualizer *
-    scope, GstCaps * caps);
-static gboolean gst_audio_visualizer_sink_setcaps (GstAudioVisualizer *
-    scope, GstCaps * caps);
-
-static GstFlowReturn gst_audio_visualizer_chain (GstPad * pad,
-    GstObject * parent, GstBuffer * buffer);
-
-static gboolean gst_audio_visualizer_src_event (GstPad * pad,
-    GstObject * parent, GstEvent * event);
-static gboolean gst_audio_visualizer_sink_event (GstPad * pad,
-    GstObject * parent, GstEvent * event);
-
-static gboolean gst_audio_visualizer_src_query (GstPad * pad,
-    GstObject * parent, GstQuery * query);
-
-static GstStateChangeReturn gst_audio_visualizer_change_state (GstElement *
-    element, GstStateChange transition);
-
-static gboolean gst_audio_visualizer_do_bufferpool (GstAudioVisualizer * scope,
-    GstCaps * outcaps);
-
-static gboolean
-default_decide_allocation (GstAudioVisualizer * scope, GstQuery * query);
-
-#define GST_AUDIO_VISUALIZER_GET_PRIVATE(obj)  \
-    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_AUDIO_VISUALIZER, GstAudioVisualizerPrivate))
-
-struct _GstAudioVisualizerPrivate
-{
-  gboolean negotiated;
-
-  GstBufferPool *pool;
-  gboolean pool_active;
-  GstAllocator *allocator;
-  GstAllocationParams params;
-  GstQuery *query;
-
-  /* pads */
-  GstPad *srcpad, *sinkpad;
-
-  GstAudioVisualizerShader shader_type;
-  GstAudioVisualizerShaderFunc shader;
-  guint32 shade_amount;
-
-  GstAdapter *adapter;
-
-  GstBuffer *inbuf;
-  GstBuffer *tempbuf;
-  GstVideoFrame tempframe;
-
-  guint spf;                    /* samples per video frame */
-  guint64 frame_duration;
-
-  /* QoS stuff *//* with LOCK */
-  gdouble proportion;
-  GstClockTime earliest_time;
-
-  guint dropped;                /* frames dropped / not dropped */
-  guint processed;
-
-  /* configuration mutex */
-  GMutex config_lock;
-
-  GstSegment segment;
-};
-
-/* shading functions */
-
-#define GST_TYPE_AUDIO_VISUALIZER_SHADER (gst_audio_visualizer_shader_get_type())
-static GType
-gst_audio_visualizer_shader_get_type (void)
-{
-  static GType shader_type = 0;
-  static const GEnumValue shaders[] = {
-    {GST_AUDIO_VISUALIZER_SHADER_NONE, "None", "none"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE, "Fade", "fade"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_UP, "Fade and move up",
-        "fade-and-move-up"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_DOWN, "Fade and move down",
-        "fade-and-move-down"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_LEFT, "Fade and move left",
-        "fade-and-move-left"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_RIGHT,
-          "Fade and move right",
-        "fade-and-move-right"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_OUT,
-        "Fade and move horizontally out", "fade-and-move-horiz-out"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_IN,
-        "Fade and move horizontally in", "fade-and-move-horiz-in"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_OUT,
-        "Fade and move vertically out", "fade-and-move-vert-out"},
-    {GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_IN,
-        "Fade and move vertically in", "fade-and-move-vert-in"},
-    {0, NULL, NULL},
-  };
-
-  if (G_UNLIKELY (shader_type == 0)) {
-    /* TODO: rename when exporting it as a library */
-    shader_type =
-        g_enum_register_static ("GstAudioVisualizerShader-ExtGoom2k1", shaders);
-  }
-  return shader_type;
-}
-
-/* we're only supporting GST_VIDEO_FORMAT_xRGB right now) */
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-
-#define SHADE(_d, _s, _i, _r, _g, _b)                     \
-G_STMT_START {                                            \
-    _d[_i * 4 + 0] = (_s[_i * 4 + 0] > _b) ? _s[_i * 4 + 0] - _b : 0; \
-    _d[_i * 4 + 1] = (_s[_i * 4 + 1] > _g) ? _s[_i * 4 + 1] - _g : 0; \
-    _d[_i * 4 + 2] = (_s[_i * 4 + 2] > _r) ? _s[_i * 4 + 2] - _r : 0; \
-    _d[_i * 4 + 3] = 0;                                       \
-} G_STMT_END
-
-#else /* G_BYTE_ORDER == G_LITTLE_ENDIAN */
-
-#define SHADE(_d, _s, _i, _r, _g, _b)                     \
-G_STMT_START {                                            \
-    _d[_i * 4 + 0] = 0;                                       \
-    _d[_i * 4 + 1] = (_s[_i * 4 + 1] > _r) ? _s[_i * 4 + 1] - _r : 0; \
-    _d[_i * 4 + 2] = (_s[_i * 4 + 2] > _g) ? _s[_i * 4 + 2] - _g : 0; \
-    _d[_i * 4 + 3] = (_s[_i * 4 + 3] > _b) ? _s[_i * 4 + 3] - _b : 0; \
-} G_STMT_END
-
-#endif
-
-static void
-shader_fade (GstAudioVisualizer * scope, const GstVideoFrame * sframe,
-    GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *d;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  for (j = 0; j < height; j++) {
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    s += ss;
-    d += ds;
-  }
-}
-
-static void
-shader_fade_and_move_up (GstAudioVisualizer * scope,
-    const GstVideoFrame * sframe, GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *d;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  for (j = 1; j < height; j++) {
-    s += ss;
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    d += ds;
-  }
-}
-
-static void
-shader_fade_and_move_down (GstAudioVisualizer * scope,
-    const GstVideoFrame * sframe, GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *d;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  for (j = 1; j < height; j++) {
-    d += ds;
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    s += ss;
-  }
-}
-
-static void
-shader_fade_and_move_left (GstAudioVisualizer * scope,
-    const GstVideoFrame * sframe, GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *d;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  width -= 1;
-  s += 4;
-
-  /* move to the left */
-  for (j = 0; j < height; j++) {
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    d += ds;
-    s += ss;
-  }
-}
-
-static void
-shader_fade_and_move_right (GstAudioVisualizer * scope,
-    const GstVideoFrame * sframe, GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *d;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  width -= 1;
-  d += 4;
-
-  /* move to the right */
-  for (j = 0; j < height; j++) {
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    d += ds;
-    s += ss;
-  }
-}
-
-static void
-shader_fade_and_move_horiz_out (GstAudioVisualizer * scope,
-    const GstVideoFrame * sframe, GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *d;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  /* move upper half up */
-  for (j = 0; j < height / 2; j++) {
-    s += ss;
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    d += ds;
-  }
-  /* move lower half down */
-  for (j = 0; j < height / 2; j++) {
-    d += ds;
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    s += ss;
-  }
-}
-
-static void
-shader_fade_and_move_horiz_in (GstAudioVisualizer * scope,
-    const GstVideoFrame * sframe, GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *d;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  /* move upper half down */
-  for (j = 0; j < height / 2; j++) {
-    d += ds;
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    s += ss;
-  }
-  /* move lower half up */
-  for (j = 0; j < height / 2; j++) {
-    s += ss;
-    for (i = 0; i < width; i++) {
-      SHADE (d, s, i, r, g, b);
-    }
-    d += ds;
-  }
-}
-
-static void
-shader_fade_and_move_vert_out (GstAudioVisualizer * scope,
-    const GstVideoFrame * sframe, GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *s1, *d, *d1;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  for (j = 0; j < height; j++) {
-    /* move left half to the left */
-    s1 = s + 1;
-    for (i = 0; i < width / 2; i++) {
-      SHADE (d, s1, i, r, g, b);
-    }
-    /* move right half to the right */
-    d1 = d + 1;
-    for (; i < width - 1; i++) {
-      SHADE (d1, s, i, r, g, b);
-    }
-    s += ss;
-    d += ds;
-  }
-}
-
-static void
-shader_fade_and_move_vert_in (GstAudioVisualizer * scope,
-    const GstVideoFrame * sframe, GstVideoFrame * dframe)
-{
-  guint i, j;
-  guint32 shade_amount = scope->priv->shade_amount;
-  guint r = (shade_amount >> 16) & 0xff;
-  guint g = (shade_amount >> 8) & 0xff;
-  guint b = (shade_amount >> 0) & 0xff;
-  guint8 *s, *s1, *d, *d1;
-  gint ss, ds, width, height;
-
-  s = GST_VIDEO_FRAME_PLANE_DATA (sframe, 0);
-  ss = GST_VIDEO_FRAME_PLANE_STRIDE (sframe, 0);
-  d = GST_VIDEO_FRAME_PLANE_DATA (dframe, 0);
-  ds = GST_VIDEO_FRAME_PLANE_STRIDE (dframe, 0);
-
-  width = GST_VIDEO_FRAME_WIDTH (sframe);
-  height = GST_VIDEO_FRAME_HEIGHT (sframe);
-
-  for (j = 0; j < height; j++) {
-    /* move left half to the right */
-    d1 = d + 1;
-    for (i = 0; i < width / 2; i++) {
-      SHADE (d1, s, i, r, g, b);
-    }
-    /* move right half to the left */
-    s1 = s + 1;
-    for (; i < width - 1; i++) {
-      SHADE (d, s1, i, r, g, b);
-    }
-    s += ss;
-    d += ds;
-  }
-}
-
-static void
-gst_audio_visualizer_change_shader (GstAudioVisualizer * scope)
-{
-  GstAudioVisualizerShaderFunc shader;
-
-  switch (scope->priv->shader_type) {
-    case GST_AUDIO_VISUALIZER_SHADER_NONE:
-      shader = NULL;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE:
-      shader = shader_fade;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_UP:
-      shader = shader_fade_and_move_up;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_DOWN:
-      shader = shader_fade_and_move_down;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_LEFT:
-      shader = shader_fade_and_move_left;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_RIGHT:
-      shader = shader_fade_and_move_right;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_OUT:
-      shader = shader_fade_and_move_horiz_out;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_IN:
-      shader = shader_fade_and_move_horiz_in;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_OUT:
-      shader = shader_fade_and_move_vert_out;
-      break;
-    case GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_IN:
-      shader = shader_fade_and_move_vert_in;
-      break;
-    default:
-      GST_ERROR ("invalid shader function");
-      shader = NULL;
-      break;
-  }
-
-  scope->priv->shader = shader;
-}
-
-/* class */
-
-GType
-goom2k1_gst_audio_visualizer_get_type (void)
-{
-  static volatile gsize audio_visualizer_type = 0;
-
-  if (g_once_init_enter (&audio_visualizer_type)) {
-    static const GTypeInfo audio_visualizer_info = {
-      sizeof (GstAudioVisualizerClass),
-      NULL,
-      NULL,
-      (GClassInitFunc) gst_audio_visualizer_class_init,
-      NULL,
-      NULL,
-      sizeof (GstAudioVisualizer),
-      0,
-      (GInstanceInitFunc) gst_audio_visualizer_init,
-    };
-    GType _type;
-
-    /* TODO: rename when exporting it as a library */
-    _type = g_type_register_static (GST_TYPE_ELEMENT,
-        "GstAudioVisualizer-ExtGoom2k1", &audio_visualizer_info,
-        G_TYPE_FLAG_ABSTRACT);
-    g_once_init_leave (&audio_visualizer_type, _type);
-  }
-  return (GType) audio_visualizer_type;
-}
-
-static void
-gst_audio_visualizer_class_init (GstAudioVisualizerClass * klass)
-{
-  GObjectClass *gobject_class = (GObjectClass *) klass;
-  GstElementClass *element_class = (GstElementClass *) klass;
-
-  g_type_class_add_private (klass, sizeof (GstAudioVisualizerPrivate));
-
-  parent_class = g_type_class_peek_parent (klass);
-
-  GST_DEBUG_CATEGORY_INIT (audio_visualizer_debug,
-      "audiovisualizer-goom2k1", 0, "audio visualisation class");
-
-  gobject_class->set_property = gst_audio_visualizer_set_property;
-  gobject_class->get_property = gst_audio_visualizer_get_property;
-  gobject_class->finalize = gst_audio_visualizer_finalize;
-
-  element_class->change_state =
-      GST_DEBUG_FUNCPTR (gst_audio_visualizer_change_state);
-
-  klass->decide_allocation = GST_DEBUG_FUNCPTR (default_decide_allocation);
-
-  g_object_class_install_property (gobject_class, PROP_SHADER,
-      g_param_spec_enum ("shader", "shader type",
-          "Shader function to apply on each frame",
-          GST_TYPE_AUDIO_VISUALIZER_SHADER, DEFAULT_SHADER,
-          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, PROP_SHADE_AMOUNT,
-      g_param_spec_uint ("shade-amount", "shade amount",
-          "Shading color to use (big-endian ARGB)", 0, G_MAXUINT32,
-          DEFAULT_SHADE_AMOUNT,
-          G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-}
-
-static void
-gst_audio_visualizer_init (GstAudioVisualizer * scope,
-    GstAudioVisualizerClass * g_class)
-{
-  GstPadTemplate *pad_template;
-
-  scope->priv = GST_AUDIO_VISUALIZER_GET_PRIVATE (scope);
-
-  /* create the sink and src pads */
-  pad_template =
-      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");
-  g_return_if_fail (pad_template != NULL);
-  scope->priv->sinkpad = gst_pad_new_from_template (pad_template, "sink");
-  gst_pad_set_chain_function (scope->priv->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_audio_visualizer_chain));
-  gst_pad_set_event_function (scope->priv->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_audio_visualizer_sink_event));
-  gst_element_add_pad (GST_ELEMENT (scope), scope->priv->sinkpad);
-
-  pad_template =
-      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
-  g_return_if_fail (pad_template != NULL);
-  scope->priv->srcpad = gst_pad_new_from_template (pad_template, "src");
-  gst_pad_set_event_function (scope->priv->srcpad,
-      GST_DEBUG_FUNCPTR (gst_audio_visualizer_src_event));
-  gst_pad_set_query_function (scope->priv->srcpad,
-      GST_DEBUG_FUNCPTR (gst_audio_visualizer_src_query));
-  gst_element_add_pad (GST_ELEMENT (scope), scope->priv->srcpad);
-
-  scope->priv->adapter = gst_adapter_new ();
-  scope->priv->inbuf = gst_buffer_new ();
-
-  /* properties */
-  scope->priv->shader_type = DEFAULT_SHADER;
-  gst_audio_visualizer_change_shader (scope);
-  scope->priv->shade_amount = DEFAULT_SHADE_AMOUNT;
-
-  /* reset the initial video state */
-  gst_video_info_init (&scope->vinfo);
-  scope->priv->frame_duration = GST_CLOCK_TIME_NONE;
-
-  /* reset the initial state */
-  gst_audio_info_init (&scope->ainfo);
-  gst_video_info_init (&scope->vinfo);
-
-  g_mutex_init (&scope->priv->config_lock);
-}
-
-static void
-gst_audio_visualizer_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstAudioVisualizer *scope = GST_AUDIO_VISUALIZER (object);
-
-  switch (prop_id) {
-    case PROP_SHADER:
-      scope->priv->shader_type = g_value_get_enum (value);
-      gst_audio_visualizer_change_shader (scope);
-      break;
-    case PROP_SHADE_AMOUNT:
-      scope->priv->shade_amount = g_value_get_uint (value);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_audio_visualizer_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstAudioVisualizer *scope = GST_AUDIO_VISUALIZER (object);
-
-  switch (prop_id) {
-    case PROP_SHADER:
-      g_value_set_enum (value, scope->priv->shader_type);
-      break;
-    case PROP_SHADE_AMOUNT:
-      g_value_set_uint (value, scope->priv->shade_amount);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_audio_visualizer_finalize (GObject * object)
-{
-  GstAudioVisualizer *scope = GST_AUDIO_VISUALIZER (object);
-  GstAudioVisualizerPrivate *priv = scope->priv;
-
-  if (priv->adapter) {
-    g_object_unref (priv->adapter);
-    priv->adapter = NULL;
-  }
-  if (priv->inbuf) {
-    gst_buffer_unref (priv->inbuf);
-    priv->inbuf = NULL;
-  }
-  if (priv->tempbuf) {
-    gst_video_frame_unmap (&priv->tempframe);
-    gst_buffer_unref (priv->tempbuf);
-    priv->tempbuf = NULL;
-  }
-
-  g_mutex_clear (&priv->config_lock);
-
-  G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-gst_audio_visualizer_reset (GstAudioVisualizer * scope)
-{
-  GstAudioVisualizerPrivate *priv = scope->priv;
-
-  gst_adapter_clear (priv->adapter);
-  gst_segment_init (&priv->segment, GST_FORMAT_UNDEFINED);
-
-  GST_OBJECT_LOCK (scope);
-  priv->proportion = 1.0;
-  priv->earliest_time = -1;
-  priv->dropped = 0;
-  priv->processed = 0;
-  GST_OBJECT_UNLOCK (scope);
-}
-
-static gboolean
-gst_audio_visualizer_sink_setcaps (GstAudioVisualizer * scope, GstCaps * caps)
-{
-  GstAudioInfo info;
-
-  if (!gst_audio_info_from_caps (&info, caps))
-    goto wrong_caps;
-
-  scope->ainfo = info;
-
-  GST_DEBUG_OBJECT (scope, "audio: channels %d, rate %d",
-      GST_AUDIO_INFO_CHANNELS (&info), GST_AUDIO_INFO_RATE (&info));
-
-  if (!gst_audio_visualizer_src_negotiate (scope)) {
-    goto not_negotiated;
-  }
-
-  return TRUE;
-
-  /* Errors */
-wrong_caps:
-  {
-    GST_WARNING_OBJECT (scope, "could not parse caps");
-    return FALSE;
-  }
-not_negotiated:
-  {
-    GST_WARNING_OBJECT (scope, "failed to negotiate");
-    return FALSE;
-  }
-}
-
-static gboolean
-gst_audio_visualizer_src_setcaps (GstAudioVisualizer * scope, GstCaps * caps)
-{
-  GstVideoInfo info;
-  GstAudioVisualizerClass *klass;
-  GstAudioVisualizerPrivate *priv;
-  gboolean res;
-
-  if (!gst_video_info_from_caps (&info, caps))
-    goto wrong_caps;
-
-  klass = GST_AUDIO_VISUALIZER_CLASS (G_OBJECT_GET_CLASS (scope));
-
-  priv = scope->priv;
-
-  scope->vinfo = info;
-
-  priv->frame_duration = gst_util_uint64_scale_int (GST_SECOND,
-      GST_VIDEO_INFO_FPS_D (&info), GST_VIDEO_INFO_FPS_N (&info));
-  priv->spf = gst_util_uint64_scale_int (GST_AUDIO_INFO_RATE (&scope->ainfo),
-      GST_VIDEO_INFO_FPS_D (&info), GST_VIDEO_INFO_FPS_N (&info));
-  scope->req_spf = priv->spf;
-
-  if (priv->tempbuf) {
-    gst_video_frame_unmap (&priv->tempframe);
-    gst_buffer_unref (priv->tempbuf);
-  }
-  priv->tempbuf = gst_buffer_new_wrapped (g_malloc0 (scope->vinfo.size),
-      scope->vinfo.size);
-  gst_video_frame_map (&priv->tempframe, &scope->vinfo, priv->tempbuf,
-      GST_MAP_READWRITE);
-
-  if (klass->setup && !klass->setup (scope))
-    goto setup_failed;
-
-  GST_DEBUG_OBJECT (scope, "video: dimension %dx%d, framerate %d/%d",
-      GST_VIDEO_INFO_WIDTH (&info), GST_VIDEO_INFO_HEIGHT (&info),
-      GST_VIDEO_INFO_FPS_N (&info), GST_VIDEO_INFO_FPS_D (&info));
-  GST_DEBUG_OBJECT (scope, "blocks: spf %u, req_spf %u", priv->spf,
-      scope->req_spf);
-
-  gst_pad_set_caps (priv->srcpad, caps);
-
-  /* find a pool for the negotiated caps now */
-  res = gst_audio_visualizer_do_bufferpool (scope, caps);
-  gst_caps_unref (caps);
-
-  return res;
-
-  /* ERRORS */
-wrong_caps:
-  {
-    gst_caps_unref (caps);
-    GST_DEBUG_OBJECT (scope, "error parsing caps");
-    return FALSE;
-  }
-
-setup_failed:
-  {
-    GST_WARNING_OBJECT (scope, "failed to set up");
-    return FALSE;
-  }
-}
-
-static gboolean
-gst_audio_visualizer_src_negotiate (GstAudioVisualizer * scope)
-{
-  GstCaps *othercaps, *target;
-  GstStructure *structure;
-  GstCaps *templ;
-  gboolean ret;
-
-  templ = gst_pad_get_pad_template_caps (scope->priv->srcpad);
-
-  GST_DEBUG_OBJECT (scope, "performing negotiation");
-
-  /* see what the peer can do */
-  othercaps = gst_pad_peer_query_caps (scope->priv->srcpad, NULL);
-  if (othercaps) {
-    target = gst_caps_intersect (othercaps, templ);
-    gst_caps_unref (othercaps);
-    gst_caps_unref (templ);
-
-    if (gst_caps_is_empty (target))
-      goto no_format;
-
-    target = gst_caps_truncate (target);
-  } else {
-    target = templ;
-  }
-
-  target = gst_caps_make_writable (target);
-  structure = gst_caps_get_structure (target, 0);
-  gst_structure_fixate_field_nearest_int (structure, "width", 320);
-  gst_structure_fixate_field_nearest_int (structure, "height", 200);
-  gst_structure_fixate_field_nearest_fraction (structure, "framerate", 25, 1);
-
-  target = gst_caps_fixate (target);
-
-  GST_DEBUG_OBJECT (scope, "final caps are %" GST_PTR_FORMAT, target);
-
-  ret = gst_audio_visualizer_src_setcaps (scope, target);
-
-  return ret;
-
-no_format:
-  {
-    gst_caps_unref (target);
-    return FALSE;
-  }
-}
-
-/* takes ownership of the pool, allocator and query */
-static gboolean
-gst_audio_visualizer_set_allocation (GstAudioVisualizer * scope,
-    GstBufferPool * pool, GstAllocator * allocator,
-    GstAllocationParams * params, GstQuery * query)
-{
-  GstAllocator *oldalloc;
-  GstBufferPool *oldpool;
-  GstQuery *oldquery;
-  GstAudioVisualizerPrivate *priv = scope->priv;
-
-  GST_OBJECT_LOCK (scope);
-  oldpool = priv->pool;
-  priv->pool = pool;
-  priv->pool_active = FALSE;
-
-  oldalloc = priv->allocator;
-  priv->allocator = allocator;
-
-  oldquery = priv->query;
-  priv->query = query;
-
-  if (params)
-    priv->params = *params;
-  else
-    gst_allocation_params_init (&priv->params);
-  GST_OBJECT_UNLOCK (scope);
-
-  if (oldpool) {
-    GST_DEBUG_OBJECT (scope, "deactivating old pool %p", oldpool);
-    gst_buffer_pool_set_active (oldpool, FALSE);
-    gst_object_unref (oldpool);
-  }
-  if (oldalloc) {
-    gst_object_unref (oldalloc);
-  }
-  if (oldquery) {
-    gst_query_unref (oldquery);
-  }
-  return TRUE;
-}
-
-static gboolean
-gst_audio_visualizer_do_bufferpool (GstAudioVisualizer * scope,
-    GstCaps * outcaps)
-{
-  GstQuery *query;
-  gboolean result = TRUE;
-  GstBufferPool *pool = NULL;
-  GstAudioVisualizerClass *klass;
-  GstAllocator *allocator;
-  GstAllocationParams params;
-
-  /* not passthrough, we need to allocate */
-  /* find a pool for the negotiated caps now */
-  GST_DEBUG_OBJECT (scope, "doing allocation query");
-  query = gst_query_new_allocation (outcaps, TRUE);
-
-  if (!gst_pad_peer_query (scope->priv->srcpad, query)) {
-    /* not a problem, we use the query defaults */
-    GST_DEBUG_OBJECT (scope, "allocation query failed");
-  }
-
-  klass = GST_AUDIO_VISUALIZER_GET_CLASS (scope);
-
-  GST_DEBUG_OBJECT (scope, "calling decide_allocation");
-  g_assert (klass->decide_allocation != NULL);
-  result = klass->decide_allocation (scope, query);
-
-  GST_DEBUG_OBJECT (scope, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, result,
-      query);
-
-  if (!result)
-    goto no_decide_allocation;
-
-  /* we got configuration from our peer or the decide_allocation method,
-   * parse them */
-  if (gst_query_get_n_allocation_params (query) > 0) {
-    gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
-  } else {
-    allocator = NULL;
-    gst_allocation_params_init (&params);
-  }
-
-  if (gst_query_get_n_allocation_pools (query) > 0)
-    gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL);
-
-  /* now store */
-  result =
-      gst_audio_visualizer_set_allocation (scope, pool, allocator, &params,
-      query);
-
-  return result;
-
-  /* Errors */
-no_decide_allocation:
-  {
-    GST_WARNING_OBJECT (scope, "Subclass failed to decide allocation");
-    gst_query_unref (query);
-
-    return result;
-  }
-}
-
-static gboolean
-default_decide_allocation (GstAudioVisualizer * scope, GstQuery * query)
-{
-  GstCaps *outcaps;
-  GstBufferPool *pool;
-  guint size, min, max;
-  GstAllocator *allocator;
-  GstAllocationParams params;
-  GstStructure *config;
-  gboolean update_allocator;
-  gboolean update_pool;
-
-  gst_query_parse_allocation (query, &outcaps, NULL);
-
-  /* we got configuration from our peer or the decide_allocation method,
-   * parse them */
-  if (gst_query_get_n_allocation_params (query) > 0) {
-    /* try the allocator */
-    gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
-    update_allocator = TRUE;
-  } else {
-    allocator = NULL;
-    gst_allocation_params_init (&params);
-    update_allocator = FALSE;
-  }
-
-  if (gst_query_get_n_allocation_pools (query) > 0) {
-    gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
-    update_pool = TRUE;
-  } else {
-    pool = NULL;
-    size = GST_VIDEO_INFO_SIZE (&scope->vinfo);
-    min = max = 0;
-    update_pool = FALSE;
-  }
-
-  if (pool == NULL) {
-    /* we did not get a pool, make one ourselves then */
-    pool = gst_video_buffer_pool_new ();
-  }
-
-  config = gst_buffer_pool_get_config (pool);
-  gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
-  gst_buffer_pool_config_set_allocator (config, allocator, &params);
-  gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
-  gst_buffer_pool_set_config (pool, config);
-
-  if (update_allocator)
-    gst_query_set_nth_allocation_param (query, 0, allocator, &params);
-  else
-    gst_query_add_allocation_param (query, allocator, &params);
-
-  if (allocator)
-    gst_object_unref (allocator);
-
-  if (update_pool)
-    gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
-  else
-    gst_query_add_allocation_pool (query, pool, size, min, max);
-
-  if (pool)
-    gst_object_unref (pool);
-
-  return TRUE;
-}
-
-static GstFlowReturn
-default_prepare_output_buffer (GstAudioVisualizer * scope, GstBuffer ** outbuf)
-{
-  GstAudioVisualizerPrivate *priv;
-
-  priv = scope->priv;
-
-  g_assert (priv->pool != NULL);
-
-  /* we can't reuse the input buffer */
-  if (!priv->pool_active) {
-    GST_DEBUG_OBJECT (scope, "setting pool %p active", priv->pool);
-    if (!gst_buffer_pool_set_active (priv->pool, TRUE))
-      goto activate_failed;
-    priv->pool_active = TRUE;
-  }
-  GST_DEBUG_OBJECT (scope, "using pool alloc");
-
-  return gst_buffer_pool_acquire_buffer (priv->pool, outbuf, NULL);
-
-  /* ERRORS */
-activate_failed:
-  {
-    GST_ELEMENT_ERROR (scope, RESOURCE, SETTINGS,
-        ("failed to activate bufferpool"), ("failed to activate bufferpool"));
-    return GST_FLOW_ERROR;
-  }
-}
-
-static GstFlowReturn
-gst_audio_visualizer_chain (GstPad * pad, GstObject * parent,
-    GstBuffer * buffer)
-{
-  GstFlowReturn ret = GST_FLOW_OK;
-  GstAudioVisualizer *scope;
-  GstAudioVisualizerPrivate *priv;
-  GstAudioVisualizerClass *klass;
-  GstBuffer *inbuf;
-  guint64 dist, ts;
-  guint avail, sbpf;
-  gpointer adata;
-  gint bps, channels, rate;
-
-  scope = GST_AUDIO_VISUALIZER (parent);
-  priv = scope->priv;
-  klass = GST_AUDIO_VISUALIZER_CLASS (G_OBJECT_GET_CLASS (scope));
-
-  GST_LOG_OBJECT (scope, "chainfunc called");
-
-  /* resync on DISCONT */
-  if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
-    gst_adapter_clear (priv->adapter);
-  }
-
-  /* Make sure have an output format */
-  if (gst_pad_check_reconfigure (priv->srcpad)) {
-    if (!gst_audio_visualizer_src_negotiate (scope)) {
-      gst_pad_mark_reconfigure (priv->srcpad);
-      goto not_negotiated;
-    }
-  }
-
-  channels = GST_AUDIO_INFO_CHANNELS (&scope->ainfo);
-  rate = GST_AUDIO_INFO_RATE (&scope->ainfo);
-  bps = GST_AUDIO_INFO_BPS (&scope->ainfo);
-
-  if (bps == 0) {
-    ret = GST_FLOW_NOT_NEGOTIATED;
-    goto beach;
-  }
-
-  gst_adapter_push (priv->adapter, buffer);
-
-  g_mutex_lock (&priv->config_lock);
-
-  /* this is what we want */
-  sbpf = scope->req_spf * channels * sizeof (gint16);
-
-  inbuf = priv->inbuf;
-  /* FIXME: the timestamp in the adapter would be different */
-  gst_buffer_copy_into (inbuf, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
-
-  /* this is what we have */
-  avail = gst_adapter_available (priv->adapter);
-  GST_LOG_OBJECT (scope, "avail: %u, bpf: %u", avail, sbpf);
-  while (avail >= sbpf) {
-    GstBuffer *outbuf;
-    GstVideoFrame outframe;
-
-    /* get timestamp of the current adapter content */
-    ts = gst_adapter_prev_pts (priv->adapter, &dist);
-    if (GST_CLOCK_TIME_IS_VALID (ts)) {
-      /* convert bytes to time */
-      dist /= bps;
-      ts += gst_util_uint64_scale_int (dist, GST_SECOND, rate);
-    }
-
-    /* check for QoS, don't compute buffers that are known to be late */
-    if (GST_CLOCK_TIME_IS_VALID (ts)) {
-      GstClockTime earliest_time;
-      gdouble proportion;
-      gint64 qostime;
-
-      qostime =
-          gst_segment_to_running_time (&priv->segment, GST_FORMAT_TIME,
-          ts) + priv->frame_duration;
-
-      GST_OBJECT_LOCK (scope);
-      earliest_time = priv->earliest_time;
-      proportion = priv->proportion;
-      GST_OBJECT_UNLOCK (scope);
-
-      if (GST_CLOCK_TIME_IS_VALID (earliest_time) && qostime <= earliest_time) {
-        GstClockTime stream_time, jitter;
-        GstMessage *qos_msg;
-
-        GST_DEBUG_OBJECT (scope,
-            "QoS: skip ts: %" GST_TIME_FORMAT ", earliest: %" GST_TIME_FORMAT,
-            GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));
-
-        ++priv->dropped;
-        stream_time = gst_segment_to_stream_time (&priv->segment,
-            GST_FORMAT_TIME, ts);
-        jitter = GST_CLOCK_DIFF (qostime, earliest_time);
-        qos_msg = gst_message_new_qos (GST_OBJECT (scope), FALSE, qostime,
-            stream_time, ts, GST_BUFFER_DURATION (buffer));
-        gst_message_set_qos_values (qos_msg, jitter, proportion, 1000000);
-        gst_message_set_qos_stats (qos_msg, GST_FORMAT_BUFFERS,
-            priv->processed, priv->dropped);
-        gst_element_post_message (GST_ELEMENT (scope), qos_msg);
-
-        goto skip;
-      }
-    }
-
-    ++priv->processed;
-
-    g_mutex_unlock (&priv->config_lock);
-    ret = default_prepare_output_buffer (scope, &outbuf);
-    g_mutex_lock (&priv->config_lock);
-    /* recheck as the value could have changed */
-    sbpf = scope->req_spf * channels * sizeof (gint16);
-
-    /* no buffer allocated, we don't care why. */
-    if (ret != GST_FLOW_OK)
-      break;
-
-    /* sync controlled properties */
-    if (GST_CLOCK_TIME_IS_VALID (ts))
-      gst_object_sync_values (GST_OBJECT (scope), ts);
-
-    GST_BUFFER_TIMESTAMP (outbuf) = ts;
-    GST_BUFFER_DURATION (outbuf) = priv->frame_duration;
-
-    /* this can fail as the data size we need could have changed */
-    if (!(adata = (gpointer) gst_adapter_map (priv->adapter, sbpf)))
-      break;
-
-    gst_video_frame_map (&outframe, &scope->vinfo, outbuf, GST_MAP_READWRITE);
-
-    if (priv->shader) {
-      gst_video_frame_copy (&outframe, &priv->tempframe);
-    } else {
-      /* gst_video_frame_clear() or is output frame already cleared */
-      gint i;
-
-      for (i = 0; i < scope->vinfo.finfo->n_planes; i++) {
-        memset (outframe.data[i], 0, outframe.map[i].size);
-      }
-    }
-
-    gst_buffer_replace_all_memory (inbuf,
-        gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, adata, sbpf, 0,
-            sbpf, NULL, NULL));
-
-    /* call class->render() vmethod */
-    if (klass->render) {
-      if (!klass->render (scope, inbuf, &outframe)) {
-        ret = GST_FLOW_ERROR;
-        gst_video_frame_unmap (&outframe);
-        goto beach;
-      } else {
-        /* run various post processing (shading and geometric transformation) */
-        /* FIXME: SHADER assumes 32bpp */
-        if (priv->shader && GST_VIDEO_INFO_COMP_PSTRIDE (&scope->vinfo, 0) == 4) {
-          priv->shader (scope, &outframe, &priv->tempframe);
-        }
-      }
-    }
-    gst_video_frame_unmap (&outframe);
-
-    g_mutex_unlock (&priv->config_lock);
-    ret = gst_pad_push (priv->srcpad, outbuf);
-    outbuf = NULL;
-    g_mutex_lock (&priv->config_lock);
-
-  skip:
-    /* recheck as the value could have changed */
-    sbpf = scope->req_spf * channels * sizeof (gint16);
-    GST_LOG_OBJECT (scope, "avail: %u, bpf: %u", avail, sbpf);
-    /* we want to take less or more, depending on spf : req_spf */
-    if (avail - sbpf >= sbpf) {
-      gst_adapter_flush (priv->adapter, sbpf);
-      gst_adapter_unmap (priv->adapter);
-    } else if (avail >= sbpf) {
-      /* just flush a bit and stop */
-      gst_adapter_flush (priv->adapter, (avail - sbpf));
-      gst_adapter_unmap (priv->adapter);
-      break;
-    }
-    avail = gst_adapter_available (priv->adapter);
-
-    if (ret != GST_FLOW_OK)
-      break;
-  }
-
-  g_mutex_unlock (&priv->config_lock);
-
-beach:
-  return ret;
-
-  /* ERRORS */
-not_negotiated:
-  {
-    GST_DEBUG_OBJECT (scope, "Failed to renegotiate");
-    return GST_FLOW_NOT_NEGOTIATED;
-  }
-}
-
-static gboolean
-gst_audio_visualizer_src_event (GstPad * pad, GstObject * parent,
-    GstEvent * event)
-{
-  gboolean res;
-  GstAudioVisualizer *scope;
-  GstAudioVisualizerPrivate *priv;
-
-  scope = GST_AUDIO_VISUALIZER (parent);
-  priv = scope->priv;
-
-  switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_QOS:
-    {
-      gdouble proportion;
-      GstClockTimeDiff diff;
-      GstClockTime timestamp;
-
-      gst_event_parse_qos (event, NULL, &proportion, &diff, &timestamp);
-
-      /* save stuff for the _chain() function */
-      GST_OBJECT_LOCK (scope);
-      priv->proportion = proportion;
-      if (diff >= 0)
-        /* we're late, this is a good estimate for next displayable
-         * frame (see part-qos.txt) */
-        priv->earliest_time = timestamp + 2 * diff + priv->frame_duration;
-      else
-        priv->earliest_time = timestamp + diff;
-      GST_OBJECT_UNLOCK (scope);
-
-      res = gst_pad_push_event (priv->sinkpad, event);
-      break;
-    }
-    case GST_EVENT_RECONFIGURE:
-      /* dont't forward */
-      gst_event_unref (event);
-      res = TRUE;
-      break;
-    default:
-      res = gst_pad_event_default (pad, parent, event);
-      break;
-  }
-
-  return res;
-}
-
-static gboolean
-gst_audio_visualizer_sink_event (GstPad * pad, GstObject * parent,
-    GstEvent * event)
-{
-  gboolean res;
-  GstAudioVisualizer *scope;
-
-  scope = GST_AUDIO_VISUALIZER (parent);
-
-  switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_CAPS:
-    {
-      GstCaps *caps;
-
-      gst_event_parse_caps (event, &caps);
-      res = gst_audio_visualizer_sink_setcaps (scope, caps);
-      gst_event_unref (event);
-      break;
-    }
-    case GST_EVENT_FLUSH_STOP:
-      gst_audio_visualizer_reset (scope);
-      res = gst_pad_push_event (scope->priv->srcpad, event);
-      break;
-    case GST_EVENT_SEGMENT:
-    {
-      /* the newsegment values are used to clip the input samples
-       * and to convert the incomming timestamps to running time so
-       * we can do QoS */
-      gst_event_copy_segment (event, &scope->priv->segment);
-
-      res = gst_pad_push_event (scope->priv->srcpad, event);
-      break;
-    }
-    default:
-      res = gst_pad_event_default (pad, parent, event);
-      break;
-  }
-
-  return res;
-}
-
-static gboolean
-gst_audio_visualizer_src_query (GstPad * pad, GstObject * parent,
-    GstQuery * query)
-{
-  gboolean res = FALSE;
-  GstAudioVisualizer *scope;
-
-  scope = GST_AUDIO_VISUALIZER (parent);
-
-  switch (GST_QUERY_TYPE (query)) {
-    case GST_QUERY_LATENCY:
-    {
-      /* We need to send the query upstream and add the returned latency to our
-       * own */
-      GstClockTime min_latency, max_latency;
-      gboolean us_live;
-      GstClockTime our_latency;
-      guint max_samples;
-      gint rate = GST_AUDIO_INFO_RATE (&scope->ainfo);
-
-      if (rate == 0)
-        break;
-
-      if ((res = gst_pad_peer_query (scope->priv->sinkpad, query))) {
-        gst_query_parse_latency (query, &us_live, &min_latency, &max_latency);
-
-        GST_DEBUG_OBJECT (scope, "Peer latency: min %"
-            GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
-            GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
-
-        /* the max samples we must buffer buffer */
-        max_samples = MAX (scope->req_spf, scope->priv->spf);
-        our_latency = gst_util_uint64_scale_int (max_samples, GST_SECOND, rate);
-
-        GST_DEBUG_OBJECT (scope, "Our latency: %" GST_TIME_FORMAT,
-            GST_TIME_ARGS (our_latency));
-
-        /* we add some latency but only if we need to buffer more than what
-         * upstream gives us */
-        min_latency += our_latency;
-        if (max_latency != -1)
-          max_latency += our_latency;
-
-        GST_DEBUG_OBJECT (scope, "Calculated total latency : min %"
-            GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
-            GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
-
-        gst_query_set_latency (query, TRUE, min_latency, max_latency);
-      }
-      break;
-    }
-    default:
-      res = gst_pad_query_default (pad, parent, query);
-      break;
-  }
-
-  return res;
-}
-
-static GstStateChangeReturn
-gst_audio_visualizer_change_state (GstElement * element,
-    GstStateChange transition)
-{
-  GstStateChangeReturn ret;
-  GstAudioVisualizer *scope;
-
-  scope = GST_AUDIO_VISUALIZER (element);
-
-  switch (transition) {
-    case GST_STATE_CHANGE_READY_TO_PAUSED:
-      gst_audio_visualizer_reset (scope);
-      break;
-    default:
-      break;
-  }
-
-  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
-  switch (transition) {
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-      gst_audio_visualizer_set_allocation (scope, NULL, NULL, NULL, NULL);
-      break;
-    case GST_STATE_CHANGE_READY_TO_NULL:
-      break;
-    default:
-      break;
-  }
-
-  return ret;
-}
diff --git a/gst/goom2k1/gstaudiovisualizer.h b/gst/goom2k1/gstaudiovisualizer.h
deleted file mode 100644
index 9a618ab..0000000
--- a/gst/goom2k1/gstaudiovisualizer.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* GStreamer
- * Copyright (C) <2011> Stefan Kost <ensonic@users.sf.net>
- * Copyright (C) <2015> Luis de Bethencourt <luis@debethencourt.com>
- *
- * gstaudiovisualizer.c: base class for audio visualisation elements
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef __GST_AUDIO_VISUALIZER_H__
-#define __GST_AUDIO_VISUALIZER_H__
-
-#include <gst/gst.h>
-#include <gst/base/gstbasetransform.h>
-
-#include <gst/video/video.h>
-#include <gst/audio/audio.h>
-#include <gst/base/gstadapter.h>
-
-G_BEGIN_DECLS
-#define GST_TYPE_AUDIO_VISUALIZER            (goom2k1_gst_audio_visualizer_get_type())
-#define GST_AUDIO_VISUALIZER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIO_VISUALIZER,GstAudioVisualizer))
-#define GST_AUDIO_VISUALIZER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIO_VISUALIZER,GstAudioVisualizerClass))
-#define GST_AUDIO_VISUALIZER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_AUDIO_VISUALIZER,GstAudioVisualizerClass))
-#define GST_IS_SYNAESTHESIA(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIO_VISUALIZER))
-#define GST_IS_SYNAESTHESIA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIO_VISUALIZER))
-typedef struct _GstAudioVisualizer GstAudioVisualizer;
-typedef struct _GstAudioVisualizerClass GstAudioVisualizerClass;
-typedef struct _GstAudioVisualizerPrivate GstAudioVisualizerPrivate;
-
-typedef void (*GstAudioVisualizerShaderFunc)(GstAudioVisualizer *scope, const GstVideoFrame *s, GstVideoFrame *d);
-
-/**
- * GstAudioVisualizerShader:
- * @GST_AUDIO_VISUALIZER_SHADER_NONE: no shading
- * @GST_AUDIO_VISUALIZER_SHADER_FADE: plain fading
- * @GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_UP: fade and move up
- * @GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_DOWN: fade and move down
- * @GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_LEFT: fade and move left
- * @GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_RIGHT: fade and move right
- * @GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_OUT: fade and move horizontally out
- * @GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_IN: fade and move horizontally in
- * @GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_OUT: fade and move vertically out
- * @GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_IN: fade and move vertically in
- *
- * Different types of supported background shading functions.
- */
-typedef enum {
-  GST_AUDIO_VISUALIZER_SHADER_NONE,
-  GST_AUDIO_VISUALIZER_SHADER_FADE,
-  GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_UP,
-  GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_DOWN,
-  GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_LEFT,
-  GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_RIGHT,
-  GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_OUT,
-  GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_IN,
-  GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_OUT,
-  GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_IN
-} GstAudioVisualizerShader;
-
-struct _GstAudioVisualizer
-{
-  GstElement parent;
-
-  guint req_spf;                /* min samples per frame wanted by the subclass */
-
-  /* video state */
-  GstVideoInfo vinfo;
-
-  /* audio state */
-  GstAudioInfo ainfo;
-
-  /* <private> */
-  GstAudioVisualizerPrivate *priv;
-};
-
-struct _GstAudioVisualizerClass
-{
-  GstElementClass parent_class;
-
-  /* virtual function, called whenever the format changes */
-  gboolean (*setup) (GstAudioVisualizer * scope);
-
-  /* virtual function for rendering a frame */
-  gboolean (*render) (GstAudioVisualizer * scope, GstBuffer * audio, GstVideoFrame * video);
-
-  gboolean (*decide_allocation)   (GstAudioVisualizer * scope, GstQuery *query);
-};
-
-GType goom2k1_gst_audio_visualizer_get_type (void);
-
-G_END_DECLS
-#endif /* __GST_AUDIO_VISUALIZER_H__ */
diff --git a/gst/goom2k1/gstgoom.h b/gst/goom2k1/gstgoom.h
index e34e42e..41b818b 100644
--- a/gst/goom2k1/gstgoom.h
+++ b/gst/goom2k1/gstgoom.h
@@ -22,7 +22,8 @@
 #ifndef __GST_GOOM_H__
 #define __GST_GOOM_H__
 
-#include "gstaudiovisualizer.h"
+#include <gst/pbutils/gstaudiovisualizer.h>
+
 #include "goom_core.h"
 
 G_BEGIN_DECLS
diff --git a/gst/icydemux/Makefile.in b/gst/icydemux/Makefile.in
index 55bad13..4797a68 100644
--- a/gst/icydemux/Makefile.in
+++ b/gst/icydemux/Makefile.in
@@ -476,6 +476,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/id3demux/Makefile.in b/gst/id3demux/Makefile.in
index d45e554..a55dd64 100644
--- a/gst/id3demux/Makefile.in
+++ b/gst/id3demux/Makefile.in
@@ -476,6 +476,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/imagefreeze/Makefile.in b/gst/imagefreeze/Makefile.in
index ad5d057..6e91afe 100644
--- a/gst/imagefreeze/Makefile.in
+++ b/gst/imagefreeze/Makefile.in
@@ -476,6 +476,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/interleave/Makefile.in b/gst/interleave/Makefile.in
index 9f6826b..8e51d34 100644
--- a/gst/interleave/Makefile.in
+++ b/gst/interleave/Makefile.in
@@ -478,6 +478,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/interleave/deinterleave.c b/gst/interleave/deinterleave.c
index f7c0c94..cdf71f9 100644
--- a/gst/interleave/deinterleave.c
+++ b/gst/interleave/deinterleave.c
@@ -134,6 +134,8 @@
 
 static gboolean gst_deinterleave_sink_event (GstPad * pad, GstObject * parent,
     GstEvent * event);
+static gboolean gst_deinterleave_sink_query (GstPad * pad, GstObject * parent,
+    GstQuery * query);
 
 static gboolean gst_deinterleave_src_query (GstPad * pad, GstObject * parent,
     GstQuery * query);
@@ -212,6 +214,8 @@
       GST_DEBUG_FUNCPTR (gst_deinterleave_chain));
   gst_pad_set_event_function (self->sink,
       GST_DEBUG_FUNCPTR (gst_deinterleave_sink_event));
+  gst_pad_set_query_function (self->sink,
+      GST_DEBUG_FUNCPTR (gst_deinterleave_sink_query));
   gst_element_add_pad (GST_ELEMENT (self), self->sink);
 }
 
@@ -357,6 +361,56 @@
 }
 
 static gboolean
+gst_deinterleave_check_caps_change (GstDeinterleave * self,
+    GstAudioInfo * old_info, GstAudioInfo * new_info)
+{
+  gint i;
+  gboolean same_layout = TRUE;
+  gboolean was_unpositioned;
+  gboolean is_unpositioned = GST_AUDIO_INFO_IS_UNPOSITIONED (new_info);
+  gint new_channels = GST_AUDIO_INFO_CHANNELS (new_info);
+  gint old_channels;
+
+  was_unpositioned = GST_AUDIO_INFO_IS_UNPOSITIONED (old_info);
+  old_channels = GST_AUDIO_INFO_CHANNELS (old_info);
+
+  /* We allow caps changes as long as the number of channels doesn't change
+   * and the channel positions stay the same. _getcaps() should've cared
+   * for this already but better be safe.
+   */
+  if (new_channels != old_channels)
+    goto cannot_change_caps;
+
+  /* Now check the channel positions. If we had no channel positions
+   * and get them or the other way around things have changed.
+   * If we had channel positions and get different ones things have
+   * changed too of course
+   */
+  if ((!was_unpositioned && is_unpositioned) || (was_unpositioned
+          && !is_unpositioned))
+    goto cannot_change_caps;
+
+  if (!is_unpositioned) {
+    if (GST_AUDIO_INFO_CHANNELS (old_info) !=
+        GST_AUDIO_INFO_CHANNELS (new_info))
+      goto cannot_change_caps;
+    for (i = 0; i < GST_AUDIO_INFO_CHANNELS (old_info); i++) {
+      if (new_info->position[i] != old_info->position[i]) {
+        same_layout = FALSE;
+        break;
+      }
+    }
+    if (!same_layout)
+      goto cannot_change_caps;
+  }
+
+  return TRUE;
+
+cannot_change_caps:
+  return FALSE;
+}
+
+static gboolean
 gst_deinterleave_sink_setcaps (GstDeinterleave * self, GstCaps * caps)
 {
   GstCaps *srccaps;
@@ -371,51 +425,17 @@
     goto unsupported_caps;
 
   if (self->sinkcaps && !gst_caps_is_equal (caps, self->sinkcaps)) {
-    gint i;
-    gboolean same_layout = TRUE;
-    gboolean was_unpositioned;
-    gboolean is_unpositioned =
-        GST_AUDIO_INFO_IS_UNPOSITIONED (&self->audio_info);
-    gint new_channels = GST_AUDIO_INFO_CHANNELS (&self->audio_info);
-    gint old_channels;
     GstAudioInfo old_info;
 
     gst_audio_info_init (&old_info);
     if (!gst_audio_info_from_caps (&old_info, self->sinkcaps))
       goto info_from_caps_failed;
-    was_unpositioned = GST_AUDIO_INFO_IS_UNPOSITIONED (&old_info);
-    old_channels = GST_AUDIO_INFO_CHANNELS (&old_info);
 
-    /* We allow caps changes as long as the number of channels doesn't change
-     * and the channel positions stay the same. _getcaps() should've cared
-     * for this already but better be safe.
-     */
-    if (new_channels != old_channels ||
-        !gst_deinterleave_set_process_function (self))
-      goto cannot_change_caps;
-
-    /* Now check the channel positions. If we had no channel positions
-     * and get them or the other way around things have changed.
-     * If we had channel positions and get different ones things have
-     * changed too of course
-     */
-    if ((!was_unpositioned && is_unpositioned) || (was_unpositioned
-            && !is_unpositioned))
-      goto cannot_change_caps;
-
-    if (!is_unpositioned) {
-      if (GST_AUDIO_INFO_CHANNELS (&old_info) !=
-          GST_AUDIO_INFO_CHANNELS (&self->audio_info))
+    if (gst_deinterleave_check_caps_change (self, &old_info, &self->audio_info)) {
+      if (!gst_deinterleave_set_process_function (self))
         goto cannot_change_caps;
-      for (i = 0; i < GST_AUDIO_INFO_CHANNELS (&old_info); i++) {
-        if (self->audio_info.position[i] != old_info.position[i]) {
-          same_layout = FALSE;
-          break;
-        }
-      }
-      if (!same_layout)
-        goto cannot_change_caps;
-    }
+    } else
+      goto cannot_change_caps;
 
   }
 
@@ -500,9 +520,37 @@
   }
 }
 
+static gboolean
+gst_deinterleave_sink_acceptcaps (GstPad * pad, GstObject * parent,
+    GstCaps * caps)
+{
+  GstDeinterleave *self = GST_DEINTERLEAVE (parent);
+  GstCaps *templ_caps = gst_pad_get_pad_template_caps (pad);
+  gboolean ret;
+
+  ret = gst_caps_can_intersect (templ_caps, caps);
+  gst_caps_unref (templ_caps);
+  if (ret && self->sinkcaps) {
+    GstAudioInfo new_info;
+
+    gst_audio_info_init (&new_info);
+    if (!gst_audio_info_from_caps (&new_info, caps))
+      goto info_from_caps_failed;
+    ret =
+        gst_deinterleave_check_caps_change (self, &self->audio_info, &new_info);
+  }
+
+  return ret;
+
+info_from_caps_failed:
+  {
+    GST_ERROR_OBJECT (self, "coud not get info from caps");
+    return FALSE;
+  }
+}
+
 static GstCaps *
-gst_deinterleave_sink_getcaps (GstPad * pad, GstObject * parent,
-    GstCaps * filter)
+gst_deinterleave_getcaps (GstPad * pad, GstObject * parent, GstCaps * filter)
 {
   GstDeinterleave *self = GST_DEINTERLEAVE (parent);
   GstCaps *ret;
@@ -520,8 +568,10 @@
   for (l = GST_ELEMENT (self)->pads; l != NULL; l = l->next) {
     GstPad *ourpad = GST_PAD (l->data);
     GstCaps *peercaps = NULL, *ourcaps;
+    GstCaps *templ_caps = gst_pad_get_pad_template_caps (ourpad);
 
-    ourcaps = gst_caps_copy (gst_pad_get_pad_template_caps (ourpad));
+    ourcaps = gst_caps_copy (templ_caps);
+    gst_caps_unref (templ_caps);
 
     if (pad == ourpad) {
       if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK)
@@ -562,6 +612,14 @@
   }
   GST_OBJECT_UNLOCK (self);
 
+  if (filter) {
+    GstCaps *aux;
+
+    aux = gst_caps_intersect (ret, filter);
+    gst_caps_unref (ret);
+    ret = aux;
+  }
+
   GST_DEBUG_OBJECT (pad, "Intersected caps to %" GST_PTR_FORMAT, ret);
 
   return ret;
@@ -613,6 +671,41 @@
 }
 
 static gboolean
+gst_deinterleave_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
+{
+  gboolean res;
+
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_CAPS:{
+      GstCaps *filter;
+      GstCaps *caps;
+
+      gst_query_parse_caps (query, &filter);
+      caps = gst_deinterleave_getcaps (pad, parent, filter);
+      gst_query_set_caps_result (query, caps);
+      gst_caps_unref (caps);
+      res = TRUE;
+      break;
+    }
+    case GST_QUERY_ACCEPT_CAPS:{
+      GstCaps *caps;
+      gboolean ret;
+
+      gst_query_parse_accept_caps (query, &caps);
+      ret = gst_deinterleave_sink_acceptcaps (pad, parent, caps);
+      gst_query_set_accept_caps_result (query, ret);
+      res = TRUE;
+      break;
+    }
+    default:
+      res = gst_pad_query_default (pad, parent, query);
+      break;
+  }
+
+  return res;
+}
+
+static gboolean
 gst_deinterleave_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
 {
   GstDeinterleave *self = GST_DEINTERLEAVE (parent);
@@ -648,7 +741,7 @@
     GstCaps *filter, *caps;
 
     gst_query_parse_caps (query, &filter);
-    caps = gst_deinterleave_sink_getcaps (pad, parent, filter);
+    caps = gst_deinterleave_getcaps (pad, parent, filter);
     gst_query_set_caps_result (query, caps);
     gst_caps_unref (caps);
   }
diff --git a/gst/interleave/interleave.h b/gst/interleave/interleave.h
index 78f519d..e69936a 100644
--- a/gst/interleave/interleave.h
+++ b/gst/interleave/interleave.h
@@ -70,8 +70,6 @@
 
   GstEvent *pending_segment;
 
-  GstPadEventFunction collect_event;
-
   GstInterleaveFunc func;
 
   GstPad *src;
diff --git a/gst/isomp4/Makefile.in b/gst/isomp4/Makefile.in
index 307df13..8fd7b53 100644
--- a/gst/isomp4/Makefile.in
+++ b/gst/isomp4/Makefile.in
@@ -485,6 +485,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/isomp4/atoms.c b/gst/isomp4/atoms.c
index 267c4f0..e0ec513 100644
--- a/gst/isomp4/atoms.c
+++ b/gst/isomp4/atoms.c
@@ -2965,9 +2965,7 @@
 static void
 atom_tag_data_alloc_data (AtomTagData * data, guint size)
 {
-  if (data->data != NULL) {
-    g_free (data->data);
-  }
+  g_free (data->data);
   data->data = g_new0 (guint8, size);
   data->datalen = size;
 }
@@ -3185,8 +3183,7 @@
 static void
 atom_hdlr_set_name (AtomHDLR * hdlr, const char *name)
 {
-  if (hdlr->name)
-    g_free (hdlr->name);
+  g_free (hdlr->name);
   hdlr->name = g_strdup (name);
 }
 
@@ -3471,7 +3468,7 @@
 }
 
 static AtomInfo *
-build_pasp_extension (AtomTRAK * trak, gint par_width, gint par_height)
+build_pasp_extension (gint par_width, gint par_height)
 {
   AtomData *atom_data = atom_data_new (FOURCC_pasp);
   guint8 *data;
@@ -3534,7 +3531,7 @@
   /* QT spec has a pasp extension atom in stsd that can hold PAR */
   if (par_n && (context->flavor == ATOMS_TREE_FLAVOR_MOV)) {
     ste->extension_atoms = g_list_append (ste->extension_atoms,
-        build_pasp_extension (trak, par_n, par_d));
+        build_pasp_extension (par_n, par_d));
   }
 
   return ste;
@@ -4288,8 +4285,8 @@
 }
 
 static AtomInfo *
-build_mov_wave_extension (AtomTRAK * trak, guint32 fourcc, AtomInfo * atom1,
-    AtomInfo * atom2, gboolean terminator)
+build_mov_wave_extension (guint32 fourcc, AtomInfo * atom1, AtomInfo * atom2,
+    gboolean terminator)
 {
   AtomWAVE *wave;
   AtomFRMA *frma;
@@ -4342,17 +4339,17 @@
   mp4a = build_codec_data_extension (FOURCC_mp4a, buf);
   gst_buffer_unref (buf);
 
-  return build_mov_wave_extension (trak, FOURCC_mp4a, mp4a, esds, TRUE);
+  return build_mov_wave_extension (FOURCC_mp4a, mp4a, esds, TRUE);
 }
 
 AtomInfo *
-build_mov_alac_extension (AtomTRAK * trak, const GstBuffer * codec_data)
+build_mov_alac_extension (const GstBuffer * codec_data)
 {
   AtomInfo *alac;
 
   alac = build_codec_data_extension (FOURCC_alac, codec_data);
 
-  return build_mov_wave_extension (trak, FOURCC_alac, NULL, alac, TRUE);
+  return build_mov_wave_extension (FOURCC_alac, NULL, alac, TRUE);
 }
 
 AtomInfo *
@@ -4365,8 +4362,7 @@
     return NULL;
   }
 
-  atom_data =
-      atom_data_new_from_data (GST_MAKE_FOURCC ('f', 'i', 'e', 'l'), &f, 1);
+  atom_data = atom_data_new_from_data (FOURCC_fiel, &f, 1);
 
   return build_atom_info_wrapper ((Atom *) atom_data, atom_data_copy_data,
       atom_data_free);
@@ -4381,18 +4377,15 @@
     return NULL;
   }
 
-  atom_data =
-      atom_data_new_from_gst_buffer (GST_MAKE_FOURCC ('j', 'p', '2', 'x'),
-      prefix);
+  atom_data = atom_data_new_from_gst_buffer (FOURCC_jp2x, prefix);
 
   return build_atom_info_wrapper ((Atom *) atom_data, atom_data_copy_data,
       atom_data_free);
 }
 
 AtomInfo *
-build_jp2h_extension (AtomTRAK * trak, gint width, gint height,
-    const gchar * colorspace, gint ncomp, const GValue * cmap_array,
-    const GValue * cdef_array)
+build_jp2h_extension (gint width, gint height, const gchar * colorspace,
+    gint ncomp, const GValue * cmap_array, const GValue * cdef_array)
 {
   AtomData *atom_data;
   GstBuffer *buf;
@@ -4439,8 +4432,7 @@
 
   /* ihdr = image header box */
   gst_byte_writer_put_uint32_be_unchecked (&writer, 22);
-  gst_byte_writer_put_uint32_le_unchecked (&writer, GST_MAKE_FOURCC ('i', 'h',
-          'd', 'r'));
+  gst_byte_writer_put_uint32_le_unchecked (&writer, FOURCC_ihdr);
   gst_byte_writer_put_uint32_be_unchecked (&writer, height);
   gst_byte_writer_put_uint32_be_unchecked (&writer, width);
   gst_byte_writer_put_uint16_be_unchecked (&writer, ncomp);
@@ -4455,8 +4447,7 @@
 
   /* colour specification box */
   gst_byte_writer_put_uint32_be_unchecked (&writer, 15);
-  gst_byte_writer_put_uint32_le_unchecked (&writer, GST_MAKE_FOURCC ('c', 'o',
-          'l', 'r'));
+  gst_byte_writer_put_uint32_le_unchecked (&writer, FOURCC_colr);
 
   /* specification method: enumerated */
   gst_byte_writer_put_uint8_unchecked (&writer, 0x1);
@@ -4469,8 +4460,7 @@
 
   if (cmap_array) {
     gst_byte_writer_put_uint32_be_unchecked (&writer, cmap_size);
-    gst_byte_writer_put_uint32_le_unchecked (&writer,
-        GST_MAKE_FOURCC ('c', 'm', 'a', 'p'));
+    gst_byte_writer_put_uint32_le_unchecked (&writer, FOURCC_cmap);
     for (i = 0; i < cmap_array_size; i++) {
       const GValue *item;
       gint value;
@@ -4497,8 +4487,7 @@
 
   if (cdef_array) {
     gst_byte_writer_put_uint32_be_unchecked (&writer, cdef_size);
-    gst_byte_writer_put_uint32_le_unchecked (&writer,
-        GST_MAKE_FOURCC ('c', 'd', 'e', 'f'));
+    gst_byte_writer_put_uint32_le_unchecked (&writer, FOURCC_cdef);
     gst_byte_writer_put_uint16_be_unchecked (&writer, cdef_array_size);
     for (i = 0; i < cdef_array_size; i++) {
       const GValue *item;
@@ -4564,7 +4553,7 @@
   GST_WRITE_UINT8 (ext + 8, 1);
 
   buf = GST_BUFFER_NEW_READONLY (ext, sizeof (ext));
-  res = build_codec_data_extension (GST_MAKE_FOURCC ('d', 'a', 'm', 'r'), buf);
+  res = build_codec_data_extension (FOURCC_damr, buf);
   gst_buffer_unref (buf);
   return res;
 }
@@ -4586,7 +4575,7 @@
   GST_WRITE_UINT8 (ext + 6, 0);
 
   buf = GST_BUFFER_NEW_READONLY (ext, sizeof (ext));
-  res = build_codec_data_extension (GST_MAKE_FOURCC ('d', '2', '6', '3'), buf);
+  res = build_codec_data_extension (FOURCC_d263, buf);
   gst_buffer_unref (buf);
   return res;
 }
@@ -4731,6 +4720,44 @@
 }
 
 AtomInfo *
+build_opus_extension (guint32 rate, guint8 channels, guint8 mapping_family,
+    guint8 stream_count, guint8 coupled_count, guint8 channel_mapping[256],
+    guint16 pre_skip, guint16 output_gain)
+{
+  AtomData *atom_data;
+  guint8 *data_block;
+  GstByteWriter bw;
+  gboolean hdl = TRUE;
+  guint data_block_len;
+
+  gst_byte_writer_init (&bw);
+  hdl &= gst_byte_writer_put_uint8 (&bw, 0x00); /* version number */
+  hdl &= gst_byte_writer_put_uint8 (&bw, channels);
+  hdl &= gst_byte_writer_put_uint16_le (&bw, pre_skip);
+  hdl &= gst_byte_writer_put_uint32_le (&bw, rate);
+  hdl &= gst_byte_writer_put_uint16_le (&bw, output_gain);
+  hdl &= gst_byte_writer_put_uint8 (&bw, mapping_family);
+  if (mapping_family > 0) {
+    hdl &= gst_byte_writer_put_uint8 (&bw, stream_count);
+    hdl &= gst_byte_writer_put_uint8 (&bw, coupled_count);
+    hdl &= gst_byte_writer_put_data (&bw, channel_mapping, channels);
+  }
+
+  if (!hdl) {
+    GST_WARNING ("Error creating header");
+    return NULL;
+  }
+
+  data_block_len = gst_byte_writer_get_size (&bw);
+  data_block = gst_byte_writer_reset_and_get_data (&bw);
+  atom_data = atom_data_new_from_data (FOURCC_dops, data_block, data_block_len);
+  g_free (data_block);
+
+  return build_atom_info_wrapper ((Atom *) atom_data, atom_data_copy_data,
+      atom_data_free);
+}
+
+AtomInfo *
 build_uuid_xmp_atom (GstBuffer * xmp_data)
 {
   AtomUUID *uuid;
diff --git a/gst/isomp4/atoms.h b/gst/isomp4/atoms.h
index f8789e4..b105a4d 100644
--- a/gst/isomp4/atoms.h
+++ b/gst/isomp4/atoms.h
@@ -948,15 +948,14 @@
 AtomInfo *   build_codec_data_extension  (guint32 fourcc, const GstBuffer * codec_data);
 AtomInfo *   build_mov_aac_extension     (AtomTRAK * trak, const GstBuffer * codec_data,
                                           guint32 avg_bitrate, guint32 max_bitrate);
-AtomInfo *   build_mov_alac_extension    (AtomTRAK * trak, const GstBuffer * codec_data);
+AtomInfo *   build_mov_alac_extension    (const GstBuffer * codec_data);
 AtomInfo *   build_esds_extension        (AtomTRAK * trak, guint8 object_type,
                                           guint8 stream_type, const GstBuffer * codec_data,
                                           guint32 avg_bitrate, guint32 max_bitrate);
 AtomInfo *   build_btrt_extension        (guint32 buffer_size_db, guint32 avg_bitrate,
                                           guint32 max_bitrate);
-AtomInfo *   build_jp2h_extension        (AtomTRAK * trak, gint width, gint height,
-                                          const gchar *colorspace, gint ncomp,
-                                          const GValue * cmap_array,
+AtomInfo *   build_jp2h_extension        (gint width, gint height, const gchar *colorspace,
+                                          gint ncomp, const GValue * cmap_array,
                                           const GValue * cdef_array);
 
 AtomInfo *   build_jp2x_extension        (const GstBuffer * prefix);
@@ -964,6 +963,11 @@
 AtomInfo *   build_ac3_extension         (guint8 fscod, guint8 bsid,
                                           guint8 bsmod, guint8 acmod,
                                           guint8 lfe_on, guint8 bitrate_code);
+AtomInfo *   build_opus_extension        (guint32 rate, guint8 channels, guint8 mapping_family,
+                                          guint8 stream_count, guint8 coupled_count,
+                                          guint8 channel_mapping[256], guint16 pre_skip,
+                                          guint16 output_gain);
+
 AtomInfo *   build_amr_extension         (void);
 AtomInfo *   build_h263_extension        (void);
 AtomInfo *   build_gama_atom             (gdouble gamma);
diff --git a/gst/isomp4/fourcc.h b/gst/isomp4/fourcc.h
index 4bff1e0..5bb43e9 100644
--- a/gst/isomp4/fourcc.h
+++ b/gst/isomp4/fourcc.h
@@ -103,7 +103,9 @@
 #define FOURCC_ctab     GST_MAKE_FOURCC('c','t','a','b')
 #define FOURCC_ctts     GST_MAKE_FOURCC('c','t','t','s')
 #define FOURCC_cslg     GST_MAKE_FOURCC('c','s','l','g')
+#define FOURCC_d263     GST_MAKE_FOURCC('d','2','6','3')
 #define FOURCC_dac3     GST_MAKE_FOURCC('d','a','c','3')
+#define FOURCC_damr     GST_MAKE_FOURCC('d','a','m','r')
 #define FOURCC_data     GST_MAKE_FOURCC('d','a','t','a')
 #define FOURCC_dcom     GST_MAKE_FOURCC('d','c','o','m')
 #define FOURCC_desc     GST_MAKE_FOURCC('d','e','s','c')
@@ -115,6 +117,10 @@
 #define FOURCC_dref     GST_MAKE_FOURCC('d','r','e','f')
 #define FOURCC_drmi     GST_MAKE_FOURCC('d','r','m','i')
 #define FOURCC_drms     GST_MAKE_FOURCC('d','r','m','s')
+#define FOURCC_dvcp     GST_MAKE_FOURCC('d','v','c','p')
+#define FOURCC_dvc_     GST_MAKE_FOURCC('d','v','c',' ')
+#define FOURCC_dv5p     GST_MAKE_FOURCC('d','v','5','p')
+#define FOURCC_dv5n     GST_MAKE_FOURCC('d','v','5','n')
 #define FOURCC_edts     GST_MAKE_FOURCC('e','d','t','s')
 #define FOURCC_elst     GST_MAKE_FOURCC('e','l','s','t')
 #define FOURCC_enda     GST_MAKE_FOURCC('e','n','d','a')
@@ -159,10 +165,12 @@
 #define FOURCC_minf     GST_MAKE_FOURCC('m','i','n','f')
 #define FOURCC_moov     GST_MAKE_FOURCC('m','o','o','v')
 #define FOURCC_mp4a     GST_MAKE_FOURCC('m','p','4','a')
-#define FOURCC_mp4s	GST_MAKE_FOURCC('m','p','4','s')
+#define FOURCC_mp4s     GST_MAKE_FOURCC('m','p','4','s')
 #define FOURCC_mp4s     GST_MAKE_FOURCC('m','p','4','s')
 #define FOURCC_mp4v     GST_MAKE_FOURCC('m','p','4','v')
 #define FOURCC_name     GST_MAKE_FOURCC('n','a','m','e')
+#define FOURCC_opus     GST_MAKE_FOURCC('O','p','u','s')
+#define FOURCC_dops     GST_MAKE_FOURCC('d','O','p','s')
 #define FOURCC_pasp     GST_MAKE_FOURCC('p','a','s','p')
 #define FOURCC_pcst     GST_MAKE_FOURCC('p','c','s','t')
 #define FOURCC_pgap     GST_MAKE_FOURCC('p','g','a','p')
@@ -195,6 +203,7 @@
 #define FOURCC_sowt     GST_MAKE_FOURCC('s','o','w','t')
 #define FOURCC_stbl     GST_MAKE_FOURCC('s','t','b','l')
 #define FOURCC_stco     GST_MAKE_FOURCC('s','t','c','o')
+#define FOURCC_stpp     GST_MAKE_FOURCC('s','t','p','p')
 #define FOURCC_stps     GST_MAKE_FOURCC('s','t','p','s')
 #define FOURCC_strf     GST_MAKE_FOURCC('s','t','r','f')
 #define FOURCC_strm     GST_MAKE_FOURCC('s','t','r','m')
@@ -222,6 +231,7 @@
 #define FOURCC_url_     GST_MAKE_FOURCC('u','r','l',' ')
 #define FOURCC_uuid     GST_MAKE_FOURCC('u','u','i','d')
 #define FOURCC_v210     GST_MAKE_FOURCC('v','2','1','0')
+#define FOURCC_vc_1     GST_MAKE_FOURCC('v','c','-','1')
 #define FOURCC_vide     GST_MAKE_FOURCC('v','i','d','e')
 #define FOURCC_vmhd     GST_MAKE_FOURCC('v','m','h','d')
 #define FOURCC_wave     GST_MAKE_FOURCC('w','a','v','e')
@@ -243,6 +253,7 @@
 #define FOURCC_3gp4     GST_MAKE_FOURCC('3','g','p','4')
 #define FOURCC_3gp6     GST_MAKE_FOURCC('3','g','p','6')
 #define FOURCC_3gr6     GST_MAKE_FOURCC('3','g','r','6')
+#define FOURCC_3g__     GST_MAKE_FOURCC('3','g',0,0)
 #define FOURCC_isml     GST_MAKE_FOURCC('i','s','m','l')
 #define FOURCC_iso2     GST_MAKE_FOURCC('i','s','o','2')
 #define FOURCC_isom     GST_MAKE_FOURCC('i','s','o','m')
@@ -298,6 +309,7 @@
 #define FOURCC_traf     GST_MAKE_FOURCC('t','r','a','f')
 #define FOURCC_trex     GST_MAKE_FOURCC('t','r','e','x')
 #define FOURCC_trun     GST_MAKE_FOURCC('t','r','u','n')
+#define FOURCC_wma_     GST_MAKE_FOURCC('w','m','a',' ')
 
 /* MPEG DASH */
 #define FOURCC_tfdt     GST_MAKE_FOURCC('t','f','d','t')
diff --git a/gst/isomp4/gstqtmux.c b/gst/isomp4/gstqtmux.c
index 7f72443..9ac7c77 100644
--- a/gst/isomp4/gstqtmux.c
+++ b/gst/isomp4/gstqtmux.c
@@ -122,6 +122,7 @@
 #include <gst/audio/audio.h>
 #include <gst/video/video.h>
 #include <gst/tag/tag.h>
+#include <gst/pbutils/pbutils.h>
 
 #include <sys/types.h>
 #ifdef G_OS_WIN32
@@ -2461,10 +2462,8 @@
       guint32 lateness = 0;
       guint32 duration = qtpad->trak->tkhd.duration;
       gboolean has_gap;
-      gboolean has_shift;
 
       has_gap = (qtpad->first_ts > (qtmux->first_ts + qtpad->dts_adjustment));
-      has_shift = (qtpad->dts_adjustment > 0);
 
       if (has_gap) {
         GstClockTime diff;
@@ -2480,11 +2479,14 @@
             (guint32) (1 * 65536.0));
       }
 
-      if (has_gap || has_shift) {
-        GstClockTime ctts;
+      /* has shift */
+      if (has_gap || (qtpad->dts_adjustment > 0)) {
+        GstClockTime ctts = 0;
         guint32 media_start;
 
-        ctts = qtpad->first_ts - qtpad->first_dts;
+        if (qtpad->first_ts > qtpad->first_dts)
+          ctts = qtpad->first_ts - qtpad->first_dts;
+
         media_start = gst_util_uint64_scale_round (ctts,
             atom_trak_get_timescale (qtpad->trak), GST_SECOND);
 
@@ -3644,7 +3646,7 @@
       GST_WARNING_OBJECT (qtmux, "unexpected codec-data size, possibly broken");
     }
     if (format == GST_QT_MUX_FORMAT_QT)
-      ext_atom = build_mov_alac_extension (qtpad->trak, codec_config);
+      ext_atom = build_mov_alac_extension (codec_config);
     else
       ext_atom = build_codec_data_extension (FOURCC_alac, codec_config);
     /* set some more info */
@@ -3665,6 +3667,49 @@
      * the stream itself. Abuse the prepare_buf_func so we parse a frame
      * and get the needed data */
     qtpad->prepare_buf_func = gst_qt_mux_prepare_parse_ac3_frame;
+  } else if (strcmp (mimetype, "audio/x-opus") == 0) {
+    /* Based on the specification defined in:
+     * https://www.opus-codec.org/docs/opus_in_isobmff.html */
+    guint8 channels, mapping_family, stream_count, coupled_count;
+    guint16 pre_skip;
+    gint16 output_gain;
+    guint32 rate;
+    guint8 channel_mapping[256];
+    const GValue *streamheader;
+    const GValue *first_element;
+    GstBuffer *header;
+
+    entry.fourcc = FOURCC_opus;
+    entry.sample_size = 16;
+
+    streamheader = gst_structure_get_value (structure, "streamheader");
+    if (streamheader && GST_VALUE_HOLDS_ARRAY (streamheader) &&
+        gst_value_array_get_size (streamheader) != 0) {
+      first_element = gst_value_array_get_value (streamheader, 0);
+      header = gst_value_get_buffer (first_element);
+      if (!gst_codec_utils_opus_parse_header (header, &rate, &channels,
+              &mapping_family, &stream_count, &coupled_count, channel_mapping,
+              &pre_skip, &output_gain)) {
+        GST_ERROR_OBJECT (qtmux, "Incomplete OpusHead");
+        goto refuse_caps;
+      }
+    } else {
+      GST_WARNING_OBJECT (qtmux,
+          "no streamheader field in caps %" GST_PTR_FORMAT, caps);
+
+      if (!gst_codec_utils_opus_parse_caps (caps, &rate, &channels,
+              &mapping_family, &stream_count, &coupled_count,
+              channel_mapping)) {
+        GST_ERROR_OBJECT (qtmux, "Incomplete Opus caps");
+        goto refuse_caps;
+      }
+      pre_skip = 0;
+      output_gain = 0;
+    }
+
+    entry.channels = channels;
+    ext_atom = build_opus_extension (rate, channels, mapping_family,
+        stream_count, coupled_count, channel_mapping, pre_skip, output_gain);
   }
 
   if (!entry.fourcc)
@@ -3957,15 +4002,15 @@
     switch (version) {
       case 25:
         if (pal)
-          entry.fourcc = GST_MAKE_FOURCC ('d', 'v', 'c', 'p');
+          entry.fourcc = FOURCC_dvcp;
         else
-          entry.fourcc = GST_MAKE_FOURCC ('d', 'v', 'c', ' ');
+          entry.fourcc = FOURCC_dvc_;
         break;
       case 50:
         if (pal)
-          entry.fourcc = GST_MAKE_FOURCC ('d', 'v', '5', 'p');
+          entry.fourcc = FOURCC_dv5p;
         else
-          entry.fourcc = GST_MAKE_FOURCC ('d', 'v', '5', 'n');
+          entry.fourcc = FOURCC_dv5n;
         break;
       default:
         GST_WARNING_OBJECT (qtmux, "unrecognized dv version");
@@ -3998,8 +4043,8 @@
     colorspace = gst_structure_get_string (structure, "colorspace");
     if (colorspace &&
         (ext_atom =
-            build_jp2h_extension (qtpad->trak, width, height, colorspace, ncomp,
-                cmap_array, cdef_array)) != NULL) {
+            build_jp2h_extension (width, height, colorspace, ncomp, cmap_array,
+                cdef_array)) != NULL) {
       ext_atom_list = g_list_append (ext_atom_list, ext_atom);
 
       ext_atom = build_fiel_extension (fields);
@@ -4033,13 +4078,13 @@
 
     variant = gst_structure_get_string (structure, "format");
     if (!variant || !g_strcmp0 (variant, "standard"))
-      entry.fourcc = GST_MAKE_FOURCC ('a', 'p', 'c', 'n');
+      entry.fourcc = FOURCC_apcn;
     else if (!g_strcmp0 (variant, "lt"))
-      entry.fourcc = GST_MAKE_FOURCC ('a', 'p', 'c', 's');
+      entry.fourcc = FOURCC_apcs;
     else if (!g_strcmp0 (variant, "hq"))
-      entry.fourcc = GST_MAKE_FOURCC ('a', 'p', 'c', 'h');
+      entry.fourcc = FOURCC_apch;
     else if (!g_strcmp0 (variant, "proxy"))
-      entry.fourcc = GST_MAKE_FOURCC ('a', 'p', '4', 'h');
+      entry.fourcc = FOURCC_ap4h;
   }
 
   if (!entry.fourcc)
diff --git a/gst/isomp4/gstqtmuxmap.c b/gst/isomp4/gstqtmuxmap.c
index 1a8b6ce..61b11a4 100644
--- a/gst/isomp4/gstqtmuxmap.c
+++ b/gst/isomp4/gstqtmuxmap.c
@@ -88,20 +88,15 @@
 
 #define PCM_CAPS \
   "audio/x-raw, " \
-  "format = (string) { S8, U8 }, " \
-  "layout = (string) interleaved, " \
-  COMMON_AUDIO_CAPS (2, MAX) "; " \
-  "audio/x-raw, " \
-  "format = (string) { S16LE, S16BE }, " \
+  "format = (string) { S16LE, S16BE, S8, U8 }, " \
   "layout = (string) interleaved, " \
   COMMON_AUDIO_CAPS (2, MAX)
 
 #define PCM_CAPS_FULL \
   "audio/x-raw, " \
-  "format = (string) { S32LE, S32BE, S24LE, S24BE }, " \
+  "format = (string) { S32LE, S32BE, S24LE, S24BE, S16LE, S16BE, S8, U8 }, " \
   "layout = (string) interleaved, " \
-  COMMON_AUDIO_CAPS (2, MAX) "; " \
-  PCM_CAPS
+  COMMON_AUDIO_CAPS (2, MAX)
 
 #define MP3_CAPS \
   "audio/mpeg, " \
@@ -137,6 +132,12 @@
   "audio/x-alac, " \
   COMMON_AUDIO_CAPS(2, MAX)
 
+#define OPUS_CAPS \
+  "audio/x-opus, " \
+  "channel-mapping-family = (int) [0, 255], " \
+  COMMON_AUDIO_CAPS(8, MAX)
+
+
 #define TEXT_UTF8 \
   "text/x-raw, " \
   "format=(string)utf8"
@@ -189,7 +190,8 @@
         GST_STATIC_CAPS ("video/quicktime, variant = (string) iso"),
         GST_STATIC_CAPS (MPEG4V_CAPS "; " H264_CAPS ";"
             "video/x-mp4-part," COMMON_VIDEO_CAPS),
-        GST_STATIC_CAPS (MP3_CAPS "; " AAC_CAPS " ; " AC3_CAPS " ; " ALAC_CAPS),
+        GST_STATIC_CAPS (MP3_CAPS "; "
+            AAC_CAPS " ; " AC3_CAPS " ; " ALAC_CAPS " ; " OPUS_CAPS),
       GST_STATIC_CAPS (TEXT_UTF8)}
   ,
   /* Microsoft Smooth Streaming fmp4/isml */
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
index cc40893..77bb73e 100644
--- a/gst/isomp4/qtdemux.c
+++ b/gst/isomp4/qtdemux.c
@@ -1242,6 +1242,7 @@
     GstClockTime media_time;
     GstClockTime seg_time;
     QtDemuxSegment *seg;
+    gboolean empty_segment = FALSE;
 
     str = qtdemux->streams[n];
 
@@ -1255,41 +1256,61 @@
     seg = &str->segments[seg_idx];
     seg_time = desired_time - seg->time;
 
+    while (QTSEGMENT_IS_EMPTY (seg)) {
+      seg_time = 0;
+      empty_segment = TRUE;
+      GST_DEBUG_OBJECT (str->pad, "Segment %d is empty, moving to next one",
+          seg_idx);
+      seg_idx++;
+      if (seg_idx == str->n_segments)
+        break;
+      seg = &str->segments[seg_idx];
+    }
+
+    if (seg_idx == str->n_segments) {
+      /* FIXME track shouldn't have the last segment as empty, but if it
+       * happens we better handle it */
+      continue;
+    }
+
     /* get the media time in the segment */
     media_start = seg->media_start + seg_time;
 
     /* get the index of the sample with media time */
     index = gst_qtdemux_find_index_linear (qtdemux, str, media_start);
     GST_DEBUG_OBJECT (qtdemux, "sample for %" GST_TIME_FORMAT " at %u"
-        " at offset %" G_GUINT64_FORMAT,
-        GST_TIME_ARGS (media_start), index, str->samples[index].offset);
+        " at offset %" G_GUINT64_FORMAT " (empty segment: %d)",
+        GST_TIME_ARGS (media_start), index, str->samples[index].offset,
+        empty_segment);
 
-    /* find previous keyframe */
-    kindex = gst_qtdemux_find_keyframe (qtdemux, str, index);
+    if (!empty_segment) {
+      /* find previous keyframe */
+      kindex = gst_qtdemux_find_keyframe (qtdemux, str, index);
 
-    /* if the keyframe is at a different position, we need to update the
-     * requested seek time */
-    if (index != kindex) {
-      index = kindex;
+      /* if the keyframe is at a different position, we need to update the
+       * requested seek time */
+      if (index != kindex) {
+        index = kindex;
 
-      /* get timestamp of keyframe */
-      media_time = QTSAMPLE_DTS (str, &str->samples[kindex]);
-      GST_DEBUG_OBJECT (qtdemux,
-          "keyframe at %u with time %" GST_TIME_FORMAT " at offset %"
-          G_GUINT64_FORMAT, kindex, GST_TIME_ARGS (media_time),
-          str->samples[kindex].offset);
+        /* get timestamp of keyframe */
+        media_time = QTSAMPLE_DTS (str, &str->samples[kindex]);
+        GST_DEBUG_OBJECT (qtdemux,
+            "keyframe at %u with time %" GST_TIME_FORMAT " at offset %"
+            G_GUINT64_FORMAT, kindex, GST_TIME_ARGS (media_time),
+            str->samples[kindex].offset);
 
-      /* keyframes in the segment get a chance to change the
-       * desired_offset. keyframes out of the segment are
-       * ignored. */
-      if (media_time >= seg->media_start) {
-        GstClockTime seg_time;
+        /* keyframes in the segment get a chance to change the
+         * desired_offset. keyframes out of the segment are
+         * ignored. */
+        if (media_time >= seg->media_start) {
+          GstClockTime seg_time;
 
-        /* this keyframe is inside the segment, convert back to
-         * segment time */
-        seg_time = (media_time - seg->media_start) + seg->time;
-        if (seg_time < min_offset)
-          min_offset = seg_time;
+          /* this keyframe is inside the segment, convert back to
+           * segment time */
+          seg_time = (media_time - seg->media_start) + seg->time;
+          if (seg_time < min_offset)
+            min_offset = seg_time;
+        }
       }
     }
 
@@ -1974,6 +1995,9 @@
       qtdemux->streams[n]->time_position = 0;
       qtdemux->streams[n]->accumulated_base = 0;
     }
+    if (!qtdemux->pending_newsegment) {
+      qtdemux->pending_newsegment = gst_event_new_segment (&qtdemux->segment);
+    }
   }
 }
 
@@ -2103,6 +2127,14 @@
       res = TRUE;
       goto drop;
     }
+    case GST_EVENT_FLUSH_START:
+    {
+      if (gst_event_get_seqnum (event) == demux->offset_seek_seqnum) {
+        gst_event_unref (event);
+        goto drop;
+      }
+      break;
+    }
     case GST_EVENT_FLUSH_STOP:
     {
       guint64 dur;
@@ -2110,6 +2142,11 @@
       dur = demux->segment.duration;
       gst_qtdemux_reset (demux, FALSE);
       demux->segment.duration = dur;
+
+      if (gst_event_get_seqnum (event) == demux->offset_seek_seqnum) {
+        gst_event_unref (event);
+        goto drop;
+      }
       break;
     }
     case GST_EVENT_EOS:
@@ -2364,6 +2401,8 @@
     qtdemux->major_brand = QT_FOURCC (buffer + 8);
     GST_DEBUG_OBJECT (qtdemux, "major brand: %" GST_FOURCC_FORMAT,
         GST_FOURCC_ARGS (qtdemux->major_brand));
+    if (qtdemux->comp_brands)
+      gst_buffer_unref (qtdemux->comp_brands);
     buf = qtdemux->comp_brands = gst_buffer_new_and_alloc (length - 16);
     gst_buffer_fill (buf, 0, buffer + 16, length - 16);
   }
@@ -4110,8 +4149,6 @@
  * This will push out a NEWSEGMENT event with the right values and
  * position the stream index to the first decodable sample before
  * @offset.
- *
- * PULL-BASED
  */
 static gboolean
 gst_qtdemux_activate_segment (GstQTDemux * qtdemux, QtDemuxStream * stream,
@@ -4243,6 +4280,10 @@
     return TRUE;
   }
 
+  /* We don't need to look for a sample in push-based */
+  if (!qtdemux->pullbased)
+    return TRUE;
+
   /* and move to the keyframe before the indicated media time of the
    * segment */
   if (G_LIKELY (!QTSEGMENT_IS_EMPTY (segment))) {
@@ -4291,9 +4332,9 @@
     /* moving forwards check if we move past a keyframe */
     if (kf_index > stream->sample_index) {
       GST_DEBUG_OBJECT (stream->pad,
-	   "moving forwards to keyframe at %u (pts %" GST_TIME_FORMAT " dts %"GST_TIME_FORMAT" )", kf_index,
-	   GST_TIME_ARGS (QTSAMPLE_PTS(stream, &stream->samples[kf_index])),
-	   GST_TIME_ARGS (QTSAMPLE_DTS(stream, &stream->samples[kf_index])));
+           "moving forwards to keyframe at %u (pts %" GST_TIME_FORMAT " dts %"GST_TIME_FORMAT" )", kf_index,
+           GST_TIME_ARGS (QTSAMPLE_PTS(stream, &stream->samples[kf_index])),
+           GST_TIME_ARGS (QTSAMPLE_DTS(stream, &stream->samples[kf_index])));
       gst_qtdemux_move_stream (qtdemux, stream, kf_index);
     } else {
       GST_DEBUG_OBJECT (stream->pad,
@@ -5450,7 +5491,10 @@
       GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
       GST_SEEK_TYPE_NONE, -1);
 
+  /* store seqnum to drop flush events, they don't need to reach downstream */
+  demux->offset_seek_seqnum = gst_event_get_seqnum (event);
   res = gst_pad_push_event (demux->sinkpad, event);
+  demux->offset_seek_seqnum = 0;
 
   return res;
 }
@@ -5508,6 +5552,62 @@
   demux->todrop -= bytes;
 }
 
+static void
+gst_qtdemux_check_send_pending_segment (GstQTDemux * demux)
+{
+  if (G_UNLIKELY (demux->pending_newsegment)) {
+    gint i;
+
+    gst_qtdemux_push_pending_newsegment (demux);
+    /* clear to send tags on all streams */
+    for (i = 0; i < demux->n_streams; i++) {
+      QtDemuxStream *stream;
+      stream = demux->streams[i];
+      gst_qtdemux_push_tags (demux, stream);
+      if (stream->sparse) {
+        GST_INFO_OBJECT (demux, "Sending gap event on stream %d", i);
+        gst_pad_push_event (stream->pad,
+            gst_event_new_gap (stream->segment.position, GST_CLOCK_TIME_NONE));
+      }
+    }
+  }
+}
+
+static void
+gst_qtdemux_stream_send_initial_gap_segments (GstQTDemux * demux,
+    QtDemuxStream * stream)
+{
+  gint i;
+
+  /* Push any initial gap segments before proceeding to the
+   * 'real' data */
+  for (i = 0; i < stream->n_segments; i++) {
+    gst_qtdemux_activate_segment (demux, stream, i, stream->time_position);
+
+    if (QTSEGMENT_IS_EMPTY (&stream->segments[i])) {
+      GstClockTime ts, dur;
+      GstEvent *gap;
+
+      ts = stream->time_position;
+      dur =
+          stream->segments[i].duration - (stream->time_position -
+          stream->segments[i].time);
+      gap = gst_event_new_gap (ts, dur);
+      stream->time_position += dur;
+
+      GST_DEBUG_OBJECT (stream->pad, "Pushing gap for empty "
+          "segment: %" GST_PTR_FORMAT, gap);
+      gst_pad_push_event (stream->pad, gap);
+    } else {
+      /* Only support empty segment at the beginning followed by
+       * one non-empty segment, this was checked when parsing the
+       * edts atom, arriving here is unexpected */
+      g_assert (i + 1 == stream->n_segments);
+      break;
+    }
+  }
+}
+
 static GstFlowReturn
 gst_qtdemux_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * inbuf)
 {
@@ -5677,6 +5777,8 @@
         extract_initial_length_and_fourcc (data, demux->neededbytes, NULL,
             &fourcc);
         if (fourcc == FOURCC_moov) {
+          gint n;
+
           /* in usual fragmented setup we could try to scan for more
            * and end up at the the moov (after mdat) again */
           if (demux->got_moov && demux->n_streams > 0 &&
@@ -5710,7 +5812,6 @@
             if (!demux->got_moov)
               qtdemux_expose_streams (demux);
             else {
-              gint n;
 
               for (n = 0; n < demux->n_streams; n++) {
                 QtDemuxStream *stream = demux->streams[n];
@@ -5720,6 +5821,15 @@
             }
 
             demux->got_moov = TRUE;
+            gst_qtdemux_check_send_pending_segment (demux);
+
+            /* fragmented streams headers shouldn't contain edts atoms */
+            if (!demux->fragmented) {
+              for (n = 0; n < demux->n_streams; n++) {
+                gst_qtdemux_stream_send_initial_gap_segments (demux,
+                    demux->streams[n]);
+              }
+            }
 
             g_node_destroy (demux->moov_node);
             demux->moov_node = NULL;
@@ -5945,20 +6055,7 @@
         /* first buffer? */
         /* initial newsegment sent here after having added pads,
          * possible others in sink_event */
-        if (G_UNLIKELY (demux->pending_newsegment)) {
-          gst_qtdemux_push_pending_newsegment (demux);
-          /* clear to send tags on all streams */
-          for (i = 0; i < demux->n_streams; i++) {
-            stream = demux->streams[i];
-            gst_qtdemux_push_tags (demux, stream);
-            if (stream->sparse) {
-              GST_INFO_OBJECT (demux, "Sending gap event on stream %d", i);
-              gst_pad_push_event (stream->pad,
-                  gst_event_new_gap (stream->segment.position,
-                      GST_CLOCK_TIME_NONE));
-            }
-          }
-        }
+        gst_qtdemux_check_send_pending_segment (demux);
 
         /* Figure out which stream this packet belongs to */
         for (i = 0; i < demux->n_streams; i++) {
@@ -6031,6 +6128,8 @@
 
           /* combine flows */
           ret = gst_qtdemux_combine_flows (demux, stream, ret);
+          if (ret != GST_FLOW_OK && ret != GST_FLOW_NOT_LINKED)
+            goto non_ok_unlinked_flow;
         } else {
           /* skip this data, stream is EOS */
           gst_adapter_flush (demux->adapter, demux->neededbytes);
@@ -6074,6 +6173,12 @@
   return ret;
 
   /* ERRORS */
+non_ok_unlinked_flow:
+  {
+    GST_DEBUG_OBJECT (demux, "Stopping, combined return flow %s",
+        gst_flow_get_name (ret));
+    return ret;
+  }
 unknown_stream:
   {
     GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL), ("unknown stream found"));
@@ -6237,7 +6342,7 @@
     method = QT_FOURCC ((guint8 *) dcom->data + 8);
     switch (method) {
 #ifdef HAVE_ZLIB
-      case GST_MAKE_FOURCC ('z', 'l', 'i', 'b'):{
+      case FOURCC_zlib:{
         guint uncompressed_length;
         guint compressed_length;
         guint8 *buf;
@@ -7855,6 +7960,10 @@
     GNode * trak)
 {
   GNode *edts;
+  /* accept edts if they contain gaps at start and there is only
+   * one media segment */
+  gboolean allow_pushbased_edts = TRUE;
+  gint media_segments_count = 0;
 
   /* parse and prepare segment info from the edit list */
   GST_DEBUG_OBJECT (qtdemux, "looking for edit list container");
@@ -7907,6 +8016,7 @@
       if (media_time != G_MAXUINT32) {
         segment->media_start = QTSTREAMTIME_TO_GSTTIME (stream, media_time);
         segment->media_stop = segment->media_start + segment->duration;
+        media_segments_count++;
       } else {
         segment->media_start = GST_CLOCK_TIME_NONE;
         segment->media_stop = GST_CLOCK_TIME_NONE;
@@ -7944,12 +8054,14 @@
     }
     GST_DEBUG_OBJECT (qtdemux, "found %d segments", count);
     stream->n_segments = count;
+    if (media_segments_count != 1)
+      allow_pushbased_edts = FALSE;
   }
 done:
 
   /* push based does not handle segments, so act accordingly here,
    * and warn if applicable */
-  if (!qtdemux->pullbased) {
+  if (!qtdemux->pullbased && !allow_pushbased_edts) {
     GST_WARNING_OBJECT (qtdemux, "streaming; discarding edit list segments");
     /* remove and use default one below, we stream like it anyway */
     g_free (stream->segments);
@@ -8208,7 +8320,7 @@
     goto bad_data;
   }
 
-  if (QT_FOURCC (map.data + 4) != GST_MAKE_FOURCC ('d', 'a', 'm', 'r')) {
+  if (QT_FOURCC (map.data + 4) != FOURCC_damr) {
     GST_DEBUG ("Unknown atom in %" GST_FOURCC_FORMAT,
         GST_FOURCC_ARGS (QT_UINT32 (map.data + 4)));
     goto bad_data;
@@ -8457,6 +8569,7 @@
   guint32 fourcc;
   guint value_size, stsd_len, len;
   guint32 track_id;
+  guint32 dummy;
 
   GST_DEBUG_OBJECT (qtdemux, "parse_trak");
 
@@ -8488,6 +8601,8 @@
     gst_qtdemux_stream_flush_segments_data (qtdemux, stream);
     gst_qtdemux_stream_flush_samples_data (qtdemux, stream);
   }
+  /* need defaults for fragments */
+  qtdemux_parse_trex (qtdemux, stream, &dummy, &dummy, &dummy);
 
   if (stream->pending_tags == NULL)
     stream->pending_tags = gst_tag_list_new_empty ();
@@ -9341,7 +9456,7 @@
           gst_buffer_unref (buf);
           break;
         }
-        case GST_MAKE_FOURCC ('v', 'c', '-', '1'):
+        case FOURCC_vc_1:
         {
           gint len = QT_UINT32 (stsd_data) - 0x66;
           const guint8 *vc1_data = stsd_data + 0x66;
@@ -9636,7 +9751,7 @@
         }
         break;
       }
-      case GST_MAKE_FOURCC ('w', 'm', 'a', ' '):
+      case FOURCC_wma_:
       {
         gint len = QT_UINT32 (stsd_data) - offset;
         const guint8 *wfex_data = stsd_data + offset;
@@ -9743,6 +9858,38 @@
         }
         break;
       }
+      case FOURCC_opus:
+      {
+        GNode *opus;
+        const guint8 *opus_data;
+        guint8 *channel_mapping = NULL;
+        guint32 rate;
+        guint8 channels;
+        guint8 channel_mapping_family;
+        guint8 stream_count;
+        guint8 coupled_count;
+        guint8 i;
+
+        opus = qtdemux_tree_get_child_by_type (stsd, FOURCC_opus);
+        opus_data = opus->data;
+
+        channels = GST_READ_UINT8 (opus_data + 45);
+        rate = GST_READ_UINT32_LE (opus_data + 48);
+        channel_mapping_family = GST_READ_UINT8 (opus_data + 54);
+        stream_count = GST_READ_UINT8 (opus_data + 55);
+        coupled_count = GST_READ_UINT8 (opus_data + 56);
+
+        if (channels > 0) {
+          channel_mapping = g_malloc (channels * sizeof (guint8));
+          for (i = 0; i < channels; i++)
+            channel_mapping[i] = GST_READ_UINT8 (opus_data + i + 57);
+        }
+
+        stream->caps = gst_codec_utils_opus_create_caps (rate, channels,
+            channel_mapping_family, stream_count, coupled_count,
+            channel_mapping);
+        break;
+      }
       default:
         break;
     }
@@ -10065,7 +10212,6 @@
     goto samples_failed;
 
   if (qtdemux->fragmented) {
-    guint32 dummy;
     guint64 offset;
 
     /* need all moov samples as basis; probably not many if any at all */
@@ -10083,8 +10229,6 @@
         GST_CLOCK_TIME_IS_VALID (qtdemux->segment.duration))
       stream->duration =
           GSTTIME_TO_QTSTREAMTIME (stream, qtdemux->segment.duration);
-    /* need defaults for fragments */
-    qtdemux_parse_trex (qtdemux, stream, &dummy, &dummy, &dummy);
   }
 
   /* configure segments */
@@ -10417,7 +10561,7 @@
 {
   if (major) {
     return ((qtdemux->major_brand & GST_MAKE_FOURCC (255, 255, 0, 0)) ==
-        GST_MAKE_FOURCC ('3', 'g', 0, 0));
+        FOURCC_3g__);
   } else if (qtdemux->comp_brands != NULL) {
     GstMapInfo map;
     guint8 *data;
@@ -10429,7 +10573,7 @@
     size = map.size;
     while (size >= 4) {
       res = res || ((QT_FOURCC (data) & GST_MAKE_FOURCC (255, 255, 0, 0)) ==
-          GST_MAKE_FOURCC ('3', 'g', 0, 0));
+          FOURCC_3g__);
       data += 4;
       size -= 4;
     }
@@ -11551,7 +11695,7 @@
 
   if (qtdemux->major_brand == FOURCC_mjp2)
     fmt = "Motion JPEG 2000";
-  else if ((qtdemux->major_brand & 0xffff) == GST_MAKE_FOURCC ('3', 'g', 0, 0))
+  else if ((qtdemux->major_brand & 0xffff) == FOURCC_3g__)
     fmt = "3GP";
   else if (qtdemux->major_brand == FOURCC_qt__)
     fmt = "Quicktime";
@@ -12012,7 +12156,7 @@
       _codec ("PNG still images");
       caps = gst_caps_new_empty_simple ("image/png");
       break;
-    case GST_MAKE_FOURCC ('j', 'p', 'e', 'g'):
+    case FOURCC_jpeg:
       _codec ("JPEG still images");
       caps =
           gst_caps_new_simple ("image/jpeg", "parsed", G_TYPE_BOOLEAN, TRUE,
@@ -12031,13 +12175,13 @@
       _codec ("Motion-JPEG format B");
       caps = gst_caps_new_empty_simple ("video/x-mjpeg-b");
       break;
-    case GST_MAKE_FOURCC ('m', 'j', 'p', '2'):
+    case FOURCC_mjp2:
       _codec ("JPEG-2000");
       /* override to what it should be according to spec, avoid palette_data */
       stream->bits_per_sample = 24;
       caps = gst_caps_new_simple ("image/x-j2c", "fields", G_TYPE_INT, 1, NULL);
       break;
-    case GST_MAKE_FOURCC ('S', 'V', 'Q', '3'):
+    case FOURCC_SVQ3:
       _codec ("Sorensen video v.3");
       caps = gst_caps_new_simple ("video/x-svq",
           "svqversion", G_TYPE_INT, 3, NULL);
@@ -12053,7 +12197,7 @@
       gst_caps_set_simple (caps, "format", G_TYPE_STRING, "RGB8P", NULL);
       _codec ("Windows Raw RGB");
       break;
-    case GST_MAKE_FOURCC ('r', 'a', 'w', ' '):
+    case FOURCC_raw_:
     {
       guint16 bps;
 
@@ -12084,7 +12228,7 @@
     case GST_MAKE_FOURCC ('Y', 'u', 'v', '2'):
       format = GST_VIDEO_FORMAT_I420;
       break;
-    case GST_MAKE_FOURCC ('2', 'v', 'u', 'y'):
+    case FOURCC_2vuy:
     case GST_MAKE_FOURCC ('2', 'V', 'u', 'y'):
       format = GST_VIDEO_FORMAT_UYVY;
       break;
@@ -12094,7 +12238,7 @@
     case GST_MAKE_FOURCC ('v', '2', '1', '6'):
       format = GST_VIDEO_FORMAT_v216;
       break;
-    case GST_MAKE_FOURCC ('v', '2', '1', '0'):
+    case FOURCC_v210:
       format = GST_VIDEO_FORMAT_v210;
       break;
     case GST_MAKE_FOURCC ('r', '2', '1', '0'):
@@ -12171,17 +12315,17 @@
       _codec ("GIF still images");
       caps = gst_caps_new_empty_simple ("image/gif");
       break;
-    case GST_MAKE_FOURCC ('h', '2', '6', '3'):
+    case FOURCC_h263:
     case GST_MAKE_FOURCC ('H', '2', '6', '3'):
-    case GST_MAKE_FOURCC ('s', '2', '6', '3'):
+    case FOURCC_s263:
     case GST_MAKE_FOURCC ('U', '2', '6', '3'):
       _codec ("H.263");
       /* ffmpeg uses the height/width props, don't know why */
       caps = gst_caps_new_simple ("video/x-h263",
           "variant", G_TYPE_STRING, "itu", NULL);
       break;
-    case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
-    case GST_MAKE_FOURCC ('M', 'P', '4', 'V'):
+    case FOURCC_mp4v:
+    case FOURCC_MP4V:
       _codec ("MPEG-4 video");
       caps = gst_caps_new_simple ("video/mpeg", "mpegversion", G_TYPE_INT, 4,
           "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
@@ -12209,16 +12353,21 @@
           "divxversion", G_TYPE_INT, 5, NULL);
       break;
 
+    case GST_MAKE_FOURCC ('F', 'F', 'V', '1'):
+      _codec ("FFV1");
+      caps = gst_caps_new_simple ("video/x-ffv",
+          "ffvversion", G_TYPE_INT, 1, NULL);
+      break;
+
     case GST_MAKE_FOURCC ('3', 'I', 'V', '1'):
     case GST_MAKE_FOURCC ('3', 'I', 'V', '2'):
     case GST_MAKE_FOURCC ('X', 'V', 'I', 'D'):
     case GST_MAKE_FOURCC ('x', 'v', 'i', 'd'):
-    case GST_MAKE_FOURCC ('F', 'M', 'P', '4'):
+    case FOURCC_FMP4:
     case GST_MAKE_FOURCC ('U', 'M', 'P', '4'):
       caps = gst_caps_new_simple ("video/mpeg",
           "mpegversion", G_TYPE_INT, 4, NULL);
-      if (codec_name)
-        *codec_name = g_strdup ("MPEG-4");
+      _codec ("MPEG-4");
       break;
 
     case GST_MAKE_FOURCC ('c', 'v', 'i', 'd'):
@@ -12233,38 +12382,38 @@
       _codec ("Apple video");
       caps = gst_caps_new_empty_simple ("video/x-apple-video");
       break;
-    case GST_MAKE_FOURCC ('H', '2', '6', '4'):
-    case GST_MAKE_FOURCC ('a', 'v', 'c', '1'):
+    case FOURCC_H264:
+    case FOURCC_avc1:
       _codec ("H.264 / AVC");
       caps = gst_caps_new_simple ("video/x-h264",
           "stream-format", G_TYPE_STRING, "avc",
           "alignment", G_TYPE_STRING, "au", NULL);
       break;
-    case GST_MAKE_FOURCC ('a', 'v', 'c', '3'):
+    case FOURCC_avc3:
       _codec ("H.264 / AVC");
       caps = gst_caps_new_simple ("video/x-h264",
           "stream-format", G_TYPE_STRING, "avc3",
           "alignment", G_TYPE_STRING, "au", NULL);
       break;
-    case GST_MAKE_FOURCC ('H', '2', '6', '5'):
-    case GST_MAKE_FOURCC ('h', 'v', 'c', '1'):
+    case FOURCC_H265:
+    case FOURCC_hvc1:
       _codec ("H.265 / HEVC");
       caps = gst_caps_new_simple ("video/x-h265",
           "stream-format", G_TYPE_STRING, "hvc1",
           "alignment", G_TYPE_STRING, "au", NULL);
       break;
-    case GST_MAKE_FOURCC ('h', 'e', 'v', '1'):
+    case FOURCC_hev1:
       _codec ("H.265 / HEVC");
       caps = gst_caps_new_simple ("video/x-h265",
           "stream-format", G_TYPE_STRING, "hev1",
           "alignment", G_TYPE_STRING, "au", NULL);
       break;
-    case GST_MAKE_FOURCC ('r', 'l', 'e', ' '):
+    case FOURCC_rle_:
       _codec ("Run-length encoding");
       caps = gst_caps_new_simple ("video/x-rle",
           "layout", G_TYPE_STRING, "quicktime", NULL);
       break;
-    case GST_MAKE_FOURCC ('W', 'R', 'L', 'E'):
+    case FOURCC_WRLE:
       _codec ("Run-length encoding");
       caps = gst_caps_new_simple ("video/x-rle",
           "layout", G_TYPE_STRING, "microsoft", NULL);
@@ -12281,8 +12430,8 @@
       caps = gst_caps_new_simple ("video/x-indeo",
           "indeoversion", G_TYPE_INT, 4, NULL);
       break;
-    case GST_MAKE_FOURCC ('d', 'v', 'c', 'p'):
-    case GST_MAKE_FOURCC ('d', 'v', 'c', ' '):
+    case FOURCC_dvcp:
+    case FOURCC_dvc_:
     case GST_MAKE_FOURCC ('d', 'v', 's', 'd'):
     case GST_MAKE_FOURCC ('D', 'V', 'S', 'D'):
     case GST_MAKE_FOURCC ('d', 'v', 'c', 's'):
@@ -12293,8 +12442,8 @@
       caps = gst_caps_new_simple ("video/x-dv", "dvversion", G_TYPE_INT, 25,
           "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
       break;
-    case GST_MAKE_FOURCC ('d', 'v', '5', 'n'): /* DVCPRO50 NTSC */
-    case GST_MAKE_FOURCC ('d', 'v', '5', 'p'): /* DVCPRO50 PAL */
+    case FOURCC_dv5n:          /* DVCPRO50 NTSC */
+    case FOURCC_dv5p:          /* DVCPRO50 PAL */
       _codec ("DVCPro50 Video");
       caps = gst_caps_new_simple ("video/x-dv", "dvversion", G_TYPE_INT, 50,
           "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
@@ -12317,14 +12466,14 @@
       _codec ("VP6 Flash");
       caps = gst_caps_new_empty_simple ("video/x-vp6-flash");
       break;
-    case GST_MAKE_FOURCC ('X', 'i', 'T', 'h'):
+    case FOURCC_XiTh:
       _codec ("Theora");
       caps = gst_caps_new_empty_simple ("video/x-theora");
       /* theora uses one byte of padding in the data stream because it does not
        * allow 0 sized packets while theora does */
       stream->padding = 1;
       break;
-    case GST_MAKE_FOURCC ('d', 'r', 'a', 'c'):
+    case FOURCC_drac:
       _codec ("Dirac");
       caps = gst_caps_new_empty_simple ("video/x-dirac");
       break;
@@ -12340,41 +12489,41 @@
       _codec ("AVID DNxHD");
       caps = gst_caps_from_string ("video/x-dnxhd");
       break;
-    case GST_MAKE_FOURCC ('V', 'P', '8', '0'):
+    case FOURCC_VP80:
       _codec ("On2 VP8");
       caps = gst_caps_from_string ("video/x-vp8");
       break;
-    case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
+    case FOURCC_apcs:
       _codec ("Apple ProRes LT");
       caps =
           gst_caps_new_simple ("video/x-prores", "variant", G_TYPE_STRING, "lt",
           NULL);
       break;
-    case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
+    case FOURCC_apch:
       _codec ("Apple ProRes HQ");
       caps =
           gst_caps_new_simple ("video/x-prores", "variant", G_TYPE_STRING, "hq",
           NULL);
       break;
-    case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
+    case FOURCC_apcn:
       _codec ("Apple ProRes");
       caps =
           gst_caps_new_simple ("video/x-prores", "variant", G_TYPE_STRING,
           "standard", NULL);
       break;
-    case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
+    case FOURCC_apco:
       _codec ("Apple ProRes Proxy");
       caps =
           gst_caps_new_simple ("video/x-prores", "variant", G_TYPE_STRING,
           "proxy", NULL);
       break;
-    case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
+    case FOURCC_ap4h:
       _codec ("Apple ProRes 4444");
       caps =
           gst_caps_new_simple ("video/x-prores", "variant", G_TYPE_STRING,
           "4444", NULL);
       break;
-    case GST_MAKE_FOURCC ('v', 'c', '-', '1'):
+    case FOURCC_vc_1:
     case FOURCC_ovc1:
       _codec ("VC-1");
       caps = gst_caps_new_simple ("video/x-wmv",
@@ -12388,6 +12537,7 @@
       g_snprintf (fourstr, 5, "%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc));
       s = g_strdup_printf ("video/x-gst-fourcc-%s", g_strstrip (fourstr));
       caps = gst_caps_new_empty_simple (s);
+      g_free (s);
       break;
     }
   }
@@ -12425,15 +12575,15 @@
 
   switch (fourcc) {
     case GST_MAKE_FOURCC ('N', 'O', 'N', 'E'):
-    case GST_MAKE_FOURCC ('r', 'a', 'w', ' '):
+    case FOURCC_raw_:
       /* 8-bit audio is unsigned */
       if (depth == 8)
         format = GST_AUDIO_FORMAT_U8;
       /* otherwise it's signed and big-endian just like 'twos' */
-    case GST_MAKE_FOURCC ('t', 'w', 'o', 's'):
+    case FOURCC_twos:
       endian = G_BIG_ENDIAN;
       /* fall-through */
-    case GST_MAKE_FOURCC ('s', 'o', 'w', 't'):
+    case FOURCC_sowt:
     {
       gchar *str;
 
@@ -12478,11 +12628,11 @@
           "format", G_TYPE_STRING, "S32BE",
           "layout", G_TYPE_STRING, "interleaved", NULL);
       break;
-    case GST_MAKE_FOURCC ('u', 'l', 'a', 'w'):
+    case FOURCC_ulaw:
       _codec ("Mu-law audio");
       caps = gst_caps_new_empty_simple ("audio/x-mulaw");
       break;
-    case GST_MAKE_FOURCC ('a', 'l', 'a', 'w'):
+    case FOURCC_alaw:
       _codec ("A-law audio");
       caps = gst_caps_new_empty_simple ("audio/x-alaw");
       break;
@@ -12509,7 +12659,7 @@
     case 0x5500736d:
     case 0x6d730055:
       /* MPEG layer 3, CBR only (pre QT4.1) */
-    case GST_MAKE_FOURCC ('.', 'm', 'p', '3'):
+    case FOURCC__mp3:
       _codec ("MPEG-1 layer 3");
       /* MPEG layer 3, CBR & VBR (QT4.1 and later) */
       caps = gst_caps_new_simple ("audio/mpeg", "layer", G_TYPE_INT, 3,
@@ -12523,7 +12673,7 @@
       stream->sampled = TRUE;
       break;
     case GST_MAKE_FOURCC ('s', 'a', 'c', '3'): // Nero Recode
-    case GST_MAKE_FOURCC ('a', 'c', '-', '3'):
+    case FOURCC_ac_3:
       _codec ("AC-3 audio");
       caps = gst_caps_new_simple ("audio/x-ac3",
           "framed", G_TYPE_BOOLEAN, TRUE, NULL);
@@ -12543,12 +12693,12 @@
           "framed", G_TYPE_BOOLEAN, TRUE, NULL);
       stream->sampled = TRUE;
       break;
-    case GST_MAKE_FOURCC ('M', 'A', 'C', '3'):
+    case FOURCC_MAC3:
       _codec ("MACE-3");
       caps = gst_caps_new_simple ("audio/x-mace",
           "maceversion", G_TYPE_INT, 3, NULL);
       break;
-    case GST_MAKE_FOURCC ('M', 'A', 'C', '6'):
+    case FOURCC_MAC6:
       _codec ("MACE-6");
       caps = gst_caps_new_simple ("audio/x-mace",
           "maceversion", G_TYPE_INT, 6, NULL);
@@ -12561,7 +12711,7 @@
       _codec ("DV audio");
       caps = gst_caps_new_empty_simple ("audio/x-dv");
       break;
-    case GST_MAKE_FOURCC ('m', 'p', '4', 'a'):
+    case FOURCC_mp4a:
       _codec ("MPEG-4 AAC audio");
       caps = gst_caps_new_simple ("audio/mpeg",
           "mpegversion", G_TYPE_INT, 4, "framed", G_TYPE_BOOLEAN, TRUE,
@@ -12571,7 +12721,7 @@
       _codec ("QDesign Music");
       caps = gst_caps_new_empty_simple ("audio/x-qdm");
       break;
-    case GST_MAKE_FOURCC ('Q', 'D', 'M', '2'):
+    case FOURCC_QDM2:
       _codec ("QDesign Music v.2");
       /* FIXME: QDesign music version 2 (no constant) */
       if (FALSE && data) {
@@ -12583,24 +12733,24 @@
         caps = gst_caps_new_empty_simple ("audio/x-qdm2");
       }
       break;
-    case GST_MAKE_FOURCC ('a', 'g', 's', 'm'):
+    case FOURCC_agsm:
       _codec ("GSM audio");
       caps = gst_caps_new_empty_simple ("audio/x-gsm");
       break;
-    case GST_MAKE_FOURCC ('s', 'a', 'm', 'r'):
+    case FOURCC_samr:
       _codec ("AMR audio");
       caps = gst_caps_new_empty_simple ("audio/AMR");
       break;
-    case GST_MAKE_FOURCC ('s', 'a', 'w', 'b'):
+    case FOURCC_sawb:
       _codec ("AMR-WB audio");
       caps = gst_caps_new_empty_simple ("audio/AMR-WB");
       break;
-    case GST_MAKE_FOURCC ('i', 'm', 'a', '4'):
+    case FOURCC_ima4:
       _codec ("Quicktime IMA ADPCM");
       caps = gst_caps_new_simple ("audio/x-adpcm",
           "layout", G_TYPE_STRING, "quicktime", NULL);
       break;
-    case GST_MAKE_FOURCC ('a', 'l', 'a', 'c'):
+    case FOURCC_alac:
       _codec ("Apple lossless audio");
       caps = gst_caps_new_empty_simple ("audio/x-alac");
       break;
@@ -12608,11 +12758,15 @@
       _codec ("QualComm PureVoice");
       caps = gst_caps_from_string ("audio/qcelp");
       break;
-    case GST_MAKE_FOURCC ('w', 'm', 'a', ' '):
+    case FOURCC_wma_:
     case FOURCC_owma:
       _codec ("WMA");
       caps = gst_caps_new_empty_simple ("audio/x-wma");
       break;
+    case FOURCC_opus:
+      _codec ("Opus");
+      caps = gst_caps_new_empty_simple ("audio/x-opus");
+      break;
     case GST_MAKE_FOURCC ('l', 'p', 'c', 'm'):
     {
       guint32 flags = 0;
@@ -12677,6 +12831,7 @@
       g_snprintf (fourstr, 5, "%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc));
       s = g_strdup_printf ("audio/x-gst-fourcc-%s", g_strstrip (fourstr));
       caps = gst_caps_new_empty_simple (s);
+      g_free (s);
       break;
     }
   }
@@ -12710,15 +12865,15 @@
   GST_DEBUG_OBJECT (qtdemux, "resolve fourcc 0x%08x", GUINT32_TO_BE (fourcc));
 
   switch (fourcc) {
-    case GST_MAKE_FOURCC ('m', 'p', '4', 's'):
+    case FOURCC_mp4s:
       _codec ("DVD subtitle");
       caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
       stream->need_process = TRUE;
       break;
-    case GST_MAKE_FOURCC ('t', 'e', 'x', 't'):
+    case FOURCC_text:
       _codec ("Quicktime timed text");
       goto text;
-    case GST_MAKE_FOURCC ('t', 'x', '3', 'g'):
+    case FOURCC_tx3g:
       _codec ("3GPP timed text");
     text:
       caps = gst_caps_new_simple ("text/x-raw", "format", G_TYPE_STRING,
@@ -12726,6 +12881,10 @@
       /* actual text piece needs to be extracted */
       stream->need_process = TRUE;
       break;
+    case FOURCC_stpp:
+      _codec ("XML subtitles");
+      caps = gst_caps_new_empty_simple ("application/ttml+xml");
+      break;
     default:
     {
       char *s, fourstr[5];
@@ -12733,6 +12892,7 @@
       g_snprintf (fourstr, 5, "%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc));
       s = g_strdup_printf ("text/x-gst-fourcc-%s", g_strstrip (fourstr));
       caps = gst_caps_new_empty_simple (s);
+      g_free (s);
       break;
     }
   }
@@ -12746,7 +12906,7 @@
   GstCaps *caps;
 
   switch (fourcc) {
-    case GST_MAKE_FOURCC ('m', '1', 'v', ' '):
+    case FOURCC_m1v:
       _codec ("MPEG 1 video");
       caps = gst_caps_new_simple ("video/mpeg", "mpegversion", G_TYPE_INT, 1,
           "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
diff --git a/gst/isomp4/qtdemux.h b/gst/isomp4/qtdemux.h
index 05cd806..53bd071 100644
--- a/gst/isomp4/qtdemux.h
+++ b/gst/isomp4/qtdemux.h
@@ -121,6 +121,7 @@
                                      * newsegment in TIME format which likely
                                      * means that upstream is driving the pipeline
                                      * (adaptive demuxers / dlna) */
+  guint32 offset_seek_seqnum;
   gint64 seek_offset;
   gint64 push_seek_start;
   gint64 push_seek_stop;
diff --git a/gst/isomp4/qtdemux_types.c b/gst/isomp4/qtdemux_types.c
index 8e8189d..dc71228 100644
--- a/gst/isomp4/qtdemux_types.c
+++ b/gst/isomp4/qtdemux_types.c
@@ -201,6 +201,7 @@
   {FOURCC_schi, "scheme information", QT_FLAG_CONTAINER},
   {FOURCC_pssh, "protection system specific header", 0},
   {FOURCC_tenc, "track encryption", 0},
+  {FOURCC_stpp, "XML subtitle sample entry", 0},
   {0, "unknown", 0,},
 };
 
diff --git a/gst/law/Makefile.in b/gst/law/Makefile.in
index 04584df..6b1e5d2 100644
--- a/gst/law/Makefile.in
+++ b/gst/law/Makefile.in
@@ -487,6 +487,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/level/Makefile.in b/gst/level/Makefile.in
index 3401aea..4f4f4cc 100644
--- a/gst/level/Makefile.in
+++ b/gst/level/Makefile.in
@@ -476,6 +476,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/matroska/Makefile.in b/gst/matroska/Makefile.in
index 38835ca..6ea5d6e 100644
--- a/gst/matroska/Makefile.in
+++ b/gst/matroska/Makefile.in
@@ -485,6 +485,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/matroska/ebml-write.c b/gst/matroska/ebml-write.c
index d123f2c..08e93bc 100644
--- a/gst/matroska/ebml-write.c
+++ b/gst/matroska/ebml-write.c
@@ -215,7 +215,8 @@
 
   GST_INFO ("seeking to %" G_GUINT64_FORMAT, new_pos);
 
-  gst_segment_init (&segment, GST_FORMAT_BYTES);
+  gst_segment_init (&segment,
+      ebml->streamable ? GST_FORMAT_TIME : GST_FORMAT_BYTES);
   segment.start = new_pos;
   segment.stop = -1;
   segment.position = 0;
diff --git a/gst/matroska/ebml-write.h b/gst/matroska/ebml-write.h
index 2dbe350..c7143fe 100644
--- a/gst/matroska/ebml-write.h
+++ b/gst/matroska/ebml-write.h
@@ -60,6 +60,8 @@
   guint64 streamheader_pos;
 
   GstCaps *caps;
+
+  gboolean streamable;
 } GstEbmlWrite;
 
 typedef struct _GstEbmlWriteClass {
diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
index 2fb4928..6c6933b 100644
--- a/gst/matroska/matroska-demux.c
+++ b/gst/matroska/matroska-demux.c
@@ -940,6 +940,34 @@
         break;
       }
 
+        /* codec delay */
+      case GST_MATROSKA_ID_CODECDELAY:{
+        guint64 num;
+
+        if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
+          break;
+
+        context->codec_delay = num;
+
+        GST_DEBUG_OBJECT (demux, "CodecDelay: %" GST_TIME_FORMAT,
+            GST_TIME_ARGS (num));
+        break;
+      }
+
+        /* codec delay */
+      case GST_MATROSKA_ID_SEEKPREROLL:{
+        guint64 num;
+
+        if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
+          break;
+
+        context->seek_preroll = num;
+
+        GST_DEBUG_OBJECT (demux, "SeekPreroll: %" GST_TIME_FORMAT,
+            GST_TIME_ARGS (num));
+        break;
+      }
+
         /* name of this track */
       case GST_MATROSKA_ID_TRACKNAME:{
         gchar *text;
@@ -2943,6 +2971,33 @@
   return GST_FLOW_OK;
 }
 
+static GstFlowReturn
+gst_matroska_demux_add_prores_header (GstElement * element,
+    GstMatroskaTrackContext * stream, GstBuffer ** buf)
+{
+  GstBuffer *newbuf = gst_buffer_new_allocate (NULL, 8, NULL);
+  GstMapInfo map;
+  guint32 frame_size;
+
+  if (!gst_buffer_map (newbuf, &map, GST_MAP_WRITE)) {
+    GST_ERROR ("Failed to map newly allocated buffer");
+    return GST_FLOW_ERROR;
+  }
+
+  frame_size = gst_buffer_get_size (*buf);
+
+  GST_WRITE_UINT32_BE (map.data, frame_size);
+  map.data[4] = 'i';
+  map.data[5] = 'c';
+  map.data[6] = 'p';
+  map.data[7] = 'f';
+
+  gst_buffer_unmap (newbuf, &map);
+  *buf = gst_buffer_append (newbuf, *buf);
+
+  return GST_FLOW_OK;
+}
+
 /* @text must be null-terminated */
 static gboolean
 gst_matroska_demux_subtitle_chunk_has_tag (GstElement * element,
@@ -3162,6 +3217,7 @@
   gboolean readblock = FALSE;
   guint32 id;
   guint64 block_duration = -1;
+  gint64 block_discardpadding = 0;
   GstBuffer *buf = NULL;
   GstMapInfo map;
   gint stream_num = -1, n, laces = 0;
@@ -3326,6 +3382,13 @@
         break;
       }
 
+      case GST_MATROSKA_ID_DISCARDPADDING:{
+        ret = gst_ebml_read_sint (ebml, &id, &block_discardpadding);
+        GST_DEBUG_OBJECT (demux, "DiscardPadding: %" GST_STIME_FORMAT,
+            GST_STIME_ARGS (block_discardpadding));
+        break;
+      }
+
       case GST_MATROSKA_ID_REFERENCEBLOCK:{
         ret = gst_ebml_read_sint (ebml, &id, &referenceblock);
         GST_DEBUG_OBJECT (demux, "ReferenceBlock: %" G_GINT64_FORMAT,
@@ -3505,7 +3568,8 @@
         GST_OBJECT_LOCK (demux);
         earliest_time = videocontext->earliest_time;
         GST_OBJECT_UNLOCK (demux);
-        earliest_stream_time = gst_segment_to_position (&demux->common.segment,
+        earliest_stream_time =
+            gst_segment_position_from_running_time (&demux->common.segment,
             GST_FORMAT_TIME, earliest_time);
 
         if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
@@ -3550,8 +3614,6 @@
         goto next_lace;
       }
 
-      buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
-
       if (!stream->dts_only) {
         GST_BUFFER_PTS (sub) = lace_time;
       } else {
@@ -3560,6 +3622,8 @@
           GST_BUFFER_PTS (sub) = lace_time;
       }
 
+      buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
+
       if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
         GstClockTime last_stop_end;
 
@@ -3702,6 +3766,40 @@
          Therefore, create an aligned copy if necessary. */
       sub = gst_matroska_demux_align_buffer (demux, sub, stream->alignment);
 
+      if (!strcmp (stream->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
+        guint64 start_clip = 0, end_clip = 0;
+
+        /* Codec delay is part of the timestamps */
+        if (GST_BUFFER_PTS_IS_VALID (sub) && stream->codec_delay) {
+          if (GST_BUFFER_PTS (sub) > stream->codec_delay) {
+            GST_BUFFER_PTS (sub) -= stream->codec_delay;
+          } else {
+            GST_BUFFER_PTS (sub) = 0;
+            start_clip =
+                gst_util_uint64_scale_round (stream->codec_delay, 48000,
+                GST_SECOND);
+
+            if (GST_BUFFER_DURATION_IS_VALID (sub)) {
+              if (GST_BUFFER_DURATION (sub) > stream->codec_delay)
+                GST_BUFFER_DURATION (sub) -= stream->codec_delay;
+              else
+                GST_BUFFER_DURATION (sub) = 0;
+            }
+          }
+        }
+
+        if (block_discardpadding) {
+          end_clip =
+              gst_util_uint64_scale_round (block_discardpadding, 48000,
+              GST_SECOND);
+        }
+
+        if (start_clip || end_clip) {
+          gst_buffer_add_audio_clipping_meta (sub, GST_FORMAT_DEFAULT,
+              start_clip, end_clip);
+        }
+      }
+
       if (GST_BUFFER_PTS_IS_VALID (sub)) {
         stream->pos = GST_BUFFER_PTS (sub);
         if (GST_BUFFER_DURATION_IS_VALID (sub))
@@ -5157,6 +5255,48 @@
   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_VP9)) {
     caps = gst_caps_new_empty_simple ("video/x-vp9");
     *codec_name = g_strdup_printf ("On2 VP9");
+  } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_VIDEO_PRORES)) {
+    guint32 fourcc;
+    const gchar *variant, *variant_descr = "";
+
+    /* Expect a fourcc in the codec private data */
+    if (size < 4) {
+      GST_WARNING ("Too small PRORESS fourcc (%d bytes)", size);
+      return NULL;
+    }
+
+    fourcc = GST_STR_FOURCC (data);
+    switch (fourcc) {
+      case GST_MAKE_FOURCC ('a', 'p', 'c', 's'):
+        variant_descr = " 4:2:2 LT";
+        variant = "lt";
+        break;
+      case GST_MAKE_FOURCC ('a', 'p', 'c', 'h'):
+        variant = "hq";
+        variant_descr = " 4:2:2 HQ";
+        break;
+      case GST_MAKE_FOURCC ('a', 'p', '4', 'h'):
+        variant = "4444";
+        variant_descr = " 4:4:4:4";
+        break;
+      case GST_MAKE_FOURCC ('a', 'p', 'c', 'o'):
+        variant = "proxy";
+        variant_descr = " 4:2:2 Proxy";
+        break;
+      case GST_MAKE_FOURCC ('a', 'p', 'c', 'n'):
+      default:
+        variant = "standard";
+        variant_descr = " 4:2:2 SD";
+        break;
+    }
+
+    GST_LOG ("Prores video, codec fourcc %" GST_FOURCC_FORMAT,
+        GST_FOURCC_ARGS (fourcc));
+
+    caps = gst_caps_new_simple ("video/x-prores",
+        "format", G_TYPE_STRING, variant, NULL);
+    *codec_name = g_strdup_printf ("Apple ProRes%s", variant_descr);
+    context->postprocess_frame = gst_matroska_demux_add_prores_header;
   } else {
     GST_WARNING ("Unknown codec '%s', cannot build Caps", codec_id);
     return NULL;
@@ -5377,7 +5517,9 @@
     /* FIXME: Channel mask and reordering */
     caps = gst_caps_new_simple ("audio/x-raw",
         "format", G_TYPE_STRING, gst_audio_format_to_string (format),
-        "layout", G_TYPE_STRING, "interleaved", NULL);
+        "layout", G_TYPE_STRING, "interleaved",
+        "channel-mask", GST_TYPE_BITMASK,
+        gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
 
     *codec_name = g_strdup_printf ("Raw %d-bit PCM audio",
         audiocontext->bitdepth);
@@ -5392,7 +5534,9 @@
     /* FIXME: Channel mask and reordering */
     caps = gst_caps_new_simple ("audio/x-raw",
         "format", G_TYPE_STRING, format,
-        "layout", G_TYPE_STRING, "interleaved", NULL);
+        "layout", G_TYPE_STRING, "interleaved",
+        "channel-mask", GST_TYPE_BITMASK,
+        gst_audio_channel_get_fallback_mask (audiocontext->channels), NULL);
     *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio",
         audiocontext->bitdepth);
     context->alignment = audiocontext->bitdepth / 8;
@@ -5436,20 +5580,28 @@
     /* FIXME: mark stream as broken and skip if there are no stream headers */
     context->send_stream_headers = TRUE;
   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
-    caps = gst_caps_new_empty_simple ("audio/x-opus");
-    *codec_name = g_strdup ("Opus");
-    context->stream_headers =
-        gst_matroska_parse_opus_stream_headers (context->codec_priv,
-        context->codec_priv_size);
-    if (context->stream_headers) {
-      /* There was a valid header. Multistream headers are more than
-       * 19 bytes, as they include an extra channel mapping table. */
-      gboolean multistream = (context->codec_priv_size > 19);
-      gst_caps_set_simple (caps, "multistream", G_TYPE_BOOLEAN, multistream,
-          NULL);
+    GstBuffer *tmp;
+
+    if (context->codec_priv_size >= 19) {
+      if (audiocontext->samplerate)
+        GST_WRITE_UINT32_LE ((guint8 *) context->codec_priv + 12,
+            audiocontext->samplerate);
+      if (context->codec_delay) {
+        guint64 delay =
+            gst_util_uint64_scale_round (context->codec_delay, 48000,
+            GST_SECOND);
+        GST_WRITE_UINT16_LE ((guint8 *) context->codec_priv + 10, delay);
+      }
+
+      tmp =
+          gst_buffer_new_wrapped (g_memdup (context->codec_priv,
+              context->codec_priv_size), context->codec_priv_size);
+      caps = gst_codec_utils_opus_create_caps_from_header (tmp, NULL);
+      gst_buffer_unref (tmp);
+      *codec_name = g_strdup ("Opus");
+    } else {
+      GST_WARNING ("Invalid Opus codec data size");
     }
-    /* FIXME: mark stream as broken and skip if there are no stream headers */
-    context->send_stream_headers = TRUE;
   } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
     gst_riff_strf_auds auds;
 
diff --git a/gst/matroska/matroska-ids.c b/gst/matroska/matroska-ids.c
index 273d4e1..74b4147 100644
--- a/gst/matroska/matroska-ids.c
+++ b/gst/matroska/matroska-ids.c
@@ -305,10 +305,7 @@
     GstBuffer * buf)
 {
   if (track->dts_only) {
-    if (GST_BUFFER_DTS_IS_VALID (buf))
-      return GST_BUFFER_DTS (buf);
-    else
-      return GST_BUFFER_PTS (buf);
+    return GST_BUFFER_DTS_OR_PTS (buf);
   } else {
     return GST_BUFFER_PTS (buf);
   }
diff --git a/gst/matroska/matroska-ids.h b/gst/matroska/matroska-ids.h
index 661a4a1..c4419c2 100644
--- a/gst/matroska/matroska-ids.h
+++ b/gst/matroska/matroska-ids.h
@@ -109,6 +109,8 @@
 #define GST_MATROSKA_ID_CODECDOWNLOADURL           0x26B240
 /* semi-draft */
 #define GST_MATROSKA_ID_CODECDECODEALL             0xAA
+#define GST_MATROSKA_ID_SEEKPREROLL                0x56BB
+#define GST_MATROSKA_ID_CODECDELAY                 0x56AA
 
 /* IDs in the TrackTranslate master */
 #define GST_MATROSKA_ID_TRACKTRANSLATEEDITIONUID   0x66FC
@@ -249,6 +251,7 @@
 /* semi-draft */
 #define GST_MATROSKA_ID_CODECSTATE                 0xA4
 #define GST_MATROSKA_ID_SLICES                     0x8E
+#define GST_MATROSKA_ID_DISCARDPADDING             0x75A2
 
 /* IDs in the BlockAdditions master */
 #define GST_MATROSKA_ID_BLOCKMORE                  0xA6
@@ -348,6 +351,7 @@
 #define GST_MATROSKA_CODEC_ID_VIDEO_VP8          "V_VP8"
 #define GST_MATROSKA_CODEC_ID_VIDEO_VP9          "V_VP9"
 #define GST_MATROSKA_CODEC_ID_VIDEO_MPEGH_HEVC   "V_MPEGH/ISO/HEVC"
+#define GST_MATROSKA_CODEC_ID_VIDEO_PRORES       "V_PRORES"
 
 #define GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L1       "A_MPEG/L1"
 #define GST_MATROSKA_CODEC_ID_AUDIO_MPEG1_L2       "A_MPEG/L2"
@@ -530,6 +534,8 @@
   guint64       default_duration;
   guint64       pos;
   gdouble       timecodescale;
+  guint64       seek_preroll;
+  guint64       codec_delay;
 
   gboolean      set_discont; /* TRUE = set DISCONT flag on next buffer */
 
diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c
index 622f85a..399ba4e 100644
--- a/gst/matroska/matroska-mux.c
+++ b/gst/matroska/matroska-mux.c
@@ -125,9 +125,13 @@
         COMMON_VIDEO_CAPS "; "
         "video/x-vp8, "
         COMMON_VIDEO_CAPS "; "
+        "video/x-vp9, "
+        COMMON_VIDEO_CAPS "; "
         "video/x-raw, "
         "format = (string) { YUY2, I420, YV12, UYVY, AYUV, GRAY8, BGR, RGB }, "
         COMMON_VIDEO_CAPS "; "
+        "video/x-prores, "
+        COMMON_VIDEO_CAPS "; "
         "video/x-wmv, " "wmvversion = (int) [ 1, 3 ], " COMMON_VIDEO_CAPS)
     );
 
@@ -456,7 +460,7 @@
   mux->doctype_version = DEFAULT_DOCTYPE_VERSION;
   mux->writing_app = g_strdup (DEFAULT_WRITING_APP);
   mux->min_index_interval = DEFAULT_MIN_INDEX_INTERVAL;
-  mux->streamable = DEFAULT_STREAMABLE;
+  mux->ebml_write->streamable = DEFAULT_STREAMABLE;
 
   /* initialize internal variables */
   mux->index = NULL;
@@ -488,8 +492,7 @@
 
   gst_object_unref (mux->collect);
   gst_object_unref (mux->ebml_write);
-  if (mux->writing_app)
-    g_free (mux->writing_app);
+  g_free (mux->writing_app);
 
   g_array_free (mux->used_uids, TRUE);
 
@@ -906,8 +909,7 @@
     const char *id)
 {
   g_assert (context && id);
-  if (context->codec_id)
-    g_free (context->codec_id);
+  g_free (context->codec_id);
   context->codec_id = g_strdup (id);
 }
 
@@ -1249,6 +1251,30 @@
       context->codec_priv = priv_data;
       context->codec_priv_size = priv_data_size;
     }
+  } else if (strcmp (mimetype, "video/x-prores") == 0) {
+    const gchar *variant;
+
+    gst_matroska_mux_free_codec_priv (context);
+
+    variant = gst_structure_get_string (structure, "format");
+    if (!variant || !g_strcmp0 (variant, "standard"))
+      context->codec_priv = g_strdup ("apcn");
+    else if (!g_strcmp0 (variant, "hq"))
+      context->codec_priv = g_strdup ("apch");
+    else if (!g_strcmp0 (variant, "lt"))
+      context->codec_priv = g_strdup ("apcs");
+    else if (!g_strcmp0 (variant, "proxy"))
+      context->codec_priv = g_strdup ("apco");
+    else if (!g_strcmp0 (variant, "4444"))
+      context->codec_priv = g_strdup ("ap4h");
+    else {
+      GST_WARNING_OBJECT (mux, "Unhandled prores format: %s", variant);
+
+      goto refuse_caps;
+    }
+
+    context->codec_priv_size = sizeof (guint32);
+    gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_VIDEO_PRORES);
   }
 
   return TRUE;
@@ -1616,12 +1642,11 @@
     goto wrong_type;
 
   bufarr = g_value_peek_pointer (streamheader);
-  if (bufarr->len <= 0 || bufarr->len > 255)    /* one header, and count stored in a byte */
-    goto wrong_count;
-  if (bufarr->len != 1 && bufarr->len != 2)
+  if (bufarr->len != 1 && bufarr->len != 2)     /* one header, and count stored in a byte */
     goto wrong_count;
 
-  context->xiph_headers_to_skip = bufarr->len;
+  /* Opus headers are not in-band */
+  context->xiph_headers_to_skip = 0;
 
   bufval = &g_array_index (bufarr, GValue, 0);
   if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
@@ -1635,6 +1660,12 @@
   context->codec_priv = g_malloc0 (context->codec_priv_size);
   gst_buffer_extract (buf, 0, context->codec_priv, -1);
 
+  context->codec_delay =
+      GST_READ_UINT16_LE ((guint8 *) context->codec_priv + 10);
+  context->codec_delay =
+      gst_util_uint64_scale_round (context->codec_delay, GST_SECOND, 48000);
+  context->seek_preroll = 80 * GST_MSECOND;
+
   return TRUE;
 
 /* ERRORS */
@@ -2509,6 +2540,7 @@
         gst_ebml_write_uint (ebml, GST_MATROSKA_ID_AUDIOBITDEPTH,
             audiocontext->bitdepth);
       }
+
       gst_ebml_write_master_finish (ebml, master);
 
       break;
@@ -2526,6 +2558,16 @@
   if (context->codec_priv)
     gst_ebml_write_binary (ebml, GST_MATROSKA_ID_CODECPRIVATE,
         context->codec_priv, context->codec_priv_size);
+
+  if (context->seek_preroll) {
+    gst_ebml_write_uint (ebml, GST_MATROSKA_ID_SEEKPREROLL,
+        context->seek_preroll);
+  }
+
+  if (context->codec_delay) {
+    gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CODECDELAY,
+        context->codec_delay);
+  }
 }
 
 #if 0
@@ -2668,7 +2710,7 @@
 #endif
 
   /* if not streaming, check if downstream is seekable */
-  if (!mux->streamable) {
+  if (!mux->ebml_write->streamable) {
     gboolean seekable;
     GstQuery *query;
 
@@ -2682,7 +2724,7 @@
       seekable = FALSE;
     }
     if (!seekable) {
-      mux->streamable = TRUE;
+      mux->ebml_write->streamable = TRUE;
       g_object_notify (G_OBJECT (mux), "streamable");
       GST_WARNING_OBJECT (mux, "downstream is not seekable, but "
           "streamable=false. Will ignore that and create streamable output "
@@ -2718,7 +2760,7 @@
       gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEGMENT);
   mux->segment_master = ebml->pos;
 
-  if (!mux->streamable) {
+  if (!mux->ebml_write->streamable) {
     /* seekhead (table of contents) - we set the positions later */
     mux->seekhead_pos = ebml->pos;
     master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_SEEKHEAD);
@@ -2731,7 +2773,7 @@
     gst_ebml_write_master_finish (ebml, master);
   }
 
-  if (mux->streamable) {
+  if (mux->ebml_write->streamable) {
     const GstTagList *tags;
     gboolean has_main_tags;
 
@@ -2772,7 +2814,7 @@
   gst_ebml_write_uint (ebml, GST_MATROSKA_ID_TIMECODESCALE, mux->time_scale);
   mux->duration_pos = ebml->pos;
   /* get duration */
-  if (!mux->streamable) {
+  if (!mux->ebml_write->streamable) {
     for (collected = mux->collect->data; collected;
         collected = g_slist_next (collected)) {
       GstMatroskaPad *collect_pad;
@@ -2836,7 +2878,7 @@
 #if 0
   /* chapters */
   toc = gst_toc_setter_get_toc (GST_TOC_SETTER (mux));
-  if (toc != NULL && !mux->streamable) {
+  if (toc != NULL && !mux->ebml_write->streamable) {
     guint64 master_chapters = 0;
     GstTocEntry *toc_entry;
     GList *cur, *to_write = NULL;
@@ -3427,12 +3469,13 @@
   gboolean write_duration;
   gint16 relative_timestamp;
   gint64 relative_timestamp64;
-  guint64 block_duration;
+  guint64 block_duration, duration_diff = 0;
   gboolean is_video_keyframe = FALSE;
   gboolean is_video_invisible = FALSE;
   GstMatroskamuxPad *pad;
   gint flags = 0;
   GstClockTime buffer_timestamp;
+  GstAudioClippingMeta *cmeta = NULL;
 
   /* write data */
   pad = GST_MATROSKAMUX_PAD_CAST (collect_pad->collect.pad);
@@ -3452,6 +3495,11 @@
     buf = gst_matroska_mux_handle_dirac_packet (mux, collect_pad, buf);
     if (!buf)
       return GST_FLOW_OK;
+  } else if (strcmp (collect_pad->track->codec_id,
+          GST_MATROSKA_CODEC_ID_VIDEO_PRORES) == 0) {
+    /* Remove the 'Frame container atom' header' */
+    buf = gst_buffer_make_writable (buf);
+    gst_buffer_resize (buf, 8, gst_buffer_get_size (buf) - 8);
   }
 
   buffer_timestamp =
@@ -3468,6 +3516,17 @@
     return GST_FLOW_OK;
   }
 
+  if (!strcmp (collect_pad->track->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)
+      && collect_pad->track->codec_delay) {
+    /* All timestamps should include the codec delay */
+    if (buffer_timestamp > collect_pad->track->codec_delay) {
+      buffer_timestamp += collect_pad->track->codec_delay;
+    } else {
+      buffer_timestamp = 0;
+      duration_diff = collect_pad->track->codec_delay - buffer_timestamp;
+    }
+  }
+
   /* set the timestamp for outgoing buffers */
   ebml->timestamp = buffer_timestamp;
 
@@ -3493,7 +3552,7 @@
     if (mux->cluster_time +
         mux->max_cluster_duration < buffer_timestamp
         || is_video_keyframe || mux->force_key_unit_event) {
-      if (!mux->streamable)
+      if (!mux->ebml_write->streamable)
         gst_ebml_write_master_finish (ebml, mux->cluster);
 
       /* Forward the GstForceKeyUnit event after finishing the cluster */
@@ -3536,7 +3595,7 @@
    * the block in the cluster which contains the timestamp, should also work
    * for files with multiple audio tracks.
    */
-  if (!mux->streamable &&
+  if (!mux->ebml_write->streamable &&
       (is_video_keyframe ||
           ((collect_pad->track->type == GST_MATROSKA_TRACK_TYPE_AUDIO) &&
               (mux->num_streams == 1)))) {
@@ -3570,8 +3629,8 @@
   write_duration = FALSE;
   block_duration = 0;
   if (pad->frame_duration && GST_BUFFER_DURATION_IS_VALID (buf)) {
-    block_duration = gst_util_uint64_scale (GST_BUFFER_DURATION (buf),
-        1, mux->time_scale);
+    block_duration = GST_BUFFER_DURATION (buf) + duration_diff;
+    block_duration = gst_util_uint64_scale (block_duration, 1, mux->time_scale);
 
     /* small difference should be ok. */
     if (block_duration > collect_pad->default_duration_scaled + 1 ||
@@ -3600,7 +3659,16 @@
   if (is_video_invisible)
     flags |= 0x08;
 
-  if (mux->doctype_version > 1 && !write_duration) {
+  if (!strcmp (collect_pad->track->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)) {
+    cmeta = gst_buffer_get_audio_clipping_meta (buf);
+    g_assert (!cmeta || cmeta->format == GST_FORMAT_DEFAULT);
+
+    /* Start clipping is done via header and CodecDelay */
+    if (cmeta && !cmeta->end)
+      cmeta = NULL;
+  }
+
+  if (mux->doctype_version > 1 && !write_duration && !cmeta) {
     if (is_video_keyframe)
       flags |= 0x80;
 
@@ -3625,6 +3693,17 @@
         relative_timestamp, flags);
     if (write_duration)
       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_BLOCKDURATION, block_duration);
+
+    if (!strcmp (collect_pad->track->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_OPUS)
+        && cmeta) {
+      /* Start clipping is done via header and CodecDelay */
+      if (cmeta->end) {
+        guint64 end =
+            gst_util_uint64_scale_round (cmeta->end, GST_SECOND, 48000);
+        gst_ebml_write_sint (ebml, GST_MATROSKA_ID_DISCARDPADDING, end);
+      }
+    }
+
     gst_ebml_write_buffer_header (ebml, GST_MATROSKA_ID_BLOCK,
         gst_buffer_get_size (buf) + gst_buffer_get_size (hdr));
     gst_ebml_write_buffer (ebml, hdr);
@@ -3677,7 +3756,7 @@
   /* if there is no best pad, we have reached EOS */
   if (best == NULL) {
     GST_DEBUG_OBJECT (mux, "No best pad. Finishing...");
-    if (!mux->streamable) {
+    if (!mux->ebml_write->streamable) {
       gst_matroska_mux_finish (mux);
     } else {
       GST_DEBUG_OBJECT (mux, "... but streamable, nothing to finish");
@@ -3796,7 +3875,7 @@
       mux->min_index_interval = g_value_get_int64 (value);
       break;
     case PROP_STREAMABLE:
-      mux->streamable = g_value_get_boolean (value);
+      mux->ebml_write->streamable = g_value_get_boolean (value);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -3824,7 +3903,7 @@
       g_value_set_int64 (value, mux->min_index_interval);
       break;
     case PROP_STREAMABLE:
-      g_value_set_boolean (value, mux->streamable);
+      g_value_set_boolean (value, mux->ebml_write->streamable);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
diff --git a/gst/matroska/matroska-mux.h b/gst/matroska/matroska-mux.h
index dab82e0..c389416 100644
--- a/gst/matroska/matroska-mux.h
+++ b/gst/matroska/matroska-mux.h
@@ -104,7 +104,6 @@
   GstMatroskaIndex *index;
   guint          num_indexes;
   GstClockTimeDiff min_index_interval;
-  gboolean       streamable;
  
   /* timescale in the file */
   guint64        time_scale;
diff --git a/gst/matroska/matroska-parse.c b/gst/matroska/matroska-parse.c
index 2735b39..9bc5ce1 100644
--- a/gst/matroska/matroska-parse.c
+++ b/gst/matroska/matroska-parse.c
@@ -1839,7 +1839,8 @@
         GST_OBJECT_LOCK (parse);
         earliest_time = videocontext->earliest_time;
         GST_OBJECT_UNLOCK (parse);
-        earliest_stream_time = gst_segment_to_position (&parse->common.segment,
+        earliest_stream_time =
+            gst_segment_position_from_running_time (&parse->common.segment,
             GST_FORMAT_TIME, earliest_time);
 
         if (GST_CLOCK_TIME_IS_VALID (lace_time) &&
diff --git a/gst/matroska/matroska-read-common.c b/gst/matroska/matroska-read-common.c
index 537fed9..691d462 100644
--- a/gst/matroska/matroska-read-common.c
+++ b/gst/matroska/matroska-read-common.c
@@ -815,8 +815,7 @@
 
       case GST_MATROSKA_ID_TARGETTYPE:
         if ((ret = gst_ebml_read_ascii (ebml, &id, &str)) == GST_FLOW_OK) {
-          if (*target_type != NULL)
-            g_free (*target_type);
+          g_free (*target_type);
           *target_type = str;
         }
         break;
@@ -1258,8 +1257,7 @@
         GST_DEBUG_OBJECT (common->sinkpad, "EbmlDocType: %s",
             GST_STR_NULL (text));
 
-        if (doctype)
-          g_free (doctype);
+        g_free (doctype);
         doctype = text;
         break;
       }
diff --git a/gst/matroska/webm-mux.c b/gst/matroska/webm-mux.c
index 0ba330f..508f095 100644
--- a/gst/matroska/webm-mux.c
+++ b/gst/matroska/webm-mux.c
@@ -25,13 +25,13 @@
  * <refsect2>
  * <title>Example launch line</title>
  * |[
- * gst-launch-0.10 webmmux name=mux ! filesink location=newfile.webm         \
+ * gst-launch-1.0 webmmux name=mux ! filesink location=newfile.webm         \
  *   uridecodebin uri=file:///path/to/somefile.ogv name=demux                \
  *   demux. ! videoconvert ! vp8enc ! queue ! mux.video_0    \
  *   demux. ! progressreport ! audioconvert ! audiorate ! vorbisenc ! queue ! mux.audio_0
  * ]| This pipeline re-encodes a video file of any format into a WebM file.
  * |[
- * gst-launch-0.10 webmmux name=mux ! filesink location=test.webm            \
+ * gst-launch-1.0 webmmux name=mux ! filesink location=test.webm            \
  *   videotestsrc num-buffers=250 ! video/x-raw,framerate=25/1 ! videoconvert ! vp8enc ! queue ! mux.video_0 \
  *   audiotestsrc samplesperbuffer=44100 num-buffers=10 ! audio/x-raw,rate=44100 ! vorbisenc ! queue ! mux.audio_0
  * ]| This pipeline muxes a test video and a sine wave into a WebM file.
@@ -70,10 +70,11 @@
     );
 
 static GstStaticPadTemplate webm_audiosink_templ =
-GST_STATIC_PAD_TEMPLATE ("audio_%u",
+    GST_STATIC_PAD_TEMPLATE ("audio_%u",
     GST_PAD_SINK,
     GST_PAD_REQUEST,
-    GST_STATIC_CAPS ("audio/x-vorbis, " COMMON_AUDIO_CAPS)
+    GST_STATIC_CAPS ("audio/x-vorbis, " COMMON_AUDIO_CAPS ";"
+        "audio/x-opus, " COMMON_AUDIO_CAPS)
     );
 
 static void
diff --git a/gst/monoscope/Makefile.in b/gst/monoscope/Makefile.in
index b5cc9ba..275bfce 100644
--- a/gst/monoscope/Makefile.in
+++ b/gst/monoscope/Makefile.in
@@ -477,6 +477,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/multifile/Makefile.in b/gst/multifile/Makefile.in
index 7b402b7..febe0e3 100644
--- a/gst/multifile/Makefile.in
+++ b/gst/multifile/Makefile.in
@@ -506,6 +506,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/multifile/gstmultifilesink.c b/gst/multifile/gstmultifilesink.c
index ebc22c2..c74c20b 100644
--- a/gst/multifile/gstmultifilesink.c
+++ b/gst/multifile/gstmultifilesink.c
@@ -180,7 +180,7 @@
 static GType
 gst_multi_file_sink_next_get_type (void)
 {
-  static GType multi_file_sync_next_type = 0;
+  static GType multi_file_sink_next_type = 0;
   static const GEnumValue next_types[] = {
     {GST_MULTI_FILE_SINK_NEXT_BUFFER, "New file for each buffer", "buffer"},
     {GST_MULTI_FILE_SINK_NEXT_DISCONT, "New file after each discontinuity",
@@ -199,12 +199,12 @@
     {0, NULL, NULL}
   };
 
-  if (!multi_file_sync_next_type) {
-    multi_file_sync_next_type =
+  if (!multi_file_sink_next_type) {
+    multi_file_sink_next_type =
         g_enum_register_static ("GstMultiFileSinkNext", next_types);
   }
 
-  return multi_file_sync_next_type;
+  return multi_file_sink_next_type;
 }
 
 #define gst_multi_file_sink_parent_class parent_class
diff --git a/gst/multifile/gstsplitmuxsink.c b/gst/multifile/gstsplitmuxsink.c
index aef9e64..d39c038 100644
--- a/gst/multifile/gstsplitmuxsink.c
+++ b/gst/multifile/gstsplitmuxsink.c
@@ -1027,8 +1027,6 @@
   }
 
   buf = gst_pad_probe_info_get_buffer (info);
-  ctx->in_running_time = gst_segment_to_running_time (&ctx->in_segment,
-      GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buf));
   buf_info = mq_stream_buf_new ();
 
   if (GST_BUFFER_PTS_IS_VALID (buf))
diff --git a/gst/multipart/Makefile.in b/gst/multipart/Makefile.in
index db805eb..7856fc3 100644
--- a/gst/multipart/Makefile.in
+++ b/gst/multipart/Makefile.in
@@ -478,6 +478,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/multipart/multipartdemux.c b/gst/multipart/multipartdemux.c
index 640e592..7695ae5 100644
--- a/gst/multipart/multipartdemux.c
+++ b/gst/multipart/multipartdemux.c
@@ -733,7 +733,7 @@
 
   switch (prop_id) {
     case PROP_BOUNDARY:
-      /* Not really that usefull anymore as we can reliably autoscan */
+      /* Not really that useful anymore as we can reliably autoscan */
       g_free (filter->boundary);
       filter->boundary = g_value_dup_string (value);
       if (filter->boundary != NULL) {
diff --git a/gst/replaygain/Makefile.in b/gst/replaygain/Makefile.in
index 13da9ac..47a6a08 100644
--- a/gst/replaygain/Makefile.in
+++ b/gst/replaygain/Makefile.in
@@ -481,6 +481,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/rtp/Makefile.in b/gst/rtp/Makefile.in
index 91a6b40..b51f5f3 100644
--- a/gst/rtp/Makefile.in
+++ b/gst/rtp/Makefile.in
@@ -526,6 +526,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/rtp/README b/gst/rtp/README
index 5042bd5..814311e 100644
--- a/gst/rtp/README
+++ b/gst/rtp/README
@@ -392,7 +392,7 @@
 
 2029 RTP Payload Format of Sun's CellB Video Encoding.
 
-usefull
--------
+useful
+------
 
 http://www.iana.org/assignments/rtp-parameters
diff --git a/gst/rtp/gstrtpgstpay.c b/gst/rtp/gstrtpgstpay.c
index 8d50b6c..20076fb 100644
--- a/gst/rtp/gstrtpgstpay.c
+++ b/gst/rtp/gstrtpgstpay.c
@@ -171,8 +171,7 @@
     if (rtpgstpay->taglist)
       gst_tag_list_unref (rtpgstpay->taglist);
     rtpgstpay->taglist = NULL;
-    if (rtpgstpay->stream_id)
-      g_free (rtpgstpay->stream_id);
+    g_free (rtpgstpay->stream_id);
     rtpgstpay->stream_id = NULL;
     rtpgstpay->current_CV = 0;
     rtpgstpay->next_CV = 0;
@@ -545,8 +544,7 @@
 
       gst_event_parse_stream_start (event, &stream_id);
       if (stream_id) {
-        if (rtpgstpay->stream_id)
-          g_free (rtpgstpay->stream_id);
+        g_free (rtpgstpay->stream_id);
         rtpgstpay->stream_id = g_strdup (stream_id);
       }
       etype = 4;
diff --git a/gst/rtp/gstrtph264pay.c b/gst/rtp/gstrtph264pay.c
index ea1aa50..c8100ec 100644
--- a/gst/rtp/gstrtph264pay.c
+++ b/gst/rtp/gstrtph264pay.c
@@ -124,11 +124,12 @@
 
   g_object_class_install_property (G_OBJECT_CLASS (klass),
       PROP_CONFIG_INTERVAL,
-      g_param_spec_uint ("config-interval",
+      g_param_spec_int ("config-interval",
           "SPS PPS Send Interval",
           "Send SPS and PPS Insertion Interval in seconds (sprop parameter sets "
-          "will be multiplexed in the data stream when detected.) (0 = disabled)",
-          0, 3600, DEFAULT_CONFIG_INTERVAL,
+          "will be multiplexed in the data stream when detected.) "
+          "(0 = disabled, -1 = send with every IDR frame)",
+          -1, 3600, DEFAULT_CONFIG_INTERVAL,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
       );
 
@@ -829,6 +830,10 @@
       GST_DEBUG_OBJECT (rtph264pay, "no previous SPS/PPS time, send now");
       send_spspps = TRUE;
     }
+  } else if (nalType == IDR_TYPE_ID && rtph264pay->spspps_interval == -1) {
+    GST_DEBUG_OBJECT (rtph264pay, "sending SPS/PPS before current IDR frame");
+    /* send SPS/PPS before every IDR frame */
+    send_spspps = TRUE;
   }
 
   if (send_spspps || rtph264pay->send_spspps) {
@@ -1373,7 +1378,7 @@
       rtph264pay->update_caps = TRUE;
       break;
     case PROP_CONFIG_INTERVAL:
-      rtph264pay->spspps_interval = g_value_get_uint (value);
+      rtph264pay->spspps_interval = g_value_get_int (value);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1394,7 +1399,7 @@
       g_value_set_string (value, rtph264pay->sprop_parameter_sets);
       break;
     case PROP_CONFIG_INTERVAL:
-      g_value_set_uint (value, rtph264pay->spspps_interval);
+      g_value_set_int (value, rtph264pay->spspps_interval);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
diff --git a/gst/rtp/gstrtph264pay.h b/gst/rtp/gstrtph264pay.h
index 44f7af4..c5a5e9f 100644
--- a/gst/rtp/gstrtph264pay.h
+++ b/gst/rtp/gstrtph264pay.h
@@ -71,7 +71,7 @@
 
   GstAdapter *adapter;
 
-  guint spspps_interval;
+  gint spspps_interval;
   gboolean send_spspps;
   GstClockTime last_spspps;
 
diff --git a/gst/rtp/gstrtpj2kdepay.c b/gst/rtp/gstrtpj2kdepay.c
index 04e69b7..f132811 100644
--- a/gst/rtp/gstrtpj2kdepay.c
+++ b/gst/rtp/gstrtpj2kdepay.c
@@ -374,16 +374,13 @@
     goto done;
 
   if (avail > 2) {
-    GList *list, *walk;
-    GstBufferList *buflist;
+    GstBuffer *outbuf;
 
     /* take the last bytes of the JPEG 2000 data to see if there is an EOC
      * marker */
     gst_adapter_copy (rtpj2kdepay->f_adapter, end, avail - 2, 2);
 
     if (end[0] != 0xff && end[1] != 0xd9) {
-      GstBuffer *outbuf;
-
       end[0] = 0xff;
       end[1] = 0xd9;
 
@@ -397,21 +394,11 @@
       avail += 2;
     }
 
-    GST_DEBUG_OBJECT (rtpj2kdepay, "pushing buffer list of %u bytes", avail);
-    list = gst_adapter_take_list (rtpj2kdepay->f_adapter, avail);
-
-    buflist = gst_buffer_list_new ();
-
-    for (walk = list; walk; walk = g_list_next (walk)) {
-      gst_rtp_drop_meta (GST_ELEMENT_CAST (depayload),
-          GST_BUFFER_CAST (walk->data),
-          g_quark_from_static_string (GST_META_TAG_VIDEO_STR));
-      gst_buffer_list_add (buflist, GST_BUFFER_CAST (walk->data));
-    }
-
-    g_list_free (list);
-
-    ret = gst_rtp_base_depayload_push_list (depayload, buflist);
+    GST_DEBUG_OBJECT (rtpj2kdepay, "pushing buffer of %u bytes", avail);
+    outbuf = gst_adapter_take_buffer (rtpj2kdepay->f_adapter, avail);
+    gst_rtp_drop_meta (GST_ELEMENT_CAST (depayload),
+        outbuf, g_quark_from_static_string (GST_META_TAG_VIDEO_STR));
+    ret = gst_rtp_base_depayload_push (depayload, outbuf);
   } else {
     GST_WARNING_OBJECT (rtpj2kdepay, "empty packet");
     gst_adapter_clear (rtpj2kdepay->f_adapter);
diff --git a/gst/rtp/gstrtpjpegpay.c b/gst/rtp/gstrtpjpegpay.c
index 65fcb17..559065d 100644
--- a/gst/rtp/gstrtpjpegpay.c
+++ b/gst/rtp/gstrtpjpegpay.c
@@ -359,10 +359,8 @@
     res = gst_rtp_base_payload_set_outcaps (basepayload, NULL);
   }
 
-  if (dim != NULL)
-    g_free (dim);
-  if (rate != NULL)
-    g_free (rate);
+  g_free (dim);
+  g_free (rate);
 
   return res;
 
diff --git a/gst/rtp/gstrtptheorapay.c b/gst/rtp/gstrtptheorapay.c
index 802a335..c2b4640 100644
--- a/gst/rtp/gstrtptheorapay.c
+++ b/gst/rtp/gstrtptheorapay.c
@@ -164,8 +164,7 @@
   gst_rtp_theora_pay_clear_packet (rtptheorapay);
   g_list_free_full (rtptheorapay->headers, (GDestroyNotify) gst_buffer_unref);
   rtptheorapay->headers = NULL;
-  if (rtptheorapay->config_data)
-    g_free (rtptheorapay->config_data);
+  g_free (rtptheorapay->config_data);
   rtptheorapay->config_data = NULL;
   rtptheorapay->last_config = GST_CLOCK_TIME_NONE;
 }
@@ -516,8 +515,7 @@
   configuration = g_base64_encode (config, configlen);
 
   /* store for later re-sending */
-  if (rtptheorapay->config_data)
-    g_free (rtptheorapay->config_data);
+  g_free (rtptheorapay->config_data);
   rtptheorapay->config_size = configlen - 4 - 3 - 2;
   rtptheorapay->config_data = g_malloc (rtptheorapay->config_size);
   rtptheorapay->config_extra_len = extralen;
diff --git a/gst/rtp/gstrtpvorbispay.c b/gst/rtp/gstrtpvorbispay.c
index 4350705..2557bb5 100644
--- a/gst/rtp/gstrtpvorbispay.c
+++ b/gst/rtp/gstrtpvorbispay.c
@@ -156,8 +156,7 @@
   gst_rtp_vorbis_pay_clear_packet (rtpvorbispay);
   g_list_free_full (rtpvorbispay->headers, (GDestroyNotify) gst_buffer_unref);
   rtpvorbispay->headers = NULL;
-  if (rtpvorbispay->config_data)
-    g_free (rtpvorbispay->config_data);
+  g_free (rtpvorbispay->config_data);
   rtpvorbispay->config_data = NULL;
   rtpvorbispay->last_config = GST_CLOCK_TIME_NONE;
 }
@@ -508,8 +507,7 @@
   configuration = g_base64_encode (config, configlen);
 
   /* store for later re-sending */
-  if (rtpvorbispay->config_data)
-    g_free (rtpvorbispay->config_data);
+  g_free (rtpvorbispay->config_data);
   rtpvorbispay->config_size = configlen - 4 - 3 - 2;
   rtpvorbispay->config_data = g_malloc (rtpvorbispay->config_size);
   rtpvorbispay->config_extra_len = extralen;
diff --git a/gst/rtp/gstrtpvp8pay.c b/gst/rtp/gstrtpvp8pay.c
index 1c4c625..d7576ab 100644
--- a/gst/rtp/gstrtpvp8pay.c
+++ b/gst/rtp/gstrtpvp8pay.c
@@ -126,7 +126,7 @@
 
   gst_element_class_set_static_metadata (element_class, "RTP VP8 payloader",
       "Codec/Payloader/Network/RTP",
-      "Puts VP8 video in RTP packets)", "Sjoerd Simons <sjoerd@luon.net>");
+      "Puts VP8 video in RTP packets", "Sjoerd Simons <sjoerd@luon.net>");
 
   pay_class->handle_buffer = gst_rtp_vp8_pay_handle_buffer;
   pay_class->sink_event = gst_rtp_vp8_pay_sink_event;
diff --git a/gst/rtpmanager/Makefile.in b/gst/rtpmanager/Makefile.in
index d358908..1c3d829 100644
--- a/gst/rtpmanager/Makefile.in
+++ b/gst/rtpmanager/Makefile.in
@@ -490,6 +490,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/rtpmanager/gstrtpbin.c b/gst/rtpmanager/gstrtpbin.c
index 21e1cd8..bc7ec6d 100644
--- a/gst/rtpmanager/gstrtpbin.c
+++ b/gst/rtpmanager/gstrtpbin.c
@@ -272,6 +272,9 @@
   SIGNAL_REQUEST_AUX_SENDER,
   SIGNAL_REQUEST_AUX_RECEIVER,
 
+  SIGNAL_ON_NEW_SENDER_SSRC,
+  SIGNAL_ON_SENDER_SSRC_ACTIVE,
+
   LAST_SIGNAL
 };
 
@@ -290,6 +293,10 @@
 #define DEFAULT_DO_RETRANSMISSION    FALSE
 #define DEFAULT_RTP_PROFILE          GST_RTP_PROFILE_AVP
 #define DEFAULT_NTP_TIME_SOURCE      GST_RTP_NTP_TIME_SOURCE_NTP
+#define DEFAULT_RTCP_SYNC_SEND_TIME  TRUE
+#define DEFAULT_MAX_RTCP_RTP_TIME_DIFF 1000
+#define DEFAULT_MAX_DROPOUT_TIME     60000
+#define DEFAULT_MAX_MISORDER_TIME    2000
 
 enum
 {
@@ -308,7 +315,11 @@
   PROP_DO_SYNC_EVENT,
   PROP_DO_RETRANSMISSION,
   PROP_RTP_PROFILE,
-  PROP_NTP_TIME_SOURCE
+  PROP_NTP_TIME_SOURCE,
+  PROP_RTCP_SYNC_SEND_TIME,
+  PROP_MAX_RTCP_RTP_TIME_DIFF,
+  PROP_MAX_DROPOUT_TIME,
+  PROP_MAX_MISORDER_TIME
 };
 
 #define GST_RTP_BIN_RTCP_SYNC_TYPE (gst_rtp_bin_rtcp_sync_get_type())
@@ -561,6 +572,21 @@
       stream->session->id, stream->ssrc);
 }
 
+static void
+on_new_sender_ssrc (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
+{
+  g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_NEW_SENDER_SSRC], 0,
+      sess->id, ssrc);
+}
+
+static void
+on_sender_ssrc_active (GstElement * session, guint32 ssrc,
+    GstRtpBinSession * sess)
+{
+  g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SENDER_SSRC_ACTIVE],
+      0, sess->id, ssrc);
+}
+
 /* must be called with the SESSION lock */
 static GstRtpBinStream *
 find_stream_by_ssrc (GstRtpBinSession * session, guint32 ssrc)
@@ -625,12 +651,16 @@
   /* configure SDES items */
   GST_OBJECT_LOCK (rtpbin);
   g_object_set (session, "sdes", rtpbin->sdes, "rtp-profile",
-      rtpbin->rtp_profile, NULL);
+      rtpbin->rtp_profile, "rtcp-sync-send-time", rtpbin->rtcp_sync_send_time,
+      NULL);
   if (rtpbin->use_pipeline_clock)
     g_object_set (session, "use-pipeline-clock", rtpbin->use_pipeline_clock,
         NULL);
   else
     g_object_set (session, "ntp-time-source", rtpbin->ntp_time_source, NULL);
+
+  g_object_set (session, "max-dropout-time", rtpbin->max_dropout_time,
+      "max-misorder-time", rtpbin->max_misorder_time, NULL);
   GST_OBJECT_UNLOCK (rtpbin);
 
   /* provide clock_rate to the session manager when needed */
@@ -654,6 +684,10 @@
   g_signal_connect (sess->session, "on-timeout", (GCallback) on_timeout, sess);
   g_signal_connect (sess->session, "on-sender-timeout",
       (GCallback) on_sender_timeout, sess);
+  g_signal_connect (sess->session, "on-new-sender-ssrc",
+      (GCallback) on_new_sender_ssrc, sess);
+  g_signal_connect (sess->session, "on-sender-ssrc-active",
+      (GCallback) on_sender_ssrc_active, sess);
 
   gst_bin_add (GST_BIN_CAST (rtpbin), session);
   gst_bin_add (GST_BIN_CAST (rtpbin), demux);
@@ -955,6 +989,21 @@
   GST_RTP_BIN_UNLOCK (bin);
 }
 
+static void
+gst_rtp_bin_propagate_property_to_session (GstRtpBin * bin,
+    const gchar * name, const GValue * value)
+{
+  GSList *sessions;
+
+  GST_RTP_BIN_LOCK (bin);
+  for (sessions = bin->sessions; sessions; sessions = g_slist_next (sessions)) {
+    GstRtpBinSession *sess = (GstRtpBinSession *) sessions->data;
+
+    g_object_set_property (G_OBJECT (sess->session), name, value);
+  }
+  GST_RTP_BIN_UNLOCK (bin);
+}
+
 /* get a client with the given SDES name. Must be called with RTP_BIN_LOCK */
 static GstRtpBinClient *
 get_client (GstRtpBin * bin, guint8 len, guint8 * data, gboolean * created)
@@ -1041,6 +1090,7 @@
           ntpns = clock_time;
           break;
         default:
+          ntpns = -1;           /* Fix uninited compiler warning */
           g_assert_not_reached ();
           break;
       }
@@ -1549,6 +1599,10 @@
   g_object_set (buffer, "do-lost", rtpbin->do_lost, NULL);
   g_object_set (buffer, "mode", rtpbin->buffer_mode, NULL);
   g_object_set (buffer, "do-retransmission", rtpbin->do_retransmission, NULL);
+  g_object_set (buffer, "max-rtcp-rtp-time-diff",
+      rtpbin->max_rtcp_rtp_time_diff, NULL);
+  g_object_set (buffer, "max-dropout-time", rtpbin->max_dropout_time,
+      "max-misorder-time", rtpbin->max_misorder_time, NULL);
 
   g_signal_emit (rtpbin, gst_rtp_bin_signals[SIGNAL_NEW_JITTERBUFFER], 0,
       buffer, session->id, ssrc);
@@ -2062,6 +2116,36 @@
       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
           request_aux_receiver), _gst_element_accumulator, NULL,
       g_cclosure_marshal_generic, GST_TYPE_ELEMENT, 1, G_TYPE_UINT);
+  /**
+   * GstRtpBin::on-new-sender-ssrc:
+   * @rtpbin: the object which received the signal
+   * @session: the session
+   * @ssrc: the sender SSRC
+   *
+   * Since: 1.8
+   *
+   * Notify of a new sender SSRC that entered @session.
+   */
+  gst_rtp_bin_signals[SIGNAL_ON_NEW_SENDER_SSRC] =
+      g_signal_new ("on-new-sender-ssrc", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_new_sender_ssrc),
+      NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2, G_TYPE_UINT,
+      G_TYPE_UINT);
+  /**
+   * GstRtpBin::on-ssrc-active:
+   * @rtpbin: the object which received the signal
+   * @session: the session
+   * @ssrc: the sender SSRC
+   *
+   * Since: 1.8
+   *
+   * Notify of a sender SSRC that is active, i.e., sending RTCP.
+   */
+  gst_rtp_bin_signals[SIGNAL_ON_SENDER_SSRC_ACTIVE] =
+      g_signal_new ("on-sender-ssrc-active", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
+          on_sender_ssrc_active), NULL, NULL, g_cclosure_marshal_generic,
+      G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
 
   g_object_class_install_property (gobject_class, PROP_SDES,
       g_param_spec_boxed ("sdes", "SDES",
@@ -2171,6 +2255,32 @@
           gst_rtp_ntp_time_source_get_type (), DEFAULT_NTP_TIME_SOURCE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_RTCP_SYNC_SEND_TIME,
+      g_param_spec_boolean ("rtcp-sync-send-time", "RTCP Sync Send Time",
+          "Use send time or capture time for RTCP sync "
+          "(TRUE = send time, FALSE = capture time)",
+          DEFAULT_RTCP_SYNC_SEND_TIME,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_MAX_RTCP_RTP_TIME_DIFF,
+      g_param_spec_int ("max-rtcp-rtp-time-diff", "Max RTCP RTP Time Diff",
+          "Maximum amount of time in ms that the RTP time in RTCP SRs "
+          "is allowed to be ahead (-1 disabled)", -1, G_MAXINT,
+          DEFAULT_MAX_RTCP_RTP_TIME_DIFF,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_MAX_DROPOUT_TIME,
+      g_param_spec_uint ("max-dropout-time", "Max dropout time",
+          "The maximum time (milliseconds) of missing packets tolerated.",
+          0, G_MAXUINT, DEFAULT_MAX_DROPOUT_TIME,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_MAX_MISORDER_TIME,
+      g_param_spec_uint ("max-misorder-time", "Max misorder time",
+          "The maximum time (milliseconds) of misordered packets tolerated.",
+          0, G_MAXUINT, DEFAULT_MAX_MISORDER_TIME,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_bin_change_state);
   gstelement_class->request_new_pad =
       GST_DEBUG_FUNCPTR (gst_rtp_bin_request_new_pad);
@@ -2235,6 +2345,10 @@
   rtpbin->do_retransmission = DEFAULT_DO_RETRANSMISSION;
   rtpbin->rtp_profile = DEFAULT_RTP_PROFILE;
   rtpbin->ntp_time_source = DEFAULT_NTP_TIME_SOURCE;
+  rtpbin->rtcp_sync_send_time = DEFAULT_RTCP_SYNC_SEND_TIME;
+  rtpbin->max_rtcp_rtp_time_diff = DEFAULT_MAX_RTCP_RTP_TIME_DIFF;
+  rtpbin->max_dropout_time = DEFAULT_MAX_DROPOUT_TIME;
+  rtpbin->max_misorder_time = DEFAULT_MAX_MISORDER_TIME;
 
   /* some default SDES entries */
   cname = g_strdup_printf ("user%u@host-%x", g_random_int (), g_random_int ());
@@ -2412,6 +2526,45 @@
       GST_RTP_BIN_UNLOCK (rtpbin);
       break;
     }
+    case PROP_RTCP_SYNC_SEND_TIME:{
+      GSList *sessions;
+      GST_RTP_BIN_LOCK (rtpbin);
+      rtpbin->rtcp_sync_send_time = g_value_get_boolean (value);
+      for (sessions = rtpbin->sessions; sessions;
+          sessions = g_slist_next (sessions)) {
+        GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
+
+        g_object_set (G_OBJECT (session->session),
+            "rtcp-sync-send-time", rtpbin->rtcp_sync_send_time, NULL);
+      }
+      GST_RTP_BIN_UNLOCK (rtpbin);
+      break;
+    }
+    case PROP_MAX_RTCP_RTP_TIME_DIFF:
+      GST_RTP_BIN_LOCK (rtpbin);
+      rtpbin->max_rtcp_rtp_time_diff = g_value_get_int (value);
+      GST_RTP_BIN_UNLOCK (rtpbin);
+      gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
+          "max-rtcp-rtp-time-diff", value);
+      break;
+    case PROP_MAX_DROPOUT_TIME:
+      GST_RTP_BIN_LOCK (rtpbin);
+      rtpbin->max_dropout_time = g_value_get_uint (value);
+      GST_RTP_BIN_UNLOCK (rtpbin);
+      gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
+          "max-dropout-time", value);
+      gst_rtp_bin_propagate_property_to_session (rtpbin, "max-dropout-time",
+          value);
+      break;
+    case PROP_MAX_MISORDER_TIME:
+      GST_RTP_BIN_LOCK (rtpbin);
+      rtpbin->max_misorder_time = g_value_get_uint (value);
+      GST_RTP_BIN_UNLOCK (rtpbin);
+      gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
+          "max-misorder-time", value);
+      gst_rtp_bin_propagate_property_to_session (rtpbin, "max-dropout-time",
+          value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2480,6 +2633,21 @@
     case PROP_NTP_TIME_SOURCE:
       g_value_set_enum (value, rtpbin->ntp_time_source);
       break;
+    case PROP_RTCP_SYNC_SEND_TIME:
+      g_value_set_boolean (value, rtpbin->rtcp_sync_send_time);
+      break;
+    case PROP_MAX_RTCP_RTP_TIME_DIFF:
+      GST_RTP_BIN_LOCK (rtpbin);
+      g_value_set_int (value, rtpbin->max_rtcp_rtp_time_diff);
+      GST_RTP_BIN_UNLOCK (rtpbin);
+      break;
+    case PROP_MAX_DROPOUT_TIME:
+      g_value_set_uint (value, rtpbin->max_dropout_time);
+      break;
+    case PROP_MAX_MISORDER_TIME:
+      g_value_set_uint (value, rtpbin->max_misorder_time);
+      break;
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
diff --git a/gst/rtpmanager/gstrtpbin.h b/gst/rtpmanager/gstrtpbin.h
index 87c1fad..e74a718 100644
--- a/gst/rtpmanager/gstrtpbin.h
+++ b/gst/rtpmanager/gstrtpbin.h
@@ -69,6 +69,10 @@
   GstClockTime    buffer_start;
   gboolean        do_retransmission;
   GstRTPProfile   rtp_profile;
+  gboolean        rtcp_sync_send_time;
+  gint            max_rtcp_rtp_time_diff;
+  guint32         max_dropout_time;
+  guint32         max_misorder_time;
 
   /* a list of session */
   GSList         *sessions;
@@ -117,6 +121,9 @@
 
   GstElement* (*request_aux_sender)   (GstRtpBin *rtpbin, guint session);
   GstElement* (*request_aux_receiver) (GstRtpBin *rtpbin, guint session);
+
+  void     (*on_new_sender_ssrc)      (GstRtpBin *rtpbin, guint session, guint32 ssrc);
+  void     (*on_sender_ssrc_active)   (GstRtpBin *rtpbin, guint session, guint32 ssrc);
 };
 
 GType gst_rtp_bin_get_type (void);
diff --git a/gst/rtpmanager/gstrtpjitterbuffer.c b/gst/rtpmanager/gstrtpjitterbuffer.c
index e028c3e..1349e32 100644
--- a/gst/rtpmanager/gstrtpjitterbuffer.c
+++ b/gst/rtpmanager/gstrtpjitterbuffer.c
@@ -5,6 +5,8 @@
  *  Copyright 2007 Nokia Corporation
  *   @author: Philippe Kalaf <philippe.kalaf@collabora.co.uk>.
  *  Copyright 2007 Wim Taymans <wim.taymans@gmail.com>
+ *  Copyright 2015 Kurento (http://kurento.org/)
+ *   @author: Miguel París <mparisdiaz@gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -136,6 +138,9 @@
 #define DEFAULT_RTX_MIN_RETRY_TIMEOUT   -1
 #define DEFAULT_RTX_RETRY_PERIOD    -1
 #define DEFAULT_RTX_MAX_RETRIES    -1
+#define DEFAULT_MAX_RTCP_RTP_TIME_DIFF 1000
+#define DEFAULT_MAX_DROPOUT_TIME    60000
+#define DEFAULT_MAX_MISORDER_TIME   2000
 
 #define DEFAULT_AUTO_RTX_DELAY (20 * GST_MSECOND)
 #define DEFAULT_AUTO_RTX_TIMEOUT (40 * GST_MSECOND)
@@ -158,7 +163,10 @@
   PROP_RTX_MIN_RETRY_TIMEOUT,
   PROP_RTX_RETRY_PERIOD,
   PROP_RTX_MAX_RETRIES,
-  PROP_STATS
+  PROP_STATS,
+  PROP_MAX_RTCP_RTP_TIME_DIFF,
+  PROP_MAX_DROPOUT_TIME,
+  PROP_MAX_MISORDER_TIME
 };
 
 #define JBUF_LOCK(priv)   (g_mutex_lock (&(priv)->jbuf_lock))
@@ -255,6 +263,9 @@
   gint rtx_min_retry_timeout;
   gint rtx_retry_period;
   gint rtx_max_retries;
+  gint max_rtcp_rtp_time_diff;
+  guint32 max_dropout_time;
+  guint32 max_misorder_time;
 
   /* the last seqnum we pushed out */
   guint32 last_popped_seqnum;
@@ -318,6 +329,7 @@
   guint64 num_rtx_failed;
   gdouble avg_rtx_num;
   guint64 avg_rtx_rtt;
+  RTPPacketRateCtx packet_rate_ctx;
 
   /* for the jitter */
   GstClockTime last_dts;
@@ -661,6 +673,18 @@
           "The maximum number of retries to request a retransmission. "
           "(-1 not limited)", -1, G_MAXINT, DEFAULT_RTX_MAX_RETRIES,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_MAX_DROPOUT_TIME,
+      g_param_spec_uint ("max-dropout-time", "Max dropout time",
+          "The maximum time (milliseconds) of missing packets tolerated.",
+          0, G_MAXUINT, DEFAULT_MAX_DROPOUT_TIME,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_MAX_MISORDER_TIME,
+      g_param_spec_uint ("max-misorder-time", "Max misorder time",
+          "The maximum time (milliseconds) of misordered packets tolerated.",
+          0, G_MAXUINT, DEFAULT_MAX_MISORDER_TIME,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   /**
    * GstRtpJitterBuffer:stats:
    *
@@ -706,6 +730,22 @@
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
   /**
+   * GstRtpJitterBuffer:max-rtcp-rtp-time-diff
+   *
+   * The maximum amount of time in ms that the RTP time in the RTCP SRs
+   * is allowed to be ahead of the last RTP packet we received. Use
+   * -1 to disable ignoring of RTCP packets.
+   *
+   * Since: 1.8
+   */
+  g_object_class_install_property (gobject_class, PROP_MAX_RTCP_RTP_TIME_DIFF,
+      g_param_spec_int ("max-rtcp-rtp-time-diff", "Max RTCP RTP Time Diff",
+          "Maximum amount of time in ms that the RTP time in RTCP SRs "
+          "is allowed to be ahead (-1 disabled)", -1, G_MAXINT,
+          DEFAULT_MAX_RTCP_RTP_TIME_DIFF,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
    * GstRtpJitterBuffer::request-pt-map:
    * @buffer: the object which received the signal
    * @pt: the pt
@@ -822,6 +862,9 @@
   priv->rtx_min_retry_timeout = DEFAULT_RTX_MIN_RETRY_TIMEOUT;
   priv->rtx_retry_period = DEFAULT_RTX_RETRY_PERIOD;
   priv->rtx_max_retries = DEFAULT_RTX_MAX_RETRIES;
+  priv->max_rtcp_rtp_time_diff = DEFAULT_MAX_RTCP_RTP_TIME_DIFF;
+  priv->max_dropout_time = DEFAULT_MAX_DROPOUT_TIME;
+  priv->max_misorder_time = DEFAULT_MAX_MISORDER_TIME;
 
   priv->last_dts = -1;
   priv->last_rtptime = -1;
@@ -2264,7 +2307,8 @@
 
 static gboolean
 handle_big_gap_buffer (GstRtpJitterBuffer * jitterbuffer, gboolean future,
-    GstBuffer * buffer, guint8 pt, guint16 seqnum, gint gap)
+    GstBuffer * buffer, guint8 pt, guint16 seqnum, gint gap, guint max_dropout,
+    guint max_misorder)
 {
   GstRtpJitterBufferPrivate *priv;
   guint gap_packets_length;
@@ -2306,7 +2350,7 @@
       GST_DEBUG_OBJECT (jitterbuffer,
           "buffer too %s %d < %d, got 5 consecutive ones - reset",
           (future ? "new" : "old"), gap,
-          (future ? RTP_MAX_DROPOUT : -RTP_MAX_MISORDER));
+          (future ? max_dropout : -max_misorder));
       reset = TRUE;
     } else if (!all_consecutive) {
       g_queue_foreach (&priv->gap_packets, (GFunc) gst_buffer_unref, NULL);
@@ -2314,20 +2358,19 @@
       GST_DEBUG_OBJECT (jitterbuffer,
           "buffer too %s %d < %d, got no 5 consecutive ones - dropping",
           (future ? "new" : "old"), gap,
-          (future ? RTP_MAX_DROPOUT : -RTP_MAX_MISORDER));
+          (future ? max_dropout : -max_misorder));
       buffer = NULL;
     } else {
       GST_DEBUG_OBJECT (jitterbuffer,
           "buffer too %s %d < %d, got %u consecutive ones - waiting",
           (future ? "new" : "old"), gap,
-          (future ? RTP_MAX_DROPOUT : -RTP_MAX_MISORDER),
-          gap_packets_length + 1);
+          (future ? max_dropout : -max_misorder), gap_packets_length + 1);
       buffer = NULL;
     }
   } else {
     GST_DEBUG_OBJECT (jitterbuffer,
         "buffer too %s %d < %d, first one - waiting", (future ? "new" : "old"),
-        gap, -RTP_MAX_MISORDER);
+        gap, -max_misorder);
     g_queue_push_tail (&priv->gap_packets, buffer);
     buffer = NULL;
   }
@@ -2376,6 +2419,7 @@
   RTPJitterBufferItem *item;
   GstMessage *msg = NULL;
   gboolean estimated_dts = FALSE;
+  guint32 packet_rate, max_dropout, max_misorder;
 
   jitterbuffer = GST_RTP_JITTER_BUFFER_CAST (parent);
 
@@ -2480,6 +2524,18 @@
 
   expected = priv->next_in_seqnum;
 
+  packet_rate =
+      gst_rtp_packet_rate_ctx_update (&priv->packet_rate_ctx, seqnum, rtptime);
+  max_dropout =
+      gst_rtp_packet_rate_ctx_get_max_dropout (&priv->packet_rate_ctx,
+      priv->max_dropout_time);
+  max_misorder =
+      gst_rtp_packet_rate_ctx_get_max_misorder (&priv->packet_rate_ctx,
+      priv->max_misorder_time);
+  GST_TRACE_OBJECT (jitterbuffer,
+      "packet_rate: %d, max_dropout: %d, max_misorder: %d", packet_rate,
+      max_dropout, max_misorder);
+
   /* now check against our expected seqnum */
   if (G_LIKELY (expected != -1)) {
     gint gap;
@@ -2499,17 +2555,17 @@
 
       if (gap < 0) {
         /* we received an old packet */
-        if (G_UNLIKELY (gap != -1 && gap < -RTP_MAX_MISORDER)) {
+        if (G_UNLIKELY (gap != -1 && gap < -max_misorder)) {
           reset =
               handle_big_gap_buffer (jitterbuffer, FALSE, buffer, pt, seqnum,
-              gap);
+              gap, max_dropout, max_misorder);
           buffer = NULL;
         } else {
           GST_DEBUG_OBJECT (jitterbuffer, "old packet received");
         }
       } else {
         /* new packet, we are missing some packets */
-        if (G_UNLIKELY (priv->timers->len >= RTP_MAX_DROPOUT)) {
+        if (G_UNLIKELY (priv->timers->len >= max_dropout)) {
           /* If we have timers for more than RTP_MAX_DROPOUT packets
            * pending this means that we have a huge gap overall. We can
            * reset the jitterbuffer at this point because there's
@@ -2518,14 +2574,14 @@
            * next packet */
           GST_WARNING_OBJECT (jitterbuffer,
               "%d pending timers > %d - resetting", priv->timers->len,
-              RTP_MAX_DROPOUT);
+              max_dropout);
           reset = TRUE;
           gst_buffer_unref (buffer);
           buffer = NULL;
-        } else if (G_UNLIKELY (gap >= RTP_MAX_DROPOUT)) {
+        } else if (G_UNLIKELY (gap >= max_dropout)) {
           reset =
               handle_big_gap_buffer (jitterbuffer, TRUE, buffer, pt, seqnum,
-              gap);
+              gap, max_dropout, max_misorder);
           buffer = NULL;
         } else {
           GST_DEBUG_OBJECT (jitterbuffer, "%d missing packets", gap);
@@ -2901,9 +2957,11 @@
       }
 
       dts =
-          gst_segment_to_position (&priv->segment, GST_FORMAT_TIME, item->dts);
+          gst_segment_position_from_running_time (&priv->segment,
+          GST_FORMAT_TIME, item->dts);
       pts =
-          gst_segment_to_position (&priv->segment, GST_FORMAT_TIME, item->pts);
+          gst_segment_position_from_running_time (&priv->segment,
+          GST_FORMAT_TIME, item->pts);
 
       /* apply timestamp with offset to buffer now */
       GST_BUFFER_DTS (outbuf) = apply_offset (jitterbuffer, dts);
@@ -3340,10 +3398,11 @@
     GstClockTime timer_timeout = -1;
     gint i, len;
 
-    /* If we have a clock, update "now" now with the very latest running time
-     * we have. It is used below when timeouts are triggered to calculate
-     * any next possible timeout. If we only update it after waiting for the
-     * clock, we would give a too old time to the timeout functions.
+    /* If we have a clock, update "now" now with the very
+     * latest running time we have. If timers are unscheduled below we
+     * otherwise wouldn't update now (it's only updated when timers
+     * expire), and also for the very first loop iteration now would
+     * otherwise always be 0
      */
     GST_OBJECT_LOCK (jitterbuffer);
     if (GST_ELEMENT_CLOCK (jitterbuffer)) {
@@ -3446,8 +3505,10 @@
       }
 
       if (ret != GST_CLOCK_UNSCHEDULED) {
-        GST_DEBUG_OBJECT (jitterbuffer, "sync done, %d, #%d, %" G_GINT64_FORMAT,
-            ret, priv->timer_seqnum, clock_jitter);
+        now = timer_timeout + MAX (clock_jitter, 0);
+        GST_DEBUG_OBJECT (jitterbuffer,
+            "sync done, %d, #%d, %" GST_STIME_FORMAT, ret, priv->timer_seqnum,
+            GST_STIME_ARGS (clock_jitter));
       } else {
         GST_DEBUG_OBJECT (jitterbuffer, "sync unscheduled");
       }
@@ -3562,7 +3623,10 @@
         /* check how far ahead it is to our RTP timestamps */
         diff = ext_rtptime - last_rtptime;
         /* if bigger than 1 second, we drop it */
-        if (diff > clock_rate) {
+        if (jitterbuffer->priv->max_rtcp_rtp_time_diff != -1 &&
+            diff >
+            gst_util_uint64_scale (jitterbuffer->priv->max_rtcp_rtp_time_diff,
+                clock_rate, 1000)) {
           GST_DEBUG_OBJECT (jitterbuffer, "too far ahead");
           /* should drop this, but some RTSP servers end up with bogus
            * way too ahead RTCP packet when repeated PAUSE/PLAY,
@@ -3939,6 +4003,21 @@
       priv->rtx_max_retries = g_value_get_int (value);
       JBUF_UNLOCK (priv);
       break;
+    case PROP_MAX_RTCP_RTP_TIME_DIFF:
+      JBUF_LOCK (priv);
+      priv->max_rtcp_rtp_time_diff = g_value_get_int (value);
+      JBUF_UNLOCK (priv);
+      break;
+    case PROP_MAX_DROPOUT_TIME:
+      JBUF_LOCK (priv);
+      priv->max_dropout_time = g_value_get_uint (value);
+      JBUF_UNLOCK (priv);
+      break;
+    case PROP_MAX_MISORDER_TIME:
+      JBUF_LOCK (priv);
+      priv->max_misorder_time = g_value_get_uint (value);
+      JBUF_UNLOCK (priv);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -4044,6 +4123,21 @@
       g_value_take_boxed (value,
           gst_rtp_jitter_buffer_create_stats (jitterbuffer));
       break;
+    case PROP_MAX_RTCP_RTP_TIME_DIFF:
+      JBUF_LOCK (priv);
+      g_value_set_int (value, priv->max_rtcp_rtp_time_diff);
+      JBUF_UNLOCK (priv);
+      break;
+    case PROP_MAX_DROPOUT_TIME:
+      JBUF_LOCK (priv);
+      g_value_set_uint (value, priv->max_dropout_time);
+      JBUF_UNLOCK (priv);
+      break;
+    case PROP_MAX_MISORDER_TIME:
+      JBUF_LOCK (priv);
+      g_value_set_uint (value, priv->max_misorder_time);
+      JBUF_UNLOCK (priv);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
diff --git a/gst/rtpmanager/gstrtpmux.c b/gst/rtpmanager/gstrtpmux.c
index 302600c..69cafb4 100644
--- a/gst/rtpmanager/gstrtpmux.c
+++ b/gst/rtpmanager/gstrtpmux.c
@@ -156,9 +156,10 @@
           0, G_MAXUINT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SSRC,
       g_param_spec_uint ("ssrc", "SSRC",
-          "The SSRC of the packets (-1 == random)",
+          "The SSRC of the packets (default == random)",
           0, G_MAXUINT, DEFAULT_SSRC,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+          GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE |
+          G_PARAM_STATIC_STRINGS));
 
   gstelement_class->request_new_pad =
       GST_DEBUG_FUNCPTR (gst_rtp_mux_request_new_pad);
@@ -203,36 +204,52 @@
 static gboolean
 gst_rtp_mux_src_event_real (GstRTPMux * rtp_mux, GstEvent * event)
 {
-  GstIterator *iter;
-  gboolean result = FALSE;
-  gboolean done = FALSE;
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_CUSTOM_UPSTREAM:
+    {
+      const GstStructure *s = gst_event_get_structure (event);
 
-  iter = gst_element_iterate_sink_pads (GST_ELEMENT (rtp_mux));
+      if (gst_structure_has_name (s, "GstRTPCollision")) {
+        guint ssrc = 0;
 
-  while (!done) {
-    GValue item = { 0, };
+        if (!gst_structure_get_uint (s, "ssrc", &ssrc))
+          ssrc = -1;
 
-    switch (gst_iterator_next (iter, &item)) {
-      case GST_ITERATOR_OK:
-        gst_event_ref (event);
-        result |= gst_pad_push_event (g_value_get_object (&item), event);
-        g_value_reset (&item);
-        break;
-      case GST_ITERATOR_RESYNC:
-        gst_iterator_resync (iter);
-        result = FALSE;
-        break;
-      case GST_ITERATOR_ERROR:
-        GST_WARNING_OBJECT (rtp_mux, "Error iterating sinkpads");
-      case GST_ITERATOR_DONE:
-        done = TRUE;
-        break;
+        GST_DEBUG_OBJECT (rtp_mux, "collided ssrc: %" G_GUINT32_FORMAT, ssrc);
+
+        /* choose another ssrc for our stream */
+        GST_OBJECT_LOCK (rtp_mux);
+        if (ssrc == rtp_mux->current_ssrc) {
+          GstCaps *caps;
+          guint suggested_ssrc = 0;
+          guint32 new_ssrc;
+
+          if (gst_structure_get_uint (s, "suggested-ssrc", &suggested_ssrc))
+            rtp_mux->current_ssrc = suggested_ssrc;
+
+          while (ssrc == rtp_mux->current_ssrc)
+            rtp_mux->current_ssrc = g_random_int ();
+
+          new_ssrc = rtp_mux->current_ssrc;
+          GST_OBJECT_UNLOCK (rtp_mux);
+
+          caps = gst_pad_get_current_caps (rtp_mux->srcpad);
+          caps = gst_caps_make_writable (caps);
+          gst_caps_set_simple (caps, "ssrc", G_TYPE_UINT, new_ssrc, NULL);
+          gst_pad_set_caps (rtp_mux->srcpad, caps);
+          gst_caps_unref (caps);
+        } else {
+          GST_OBJECT_UNLOCK (rtp_mux);
+        }
+      }
+      break;
     }
+    default:
+      break;
   }
-  gst_iterator_free (iter);
-  gst_event_unref (event);
 
-  return result;
+
+  return gst_pad_event_default (rtp_mux->srcpad, GST_OBJECT (rtp_mux), event);
 }
 
 static void
@@ -249,6 +266,8 @@
   gst_element_add_pad (GST_ELEMENT (rtp_mux), rtp_mux->srcpad);
 
   rtp_mux->ssrc = DEFAULT_SSRC;
+  rtp_mux->current_ssrc = DEFAULT_SSRC;
+  rtp_mux->ssrc_random = TRUE;
   rtp_mux->ts_offset = DEFAULT_TIMESTAMP_OFFSET;
   rtp_mux->seqnum_offset = DEFAULT_SEQNUM_OFFSET;
 
@@ -414,6 +433,17 @@
 
   rtp_mux = GST_RTP_MUX (parent);
 
+  if (gst_pad_check_reconfigure (rtp_mux->srcpad)) {
+    GstCaps *current_caps = gst_pad_get_current_caps (pad);
+
+    if (!gst_rtp_mux_setcaps (pad, rtp_mux, current_caps)) {
+      ret = GST_FLOW_NOT_NEGOTIATED;
+      gst_buffer_list_unref (bufferlist);
+      goto out;
+    }
+    gst_caps_unref (current_caps);
+  }
+
   GST_OBJECT_LOCK (rtp_mux);
 
   padpriv = gst_pad_get_element_private (pad);
@@ -472,7 +502,18 @@
   gboolean changed = FALSE;
   GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
 
-  rtp_mux = GST_RTP_MUX (GST_OBJECT_PARENT (pad));
+  rtp_mux = GST_RTP_MUX (parent);
+
+  if (gst_pad_check_reconfigure (rtp_mux->srcpad)) {
+    GstCaps *current_caps = gst_pad_get_current_caps (pad);
+
+    if (!gst_rtp_mux_setcaps (pad, rtp_mux, current_caps)) {
+      ret = GST_FLOW_NOT_NEGOTIATED;
+      gst_buffer_unref (buffer);
+      goto out;
+    }
+    gst_caps_unref (current_caps);
+  }
 
   GST_OBJECT_LOCK (rtp_mux);
   padpriv = gst_pad_get_element_private (pad);
@@ -523,6 +564,7 @@
     ret = gst_pad_push (rtp_mux->srcpad, buffer);
   }
 
+out:
   return ret;
 }
 
@@ -532,6 +574,34 @@
   GstStructure *structure;
   gboolean ret = FALSE;
   GstRTPMuxPadPrivate *padpriv;
+  GstCaps *peercaps;
+
+  if (!gst_caps_is_fixed (caps))
+    return FALSE;
+
+  peercaps = gst_pad_peer_query_caps (rtp_mux->srcpad, NULL);
+  if (peercaps) {
+    GstCaps *tcaps, *othercaps;;
+    tcaps = gst_pad_get_pad_template_caps (pad);
+    othercaps = gst_caps_intersect_full (peercaps, tcaps,
+        GST_CAPS_INTERSECT_FIRST);
+
+    if (gst_caps_get_size (othercaps) > 0) {
+      structure = gst_caps_get_structure (othercaps, 0);
+      GST_OBJECT_LOCK (rtp_mux);
+      if (gst_structure_get_uint (structure, "ssrc", &rtp_mux->current_ssrc)) {
+        GST_DEBUG_OBJECT (pad, "Use downstream ssrc: %x",
+            rtp_mux->current_ssrc);
+        rtp_mux->have_ssrc = TRUE;
+      }
+      GST_OBJECT_UNLOCK (rtp_mux);
+    }
+
+    gst_caps_unref (othercaps);
+
+    gst_caps_unref (peercaps);
+    gst_caps_unref (tcaps);
+  }
 
   structure = gst_caps_get_structure (caps, 0);
 
@@ -545,13 +615,25 @@
           &padpriv->timestamp_offset)) {
     padpriv->have_timestamp_offset = TRUE;
   }
-  GST_OBJECT_UNLOCK (rtp_mux);
 
   caps = gst_caps_copy (caps);
 
+  /* if we don't have a specified ssrc, first try to take one from the caps,
+     and if that fails, generate one */
+  if (!rtp_mux->have_ssrc) {
+    if (rtp_mux->ssrc_random) {
+      if (!gst_structure_get_uint (structure, "ssrc", &rtp_mux->current_ssrc))
+        rtp_mux->current_ssrc = g_random_int ();
+      rtp_mux->have_ssrc = TRUE;
+    }
+  }
+
   gst_caps_set_simple (caps,
       "timestamp-offset", G_TYPE_UINT, rtp_mux->ts_base,
-      "seqnum-offset", G_TYPE_UINT, rtp_mux->seqnum_base, NULL);
+      "seqnum-offset", G_TYPE_UINT, rtp_mux->seqnum_base,
+      "ssrc", G_TYPE_UINT, rtp_mux->current_ssrc, NULL);
+
+  GST_OBJECT_UNLOCK (rtp_mux);
 
   if (rtp_mux->send_stream_start) {
     gchar s_id[32];
@@ -567,7 +649,6 @@
       "setting caps %" GST_PTR_FORMAT " on src pad..", caps);
   ret = gst_pad_set_caps (rtp_mux->srcpad, caps);
 
-  gst_structure_get_uint (structure, "ssrc", &rtp_mux->current_ssrc);
 
   gst_caps_unref (caps);
 
@@ -630,9 +711,8 @@
   GstCaps *peercaps;
   GstCaps *othercaps;
   GstCaps *tcaps;
-  GstCaps *other_filtered;
 
-  peercaps = gst_pad_peer_query_caps (mux->srcpad, filter);
+  peercaps = gst_pad_peer_query_caps (mux->srcpad, NULL);
 
   if (peercaps) {
     tcaps = gst_pad_get_pad_template_caps (pad);
@@ -649,21 +729,20 @@
   }
   gst_caps_unref (tcaps);
 
-  clear_caps (othercaps, FALSE);
+  GST_LOG_OBJECT (pad, "Intersected srcpad-peercaps and template caps: %"
+      GST_PTR_FORMAT, othercaps);
 
-  other_filtered = gst_caps_copy (othercaps);
-  clear_caps (other_filtered, TRUE);
+  clear_caps (othercaps, TRUE);
 
   g_value_init (&v, GST_TYPE_CAPS);
 
   iter = gst_element_iterate_sink_pads (GST_ELEMENT (mux));
   do {
-    gst_value_set_caps (&v, other_filtered);
+    gst_value_set_caps (&v, othercaps);
     res = gst_iterator_fold (iter, same_clock_rate_fold, &v, pad);
     gst_iterator_resync (iter);
   } while (res == GST_ITERATOR_RESYNC);
   gst_iterator_free (iter);
-  gst_caps_unref (other_filtered);
 
   caps = gst_caps_intersect ((GstCaps *) gst_value_get_caps (&v), othercaps);
 
@@ -691,8 +770,12 @@
       GstCaps *filter, *caps;
 
       gst_query_parse_caps (query, &filter);
+      GST_LOG_OBJECT (pad, "Received caps-query with filter-caps: %"
+          GST_PTR_FORMAT, filter);
       caps = gst_rtp_mux_getcaps (pad, mux, filter);
       gst_query_set_caps_result (query, caps);
+      GST_LOG_OBJECT (mux, "Answering caps-query with caps: %"
+          GST_PTR_FORMAT, caps);
       gst_caps_unref (caps);
       res = TRUE;
       break;
@@ -703,11 +786,8 @@
   }
 
   return res;
-
-
 }
 
-
 static void
 gst_rtp_mux_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec)
@@ -716,6 +796,7 @@
 
   rtp_mux = GST_RTP_MUX (object);
 
+  GST_OBJECT_LOCK (rtp_mux);
   switch (prop_id) {
     case PROP_TIMESTAMP_OFFSET:
       g_value_set_int (value, rtp_mux->ts_offset);
@@ -724,9 +805,7 @@
       g_value_set_int (value, rtp_mux->seqnum_offset);
       break;
     case PROP_SEQNUM:
-      GST_OBJECT_LOCK (rtp_mux);
       g_value_set_uint (value, rtp_mux->seqnum);
-      GST_OBJECT_UNLOCK (rtp_mux);
       break;
     case PROP_SSRC:
       g_value_set_uint (value, rtp_mux->ssrc);
@@ -735,6 +814,7 @@
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
+  GST_OBJECT_UNLOCK (rtp_mux);
 }
 
 static void
@@ -753,7 +833,12 @@
       rtp_mux->seqnum_offset = g_value_get_int (value);
       break;
     case PROP_SSRC:
+      GST_OBJECT_LOCK (rtp_mux);
       rtp_mux->ssrc = g_value_get_uint (value);
+      rtp_mux->current_ssrc = rtp_mux->ssrc;
+      rtp_mux->have_ssrc = TRUE;
+      rtp_mux->ssrc_random = FALSE;
+      GST_OBJECT_UNLOCK (rtp_mux);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -774,6 +859,8 @@
       GstCaps *caps;
 
       gst_event_parse_caps (event, &caps);
+      GST_LOG_OBJECT (pad, "Received caps-event with caps: %"
+          GST_PTR_FORMAT, caps);
       ret = gst_rtp_mux_setcaps (pad, mux, caps);
       gst_event_unref (event);
       return ret;
@@ -823,11 +910,6 @@
   g_clear_object (&rtp_mux->last_pad);
   rtp_mux->send_stream_start = TRUE;
 
-  if (rtp_mux->ssrc == -1)
-    rtp_mux->current_ssrc = g_random_int ();
-  else
-    rtp_mux->current_ssrc = rtp_mux->ssrc;
-
   if (rtp_mux->seqnum_offset == -1)
     rtp_mux->seqnum_base = g_random_int_range (0, G_MAXUINT16);
   else
@@ -841,6 +923,13 @@
 
   rtp_mux->last_stop = GST_CLOCK_TIME_NONE;
 
+  if (rtp_mux->ssrc_random) {
+    rtp_mux->have_ssrc = FALSE;
+  } else {
+    rtp_mux->current_ssrc = rtp_mux->ssrc;
+    rtp_mux->have_ssrc = TRUE;
+  }
+
   GST_DEBUG_OBJECT (rtp_mux, "set timestamp-offset to %u", rtp_mux->ts_base);
 
   GST_OBJECT_UNLOCK (rtp_mux);
diff --git a/gst/rtpmanager/gstrtpmux.h b/gst/rtpmanager/gstrtpmux.h
index 4b71dee..3de9f41 100644
--- a/gst/rtpmanager/gstrtpmux.h
+++ b/gst/rtpmanager/gstrtpmux.h
@@ -71,6 +71,8 @@
   guint16 seqnum;               /* protected by object lock */
   guint ssrc;
   guint current_ssrc;
+  gboolean have_ssrc;
+  gboolean ssrc_random;
 
   GstPad *last_pad; /* protected by object lock */
 
diff --git a/gst/rtpmanager/gstrtprtxreceive.c b/gst/rtpmanager/gstrtprtxreceive.c
index 71b8023..4773722 100644
--- a/gst/rtpmanager/gstrtprtxreceive.c
+++ b/gst/rtpmanager/gstrtprtxreceive.c
@@ -314,7 +314,7 @@
           seqnum = -1;
 
         /* retrieve ssrc of the packet that need to be retransmitted
-         * it's usefull when reconstructing the original packet from the rtx packet */
+         * it's useful when reconstructing the original packet from the rtx packet */
         if (!gst_structure_get_uint (s, "ssrc", &ssrc))
           ssrc = -1;
 
diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c
index 2604c61..4c41c5d 100644
--- a/gst/rtpmanager/gstrtpsession.c
+++ b/gst/rtpmanager/gstrtpsession.c
@@ -208,6 +208,8 @@
   SIGNAL_ON_BYE_TIMEOUT,
   SIGNAL_ON_TIMEOUT,
   SIGNAL_ON_SENDER_TIMEOUT,
+  SIGNAL_ON_NEW_SENDER_SSRC,
+  SIGNAL_ON_SENDER_SSRC_ACTIVE,
   LAST_SIGNAL
 };
 
@@ -221,8 +223,11 @@
 #define DEFAULT_USE_PIPELINE_CLOCK   FALSE
 #define DEFAULT_RTCP_MIN_INTERVAL    (RTP_STATS_MIN_INTERVAL * GST_SECOND)
 #define DEFAULT_PROBATION            RTP_DEFAULT_PROBATION
+#define DEFAULT_MAX_DROPOUT_TIME     60000
+#define DEFAULT_MAX_MISORDER_TIME    2000
 #define DEFAULT_RTP_PROFILE          GST_RTP_PROFILE_AVP
 #define DEFAULT_NTP_TIME_SOURCE      GST_RTP_NTP_TIME_SOURCE_NTP
+#define DEFAULT_RTCP_SYNC_SEND_TIME  TRUE
 
 enum
 {
@@ -238,9 +243,12 @@
   PROP_USE_PIPELINE_CLOCK,
   PROP_RTCP_MIN_INTERVAL,
   PROP_PROBATION,
+  PROP_MAX_DROPOUT_TIME,
+  PROP_MAX_MISORDER_TIME,
   PROP_STATS,
   PROP_RTP_PROFILE,
-  PROP_NTP_TIME_SOURCE
+  PROP_NTP_TIME_SOURCE,
+  PROP_RTCP_SYNC_SEND_TIME
 };
 
 #define GST_RTP_SESSION_GET_PRIVATE(obj)  \
@@ -274,6 +282,7 @@
 
   gboolean use_pipeline_clock;
   GstRtpNtpTimeSource ntp_time_source;
+  gboolean rtcp_sync_send_time;
 
   guint rtx_count;
 };
@@ -441,6 +450,28 @@
       src->ssrc);
 }
 
+static void
+on_new_sender_ssrc (RTPSession * session, RTPSource * src, GstRtpSession * sess)
+{
+  g_signal_emit (sess, gst_rtp_session_signals[SIGNAL_ON_NEW_SENDER_SSRC], 0,
+      src->ssrc);
+}
+
+static void
+on_sender_ssrc_active (RTPSession * session, RTPSource * src,
+    GstRtpSession * sess)
+{
+  g_signal_emit (sess, gst_rtp_session_signals[SIGNAL_ON_SENDER_SSRC_ACTIVE], 0,
+      src->ssrc);
+}
+
+static void
+on_notify_stats (RTPSession * session, GParamSpec * spec,
+    GstRtpSession * rtpsession)
+{
+  g_object_notify (G_OBJECT (rtpsession), "stats");
+}
+
 #define gst_rtp_session_parent_class parent_class
 G_DEFINE_TYPE (GstRtpSession, gst_rtp_session, GST_TYPE_ELEMENT);
 
@@ -517,7 +548,7 @@
           on_ssrc_validated), NULL, NULL, g_cclosure_marshal_VOID__UINT,
       G_TYPE_NONE, 1, G_TYPE_UINT);
   /**
-   * GstRtpSession::on-ssrc_active:
+   * GstRtpSession::on-ssrc-active:
    * @sess: the object which received the signal
    * @ssrc: the SSRC
    *
@@ -586,6 +617,35 @@
           on_sender_timeout), NULL, NULL, g_cclosure_marshal_VOID__UINT,
       G_TYPE_NONE, 1, G_TYPE_UINT);
 
+  /**
+   * GstRtpSession::on-new-sender-ssrc:
+   * @sess: the object which received the signal
+   * @ssrc: the sender SSRC
+   *
+   * Since: 1.8
+   *
+   * Notify of a new sender SSRC that entered @session.
+   */
+  gst_rtp_session_signals[SIGNAL_ON_NEW_SENDER_SSRC] =
+      g_signal_new ("on-new-sender-ssrc", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpSessionClass, on_new_ssrc),
+      NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
+
+  /**
+   * GstRtpSession::on-sender-ssrc-active:
+   * @sess: the object which received the signal
+   * @ssrc: the sender SSRC
+   *
+   * Since: 1.8
+   *
+   * Notify of a sender SSRC that is active, i.e., sending RTCP.
+   */
+  gst_rtp_session_signals[SIGNAL_ON_SENDER_SSRC_ACTIVE] =
+      g_signal_new ("on-sender-ssrc-active", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpSessionClass,
+          on_ssrc_active), NULL, NULL, g_cclosure_marshal_VOID__UINT,
+      G_TYPE_NONE, 1, G_TYPE_UINT);
+
   g_object_class_install_property (gobject_class, PROP_BANDWIDTH,
       g_param_spec_double ("bandwidth", "Bandwidth",
           "The bandwidth of the session in bytes per second (0 for auto-discover)",
@@ -651,6 +711,18 @@
           0, G_MAXUINT, DEFAULT_PROBATION,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_MAX_DROPOUT_TIME,
+      g_param_spec_uint ("max-dropout-time", "Max dropout time",
+          "The maximum time (milliseconds) of missing packets tolerated.",
+          0, G_MAXUINT, DEFAULT_MAX_DROPOUT_TIME,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_MAX_MISORDER_TIME,
+      g_param_spec_uint ("max-misorder-time", "Max misorder time",
+          "The maximum time (milliseconds) of misordered packets tolerated.",
+          0, G_MAXUINT, DEFAULT_MAX_MISORDER_TIME,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   /**
    * GstRtpSession::stats:
    *
@@ -663,6 +735,8 @@
    *      dropped (due to bandwidth constraints)
    *  "sent-nack-count" G_TYPE_UINT   Number of NACKs sent
    *  "recv-nack-count" G_TYPE_UINT   Number of NACKs received
+   *  "source-stats"    G_TYPE_BOXED  GValueArray of #RTPSource::stats for all
+   *      RTP sources (Since 1.8)
    *
    * Since: 1.4
    */
@@ -682,6 +756,13 @@
           gst_rtp_ntp_time_source_get_type (), DEFAULT_NTP_TIME_SOURCE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_RTCP_SYNC_SEND_TIME,
+      g_param_spec_boolean ("rtcp-sync-send-time", "RTCP Sync Send Time",
+          "Use send time or capture time for RTCP sync "
+          "(TRUE = send time, FALSE = capture time)",
+          DEFAULT_RTCP_SYNC_SEND_TIME,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_rtp_session_change_state);
   gstelement_class->request_new_pad =
@@ -726,6 +807,7 @@
   rtpsession->priv->sysclock = gst_system_clock_obtain ();
   rtpsession->priv->session = rtp_session_new ();
   rtpsession->priv->use_pipeline_clock = DEFAULT_USE_PIPELINE_CLOCK;
+  rtpsession->priv->rtcp_sync_send_time = DEFAULT_RTCP_SYNC_SEND_TIME;
 
   /* configure callbacks */
   rtp_session_set_callbacks (rtpsession->priv->session, &callbacks, rtpsession);
@@ -748,6 +830,12 @@
       (GCallback) on_timeout, rtpsession);
   g_signal_connect (rtpsession->priv->session, "on-sender-timeout",
       (GCallback) on_sender_timeout, rtpsession);
+  g_signal_connect (rtpsession->priv->session, "on-new-sender-ssrc",
+      (GCallback) on_new_sender_ssrc, rtpsession);
+  g_signal_connect (rtpsession->priv->session, "on-sender-ssrc-active",
+      (GCallback) on_sender_ssrc_active, rtpsession);
+  g_signal_connect (rtpsession->priv->session, "notify::stats",
+      (GCallback) on_notify_stats, rtpsession);
   rtpsession->priv->ptmap = g_hash_table_new_full (NULL, NULL, NULL,
       (GDestroyNotify) gst_caps_unref);
 
@@ -815,12 +903,23 @@
     case PROP_PROBATION:
       g_object_set_property (G_OBJECT (priv->session), "probation", value);
       break;
+    case PROP_MAX_DROPOUT_TIME:
+      g_object_set_property (G_OBJECT (priv->session), "max-dropout-time",
+          value);
+      break;
+    case PROP_MAX_MISORDER_TIME:
+      g_object_set_property (G_OBJECT (priv->session), "max-misorder-time",
+          value);
+      break;
     case PROP_RTP_PROFILE:
       g_object_set_property (G_OBJECT (priv->session), "rtp-profile", value);
       break;
     case PROP_NTP_TIME_SOURCE:
       priv->ntp_time_source = g_value_get_enum (value);
       break;
+    case PROP_RTCP_SYNC_SEND_TIME:
+      priv->rtcp_sync_send_time = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -875,6 +974,14 @@
     case PROP_PROBATION:
       g_object_get_property (G_OBJECT (priv->session), "probation", value);
       break;
+    case PROP_MAX_DROPOUT_TIME:
+      g_object_get_property (G_OBJECT (priv->session), "max-dropout-time",
+          value);
+      break;
+    case PROP_MAX_MISORDER_TIME:
+      g_object_get_property (G_OBJECT (priv->session), "max-misorder-time",
+          value);
+      break;
     case PROP_STATS:
       g_value_take_boxed (value, gst_rtp_session_create_stats (rtpsession));
       break;
@@ -884,6 +991,9 @@
     case PROP_NTP_TIME_SOURCE:
       g_value_set_enum (value, priv->ntp_time_source);
       break;
+    case PROP_RTCP_SYNC_SEND_TIME:
+      g_value_set_boolean (value, priv->rtcp_sync_send_time);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -946,6 +1056,7 @@
           ntpns = clock_time;
           break;
         default:
+          ntpns = -1;
           g_assert_not_reached ();
           break;
       }
@@ -2174,7 +2285,8 @@
     running_time =
         gst_segment_to_running_time (&rtpsession->send_rtp_seg, GST_FORMAT_TIME,
         timestamp);
-    running_time += priv->send_latency;
+    if (priv->rtcp_sync_send_time)
+      running_time += priv->send_latency;
   } else {
     /* no timestamp. */
     running_time = -1;
diff --git a/gst/rtpmanager/gstrtpsession.h b/gst/rtpmanager/gstrtpsession.h
index a144c28..1c1c109 100644
--- a/gst/rtpmanager/gstrtpsession.h
+++ b/gst/rtpmanager/gstrtpsession.h
@@ -72,6 +72,8 @@
   void     (*on_bye_timeout)    (GstRtpSession *sess, guint32 ssrc);
   void     (*on_timeout)        (GstRtpSession *sess, guint32 ssrc);
   void     (*on_sender_timeout) (GstRtpSession *sess, guint32 ssrc);
+  void     (*on_new_sender_ssrc)      (GstRtpSession *sess, guint32 ssrc);
+  void     (*on_sender_ssrc_active)   (GstRtpSession *sess, guint32 ssrc);
 };
 
 GType gst_rtp_session_get_type (void);
diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c
index 879b1de..75908c0 100644
--- a/gst/rtpmanager/rtpsession.c
+++ b/gst/rtpmanager/rtpsession.c
@@ -51,6 +51,8 @@
   SIGNAL_SEND_RTCP,
   SIGNAL_SEND_RTCP_FULL,
   SIGNAL_ON_RECEIVING_RTCP,
+  SIGNAL_ON_NEW_SENDER_SSRC,
+  SIGNAL_ON_SENDER_SSRC_ACTIVE,
   LAST_SIGNAL
 };
 
@@ -68,7 +70,10 @@
 #define DEFAULT_RTCP_FEEDBACK_RETENTION_WINDOW (2 * GST_SECOND)
 #define DEFAULT_RTCP_IMMEDIATE_FEEDBACK_THRESHOLD (3)
 #define DEFAULT_PROBATION            RTP_DEFAULT_PROBATION
+#define DEFAULT_MAX_DROPOUT_TIME     60000
+#define DEFAULT_MAX_MISORDER_TIME    2000
 #define DEFAULT_RTP_PROFILE          GST_RTP_PROFILE_AVP
+#define DEFAULT_RTCP_REDUCED_SIZE    FALSE
 
 enum
 {
@@ -89,8 +94,11 @@
   PROP_RTCP_FEEDBACK_RETENTION_WINDOW,
   PROP_RTCP_IMMEDIATE_FEEDBACK_THRESHOLD,
   PROP_PROBATION,
+  PROP_MAX_DROPOUT_TIME,
+  PROP_MAX_MISORDER_TIME,
   PROP_STATS,
-  PROP_RTP_PROFILE
+  PROP_RTP_PROFILE,
+  PROP_RTCP_REDUCED_SIZE
 };
 
 /* update average packet size */
@@ -362,6 +370,36 @@
       NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
       GST_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE);
 
+  /**
+   * RTPSession::on-new-sender-ssrc:
+   * @session: the object which received the signal
+   * @src: the new sender RTPSource
+   *
+   * Notify of a new sender SSRC that entered @session.
+   *
+   * Since: 1.8
+   */
+  rtp_session_signals[SIGNAL_ON_NEW_SENDER_SSRC] =
+      g_signal_new ("on-new-sender-ssrc", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_new_sender_ssrc),
+      NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
+      RTP_TYPE_SOURCE);
+
+  /**
+   * RTPSession::on-sender-ssrc-active:
+   * @session: the object which received the signal
+   * @src: the active sender RTPSource
+   *
+   * Notify of a sender SSRC that is active, i.e., sending RTCP.
+   *
+   * Since: 1.8
+   */
+  rtp_session_signals[SIGNAL_ON_SENDER_SSRC_ACTIVE] =
+      g_signal_new ("on-sender-ssrc-active", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass,
+          on_sender_ssrc_active), NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
+      G_TYPE_NONE, 1, RTP_TYPE_SOURCE);
+
   g_object_class_install_property (gobject_class, PROP_INTERNAL_SSRC,
       g_param_spec_uint ("internal-ssrc", "Internal SSRC",
           "The internal SSRC used for the session (deprecated)",
@@ -374,25 +412,25 @@
 
   g_object_class_install_property (gobject_class, PROP_BANDWIDTH,
       g_param_spec_double ("bandwidth", "Bandwidth",
-          "The bandwidth of the session (0 for auto-discover)",
+          "The bandwidth of the session in bits per second (0 for auto-discover)",
           0.0, G_MAXDOUBLE, DEFAULT_BANDWIDTH,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   g_object_class_install_property (gobject_class, PROP_RTCP_FRACTION,
       g_param_spec_double ("rtcp-fraction", "RTCP Fraction",
-          "The fraction of the bandwidth used for RTCP (or as a real fraction of the RTP bandwidth if < 1)",
+          "The fraction of the bandwidth used for RTCP in bits per second (or as a real fraction of the RTP bandwidth if < 1)",
           0.0, G_MAXDOUBLE, DEFAULT_RTCP_FRACTION,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   g_object_class_install_property (gobject_class, PROP_RTCP_RR_BANDWIDTH,
       g_param_spec_int ("rtcp-rr-bandwidth", "RTCP RR bandwidth",
-          "The RTCP bandwidth used for receivers in bytes per second (-1 = default)",
+          "The RTCP bandwidth used for receivers in bits per second (-1 = default)",
           -1, G_MAXINT, DEFAULT_RTCP_RR_BANDWIDTH,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   g_object_class_install_property (gobject_class, PROP_RTCP_RS_BANDWIDTH,
       g_param_spec_int ("rtcp-rs-bandwidth", "RTCP RS bandwidth",
-          "The RTCP bandwidth used for senders in bytes per second (-1 = default)",
+          "The RTCP bandwidth used for senders in bits per second (-1 = default)",
           -1, G_MAXINT, DEFAULT_RTCP_RS_BANDWIDTH,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
@@ -482,6 +520,18 @@
           0, G_MAXUINT, DEFAULT_PROBATION,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_MAX_DROPOUT_TIME,
+      g_param_spec_uint ("max-dropout-time", "Max dropout time",
+          "The maximum time (milliseconds) of missing packets tolerated.",
+          0, G_MAXUINT, DEFAULT_MAX_DROPOUT_TIME,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_MAX_MISORDER_TIME,
+      g_param_spec_uint ("max-misorder-time", "Max misorder time",
+          "The maximum time (milliseconds) of misordered packets tolerated.",
+          0, G_MAXUINT, DEFAULT_MAX_MISORDER_TIME,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   /**
    * RTPSession::stats:
    *
@@ -492,6 +542,8 @@
    *      dropped (due to bandwidth constraints)
    *  "sent-nack-count" G_TYPE_UINT   Number of NACKs sent
    *  "recv-nack-count" G_TYPE_UINT   Number of NACKs received
+   *  "source-stats"    G_TYPE_BOXED  GValueArray of #RTPSource::stats for all
+   *      RTP sources (Since 1.8)
    *
    * Since: 1.4
    */
@@ -505,6 +557,12 @@
           "RTP profile to use for this session", GST_TYPE_RTP_PROFILE,
           DEFAULT_RTP_PROFILE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_RTCP_REDUCED_SIZE,
+      g_param_spec_boolean ("rtcp-reduced-size", "RTCP Reduced Size",
+          "Use Reduced Size RTCP for feedback packets",
+          DEFAULT_RTCP_REDUCED_SIZE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   klass->get_source_by_ssrc =
       GST_DEBUG_FUNCPTR (rtp_session_get_source_by_ssrc);
   klass->send_rtcp = GST_DEBUG_FUNCPTR (rtp_session_send_rtcp);
@@ -549,6 +607,8 @@
   sess->mtu = DEFAULT_RTCP_MTU;
 
   sess->probation = DEFAULT_PROBATION;
+  sess->max_dropout_time = DEFAULT_MAX_DROPOUT_TIME;
+  sess->max_misorder_time = DEFAULT_MAX_MISORDER_TIME;
 
   /* some default SDES entries */
   sess->sdes = gst_structure_new_empty ("application/x-rtp-source-sdes");
@@ -582,6 +642,7 @@
   sess->rtcp_immediate_feedback_threshold =
       DEFAULT_RTCP_IMMEDIATE_FEEDBACK_THRESHOLD;
   sess->rtp_profile = DEFAULT_RTP_PROFILE;
+  sess->reduced_size_rtcp = DEFAULT_RTCP_REDUCED_SIZE;
 
   sess->last_keyframe_request = GST_CLOCK_TIME_NONE;
 
@@ -642,16 +703,43 @@
   return res;
 }
 
+static void
+create_source_stats (gpointer key, RTPSource * source, GValueArray * arr)
+{
+  GValue value = G_VALUE_INIT;
+  GstStructure *s;
+
+  g_object_get (source, "stats", &s, NULL);
+
+  g_value_init (&value, GST_TYPE_STRUCTURE);
+  gst_value_set_structure (&value, s);
+  g_value_array_append (arr, &value);
+  gst_structure_free (s);
+  g_value_unset (&value);
+}
+
 static GstStructure *
 rtp_session_create_stats (RTPSession * sess)
 {
   GstStructure *s;
+  GValueArray *source_stats;
+  GValue source_stats_v = G_VALUE_INIT;
+  guint size;
 
   s = gst_structure_new ("application/x-rtp-session-stats",
       "rtx-drop-count", G_TYPE_UINT, sess->stats.nacks_dropped,
       "sent-nack-count", G_TYPE_UINT, sess->stats.nacks_sent,
       "recv-nack-count", G_TYPE_UINT, sess->stats.nacks_received, NULL);
 
+  size = g_hash_table_size (sess->ssrcs[sess->mask_idx]);
+  source_stats = g_value_array_new (size);
+  g_hash_table_foreach (sess->ssrcs[sess->mask_idx],
+      (GHFunc) create_source_stats, source_stats);
+
+  g_value_init (&source_stats_v, G_TYPE_VALUE_ARRAY);
+  g_value_take_boxed (&source_stats_v, source_stats);
+  gst_structure_take_value (s, "source-stats", &source_stats_v);
+
   return s;
 }
 
@@ -722,6 +810,12 @@
     case PROP_PROBATION:
       sess->probation = g_value_get_uint (value);
       break;
+    case PROP_MAX_DROPOUT_TIME:
+      sess->max_dropout_time = g_value_get_uint (value);
+      break;
+    case PROP_MAX_MISORDER_TIME:
+      sess->max_misorder_time = g_value_get_uint (value);
+      break;
     case PROP_RTP_PROFILE:
       sess->rtp_profile = g_value_get_enum (value);
       /* trigger reconsideration */
@@ -731,6 +825,9 @@
       if (sess->callbacks.reconsider)
         sess->callbacks.reconsider (sess, sess->reconsider_user_data);
       break;
+    case PROP_RTCP_REDUCED_SIZE:
+      sess->reduced_size_rtcp = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -792,12 +889,21 @@
     case PROP_PROBATION:
       g_value_set_uint (value, sess->probation);
       break;
+    case PROP_MAX_DROPOUT_TIME:
+      g_value_set_uint (value, sess->max_dropout_time);
+      break;
+    case PROP_MAX_MISORDER_TIME:
+      g_value_set_uint (value, sess->max_misorder_time);
+      break;
     case PROP_STATS:
       g_value_take_boxed (value, rtp_session_create_stats (sess));
       break;
     case PROP_RTP_PROFILE:
       g_value_set_enum (value, sess->rtp_profile);
       break;
+    case PROP_RTCP_REDUCED_SIZE:
+      g_value_set_boolean (value, sess->reduced_size_rtcp);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -898,6 +1004,28 @@
   g_object_unref (source);
 }
 
+static void
+on_new_sender_ssrc (RTPSession * sess, RTPSource * source)
+{
+  g_object_ref (source);
+  RTP_SESSION_UNLOCK (sess);
+  g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_NEW_SENDER_SSRC], 0,
+      source);
+  RTP_SESSION_LOCK (sess);
+  g_object_unref (source);
+}
+
+static void
+on_sender_ssrc_active (RTPSession * sess, RTPSource * source)
+{
+  g_object_ref (source);
+  RTP_SESSION_UNLOCK (sess);
+  g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_SENDER_SSRC_ACTIVE], 0,
+      source);
+  RTP_SESSION_LOCK (sess);
+  g_object_unref (source);
+}
+
 /**
  * rtp_session_new:
  *
@@ -1102,7 +1230,7 @@
  * @sess: an #RTPSession
  * @bandwidth: the bandwidth allocated
  *
- * Set the session bandwidth in bytes per second.
+ * Set the session bandwidth in bits per second.
  */
 void
 rtp_session_set_bandwidth (RTPSession * sess, gdouble bandwidth)
@@ -1141,7 +1269,7 @@
  * @sess: an #RTPSession
  * @bandwidth: the RTCP bandwidth
  *
- * Set the bandwidth in bytes per second that should be used for RTCP
+ * Set the bandwidth in bits per second that should be used for RTCP
  * messages.
  */
 void
@@ -1564,10 +1692,9 @@
     /* for RTP packets we need to set the source in probation. Receiving RTCP
      * packets of an SSRC, on the other hand, is a strong indication that we
      * are dealing with a valid source. */
-    if (rtp)
-      g_object_set (source, "probation", sess->probation, NULL);
-    else
-      g_object_set (source, "probation", 0, NULL);
+    g_object_set (source, "probation", rtp ? sess->probation : 0,
+        "max-dropout-time", sess->max_dropout_time, "max-misorder-time",
+        sess->max_misorder_time, NULL);
 
     /* store from address, if any */
     if (pinfo->address) {
@@ -2754,6 +2881,10 @@
     sess->internal_ssrc_from_caps_or_property = TRUE;
     if (source) {
       rtp_source_update_caps (source, caps);
+
+      if (created)
+        on_new_sender_ssrc (sess, source);
+
       g_object_unref (source);
     }
 
@@ -2806,6 +2937,8 @@
     goto invalid_packet;
 
   source = obtain_internal_source (sess, pinfo.ssrc, &created, current_time);
+  if (created)
+    on_new_sender_ssrc (sess, source);
 
   prevsender = RTP_SOURCE_IS_SENDER (source);
   oldrate = source->bitrate;
@@ -3119,6 +3252,9 @@
 
   gst_rtcp_buffer_map (data->rtcp, GST_MAP_READWRITE, rtcp);
 
+  if (data->is_early && sess->reduced_size_rtcp)
+    return;
+
   if (RTP_SOURCE_IS_SENDER (own)) {
     guint64 ntptime;
     guint32 rtptime;
@@ -3715,7 +3851,7 @@
     g_hash_table_foreach (sess->ssrcs[sess->mask_idx],
         (GHFunc) session_report_blocks, data);
   }
-  if (!data->has_sdes)
+  if (!data->has_sdes && (!data->is_early || !sess->reduced_size_rtcp))
     session_sdes (sess, data);
 
   if (data->have_fir)
@@ -3817,6 +3953,10 @@
     source = obtain_internal_source (sess, sess->suggested_ssrc, &created,
         current_time);
     sess->internal_ssrc_set = TRUE;
+
+    if (created)
+      on_new_sender_ssrc (sess, source);
+
     g_object_unref (source);
   }
 
@@ -3842,6 +3982,9 @@
   /* update point-to-point status */
   session_update_ptp (sess);
 
+  /* notify about updated statistics */
+  g_object_notify (G_OBJECT (sess), "stats");
+
   /* see if we need to generate SR or RR packets */
   if (!is_rtcp_time (sess, current_time, &data))
     goto done;
@@ -3883,7 +4026,7 @@
 
   /* push out the RTCP packets */
   while ((output = g_queue_pop_head (&data.output))) {
-    gboolean do_not_suppress;
+    gboolean do_not_suppress, empty_buffer;
     GstBuffer *buffer = output->buffer;
     RTPSource *source = output->source;
 
@@ -3891,7 +4034,13 @@
     g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_SENDING_RTCP], 0,
         buffer, data.is_early, &do_not_suppress);
 
-    if (sess->callbacks.send_rtcp && (do_not_suppress || !data.may_suppress)) {
+    empty_buffer = gst_buffer_get_size (buffer) == 0;
+
+    if (empty_buffer)
+      g_warning ("rtpsession: Trying to send an empty RTCP packet");
+
+    if (sess->callbacks.send_rtcp &&
+        !empty_buffer && (do_not_suppress || !data.may_suppress)) {
       guint packet_size;
 
       packet_size = gst_buffer_get_size (buffer) + sess->header_len;
@@ -3903,11 +4052,17 @@
           sess->callbacks.send_rtcp (sess, source, buffer, output->is_bye,
           sess->send_rtcp_user_data);
       sess->stats.nacks_sent += data.nacked_seqnums;
+
+      RTP_SESSION_LOCK (sess);
+      on_sender_ssrc_active (sess, source);
+      RTP_SESSION_UNLOCK (sess);
     } else {
       GST_DEBUG ("freeing packet callback: %p"
+          " empty_buffer: %d, "
           " do_not_suppress: %d may_suppress: %d", sess->callbacks.send_rtcp,
-          do_not_suppress, data.may_suppress);
-      sess->stats.nacks_dropped += data.nacked_seqnums;
+          empty_buffer, do_not_suppress, data.may_suppress);
+      if (!empty_buffer)
+        sess->stats.nacks_dropped += data.nacked_seqnums;
       gst_buffer_unref (buffer);
     }
     g_object_unref (source);
diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h
index 5af74b8..3d99359 100644
--- a/gst/rtpmanager/rtpsession.h
+++ b/gst/rtpmanager/rtpsession.h
@@ -219,9 +219,13 @@
   GstStructure *sdes;
 
   guint         probation;
+  guint32       max_dropout_time;
+  guint32       max_misorder_time;
 
   GstRTPProfile rtp_profile;
 
+  gboolean      reduced_size_rtcp;
+
   /* bandwidths */
   gboolean     recalc_bandwidth;
   guint        bandwidth;
@@ -309,6 +313,8 @@
       guint sender_ssrc, guint media_ssrc, GstBuffer *fci);
   gboolean (*send_rtcp)     (RTPSession *sess, GstClockTime max_delay);
   void (*on_receiving_rtcp) (RTPSession *sess, GstBuffer *buffer);
+  void (*on_new_sender_ssrc)     (RTPSession *sess, RTPSource *source);
+  void (*on_sender_ssrc_active)  (RTPSession *sess, RTPSource *source);
 };
 
 GType rtp_session_get_type (void);
diff --git a/gst/rtpmanager/rtpsource.c b/gst/rtpmanager/rtpsource.c
index 5aabe41..06c869d 100644
--- a/gst/rtpmanager/rtpsource.c
+++ b/gst/rtpmanager/rtpsource.c
@@ -1,5 +1,7 @@
 /* GStreamer
  * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com>
+ * Copyright (C)  2015 Kurento (http://kurento.org/)
+ *   @author: Miguel París <mparisdiaz@gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -40,6 +42,8 @@
 #define DEFAULT_IS_SENDER            FALSE
 #define DEFAULT_SDES                 NULL
 #define DEFAULT_PROBATION            RTP_DEFAULT_PROBATION
+#define DEFAULT_MAX_DROPOUT_TIME     60000
+#define DEFAULT_MAX_MISORDER_TIME    2000
 
 enum
 {
@@ -50,7 +54,9 @@
   PROP_IS_SENDER,
   PROP_SDES,
   PROP_STATS,
-  PROP_PROBATION
+  PROP_PROBATION,
+  PROP_MAX_DROPOUT_TIME,
+  PROP_MAX_MISORDER_TIME
 };
 
 /* GObject vmethods */
@@ -219,6 +225,18 @@
           0, G_MAXUINT, DEFAULT_PROBATION,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_MAX_DROPOUT_TIME,
+      g_param_spec_uint ("max-dropout-time", "Max dropout time",
+          "The maximum time (milliseconds) of missing packets tolerated.",
+          0, G_MAXUINT, DEFAULT_MAX_DROPOUT_TIME,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_MAX_MISORDER_TIME,
+      g_param_spec_uint ("max-misorder-time", "Max misorder time",
+          "The maximum time (milliseconds) of misordered packets tolerated.",
+          0, G_MAXUINT, DEFAULT_MAX_MISORDER_TIME,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   GST_DEBUG_CATEGORY_INIT (rtp_source_debug, "rtpsource", 0, "RTP Source");
 }
 
@@ -265,6 +283,8 @@
   src->probation = DEFAULT_PROBATION;
   src->curr_probation = src->probation;
   src->closing = FALSE;
+  src->max_dropout_time = DEFAULT_MAX_DROPOUT_TIME;
+  src->max_misorder_time = DEFAULT_MAX_MISORDER_TIME;
 
   src->sdes = gst_structure_new_empty ("application/x-rtp-source-sdes");
 
@@ -505,6 +525,12 @@
     case PROP_PROBATION:
       src->probation = g_value_get_uint (value);
       break;
+    case PROP_MAX_DROPOUT_TIME:
+      src->max_dropout_time = g_value_get_uint (value);
+      break;
+    case PROP_MAX_MISORDER_TIME:
+      src->max_misorder_time = g_value_get_uint (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -541,6 +567,12 @@
     case PROP_PROBATION:
       g_value_set_uint (value, src->probation);
       break;
+    case PROP_MAX_DROPOUT_TIME:
+      g_value_set_uint (value, src->max_dropout_time);
+      break;
+    case PROP_MAX_MISORDER_TIME:
+      g_value_set_uint (value, src->max_misorder_time);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -878,6 +910,7 @@
     GST_DEBUG ("got clock-rate %d", clock_rate);
 
     src->clock_rate = clock_rate;
+    gst_rtp_packet_rate_ctx_reset (&src->packet_rate_ctx, clock_rate);
   }
   return src->clock_rate;
 }
@@ -1005,16 +1038,30 @@
 }
 
 static gboolean
-update_receiver_stats (RTPSource * src, RTPPacketInfo * pinfo)
+update_receiver_stats (RTPSource * src, RTPPacketInfo * pinfo,
+    gboolean is_receive)
 {
   guint16 seqnr, expected;
   RTPSourceStats *stats;
   gint16 delta;
+  gint32 packet_rate, max_dropout, max_misorder;
 
   stats = &src->stats;
 
   seqnr = pinfo->seqnum;
 
+  packet_rate =
+      gst_rtp_packet_rate_ctx_update (&src->packet_rate_ctx, pinfo->seqnum,
+      pinfo->rtptime);
+  max_dropout =
+      gst_rtp_packet_rate_ctx_get_max_dropout (&src->packet_rate_ctx,
+      src->max_dropout_time);
+  max_misorder =
+      gst_rtp_packet_rate_ctx_get_max_misorder (&src->packet_rate_ctx,
+      src->max_misorder_time);
+  GST_TRACE ("SSRC %08x, packet_rate: %d, max_dropout: %d, max_misorder: %d",
+      src->ssrc, packet_rate, max_dropout, max_misorder);
+
   if (stats->cycles == -1) {
     GST_DEBUG ("received first packet");
     /* first time we heard of this source */
@@ -1023,80 +1070,82 @@
     src->curr_probation = src->probation;
   }
 
-  expected = src->stats.max_seq + 1;
-  delta = gst_rtp_buffer_compare_seqnum (expected, seqnr);
+  if (is_receive) {
+    expected = src->stats.max_seq + 1;
+    delta = gst_rtp_buffer_compare_seqnum (expected, seqnr);
 
-  /* if we are still on probation, check seqnum */
-  if (src->curr_probation) {
-    /* when in probation, we require consecutive seqnums */
-    if (delta == 0) {
-      /* expected packet */
-      GST_DEBUG ("probation: seqnr %d == expected %d", seqnr, expected);
-      src->curr_probation--;
+    /* if we are still on probation, check seqnum */
+    if (src->curr_probation) {
+      /* when in probation, we require consecutive seqnums */
+      if (delta == 0) {
+        /* expected packet */
+        GST_DEBUG ("probation: seqnr %d == expected %d", seqnr, expected);
+        src->curr_probation--;
+        if (seqnr < stats->max_seq) {
+          /* sequence number wrapped - count another 64K cycle. */
+          stats->cycles += RTP_SEQ_MOD;
+        }
+        src->stats.max_seq = seqnr;
+
+        if (src->curr_probation == 0) {
+          GST_DEBUG ("probation done!");
+          init_seq (src, seqnr);
+        } else {
+          GstBuffer *q;
+
+          GST_DEBUG ("probation %d: queue packet", src->curr_probation);
+          /* when still in probation, keep packets in a list. */
+          g_queue_push_tail (src->packets, pinfo->data);
+          pinfo->data = NULL;
+          /* remove packets from queue if there are too many */
+          while (g_queue_get_length (src->packets) > RTP_MAX_PROBATION_LEN) {
+            q = g_queue_pop_head (src->packets);
+            gst_buffer_unref (q);
+          }
+          goto done;
+        }
+      } else {
+        /* unexpected seqnum in probation */
+        goto probation_seqnum;
+      }
+    } else if (delta >= 0 && delta < max_dropout) {
+      /* Clear bad packets */
+      stats->bad_seq = RTP_SEQ_MOD + 1; /* so seq == bad_seq is false */
+      g_queue_foreach (src->packets, (GFunc) gst_buffer_unref, NULL);
+      g_queue_clear (src->packets);
+
+      /* in order, with permissible gap */
       if (seqnr < stats->max_seq) {
         /* sequence number wrapped - count another 64K cycle. */
         stats->cycles += RTP_SEQ_MOD;
       }
-      src->stats.max_seq = seqnr;
-
-      if (src->curr_probation == 0) {
-        GST_DEBUG ("probation done!");
+      stats->max_seq = seqnr;
+    } else if (delta < -max_misorder || delta >= max_dropout) {
+      /* the sequence number made a very large jump */
+      if (seqnr == stats->bad_seq && src->packets->head) {
+        /* two sequential packets -- assume that the other side
+         * restarted without telling us so just re-sync
+         * (i.e., pretend this was the first packet).  */
         init_seq (src, seqnr);
       } else {
-        GstBuffer *q;
-
-        GST_DEBUG ("probation %d: queue packet", src->curr_probation);
-        /* when still in probation, keep packets in a list. */
+        /* unacceptable jump */
+        stats->bad_seq = (seqnr + 1) & (RTP_SEQ_MOD - 1);
+        g_queue_foreach (src->packets, (GFunc) gst_buffer_unref, NULL);
+        g_queue_clear (src->packets);
         g_queue_push_tail (src->packets, pinfo->data);
         pinfo->data = NULL;
-        /* remove packets from queue if there are too many */
-        while (g_queue_get_length (src->packets) > RTP_MAX_PROBATION_LEN) {
-          q = g_queue_pop_head (src->packets);
-          gst_buffer_unref (q);
-        }
-        goto done;
+        goto bad_sequence;
       }
-    } else {
-      /* unexpected seqnum in probation */
-      goto probation_seqnum;
-    }
-  } else if (delta >= 0 && delta < RTP_MAX_DROPOUT) {
-    /* Clear bad packets */
-    stats->bad_seq = RTP_SEQ_MOD + 1;   /* so seq == bad_seq is false */
-    g_queue_foreach (src->packets, (GFunc) gst_buffer_unref, NULL);
-    g_queue_clear (src->packets);
-
-    /* in order, with permissible gap */
-    if (seqnr < stats->max_seq) {
-      /* sequence number wrapped - count another 64K cycle. */
-      stats->cycles += RTP_SEQ_MOD;
-    }
-    stats->max_seq = seqnr;
-  } else if (delta < -RTP_MAX_MISORDER || delta >= RTP_MAX_DROPOUT) {
-    /* the sequence number made a very large jump */
-    if (seqnr == stats->bad_seq && src->packets->head) {
-      /* two sequential packets -- assume that the other side
-       * restarted without telling us so just re-sync
-       * (i.e., pretend this was the first packet).  */
-      init_seq (src, seqnr);
-    } else {
-      /* unacceptable jump */
-      stats->bad_seq = (seqnr + 1) & (RTP_SEQ_MOD - 1);
+    } else {                    /* delta < 0 && delta >= -max_misorder */
+      /* Clear bad packets */
+      stats->bad_seq = RTP_SEQ_MOD + 1; /* so seq == bad_seq is false */
       g_queue_foreach (src->packets, (GFunc) gst_buffer_unref, NULL);
       g_queue_clear (src->packets);
-      g_queue_push_tail (src->packets, pinfo->data);
-      pinfo->data = NULL;
-      goto bad_sequence;
-    }
-  } else {                      /* delta < 0 && delta >= -RTP_MAX_MISORDER */
-    /* Clear bad packets */
-    stats->bad_seq = RTP_SEQ_MOD + 1;   /* so seq == bad_seq is false */
-    g_queue_foreach (src->packets, (GFunc) gst_buffer_unref, NULL);
-    g_queue_clear (src->packets);
 
-    /* duplicate or reordered packet, will be filtered by jitterbuffer. */
-    GST_WARNING ("duplicate or reordered packet (seqnr %u, expected %u)", seqnr,
-        expected);
+      /* duplicate or reordered packet, will be filtered by jitterbuffer. */
+      GST_WARNING ("duplicate or reordered packet (seqnr %u, expected %u)",
+          seqnr, expected);
+    }
   }
 
   src->stats.octets_received += pinfo->payload_len;
@@ -1117,7 +1166,9 @@
   }
 bad_sequence:
   {
-    GST_WARNING ("unacceptable seqnum received");
+    GST_WARNING
+        ("unacceptable seqnum received (seqnr %u, delta %d, packet_rate: %d, max_dropout: %d, max_misorder: %d)",
+        seqnr, delta, packet_rate, max_dropout, max_misorder);
     return FALSE;
   }
 probation_seqnum:
@@ -1146,7 +1197,7 @@
   g_return_val_if_fail (RTP_IS_SOURCE (src), GST_FLOW_ERROR);
   g_return_val_if_fail (pinfo != NULL, GST_FLOW_ERROR);
 
-  if (!update_receiver_stats (src, pinfo))
+  if (!update_receiver_stats (src, pinfo, TRUE))
     return GST_FLOW_OK;
 
   /* the source that sent the packet must be a sender */
@@ -1217,7 +1268,7 @@
   src->is_sender = TRUE;
 
   /* we are also a receiver of our packets */
-  if (!update_receiver_stats (src, pinfo))
+  if (!update_receiver_stats (src, pinfo, FALSE))
     return GST_FLOW_OK;
 
   /* update stats for the SR */
@@ -1433,17 +1484,15 @@
      * We need to apply this diff to the RTP timestamp to get the RTP timestamp
      * for the given ntpnstime. */
     diff = GST_CLOCK_DIFF (src->last_rtime, running_time);
+    GST_DEBUG ("running_time %" GST_TIME_FORMAT ", diff %" GST_STIME_FORMAT,
+        GST_TIME_ARGS (running_time), GST_STIME_ARGS (diff));
 
     /* now translate the diff to RTP time, handle positive and negative cases.
      * If there is no diff, we already set rtptime correctly above. */
     if (diff > 0) {
-      GST_DEBUG ("running_time %" GST_TIME_FORMAT ", diff %" GST_TIME_FORMAT,
-          GST_TIME_ARGS (running_time), GST_TIME_ARGS (diff));
       t_rtp += gst_util_uint64_scale_int (diff, src->clock_rate, GST_SECOND);
     } else {
       diff = -diff;
-      GST_DEBUG ("running_time %" GST_TIME_FORMAT ", diff -%" GST_TIME_FORMAT,
-          GST_TIME_ARGS (running_time), GST_TIME_ARGS (diff));
       t_rtp -= gst_util_uint64_scale_int (diff, src->clock_rate, GST_SECOND);
     }
   } else {
diff --git a/gst/rtpmanager/rtpsource.h b/gst/rtpmanager/rtpsource.h
index 0f47fae..941c7d6 100644
--- a/gst/rtpmanager/rtpsource.h
+++ b/gst/rtpmanager/rtpsource.h
@@ -1,5 +1,7 @@
 /* GStreamer
  * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com>
+ * Copyright (C)  2015 Kurento (http://kurento.org/)
+ *   @author: Miguel París <mparisdiaz@gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -174,6 +176,9 @@
   guint64       bytes_received;
 
   GQueue       *packets;
+  RTPPacketRateCtx packet_rate_ctx;
+  guint32       max_dropout_time;
+  guint32       max_misorder_time;
 
   RTPSourceCallbacks callbacks;
   gpointer           user_data;
diff --git a/gst/rtpmanager/rtpstats.c b/gst/rtpmanager/rtpstats.c
index f9f7c2c..984bc9f 100644
--- a/gst/rtpmanager/rtpstats.c
+++ b/gst/rtpmanager/rtpstats.c
@@ -1,5 +1,7 @@
 /* GStreamer
  * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com>
+ * Copyright (C)  2015 Kurento (http://kurento.org/)
+ *   @author: Miguel París <mparisdiaz@gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -19,6 +21,89 @@
 
 #include "rtpstats.h"
 
+void
+gst_rtp_packet_rate_ctx_reset (RTPPacketRateCtx * ctx, guint32 clock_rate)
+{
+  ctx->clock_rate = clock_rate;
+  ctx->probed = FALSE;
+  ctx->avg_packet_rate = -1;
+}
+
+guint32
+gst_rtp_packet_rate_ctx_update (RTPPacketRateCtx * ctx, guint16 seqnum,
+    guint32 ts)
+{
+  guint64 new_ts, diff_ts;
+  gint diff_seqnum;
+  guint32 new_packet_rate;
+
+  if (ctx->clock_rate <= 0) {
+    return ctx->avg_packet_rate;
+  }
+
+  if (!ctx->probed) {
+    ctx->last_seqnum = seqnum;
+    ctx->last_ts = ts;
+    ctx->probed = TRUE;
+    return ctx->avg_packet_rate;
+  }
+
+  new_ts = ctx->last_ts;
+  gst_rtp_buffer_ext_timestamp (&new_ts, ts);
+  diff_seqnum = gst_rtp_buffer_compare_seqnum (ctx->last_seqnum, seqnum);
+  if (diff_seqnum <= 0 || new_ts <= ctx->last_ts) {
+    return ctx->avg_packet_rate;
+  }
+
+  diff_ts = new_ts - ctx->last_ts;
+  diff_ts = gst_util_uint64_scale_int (diff_ts, GST_SECOND, ctx->clock_rate);
+  new_packet_rate = gst_util_uint64_scale (diff_seqnum, GST_SECOND, diff_ts);
+
+  /* The goal is that higher packet rates "win".
+   * If there's a sudden burst, the average will go up fast,
+   * but it will go down again slowly.
+   * This is useful for bursty cases, where a lot of packets are close
+   * to each other and should allow a higher reorder/dropout there.
+   */
+  if (ctx->avg_packet_rate > new_packet_rate) {
+    ctx->avg_packet_rate = (7 * ctx->avg_packet_rate + new_packet_rate + 7) / 8;
+  } else {
+    ctx->avg_packet_rate = (ctx->avg_packet_rate + new_packet_rate + 1) / 2;
+  }
+
+  ctx->last_seqnum = seqnum;
+  ctx->last_ts = new_ts;
+
+  return ctx->avg_packet_rate;
+}
+
+guint32
+gst_rtp_packet_rate_ctx_get (RTPPacketRateCtx * ctx)
+{
+  return ctx->avg_packet_rate;
+}
+
+guint32
+gst_rtp_packet_rate_ctx_get_max_dropout (RTPPacketRateCtx * ctx, gint32 time_ms)
+{
+  if (time_ms <= 0 || !ctx->probed) {
+    return RTP_DEF_DROPOUT;
+  }
+
+  return MAX (RTP_MIN_DROPOUT, ctx->avg_packet_rate * time_ms / 1000);
+}
+
+guint32
+gst_rtp_packet_rate_ctx_get_max_misorder (RTPPacketRateCtx * ctx,
+    gint32 time_ms)
+{
+  if (time_ms <= 0 || !ctx->probed) {
+    return RTP_DEF_MISORDER;
+  }
+
+  return MAX (RTP_MIN_MISORDER, ctx->avg_packet_rate * time_ms / 1000);
+}
+
 /**
  * rtp_stats_init_defaults:
  * @stats: an #RTPSessionStats struct
diff --git a/gst/rtpmanager/rtpstats.h b/gst/rtpmanager/rtpstats.h
index d221aea..14ba9da 100644
--- a/gst/rtpmanager/rtpstats.h
+++ b/gst/rtpmanager/rtpstats.h
@@ -1,5 +1,7 @@
 /* GStreamer
  * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com>
+ * Copyright (C)  2015 Kurento (http://kurento.org/)
+ *   @author: Miguel París <mparisdiaz@gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -183,15 +185,37 @@
 #define RTP_STATS_BYE_TIMEOUT           (2 * GST_SECOND)
 
 /*
- * The maximum number of missing packets we tolerate. These are packets with a
- * sequence number bigger than the last seen packet.
+ * The default and minimum values of the maximum number of missing packets we tolerate.
+ * These are packets with asequence number bigger than the last seen packet.
  */
-#define RTP_MAX_DROPOUT      3000
+#define RTP_DEF_DROPOUT      3000
+#define RTP_MIN_DROPOUT      30
+
 /*
- * The maximum number of misordered packets we tolerate. These are packets with
- * a sequence number smaller than the last seen packet.
+ * The default and minimum values of the maximum number of misordered packets we tolerate.
+ * These are packets with a sequence number smaller than the last seen packet.
  */
-#define RTP_MAX_MISORDER     100
+#define RTP_DEF_MISORDER     100
+#define RTP_MIN_MISORDER     10
+
+/**
+ * RTPPacketRateCtx:
+ *
+ * Context to calculate the pseudo-average packet rate.
+ */
+typedef struct {
+  gboolean probed;
+  guint32 clock_rate;
+  guint16 last_seqnum;
+  guint64 last_ts;
+  guint32 avg_packet_rate;
+} RTPPacketRateCtx;
+
+void gst_rtp_packet_rate_ctx_reset (RTPPacketRateCtx * ctx, guint32 clock_rate);
+guint32 gst_rtp_packet_rate_ctx_update (RTPPacketRateCtx *ctx, guint16 seqnum, guint32 ts);
+guint32 gst_rtp_packet_rate_ctx_get (RTPPacketRateCtx *ctx);
+guint32 gst_rtp_packet_rate_ctx_get_max_dropout (RTPPacketRateCtx *ctx, gint32 time_ms);
+guint32 gst_rtp_packet_rate_ctx_get_max_misorder (RTPPacketRateCtx *ctx, gint32 time_ms);
 
 /**
  * RTPSessionStats:
diff --git a/gst/rtsp/Makefile.in b/gst/rtsp/Makefile.in
index dd1c76b..2c4c5ee 100644
--- a/gst/rtsp/Makefile.in
+++ b/gst/rtsp/Makefile.in
@@ -480,6 +480,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c
index 1f22e98..7b40f37 100644
--- a/gst/rtsp/gstrtspsrc.c
+++ b/gst/rtsp/gstrtspsrc.c
@@ -232,6 +232,7 @@
 #define DEFAULT_DO_RETRANSMISSION        TRUE
 #define DEFAULT_NTP_TIME_SOURCE  NTP_TIME_SOURCE_NTP
 #define DEFAULT_USER_AGENT       "GStreamer/" PACKAGE_VERSION
+#define DEFAULT_MAX_RTCP_RTP_TIME_DIFF 1000
 
 enum
 {
@@ -269,7 +270,8 @@
   PROP_TLS_INTERACTION,
   PROP_DO_RETRANSMISSION,
   PROP_NTP_TIME_SOURCE,
-  PROP_USER_AGENT
+  PROP_USER_AGENT,
+  PROP_MAX_RTCP_RTP_TIME_DIFF
 };
 
 #define GST_TYPE_RTSP_NAT_METHOD (gst_rtsp_nat_method_get_type())
@@ -340,6 +342,8 @@
     GstRTSPStream * stream, GstEvent * event);
 static gboolean gst_rtspsrc_push_event (GstRTSPSrc * src, GstEvent * event);
 static void gst_rtspsrc_connection_flush (GstRTSPSrc * src, gboolean flush);
+static GstRTSPResult gst_rtsp_conninfo_close (GstRTSPSrc * src,
+    GstRTSPConnInfo * info, gboolean free);
 
 typedef struct
 {
@@ -732,6 +736,13 @@
           "The User-Agent string to send to the server",
           DEFAULT_USER_AGENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_MAX_RTCP_RTP_TIME_DIFF,
+      g_param_spec_int ("max-rtcp-rtp-time-diff", "Max RTCP RTP Time Diff",
+          "Maximum amount of time in ms that the RTP time in RTCP SRs "
+          "is allowed to be ahead (-1 disabled)", -1, G_MAXINT,
+          DEFAULT_MAX_RTCP_RTP_TIME_DIFF,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   /**
    * GstRTSPSrc::handle-request:
    * @rtspsrc: a #GstRTSPSrc
@@ -879,6 +890,7 @@
   src->do_retransmission = DEFAULT_DO_RETRANSMISSION;
   src->ntp_time_source = DEFAULT_NTP_TIME_SOURCE;
   src->user_agent = g_strdup (DEFAULT_USER_AGENT);
+  src->max_rtcp_rtp_time_diff = DEFAULT_MAX_RTCP_RTP_TIME_DIFF;
 
   /* get a list of all extensions */
   src->extensions = gst_rtsp_ext_list_get ();
@@ -1072,26 +1084,22 @@
       gst_rtspsrc_set_proxy (rtspsrc, g_value_get_string (value));
       break;
     case PROP_PROXY_ID:
-      if (rtspsrc->prop_proxy_id)
-        g_free (rtspsrc->prop_proxy_id);
+      g_free (rtspsrc->prop_proxy_id);
       rtspsrc->prop_proxy_id = g_value_dup_string (value);
       break;
     case PROP_PROXY_PW:
-      if (rtspsrc->prop_proxy_pw)
-        g_free (rtspsrc->prop_proxy_pw);
+      g_free (rtspsrc->prop_proxy_pw);
       rtspsrc->prop_proxy_pw = g_value_dup_string (value);
       break;
     case PROP_RTP_BLOCKSIZE:
       rtspsrc->rtp_blocksize = g_value_get_uint (value);
       break;
     case PROP_USER_ID:
-      if (rtspsrc->user_id)
-        g_free (rtspsrc->user_id);
+      g_free (rtspsrc->user_id);
       rtspsrc->user_id = g_value_dup_string (value);
       break;
     case PROP_USER_PW:
-      if (rtspsrc->user_pw)
-        g_free (rtspsrc->user_pw);
+      g_free (rtspsrc->user_pw);
       rtspsrc->user_pw = g_value_dup_string (value);
       break;
     case PROP_BUFFER_MODE:
@@ -1102,10 +1110,8 @@
       const gchar *str;
 
       str = g_value_get_string (value);
-      if (str) {
-        sscanf (str, "%u-%u",
-            &rtspsrc->client_port_range.min, &rtspsrc->client_port_range.max);
-      } else {
+      if (sscanf (str, "%u-%u", &rtspsrc->client_port_range.min,
+              &rtspsrc->client_port_range.max) != 2) {
         rtspsrc->client_port_range.min = 0;
         rtspsrc->client_port_range.max = 0;
       }
@@ -1161,6 +1167,9 @@
       g_free (rtspsrc->user_agent);
       rtspsrc->user_agent = g_value_dup_string (value);
       break;
+    case PROP_MAX_RTCP_RTP_TIME_DIFF:
+      rtspsrc->max_rtcp_rtp_time_diff = g_value_get_int (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1304,6 +1313,9 @@
     case PROP_USER_AGENT:
       g_value_set_string (value, rtspsrc->user_agent);
       break;
+    case PROP_MAX_RTCP_RTP_TIME_DIFF:
+      g_value_set_int (value, rtspsrc->max_rtcp_rtp_time_diff);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -3493,6 +3505,11 @@
             NULL);
       }
 
+      if (g_object_class_find_property (klass, "max-rtcp-rtp-time-diff")) {
+        g_object_set (src->manager, "max-rtcp-rtp-time-diff",
+            src->max_rtcp_rtp_time_diff, NULL);
+      }
+
       /* buffer mode pauses are handled by adding offsets to buffer times,
        * but some depayloaders may have a hard time syncing output times
        * with such input times, e.g. container ones, most notably ASF */
@@ -4476,69 +4493,90 @@
     gboolean async)
 {
   GstRTSPResult res;
+  GstRTSPMessage response;
+  gboolean retry = FALSE;
+  memset (&response, 0, sizeof (response));
+  gst_rtsp_message_init (&response);
+  do {
+    if (info->connection == NULL) {
+      if (info->url == NULL) {
+        GST_DEBUG_OBJECT (src, "parsing uri (%s)...", info->location);
+        if ((res = gst_rtsp_url_parse (info->location, &info->url)) < 0)
+          goto parse_error;
+      }
+      /* create connection */
+      GST_DEBUG_OBJECT (src, "creating connection (%s)...", info->location);
+      if ((res = gst_rtsp_connection_create (info->url, &info->connection)) < 0)
+        goto could_not_create;
 
-  if (info->connection == NULL) {
-    if (info->url == NULL) {
-      GST_DEBUG_OBJECT (src, "parsing uri (%s)...", info->location);
-      if ((res = gst_rtsp_url_parse (info->location, &info->url)) < 0)
-        goto parse_error;
-    }
+      if (retry) {
+        gst_rtspsrc_setup_auth (src, &response);
+      }
 
-    /* create connection */
-    GST_DEBUG_OBJECT (src, "creating connection (%s)...", info->location);
-    if ((res = gst_rtsp_connection_create (info->url, &info->connection)) < 0)
-      goto could_not_create;
-
-    if (info->url_str)
       g_free (info->url_str);
-    info->url_str = gst_rtsp_url_get_request_uri (info->url);
+      info->url_str = gst_rtsp_url_get_request_uri (info->url);
 
-    GST_DEBUG_OBJECT (src, "sanitized uri %s", info->url_str);
+      GST_DEBUG_OBJECT (src, "sanitized uri %s", info->url_str);
 
-    if (info->url->transports & GST_RTSP_LOWER_TRANS_TLS) {
-      if (!gst_rtsp_connection_set_tls_validation_flags (info->connection,
-              src->tls_validation_flags))
-        GST_WARNING_OBJECT (src, "Unable to set TLS validation flags");
+      if (info->url->transports & GST_RTSP_LOWER_TRANS_TLS) {
+        if (!gst_rtsp_connection_set_tls_validation_flags (info->connection,
+                src->tls_validation_flags))
+          GST_WARNING_OBJECT (src, "Unable to set TLS validation flags");
 
-      if (src->tls_database)
-        gst_rtsp_connection_set_tls_database (info->connection,
-            src->tls_database);
+        if (src->tls_database)
+          gst_rtsp_connection_set_tls_database (info->connection,
+              src->tls_database);
 
-      if (src->tls_interaction)
-        gst_rtsp_connection_set_tls_interaction (info->connection,
-            src->tls_interaction);
+        if (src->tls_interaction)
+          gst_rtsp_connection_set_tls_interaction (info->connection,
+              src->tls_interaction);
+      }
+
+      if (info->url->transports & GST_RTSP_LOWER_TRANS_HTTP)
+        gst_rtsp_connection_set_tunneled (info->connection, TRUE);
+
+      if (src->proxy_host) {
+        GST_DEBUG_OBJECT (src, "setting proxy %s:%d", src->proxy_host,
+            src->proxy_port);
+        gst_rtsp_connection_set_proxy (info->connection, src->proxy_host,
+            src->proxy_port);
+      }
     }
 
-    if (info->url->transports & GST_RTSP_LOWER_TRANS_HTTP)
-      gst_rtsp_connection_set_tunneled (info->connection, TRUE);
+    if (!info->connected) {
+      /* connect */
+      if (async)
+        GST_ELEMENT_PROGRESS (src, CONTINUE, "connect",
+            ("Connecting to %s", info->location));
+      GST_DEBUG_OBJECT (src, "connecting (%s)...", info->location);
+      res = gst_rtsp_connection_connect_with_response (info->connection,
+          src->ptcp_timeout, &response);
 
-    if (src->proxy_host) {
-      GST_DEBUG_OBJECT (src, "setting proxy %s:%d", src->proxy_host,
-          src->proxy_port);
-      gst_rtsp_connection_set_proxy (info->connection, src->proxy_host,
-          src->proxy_port);
+      if (response.type == GST_RTSP_MESSAGE_HTTP_RESPONSE &&
+          response.type_data.response.code == GST_RTSP_STS_UNAUTHORIZED) {
+        gst_rtsp_conninfo_close (src, info, TRUE);
+        if (!retry)
+          retry = TRUE;
+        else
+          retry = FALSE;        // we should not retry more than once
+      } else {
+        retry = FALSE;
+      }
+
+      if (res == GST_RTSP_OK)
+        info->connected = TRUE;
+      else if (!retry)
+        goto could_not_connect;
     }
-  }
-
-  if (!info->connected) {
-    /* connect */
-    if (async)
-      GST_ELEMENT_PROGRESS (src, CONTINUE, "connect",
-          ("Connecting to %s", info->location));
-    GST_DEBUG_OBJECT (src, "connecting (%s)...", info->location);
-    if ((res =
-            gst_rtsp_connection_connect (info->connection,
-                src->ptcp_timeout)) < 0)
-      goto could_not_connect;
-
-    info->connected = TRUE;
-  }
+  } while (!info->connected && retry);
+  gst_rtsp_message_unset (&response);
   return GST_RTSP_OK;
 
   /* ERRORS */
 parse_error:
   {
     GST_ERROR_OBJECT (src, "No valid RTSP URL was provided");
+    gst_rtsp_message_unset (&response);
     return res;
   }
 could_not_create:
@@ -4546,6 +4584,7 @@
     gchar *str = gst_rtsp_strresult (res);
     GST_ERROR_OBJECT (src, "Could not create connection. (%s)", str);
     g_free (str);
+    gst_rtsp_message_unset (&response);
     return res;
   }
 could_not_connect:
@@ -4553,6 +4592,7 @@
     gchar *str = gst_rtsp_strresult (res);
     GST_ERROR_OBJECT (src, "Could not connect to server. (%s)", str);
     g_free (str);
+    gst_rtsp_message_unset (&response);
     return res;
   }
 }
diff --git a/gst/rtsp/gstrtspsrc.h b/gst/rtsp/gstrtspsrc.h
index a3d0a9a..dc218dc 100644
--- a/gst/rtsp/gstrtspsrc.h
+++ b/gst/rtsp/gstrtspsrc.h
@@ -238,6 +238,7 @@
   gboolean          do_retransmission;
   gint              ntp_time_source;
   gchar            *user_agent;
+  GstClockTime      max_rtcp_rtp_time_diff;
 
   /* state */
   GstRTSPState       state;
diff --git a/gst/shapewipe/Makefile.in b/gst/shapewipe/Makefile.in
index a7cffc9..b34cb4d 100644
--- a/gst/shapewipe/Makefile.in
+++ b/gst/shapewipe/Makefile.in
@@ -476,6 +476,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/smpte/Makefile.in b/gst/smpte/Makefile.in
index e9c7e6e..9def17c 100644
--- a/gst/smpte/Makefile.in
+++ b/gst/smpte/Makefile.in
@@ -479,6 +479,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/smpte/gstsmpte.c b/gst/smpte/gstsmpte.c
index 696a1b4..294d809 100644
--- a/gst/smpte/gstsmpte.c
+++ b/gst/smpte/gstsmpte.c
@@ -97,18 +97,6 @@
   PROP_INVERT
 };
 
-/* FIXME: should use video meta etc. */
-#define I420_Y_ROWSTRIDE(width) (GST_ROUND_UP_4(width))
-#define I420_U_ROWSTRIDE(width) (GST_ROUND_UP_8(width)/2)
-#define I420_V_ROWSTRIDE(width) ((GST_ROUND_UP_8(I420_Y_ROWSTRIDE(width)))/2)
-
-#define I420_Y_OFFSET(w,h) (0)
-#define I420_U_OFFSET(w,h) (I420_Y_OFFSET(w,h)+(I420_Y_ROWSTRIDE(w)*GST_ROUND_UP_2(h)))
-#define I420_V_OFFSET(w,h) (I420_U_OFFSET(w,h)+(I420_U_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
-
-#define I420_SIZE(w,h)     (I420_V_OFFSET(w,h)+(I420_V_ROWSTRIDE(w)*GST_ROUND_UP_2(h)/2))
-
-
 #define GST_TYPE_SMPTE_TRANSITION_TYPE (gst_smpte_transition_type_get_type())
 static GType
 gst_smpte_transition_type_get_type (void)
@@ -219,13 +207,13 @@
 static const int v_colors[] = { 128, 155, 0, 21, 235, 255, 107, 128, 128, 255 };
 
 static void
-fill_i420 (guint8 * data, gint width, gint height, gint color)
+fill_i420 (GstVideoInfo * vinfo, guint8 * data, gint height, gint color)
 {
-  gint size = I420_Y_ROWSTRIDE (width) * GST_ROUND_UP_2 (height);
+  gint size = GST_VIDEO_INFO_COMP_STRIDE (vinfo, 0) * GST_ROUND_UP_2 (height);
   gint size4 = size >> 2;
   guint8 *yp = data;
-  guint8 *up = data + I420_U_OFFSET (width, height);
-  guint8 *vp = data + I420_V_OFFSET (width, height);
+  guint8 *up = data + GST_VIDEO_INFO_COMP_OFFSET (vinfo, 1);
+  guint8 *vp = data + GST_VIDEO_INFO_COMP_OFFSET (vinfo, 2);
 
   memset (yp, y_colors[color], size);
   memset (up, u_colors[color], size4);
@@ -375,6 +363,9 @@
   if (smpte->collect) {
     gst_object_unref (smpte->collect);
   }
+  if (smpte->mask) {
+    gst_mask_destroy (smpte->mask);
+  }
 
   G_OBJECT_CLASS (parent_class)->finalize ((GObject *) smpte);
 }
@@ -496,21 +487,21 @@
 
   if (in1 == NULL) {
     /* if no input, make picture black */
-    in1 = gst_buffer_new_and_alloc (I420_SIZE (smpte->width, smpte->height));
+    in1 = gst_buffer_new_and_alloc (GST_VIDEO_INFO_SIZE (&smpte->vinfo1));
     gst_buffer_map (in1, &map, GST_MAP_WRITE);
-    fill_i420 (map.data, smpte->width, smpte->height, 7);
+    fill_i420 (&smpte->vinfo1, map.data, smpte->height, 7);
     gst_buffer_unmap (in1, &map);
   }
   if (in2 == NULL) {
     /* if no input, make picture white */
-    in2 = gst_buffer_new_and_alloc (I420_SIZE (smpte->width, smpte->height));
+    in2 = gst_buffer_new_and_alloc (GST_VIDEO_INFO_SIZE (&smpte->vinfo2));
     gst_buffer_map (in2, &map, GST_MAP_WRITE);
-    fill_i420 (map.data, smpte->width, smpte->height, 0);
+    fill_i420 (&smpte->vinfo2, map.data, smpte->height, 0);
     gst_buffer_unmap (in2, &map);
   }
 
   if (smpte->position < smpte->end_position) {
-    outbuf = gst_buffer_new_and_alloc (I420_SIZE (smpte->width, smpte->height));
+    outbuf = gst_buffer_new_and_alloc (GST_VIDEO_INFO_SIZE (&smpte->vinfo1));
 
     /* set caps if not done yet */
     if (!gst_pad_has_current_caps (smpte->srcpad)) {
diff --git a/gst/spectrum/Makefile.in b/gst/spectrum/Makefile.in
index 0c48bf9..ad2ec57 100644
--- a/gst/spectrum/Makefile.in
+++ b/gst/spectrum/Makefile.in
@@ -477,6 +477,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/udp/Makefile.in b/gst/udp/Makefile.in
index 60a3cac..8e2ffcf 100644
--- a/gst/udp/Makefile.in
+++ b/gst/udp/Makefile.in
@@ -480,6 +480,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c
index b4ebba4..34aa7e4 100644
--- a/gst/udp/gstudpsrc.c
+++ b/gst/udp/gstudpsrc.c
@@ -41,7 +41,7 @@
  * one.
  *
  * The #GstUDPSrc:caps property is mainly used to give a type to the UDP packet
- * so that they can be autoplugged in GStreamer pipelines. This is very usefull
+ * so that they can be autoplugged in GStreamer pipelines. This is very useful
  * for RTP implementations where the contents of the UDP packets is transfered
  * out-of-bounds using SDP or other means.
  *
@@ -112,24 +112,7 @@
 
 #include <gst/net/gstnetaddressmeta.h>
 
-#if GLIB_CHECK_VERSION (2, 35, 7)
 #include <gio/gnetworking.h>
-#else
-
-/* nicked from gnetworking.h */
-#ifdef G_OS_WIN32
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-#include <winsock2.h>
-#undef interface
-#include <ws2tcpip.h>           /* for socklen_t */
-#endif /* G_OS_WIN32 */
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#endif
 
 /* not 100% correct, but a good upper bound for memory allocation purposes */
 #define MAX_IPV4_UDP_PACKET_SIZE (65536 - 8)
@@ -155,6 +138,7 @@
 #define UDP_DEFAULT_USED_SOCKET        NULL
 #define UDP_DEFAULT_AUTO_MULTICAST     TRUE
 #define UDP_DEFAULT_REUSE              TRUE
+#define UDP_DEFAULT_LOOP               TRUE
 
 enum
 {
@@ -173,7 +157,8 @@
   PROP_USED_SOCKET,
   PROP_AUTO_MULTICAST,
   PROP_REUSE,
-  PROP_ADDRESS
+  PROP_ADDRESS,
+  PROP_LOOP
 };
 
 static void gst_udpsrc_uri_handler_init (gpointer g_iface, gpointer iface_data);
@@ -283,6 +268,11 @@
           "Address to receive packets for. This is equivalent to the "
           "multicast-group property for now", UDP_DEFAULT_MULTICAST_GROUP,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_LOOP,
+      g_param_spec_boolean ("loop", "Multicast Loopback",
+          "Used for setting the multicast loop parameter. TRUE = enable,"
+          " FALSE = disable", UDP_DEFAULT_LOOP,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&src_template));
@@ -322,6 +312,7 @@
   udpsrc->auto_multicast = UDP_DEFAULT_AUTO_MULTICAST;
   udpsrc->used_socket = UDP_DEFAULT_USED_SOCKET;
   udpsrc->reuse = UDP_DEFAULT_REUSE;
+  udpsrc->loop = UDP_DEFAULT_LOOP;
 
   /* configure basesrc to be a live source */
   gst_base_src_set_live (GST_BASE_SRC (udpsrc), TRUE);
@@ -808,6 +799,9 @@
     case PROP_REUSE:
       udpsrc->reuse = g_value_get_boolean (value);
       break;
+    case PROP_LOOP:
+      udpsrc->loop = g_value_get_boolean (value);
+      break;
     default:
       break;
   }
@@ -862,6 +856,9 @@
     case PROP_REUSE:
       g_value_set_boolean (value, udpsrc->reuse);
       break;
+    case PROP_LOOP:
+      g_value_set_boolean (value, udpsrc->loop);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -969,6 +966,7 @@
       goto bind_error;
 
     g_object_unref (bind_saddr);
+    g_socket_set_multicast_loopback (src->used_socket, src->loop);
   } else {
     GST_DEBUG_OBJECT (src, "using provided socket %p", src->socket);
     /* we use the configured socket, try to get some info about it */
@@ -984,7 +982,6 @@
       goto getsockname_error;
   }
 
-#if GLIB_CHECK_VERSION (2, 35, 7)
   {
     gint val = 0;
 
@@ -1016,47 +1013,6 @@
       GST_DEBUG_OBJECT (src, "could not get udp buffer size");
     }
   }
-#elif defined (SO_RCVBUF)
-  {
-    gint rcvsize, ret;
-    socklen_t len;
-
-    len = sizeof (rcvsize);
-    if (src->buffer_size != 0) {
-      rcvsize = src->buffer_size;
-
-      GST_DEBUG_OBJECT (src, "setting udp buffer of %d bytes", rcvsize);
-      /* set buffer size, Note that on Linux this is typically limited to a
-       * maximum of around 100K. Also a minimum of 128 bytes is required on
-       * Linux. */
-      ret =
-          setsockopt (g_socket_get_fd (src->used_socket), SOL_SOCKET, SO_RCVBUF,
-          (void *) &rcvsize, len);
-      if (ret != 0) {
-        GST_ELEMENT_WARNING (src, RESOURCE, SETTINGS, (NULL),
-            ("Could not create a buffer of requested %d bytes, %d: %s (%d)",
-                rcvsize, ret, g_strerror (errno), errno));
-      }
-    }
-
-    /* read the value of the receive buffer. Note that on linux this returns 2x the
-     * value we set because the kernel allocates extra memory for metadata.
-     * The default on Linux is about 100K (which is about 50K without metadata) */
-    ret =
-        getsockopt (g_socket_get_fd (src->used_socket), SOL_SOCKET, SO_RCVBUF,
-        (void *) &rcvsize, &len);
-    if (ret == 0)
-      GST_DEBUG_OBJECT (src, "have udp buffer of %d bytes", rcvsize);
-    else
-      GST_DEBUG_OBJECT (src, "could not get udp buffer size");
-  }
-#else
-  if (src->buffer_size != 0) {
-    GST_WARNING_OBJECT (src, "don't know how to set udp buffer size on this "
-        "OS. Consider upgrading your GLib to >= 2.35.7 and re-compiling the "
-        "GStreamer udp plugin");
-  }
-#endif
 
   g_socket_set_broadcast (src->used_socket, TRUE);
 
diff --git a/gst/udp/gstudpsrc.h b/gst/udp/gstudpsrc.h
index 5d7e340..a476483 100644
--- a/gst/udp/gstudpsrc.h
+++ b/gst/udp/gstudpsrc.h
@@ -60,6 +60,7 @@
   gboolean   close_socket;
   gboolean   auto_multicast;
   gboolean   reuse;
+  gboolean   loop;
 
   /* stats */
   guint      max_size;
diff --git a/gst/videobox/Makefile.in b/gst/videobox/Makefile.in
index e9c576d..d1adc29 100644
--- a/gst/videobox/Makefile.in
+++ b/gst/videobox/Makefile.in
@@ -504,6 +504,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/videocrop/Makefile.in b/gst/videocrop/Makefile.in
index 9b42b74..9631141 100644
--- a/gst/videocrop/Makefile.in
+++ b/gst/videocrop/Makefile.in
@@ -477,6 +477,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/videofilter/Makefile.in b/gst/videofilter/Makefile.in
index a672e82..eab76ae 100644
--- a/gst/videofilter/Makefile.in
+++ b/gst/videofilter/Makefile.in
@@ -480,6 +480,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/videomixer/Makefile.in b/gst/videomixer/Makefile.in
index 10d76b0..3208c5b 100644
--- a/gst/videomixer/Makefile.in
+++ b/gst/videomixer/Makefile.in
@@ -505,6 +505,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/videomixer/videomixer2.c b/gst/videomixer/videomixer2.c
index 1565986..25fc35a 100644
--- a/gst/videomixer/videomixer2.c
+++ b/gst/videomixer/videomixer2.c
@@ -801,9 +801,9 @@
     GstClockTimeDiff diff, GstClockTime timestamp)
 {
   GST_DEBUG_OBJECT (mix,
-      "Updating QoS: proportion %lf, diff %s%" GST_TIME_FORMAT ", timestamp %"
-      GST_TIME_FORMAT, proportion, (diff < 0) ? "-" : "",
-      GST_TIME_ARGS (ABS (diff)), GST_TIME_ARGS (timestamp));
+      "Updating QoS: proportion %lf, diff %" GST_STIME_FORMAT ", timestamp %"
+      GST_TIME_FORMAT, proportion, GST_STIME_ARGS (diff),
+      GST_TIME_ARGS (timestamp));
 
   GST_OBJECT_LOCK (mix);
   mix->proportion = proportion;
diff --git a/gst/wavenc/Makefile.in b/gst/wavenc/Makefile.in
index d999a32..e1ed400 100644
--- a/gst/wavenc/Makefile.in
+++ b/gst/wavenc/Makefile.in
@@ -476,6 +476,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/wavparse/Makefile.in b/gst/wavparse/Makefile.in
index bc79baa..7f6a751 100644
--- a/gst/wavparse/Makefile.in
+++ b/gst/wavparse/Makefile.in
@@ -477,6 +477,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/gst/wavparse/gstwavparse.c b/gst/wavparse/gstwavparse.c
index 205af88..1452db4 100644
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -378,12 +378,14 @@
   gboolean update;
   GstSegment seeksegment = { 0, };
   gint64 last_stop;
+  guint32 seqnum = 0;
 
   if (event) {
     GST_DEBUG_OBJECT (wav, "doing seek with event");
 
     gst_event_parse_seek (event, &rate, &format, &flags,
         &cur_type, &cur, &stop_type, &stop);
+    seqnum = gst_event_get_seqnum (event);
 
     /* no negative rates yet */
     if (rate < 0.0)
@@ -449,6 +451,7 @@
       /* BYTE seek event */
       event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, cur,
           stop_type, stop);
+      gst_event_set_seqnum (event, seqnum);
       res = gst_pad_push_event (wav->sinkpad, event);
     }
     return res;
@@ -464,9 +467,13 @@
    * as it completes one iteration (and thus might block when the sink is
    * blocking in preroll). */
   if (flush) {
+    GstEvent *fevent;
     GST_DEBUG_OBJECT (wav, "sending flush start");
-    gst_pad_push_event (wav->sinkpad, gst_event_new_flush_start ());
-    gst_pad_push_event (wav->srcpad, gst_event_new_flush_start ());
+
+    fevent = gst_event_new_flush_start ();
+    gst_event_set_seqnum (fevent, seqnum);
+    gst_pad_push_event (wav->sinkpad, gst_event_ref (fevent));
+    gst_pad_push_event (wav->srcpad, fevent);
   } else {
     gst_pad_pause_task (wav->sinkpad);
   }
@@ -545,10 +552,15 @@
 
   /* prepare for streaming again */
   if (flush) {
+    GstEvent *fevent;
+
     /* if we sent a FLUSH_START, we now send a FLUSH_STOP */
     GST_DEBUG_OBJECT (wav, "sending flush stop");
-    gst_pad_push_event (wav->sinkpad, gst_event_new_flush_stop (TRUE));
-    gst_pad_push_event (wav->srcpad, gst_event_new_flush_stop (TRUE));
+
+    fevent = gst_event_new_flush_stop (TRUE);
+    gst_event_set_seqnum (fevent, seqnum);
+    gst_pad_push_event (wav->sinkpad, gst_event_ref (fevent));
+    gst_pad_push_event (wav->srcpad, fevent);
   }
 
   /* now we did the seek and can activate the new segment values */
@@ -569,6 +581,7 @@
   if (wav->start_segment)
     gst_event_unref (wav->start_segment);
   wav->start_segment = gst_event_new_segment (&wav->segment);
+  gst_event_set_seqnum (wav->start_segment, seqnum);
 
   /* mark discont if we are going to stream from another position. */
   if (last_stop != wav->segment.position) {
@@ -1072,7 +1085,6 @@
   gboolean gotdata = FALSE;
   GstCaps *caps = NULL;
   gchar *codec_name = NULL;
-  GstEvent **event_p;
   gint64 upstream_size = 0;
   GstStructure *s;
 
@@ -1666,8 +1678,7 @@
    * the right newsegment event downstream. */
   gst_wavparse_perform_seek (wav, wav->seek_event);
   /* remove pending event */
-  event_p = &wav->seek_event;
-  gst_event_replace (event_p, NULL);
+  gst_event_replace (&wav->seek_event, NULL);
 
   /* we just started, we are discont */
   wav->discont = TRUE;
@@ -1693,10 +1704,8 @@
   /* ERROR */
 exit:
   {
-    if (codec_name)
-      g_free (codec_name);
-    if (header)
-      g_free (header);
+    g_free (codec_name);
+    g_free (header);
     if (caps)
       gst_caps_unref (caps);
     return res;
@@ -1807,7 +1816,6 @@
 {
   GstWavParse *wav = GST_WAVPARSE (element);
   gboolean res = FALSE;
-  GstEvent **event_p;
 
   GST_DEBUG_OBJECT (wav, "received event %s", GST_EVENT_TYPE_NAME (event));
 
@@ -1819,8 +1827,7 @@
       } else {
         GST_DEBUG_OBJECT (wav, "queuing seek for later");
 
-        event_p = &wav->seek_event;
-        gst_event_replace (event_p, event);
+        gst_event_replace (&wav->seek_event, event);
 
         /* we always return true */
         res = TRUE;
diff --git a/gst/y4m/Makefile.in b/gst/y4m/Makefile.in
index ad940f1..987ded3 100644
--- a/gst/y4m/Makefile.in
+++ b/gst/y4m/Makefile.in
@@ -476,6 +476,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/m4/Makefile.in b/m4/Makefile.in
index 76463a3..166b025 100644
--- a/m4/Makefile.in
+++ b/m4/Makefile.in
@@ -390,6 +390,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/pkgconfig/Makefile.in b/pkgconfig/Makefile.in
index f7fd58d..59465b3 100644
--- a/pkgconfig/Makefile.in
+++ b/pkgconfig/Makefile.in
@@ -391,6 +391,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/po/af.gmo b/po/af.gmo
index 7fdb491..6af0992 100644
--- a/po/af.gmo
+++ b/po/af.gmo
Binary files differ
diff --git a/po/af.po b/po/af.po
index 6aa7452..bbbc588 100644
--- a/po/af.po
+++ b/po/af.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins 0.7.6\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2004-03-18 14:16+0200\n"
 "Last-Translator: Petri Jooste <rkwjpj@puk.ac.za>\n"
 "Language-Team: Afrikaans <i18n@af.org.za>\n"
diff --git a/po/az.gmo b/po/az.gmo
index 9e12d7b..4377dbb 100644
--- a/po/az.gmo
+++ b/po/az.gmo
Binary files differ
diff --git a/po/az.po b/po/az.po
index a14e1d5..181059e 100644
--- a/po/az.po
+++ b/po/az.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-0.8.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2004-03-19 18:29+0200\n"
 "Last-Translator: Metin Amiroff <metin@karegen.com>\n"
 "Language-Team: Azerbaijani <translation-team-az@lists.sourceforge.net>\n"
diff --git a/po/bg.gmo b/po/bg.gmo
index c1faafe..7ab3777 100644
--- a/po/bg.gmo
+++ b/po/bg.gmo
Binary files differ
diff --git a/po/bg.po b/po/bg.po
index 64d3e0e..077bc7b 100644
--- a/po/bg.po
+++ b/po/bg.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 0.10.28.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2011-04-26 22:35+0300\n"
 "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
 "Language-Team: Bulgarian <dict@fsa-bg.org>\n"
diff --git a/po/ca.gmo b/po/ca.gmo
index 9e1800b..432e976 100644
--- a/po/ca.gmo
+++ b/po/ca.gmo
Binary files differ
diff --git a/po/ca.po b/po/ca.po
index ac89e5c..7a7ab4f 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 0.10.28.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2012-01-01 14:19+0100\n"
 "Last-Translator: Gil Forcada <gforcada@gnome.org>\n"
 "Language-Team: Catalan <ca@dodds.net>\n"
diff --git a/po/cs.gmo b/po/cs.gmo
index 9b41153..b2a659f 100644
--- a/po/cs.gmo
+++ b/po/cs.gmo
Binary files differ
diff --git a/po/cs.po b/po/cs.po
index 13cbff4..8c80a07 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -10,7 +10,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good-1.6.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2015-10-15 20:58+0200\n"
 "Last-Translator: Marek Černocký <marek@manet.cz>\n"
 "Language-Team: Czech <translation-team-cs@lists.sourceforge.net>\n"
diff --git a/po/da.gmo b/po/da.gmo
index 8dcc420..21bf4ca 100644
--- a/po/da.gmo
+++ b/po/da.gmo
Binary files differ
diff --git a/po/da.po b/po/da.po
index aec12a8..5aa529c 100644
--- a/po/da.po
+++ b/po/da.po
@@ -11,7 +11,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good-1.3.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2014-06-29 23:54+0200\n"
 "Last-Translator: Joe Hansen <joedalton2@yahoo.dk>\n"
 "Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
diff --git a/po/de.gmo b/po/de.gmo
index d3d3f2f..0e9823b 100644
--- a/po/de.gmo
+++ b/po/de.gmo
Binary files differ
diff --git a/po/de.po b/po/de.po
index c9d1a58..db9191e 100644
--- a/po/de.po
+++ b/po/de.po
@@ -14,7 +14,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 1.6.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2015-10-21 00:14+0200\n"
 "Last-Translator: Christian Kirbach <christian.kirbach@gmail.com>\n"
 "Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
diff --git a/po/el.gmo b/po/el.gmo
index 6430cb9..2998dba 100644
--- a/po/el.gmo
+++ b/po/el.gmo
Binary files differ
diff --git a/po/el.po b/po/el.po
index 3621c13..83a55df 100644
--- a/po/el.po
+++ b/po/el.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 0.10.28.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2012-05-05 19:05+0100\n"
 "Last-Translator: Savvas Radevic <vicedar@gmail.com>\n"
 "Language-Team: Greek <team@lists.gnome.gr>\n"
diff --git a/po/en_GB.gmo b/po/en_GB.gmo
index 3d52a32..78f7cba 100644
--- a/po/en_GB.gmo
+++ b/po/en_GB.gmo
Binary files differ
diff --git a/po/en_GB.po b/po/en_GB.po
index 611b520..557ea25 100644
--- a/po/en_GB.po
+++ b/po/en_GB.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins 0.8.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2004-04-26 10:41-0400\n"
 "Last-Translator: Gareth Owen <gowen72@yahoo.com>\n"
 "Language-Team: English (British) <en_gb@li.org>\n"
diff --git a/po/eo.gmo b/po/eo.gmo
index 731d215..0fc1cb1 100644
--- a/po/eo.gmo
+++ b/po/eo.gmo
Binary files differ
diff --git a/po/eo.po b/po/eo.po
index 901ffb5..8c1534c 100644
--- a/po/eo.po
+++ b/po/eo.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 0.10.28.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2011-06-04 21:48+0100\n"
 "Last-Translator: Kristjan SCHMIDT <kristjan.schmidt@googlemail.com>\n"
 "Language-Team: Esperanto <translation-team-eo@lists.sourceforge.net>\n"
diff --git a/po/es.gmo b/po/es.gmo
index 74f2e37..d78dc6c 100644
--- a/po/es.gmo
+++ b/po/es.gmo
Binary files differ
diff --git a/po/es.po b/po/es.po
index 8a80e26..2f94a90 100644
--- a/po/es.po
+++ b/po/es.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 0.10.26.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2011-02-12 18:30+0100\n"
 "Last-Translator: Jorge González González <aloriel@gmail.com>\n"
 "Language-Team: Spanish <es@li.org>\n"
diff --git a/po/eu.gmo b/po/eu.gmo
index b2f0eaf..72128cc 100644
--- a/po/eu.gmo
+++ b/po/eu.gmo
Binary files differ
diff --git a/po/eu.po b/po/eu.po
index 47cc329..c551eba 100644
--- a/po/eu.po
+++ b/po/eu.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good-0.10.18.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2010-03-25 12:37+0100\n"
 "Last-Translator: Mikel Olasagasti Uranga <hey_neken@mundurat.net>\n"
 "Language-Team: Basque <translation-team-eu@lists.sourceforge.net>\n"
diff --git a/po/fi.gmo b/po/fi.gmo
index e3e91a7..c4de1c9 100644
--- a/po/fi.gmo
+++ b/po/fi.gmo
Binary files differ
diff --git a/po/fi.po b/po/fi.po
index e3096ba..a6212f1 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -11,7 +11,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 0.10.25.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2010-11-17 23:03+0200\n"
 "Last-Translator: Tommi Vainikainen <Tommi.Vainikainen@iki.fi>\n"
 "Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n"
diff --git a/po/fr.gmo b/po/fr.gmo
index 22611c1..4358b00 100644
--- a/po/fr.gmo
+++ b/po/fr.gmo
Binary files differ
diff --git a/po/fr.po b/po/fr.po
index 4ac52f6..d4e3703 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -10,7 +10,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 1.4.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2015-04-26 19:35+0200\n"
 "Last-Translator: Stéphane Aulery <lkppo@free.fr>\n"
 "Language-Team: French <traduc@traduc.org>\n"
diff --git a/po/gl.gmo b/po/gl.gmo
index f1ff1c3..ad1f922 100644
--- a/po/gl.gmo
+++ b/po/gl.gmo
Binary files differ
diff --git a/po/gl.po b/po/gl.po
index 029cfd1..d4a67f4 100644
--- a/po/gl.po
+++ b/po/gl.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 1.0.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2012-12-15 03:46+0200\n"
 "Last-Translator: Fran Dieguez <frandieguez@ubuntu.com>\n"
 "Language-Team: Galician <proxecto@trasno.net>\n"
diff --git a/po/gst-plugins-good-1.0.pot b/po/gst-plugins-good-1.0.pot
index 38c16b8..ec5ef10 100644
--- a/po/gst-plugins-good-1.0.pot
+++ b/po/gst-plugins-good-1.0.pot
@@ -5,9 +5,9 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: gst-plugins-good 1.6.2\n"
+"Project-Id-Version: gst-plugins-good 1.7.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -20,10 +20,10 @@
 msgid "Jack server not found"
 msgstr ""
 
-#: ext/jpeg/gstjpegdec.c:925 ext/jpeg/gstjpegdec.c:1178
-#: ext/jpeg/gstjpegdec.c:1190 ext/jpeg/gstjpegdec.c:1219
-#: ext/jpeg/gstjpegdec.c:1228 ext/jpeg/gstjpegdec.c:1237
-#: ext/jpeg/gstjpegdec.c:1245
+#: ext/jpeg/gstjpegdec.c:925 ext/jpeg/gstjpegdec.c:1189
+#: ext/jpeg/gstjpegdec.c:1201 ext/jpeg/gstjpegdec.c:1230
+#: ext/jpeg/gstjpegdec.c:1239 ext/jpeg/gstjpegdec.c:1248
+#: ext/jpeg/gstjpegdec.c:1256
 msgid "Failed to decode JPEG image"
 msgstr ""
 
@@ -37,36 +37,36 @@
 msgid "Could not connect to server"
 msgstr ""
 
-#: ext/soup/gstsouphttpsrc.c:911
+#: ext/soup/gstsouphttpsrc.c:932
 msgid "No URL set."
 msgstr ""
 
-#: ext/soup/gstsouphttpsrc.c:1270
+#: ext/soup/gstsouphttpsrc.c:1292
 msgid "Server does not support seeking."
 msgstr ""
 
-#: ext/soup/gstsouphttpsrc.c:1545
+#: ext/soup/gstsouphttpsrc.c:1567
 msgid "Could not resolve server name."
 msgstr ""
 
-#: ext/soup/gstsouphttpsrc.c:1551
+#: ext/soup/gstsouphttpsrc.c:1573
 msgid "Could not establish connection to server."
 msgstr ""
 
-#: ext/soup/gstsouphttpsrc.c:1556
+#: ext/soup/gstsouphttpsrc.c:1578
 msgid "Secure connection setup failed."
 msgstr ""
 
-#: ext/soup/gstsouphttpsrc.c:1566
+#: ext/soup/gstsouphttpsrc.c:1588
 msgid ""
 "A network error occurred, or the server closed the connection unexpectedly."
 msgstr ""
 
-#: ext/soup/gstsouphttpsrc.c:1573
+#: ext/soup/gstsouphttpsrc.c:1595
 msgid "Server sent bad data."
 msgstr ""
 
-#: gst/avi/gstavidemux.c:5679
+#: gst/avi/gstavidemux.c:5689
 msgid "Internal data stream error."
 msgstr ""
 
@@ -78,50 +78,50 @@
 msgid "This file contains no playable streams."
 msgstr ""
 
-#: gst/isomp4/qtdemux.c:691 gst/isomp4/qtdemux.c:5585 gst/isomp4/qtdemux.c:5652
-#: gst/isomp4/qtdemux.c:5891
+#: gst/isomp4/qtdemux.c:691 gst/isomp4/qtdemux.c:5685 gst/isomp4/qtdemux.c:5752
+#: gst/isomp4/qtdemux.c:6001
 msgid "This file is invalid and cannot be played."
 msgstr ""
 
-#: gst/isomp4/qtdemux.c:2441
+#: gst/isomp4/qtdemux.c:2480
 msgid "Cannot play stream because it is encrypted with PlayReady DRM."
 msgstr ""
 
-#: gst/isomp4/qtdemux.c:3511 gst/isomp4/qtdemux.c:6629
-#: gst/isomp4/qtdemux.c:6636 gst/isomp4/qtdemux.c:7410
-#: gst/isomp4/qtdemux.c:7839 gst/isomp4/qtdemux.c:7846
-#: gst/isomp4/qtdemux.c:10133
+#: gst/isomp4/qtdemux.c:3550 gst/isomp4/qtdemux.c:6734
+#: gst/isomp4/qtdemux.c:6741 gst/isomp4/qtdemux.c:7515
+#: gst/isomp4/qtdemux.c:7944 gst/isomp4/qtdemux.c:7951
+#: gst/isomp4/qtdemux.c:10277
 msgid "This file is corrupt and cannot be played."
 msgstr ""
 
-#: gst/isomp4/qtdemux.c:3753
+#: gst/isomp4/qtdemux.c:3792
 msgid "Invalid atom size."
 msgstr ""
 
-#: gst/isomp4/qtdemux.c:3831
+#: gst/isomp4/qtdemux.c:3870
 msgid "This file is incomplete and cannot be played."
 msgstr ""
 
-#: gst/isomp4/qtdemux.c:8771
+#: gst/isomp4/qtdemux.c:8886
 msgid "The video in this file might not play correctly."
 msgstr ""
 
-#: gst/isomp4/qtdemux.c:10174
+#: gst/isomp4/qtdemux.c:10318
 #, c-format
 msgid "This file contains too many streams. Only playing first %d"
 msgstr ""
 
-#: gst/multifile/gstsplitmuxsrc.c:532 gst/wavparse/gstwavparse.c:2250
+#: gst/multifile/gstsplitmuxsrc.c:532 gst/wavparse/gstwavparse.c:2257
 msgid "Internal data flow error."
 msgstr ""
 
-#: gst/rtsp/gstrtspsrc.c:6894
+#: gst/rtsp/gstrtspsrc.c:6934
 msgid ""
 "No supported stream was found. You might need to install a GStreamer RTSP "
 "extension plugin for Real media streams."
 msgstr ""
 
-#: gst/rtsp/gstrtspsrc.c:6899
+#: gst/rtsp/gstrtspsrc.c:6939
 msgid ""
 "No supported stream was found. You might need to allow more transport "
 "protocols or may otherwise be missing the right GStreamer RTSP extension "
@@ -166,13 +166,13 @@
 msgid "Error recording from audio device."
 msgstr ""
 
-#: sys/oss/gstosssrc.c:377
+#: sys/oss/gstosssrc.c:376
 msgid ""
 "Could not open audio device for recording. You don't have permission to open "
 "the device."
 msgstr ""
 
-#: sys/oss/gstosssrc.c:385
+#: sys/oss/gstosssrc.c:384
 msgid "Could not open audio device for recording."
 msgstr ""
 
@@ -253,80 +253,80 @@
 msgid "Error reading %d bytes from device '%s'."
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:1085
+#: sys/v4l2/gstv4l2object.c:1160
 #, c-format
 msgid "Failed to enumerate possible video formats device '%s' can work with"
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:2577
+#: sys/v4l2/gstv4l2object.c:2740
 #, c-format
 msgid "Could not map buffers from device '%s'"
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:2585
+#: sys/v4l2/gstv4l2object.c:2748
 #, c-format
 msgid "The driver of device '%s' does not support the IO method %d"
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:2592
+#: sys/v4l2/gstv4l2object.c:2755
 #, c-format
 msgid "The driver of device '%s' does not support any known IO method."
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:3214 sys/v4l2/gstv4l2object.c:3225
+#: sys/v4l2/gstv4l2object.c:3378 sys/v4l2/gstv4l2object.c:3389
 #, c-format
 msgid "Device '%s' is busy"
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:3231 sys/v4l2/gstv4l2object.c:3243
+#: sys/v4l2/gstv4l2object.c:3395 sys/v4l2/gstv4l2object.c:3407
 #, c-format
 msgid "Device '%s' cannot capture at %dx%d"
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:3254
+#: sys/v4l2/gstv4l2object.c:3418
 #, c-format
 msgid "Device '%s' cannot capture in the specified format"
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:3267
+#: sys/v4l2/gstv4l2object.c:3431
 #, c-format
 msgid "Device '%s' does support non-contiguous planes"
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:3278
+#: sys/v4l2/gstv4l2object.c:3442
 #, c-format
 msgid "Could not get parameters on device '%s'"
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:3286
+#: sys/v4l2/gstv4l2object.c:3450
 msgid "Video device did not accept new frame rate setting."
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:3391
+#: sys/v4l2/gstv4l2object.c:3555
 msgid "Video device did not provide output format."
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:3397
+#: sys/v4l2/gstv4l2object.c:3561
 msgid "Video device returned invalid dimensions."
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:3405
+#: sys/v4l2/gstv4l2object.c:3569
 msgid "Video devices uses an unsupported interlacing method."
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:3412
+#: sys/v4l2/gstv4l2object.c:3576
 msgid "Video devices uses an unsupported pixel format."
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:3824
+#: sys/v4l2/gstv4l2object.c:4001
 msgid "Failed to configure internal buffer pool."
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:3830
+#: sys/v4l2/gstv4l2object.c:4007
 msgid "Video device did not suggest any buffer size."
 msgstr ""
 
-#: sys/v4l2/gstv4l2object.c:3845
+#: sys/v4l2/gstv4l2object.c:4022
 msgid "No downstream pool to import from."
 msgstr ""
 
@@ -364,7 +364,7 @@
 msgid "Failed to allocated required memory."
 msgstr ""
 
-#: sys/v4l2/gstv4l2src.c:510 sys/v4l2/gstv4l2videodec.c:581
+#: sys/v4l2/gstv4l2src.c:510 sys/v4l2/gstv4l2videodec.c:611
 msgid "Failed to allocate required memory."
 msgstr ""
 
@@ -388,11 +388,11 @@
 msgid "Encoder on device %s has no supported output format"
 msgstr ""
 
-#: sys/v4l2/gstv4l2videodec.c:595
+#: sys/v4l2/gstv4l2videodec.c:625
 msgid "Failed to start decoding thread."
 msgstr ""
 
-#: sys/v4l2/gstv4l2videodec.c:603
+#: sys/v4l2/gstv4l2videodec.c:633
 msgid "Failed to process frame."
 msgstr ""
 
@@ -504,10 +504,10 @@
 msgid "Failed to set output %d on device %s."
 msgstr ""
 
-#: sys/ximage/gstximagesrc.c:828
+#: sys/ximage/gstximagesrc.c:838
 msgid "Changing resolution at runtime is not yet supported."
 msgstr ""
 
-#: sys/ximage/gstximagesrc.c:842
+#: sys/ximage/gstximagesrc.c:852
 msgid "Cannot operate without a clock"
 msgstr ""
diff --git a/po/hr.gmo b/po/hr.gmo
index 38618de..6fd1409 100644
--- a/po/hr.gmo
+++ b/po/hr.gmo
Binary files differ
diff --git a/po/hr.po b/po/hr.po
index a5876c5..e63d4a1 100644
--- a/po/hr.po
+++ b/po/hr.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 0.10.28.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2012-04-16 03:04+0200\n"
 "Last-Translator: Tomislav Krznar <tomislav.krznar@gmail.com>\n"
 "Language-Team: Croatian <lokalizacija@linux.hr>\n"
diff --git a/po/hu.gmo b/po/hu.gmo
index 0868f61..b7c2c0f 100644
--- a/po/hu.gmo
+++ b/po/hu.gmo
Binary files differ
diff --git a/po/hu.po b/po/hu.po
index ce7cb8f..1a0ecca 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 1.6.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2015-11-20 23:48+0100\n"
 "Last-Translator: Balázs Úr <urbalazs@gmail.com>\n"
 "Language-Team: Hungarian <translation-team-hu@lists.sourceforge.net>\n"
diff --git a/po/id.gmo b/po/id.gmo
index 8fd1ea3..a73bfbb 100644
--- a/po/id.gmo
+++ b/po/id.gmo
Binary files differ
diff --git a/po/id.po b/po/id.po
index 4399ffc..9780ce0 100644
--- a/po/id.po
+++ b/po/id.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 1.3.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2014-07-06 21:37+0700\n"
 "Last-Translator: Andhika Padmawan <andhika.padmawan@gmail.com>\n"
 "Language-Team: Indonesian <translation-team-id@lists.sourceforge.net>\n"
diff --git a/po/it.gmo b/po/it.gmo
index 80df044..7a5d8b5 100644
--- a/po/it.gmo
+++ b/po/it.gmo
Binary files differ
diff --git a/po/it.po b/po/it.po
index 4d35f7d..c086e25 100644
--- a/po/it.po
+++ b/po/it.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 0.10.25.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2010-10-25 10:11+0200\n"
 "Last-Translator: Luca Ferretti <elle.uca@infinito.it>\n"
 "Language-Team: Italian <tp@lists.linux.it>\n"
diff --git a/po/ja.gmo b/po/ja.gmo
index 4a719cc..21a45e8 100644
--- a/po/ja.gmo
+++ b/po/ja.gmo
Binary files differ
diff --git a/po/ja.po b/po/ja.po
index 975c58e..f7c2352 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 1.0.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2012-12-22 20:13+0900\n"
 "Last-Translator: Takeshi Hamasaki <hmatrjp@users.sourceforge.jp>\n"
 "Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n"
diff --git a/po/lt.gmo b/po/lt.gmo
index 5ffc104..6555e52 100644
--- a/po/lt.gmo
+++ b/po/lt.gmo
Binary files differ
diff --git a/po/lt.po b/po/lt.po
index 4ed9960..4a6dba9 100644
--- a/po/lt.po
+++ b/po/lt.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 0.10.23.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2010-07-16 19:34+0300\n"
 "Last-Translator: Žygimantas Beručka <uid0@akl.lt>\n"
 "Language-Team: Lithuanian <komp_lt@konferencijos.lt>\n"
diff --git a/po/lv.gmo b/po/lv.gmo
index a3b68de..4cac42c 100644
--- a/po/lv.gmo
+++ b/po/lv.gmo
Binary files differ
diff --git a/po/lv.po b/po/lv.po
index 00b3f36..8297da8 100644
--- a/po/lv.po
+++ b/po/lv.po
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 1.2.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2014-04-20 16:38+0300\n"
 "Last-Translator: Rihards Prieditis <rprieditis@gmail.com>\n"
 "Language-Team: Latvian <translation-team-lv@lists.sourceforge.net>\n"
diff --git a/po/mt.gmo b/po/mt.gmo
index a60e995..55087f5 100644
--- a/po/mt.gmo
+++ b/po/mt.gmo
Binary files differ
diff --git a/po/mt.po b/po/mt.po
index a251a52..d4fabf5 100644
--- a/po/mt.po
+++ b/po/mt.po
@@ -5,7 +5,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good-0.10.10.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2008-10-26 19:09+0100\n"
 "Last-Translator: Michel Bugeja <michelbugeja@rabatmalta.com>\n"
 "Language-Team: Maltese <translation-team-mt@lists.sourceforge.net>\n"
diff --git a/po/nb.gmo b/po/nb.gmo
index b4c9a8e..ad3f572 100644
--- a/po/nb.gmo
+++ b/po/nb.gmo
Binary files differ
diff --git a/po/nb.po b/po/nb.po
index 88f1d56..f9fcd65 100644
--- a/po/nb.po
+++ b/po/nb.po
@@ -2,21 +2,21 @@
 # This file is put in the public domain.
 #
 # Kjartan Maraas <kmaraas@gnome.org>, 2004-2010.
-# Johnny A. Solbu <johnny@solbu.net>, 2012-2014
+# Johnny A. Solbu <johnny@solbu.net>, 2012-2015
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: gst-plugins-good 1.3.90\n"
+"Project-Id-Version: gst-plugins-good 1.6.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
-"PO-Revision-Date: 2014-07-22 13:14+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
+"PO-Revision-Date: 2015-12-22 21:12+0100\n"
 "Last-Translator: Johnny A. Solbu <johnny@solbu.net>\n"
 "Language-Team: Norwegian Bokmaal <i18n-nb@lister.ping.uio.no>\n"
 "Language: nb_NO\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 1.5.4\n"
+"X-Generator: Poedit 1.6.9\n"
 
 msgid "Jack server not found"
 msgstr "Jack-server ikke funnet"
@@ -47,10 +47,9 @@
 msgid "Secure connection setup failed."
 msgstr "Oppsett av sikker tilkobling feilet."
 
-#, fuzzy
 msgid ""
 "A network error occurred, or the server closed the connection unexpectedly."
-msgstr "Et nettverk feil oppstod, eller tjeneren lukket uventet tilkoblingen."
+msgstr "En nettverksfeil oppstod, eller tjeneren lukket uventet tilkoblingen."
 
 msgid "Server sent bad data."
 msgstr "Tjener sendte ugyldige data."
diff --git a/po/nl.gmo b/po/nl.gmo
index d4dd0ff..60af1d0 100644
--- a/po/nl.gmo
+++ b/po/nl.gmo
Binary files differ
diff --git a/po/nl.po b/po/nl.po
index 2b1f2d7..ce7be39 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 1.6.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2015-10-17 12:36+0200\n"
 "Last-Translator: Freek de Kruijf <f.de.kruijf@gmail.com>\n"
 "Language-Team: Dutch <vertaling@vrijschrift.org>\n"
diff --git a/po/or.gmo b/po/or.gmo
index aff2b08..95cd2d3 100644
--- a/po/or.gmo
+++ b/po/or.gmo
Binary files differ
diff --git a/po/or.po b/po/or.po
index f96e928..eefbe5f 100644
--- a/po/or.po
+++ b/po/or.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-0.8.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2004-09-27 13:32+0530\n"
 "Last-Translator: Gora Mohanty <gora_mohanty@yahoo.co.in>\n"
 "Language-Team: Oriya <gora_mohanty@yahoo.co.in>\n"
diff --git a/po/pl.gmo b/po/pl.gmo
index 1973991..fb797c9 100644
--- a/po/pl.gmo
+++ b/po/pl.gmo
Binary files differ
diff --git a/po/pl.po b/po/pl.po
index 06b1938..abd04f0 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 1.6.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2015-10-15 20:49+0200\n"
 "Last-Translator: Jakub Bogusz <qboosh@pld-linux.org>\n"
 "Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"
diff --git a/po/pt_BR.gmo b/po/pt_BR.gmo
index fbf5a76..6659d57 100644
--- a/po/pt_BR.gmo
+++ b/po/pt_BR.gmo
Binary files differ
diff --git a/po/pt_BR.po b/po/pt_BR.po
index b40325b..8c87ff0 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -13,7 +13,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good-1.4.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2015-02-01 23:02-0200\n"
 "Last-Translator: Fabrício Godoy <skarllot@gmail.com>\n"
 "Language-Team: Brazilian Portuguese <ldpbr-translation@lists.sourceforge."
diff --git a/po/ro.gmo b/po/ro.gmo
index f00ce16..23fa2c1 100644
--- a/po/ro.gmo
+++ b/po/ro.gmo
Binary files differ
diff --git a/po/ro.po b/po/ro.po
index af303fa..27247c9 100644
--- a/po/ro.po
+++ b/po/ro.po
@@ -5,7 +5,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 0.10.23.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2010-08-16 03:22+0300\n"
 "Last-Translator: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>\n"
 "Language-Team: Romanian <translation-team-ro@lists.sourceforge.net>\n"
diff --git a/po/ru.gmo b/po/ru.gmo
index 1d6d0cd..4626da1 100644
--- a/po/ru.gmo
+++ b/po/ru.gmo
Binary files differ
diff --git a/po/ru.po b/po/ru.po
index 9d4b0f6..8082e23 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 1.6.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2015-10-18 13:39+0300\n"
 "Last-Translator: Yuri Kozlov <yuray@komyakino.ru>\n"
 "Language-Team: Russian <gnu@d07.ru>\n"
diff --git a/po/sk.gmo b/po/sk.gmo
index 926bc3e..0816211 100644
--- a/po/sk.gmo
+++ b/po/sk.gmo
Binary files differ
diff --git a/po/sk.po b/po/sk.po
index 6c56d31..ecfaaa3 100644
--- a/po/sk.po
+++ b/po/sk.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 1.2.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2014-01-30 11:08+0100\n"
 "Last-Translator: Peter Tuharsky <tuharsky@misbb.sk>\n"
 "Language-Team: Slovak <sk-i18n@lists.linux.sk>\n"
diff --git a/po/sl.gmo b/po/sl.gmo
index 3f0b4a1..74aa43a 100644
--- a/po/sl.gmo
+++ b/po/sl.gmo
Binary files differ
diff --git a/po/sl.po b/po/sl.po
index efc480a..b5a7156 100644
--- a/po/sl.po
+++ b/po/sl.po
@@ -10,7 +10,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good-1.2.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2014-04-09 22:52+0100\n"
 "Last-Translator: Klemen Košir <klemen913@gmail.com>\n"
 "Language-Team: Slovenian <translation-team-sl@lists.sourceforge.net>\n"
diff --git a/po/sq.gmo b/po/sq.gmo
index 4b05cf1..f6feb2f 100644
--- a/po/sq.gmo
+++ b/po/sq.gmo
Binary files differ
diff --git a/po/sq.po b/po/sq.po
index 4bd6c6f..23973da 100644
--- a/po/sq.po
+++ b/po/sq.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins 0.8.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2004-08-07 20:29+0200\n"
 "Last-Translator: Laurent Dhima <laurenti@alblinux.net>\n"
 "Language-Team: Albanian <begraj@hotmail.com>\n"
diff --git a/po/sr.gmo b/po/sr.gmo
index 05a34ef..09e18f7 100644
--- a/po/sr.gmo
+++ b/po/sr.gmo
Binary files differ
diff --git a/po/sr.po b/po/sr.po
index 0c04e2e..d0ae47f 100644
--- a/po/sr.po
+++ b/po/sr.po
@@ -2,13 +2,13 @@
 # Copyright (C) 2014 Free Software Foundation, Inc.
 # This file is distributed under the same license as the gst-plugins-good package.
 # Danilo Segan <dsegan@gmx.net>, 2004.
-# Мирослав Николић <miroslavnikolic@rocketmail.com>, 2011—2014.
+# Мирослав Николић <miroslavnikolic@rocketmail.com>, 2011—2015.
 msgid ""
 msgstr ""
-"Project-Id-Version: gst-plugins-good-1.4.1\n"
+"Project-Id-Version: gst-plugins-good-1.6.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
-"PO-Revision-Date: 2014-09-13 10:50+0200\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
+"PO-Revision-Date: 2015-12-24 11:39+0200\n"
 "Last-Translator: Мирослав Николић <miroslavnikolic@rocketmail.com>\n"
 "Language-Team: Serbian <(nothing)>\n"
 "Language: sr\n"
@@ -47,7 +47,6 @@
 msgid "Secure connection setup failed."
 msgstr "Подешавање безбедне везе није успело."
 
-#, fuzzy
 msgid ""
 "A network error occurred, or the server closed the connection unexpectedly."
 msgstr "Дошло је до грешке на мрежи, или је сервер неочекивано затворио везу."
diff --git a/po/sv.gmo b/po/sv.gmo
index 4b90689..71a339d 100644
--- a/po/sv.gmo
+++ b/po/sv.gmo
Binary files differ
diff --git a/po/sv.po b/po/sv.po
index 6238e8b..78c227b 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 1.6.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2015-10-31 15:31+0100\n"
 "Last-Translator: Sebastian Rasmussen <sebras@gmail.com>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
diff --git a/po/tr.gmo b/po/tr.gmo
index 7ac8224..9434456 100644
--- a/po/tr.gmo
+++ b/po/tr.gmo
Binary files differ
diff --git a/po/tr.po b/po/tr.po
index 6bd8967..9edc576 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 1.4.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2015-01-10 21:07+0100\n"
 "Last-Translator: Volkan Gezer <volkangezer@gmail.com>\n"
 "Language-Team: Turkish <gnu-tr-u12a@lists.sourceforge.net>\n"
diff --git a/po/uk.gmo b/po/uk.gmo
index 6f2b3da..8634af9 100644
--- a/po/uk.gmo
+++ b/po/uk.gmo
Binary files differ
diff --git a/po/uk.po b/po/uk.po
index 8fc0b52..168eccf 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 1.6.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2015-11-13 21:55+0200\n"
 "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
 "Language-Team: Ukrainian <translation-team-uk@lists.sourceforge.net>\n"
diff --git a/po/vi.gmo b/po/vi.gmo
index 31ccb20..7005c5e 100644
--- a/po/vi.gmo
+++ b/po/vi.gmo
Binary files differ
diff --git a/po/vi.po b/po/vi.po
index 8aaa5fa..bc3b10e 100644
--- a/po/vi.po
+++ b/po/vi.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 1.6.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2015-10-16 08:17+0700\n"
 "Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n"
 "Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n"
diff --git a/po/zh_CN.gmo b/po/zh_CN.gmo
index 1f7f1d5..2cfa11d 100644
--- a/po/zh_CN.gmo
+++ b/po/zh_CN.gmo
Binary files differ
diff --git a/po/zh_CN.po b/po/zh_CN.po
index eb1333b..4f9940a 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good 1.6.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2015-10-16 19:26+0800\n"
 "Last-Translator: Tianze Wang <zwpwjwtz@126.com>\n"
 "Language-Team: Chinese (simplified) <i18n-zh@googlegroups.com>\n"
diff --git a/po/zh_HK.gmo b/po/zh_HK.gmo
index 624145a..80ab6ca 100644
--- a/po/zh_HK.gmo
+++ b/po/zh_HK.gmo
Binary files differ
diff --git a/po/zh_HK.po b/po/zh_HK.po
index 3bfa198..20e0ea8 100644
--- a/po/zh_HK.po
+++ b/po/zh_HK.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good-0.10.2 0.10.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2006-08-29 01:08+0800\n"
 "Last-Translator: Abel Cheung <abelcheung@gmail.com>\n"
 "Language-Team: Chinese (Hong Kong) <community@linuxhall.org>\n"
diff --git a/po/zh_TW.gmo b/po/zh_TW.gmo
index 1e3c053..997ac34 100644
--- a/po/zh_TW.gmo
+++ b/po/zh_TW.gmo
Binary files differ
diff --git a/po/zh_TW.po b/po/zh_TW.po
index 3f3aa9f..e306b45 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-good-0.10.2 0.10.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-12-14 19:16+0100\n"
+"POT-Creation-Date: 2015-12-24 13:17+0100\n"
 "PO-Revision-Date: 2006-08-29 01:08+0800\n"
 "Last-Translator: Abel Cheung <abelcheung@gmail.com>\n"
 "Language-Team: Chinese (traditional) <zh-l10n@linux.org.tw>\n"
diff --git a/sys/Makefile.in b/sys/Makefile.in
index fcbbec4..de42d0c 100644
--- a/sys/Makefile.in
+++ b/sys/Makefile.in
@@ -461,6 +461,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/sys/directsound/Makefile.in b/sys/directsound/Makefile.in
index e398394..5940e50 100644
--- a/sys/directsound/Makefile.in
+++ b/sys/directsound/Makefile.in
@@ -480,6 +480,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/sys/directsound/gstdirectsoundsink.c b/sys/directsound/gstdirectsoundsink.c
index a4f0bde..ffd1bfe 100644
--- a/sys/directsound/gstdirectsoundsink.c
+++ b/sys/directsound/gstdirectsoundsink.c
@@ -430,8 +430,15 @@
 
   dsoundsink = GST_DIRECTSOUND_SINK (asink);
 
-  if (dsoundsink->device_id)
+  if (dsoundsink->device_id) {
     lpGuid = string_to_guid (dsoundsink->device_id);
+    if (lpGuid == NULL) {
+      GST_ELEMENT_ERROR (dsoundsink, RESOURCE, OPEN_READ,
+          ("gst_directsound_sink_open: device set, but guid not found: %s",
+              dsoundsink->device_id), (NULL));
+      return FALSE;
+    }
+  }
 
   /* create and initialize a DirecSound object */
   if (FAILED (hRes = DirectSoundCreate (lpGuid, &dsoundsink->pDS, NULL))) {
@@ -608,7 +615,8 @@
       &dwCurrentPlayCursor, NULL);
 
   if (SUCCEEDED (hRes) && SUCCEEDED (hRes2) && (dwStatus & DSBSTATUS_PLAYING)) {
-    DWORD dwFreeBufferSize;
+    DWORD dwFreeBufferSize = 0;
+    DWORD sleepTime = 0;
 
   calculate_freesize:
     /* calculate the free size of the circular buffer */
@@ -621,7 +629,17 @@
           dwCurrentPlayCursor - dsoundsink->current_circular_offset;
 
     if (length >= dwFreeBufferSize) {
-      Sleep (100);
+      sleepTime =
+          ((length -
+              dwFreeBufferSize) * 1000) / (dsoundsink->bytes_per_sample *
+          GST_AUDIO_BASE_SINK (asink)->ringbuffer->spec.info.rate);
+      if (sleepTime > 0) {
+        GST_DEBUG_OBJECT (dsoundsink,
+            "gst_directsound_sink_write: length:%i, FreeBufSiz: %ld, sleepTime: %ld, bps: %i, rate: %i",
+            length, dwFreeBufferSize, sleepTime, dsoundsink->bytes_per_sample,
+            GST_AUDIO_BASE_SINK (asink)->ringbuffer->spec.info.rate);
+        Sleep (sleepTime);
+      }
       hRes = IDirectSoundBuffer_GetCurrentPosition (dsoundsink->pDSBSecondary,
           &dwCurrentPlayCursor, NULL);
 
diff --git a/sys/oss/Makefile.in b/sys/oss/Makefile.in
index 065d7a9..71f2c6e 100644
--- a/sys/oss/Makefile.in
+++ b/sys/oss/Makefile.in
@@ -478,6 +478,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/sys/oss/gstosssrc.c b/sys/oss/gstosssrc.c
index 742c59d..60c9e05 100644
--- a/sys/oss/gstosssrc.c
+++ b/sys/oss/gstosssrc.c
@@ -181,8 +181,7 @@
 
   switch (prop_id) {
     case PROP_DEVICE:
-      if (src->device)
-        g_free (src->device);
+      g_free (src->device);
       src->device = g_value_dup_string (value);
       break;
     default:
diff --git a/sys/oss4/Makefile.in b/sys/oss4/Makefile.in
index 28dcc0c..90973b0 100644
--- a/sys/oss4/Makefile.in
+++ b/sys/oss4/Makefile.in
@@ -479,6 +479,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/sys/osxaudio/Makefile.in b/sys/osxaudio/Makefile.in
index 2f4e7b3..7cecd5f 100644
--- a/sys/osxaudio/Makefile.in
+++ b/sys/osxaudio/Makefile.in
@@ -484,6 +484,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/sys/osxvideo/Makefile.in b/sys/osxvideo/Makefile.in
index 44c4643..2991130 100644
--- a/sys/osxvideo/Makefile.in
+++ b/sys/osxvideo/Makefile.in
@@ -478,6 +478,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/sys/sunaudio/Makefile.in b/sys/sunaudio/Makefile.in
index fa9bf36..c23856b 100644
--- a/sys/sunaudio/Makefile.in
+++ b/sys/sunaudio/Makefile.in
@@ -482,6 +482,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/sys/sunaudio/gstsunaudiosrc.c b/sys/sunaudio/gstsunaudiosrc.c
index ec1d7d7..0f454bf 100644
--- a/sys/sunaudio/gstsunaudiosrc.c
+++ b/sys/sunaudio/gstsunaudiosrc.c
@@ -177,8 +177,7 @@
 
   switch (prop_id) {
     case PROP_DEVICE:
-      if (sunaudiosrc->device)
-        g_free (sunaudiosrc->device);
+      g_free (sunaudiosrc->device);
       sunaudiosrc->device = g_value_dup_string (value);
       break;
     default:
diff --git a/sys/v4l2/Makefile.in b/sys/v4l2/Makefile.in
index 44bc72f..2134e2a 100644
--- a/sys/v4l2/Makefile.in
+++ b/sys/v4l2/Makefile.in
@@ -505,6 +505,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/sys/v4l2/gstv4l2.c b/sys/v4l2/gstv4l2.c
index 8333eab..83fcc98 100644
--- a/sys/v4l2/gstv4l2.c
+++ b/sys/v4l2/gstv4l2.c
@@ -54,6 +54,7 @@
 GST_DEBUG_CATEGORY (v4l2_debug);
 #define GST_CAT_DEFAULT v4l2_debug
 
+#ifdef GST_V4L2_ENABLE_PROBE
 /* This is a minimalist probe, for speed, we only enumerate formats */
 static GstCaps *
 gst_v4l2_probe_template_caps (const gchar * device, gint video_fd,
@@ -167,6 +168,13 @@
         gst_v4l2_probe_template_caps (it->device_path, video_fd,
             V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE));
 
+    /* Skip devices without any supported formats */
+    if (gst_caps_is_empty (sink_caps) || gst_caps_is_empty (src_caps)) {
+      gst_caps_unref (sink_caps);
+      gst_caps_unref (src_caps);
+      continue;
+    }
+
     basename = g_path_get_basename (it->device_path);
 
     if (gst_v4l2_is_video_dec (sink_caps, src_caps))
@@ -192,12 +200,21 @@
 
   return ret;
 }
+#endif
 
 static gboolean
 plugin_init (GstPlugin * plugin)
 {
+  const gchar *paths[] = { "/dev", "/dev/v4l2", NULL };
+  const gchar *names[] = { "video", NULL };
+
   GST_DEBUG_CATEGORY_INIT (v4l2_debug, "v4l2", 0, "V4L2 API calls");
 
+  /* Add some depedency, so the dynamic features get updated upon changes in
+   * /dev/video* */
+  gst_plugin_add_dependency (plugin,
+      NULL, paths, names, GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_PREFIX);
+
   if (!gst_element_register (plugin, "v4l2src", GST_RANK_PRIMARY,
           GST_TYPE_V4L2SRC) ||
       !gst_element_register (plugin, "v4l2sink", GST_RANK_NONE,
@@ -205,9 +222,12 @@
       !gst_element_register (plugin, "v4l2radio", GST_RANK_NONE,
           GST_TYPE_V4L2RADIO) ||
       !gst_device_provider_register (plugin, "v4l2deviceprovider",
-          GST_RANK_PRIMARY, GST_TYPE_V4L2_DEVICE_PROVIDER) ||
+          GST_RANK_PRIMARY, GST_TYPE_V4L2_DEVICE_PROVIDER)
       /* etc. */
-      !gst_v4l2_probe_and_register (plugin))
+#ifdef GST_V4L2_ENABLE_PROBE
+      || !gst_v4l2_probe_and_register (plugin)
+#endif
+      )
     return FALSE;
 
 #ifdef ENABLE_NLS
diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c
index 17847e6..9f7deaf 100644
--- a/sys/v4l2/gstv4l2object.c
+++ b/sys/v4l2/gstv4l2object.c
@@ -83,39 +83,83 @@
 } GstV4L2FormatDesc;
 
 static const GstV4L2FormatDesc gst_v4l2_formats[] = {
-  /* from Linux 2.6.15 videodev2.h */
+  /* RGB formats */
   {V4L2_PIX_FMT_RGB332, TRUE, GST_V4L2_RAW},
-  {V4L2_PIX_FMT_RGB555, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_ARGB555, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_XRGB555, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_ARGB555X, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_XRGB555X, TRUE, GST_V4L2_RAW},
   {V4L2_PIX_FMT_RGB565, TRUE, GST_V4L2_RAW},
-  {V4L2_PIX_FMT_RGB555X, TRUE, GST_V4L2_RAW},
   {V4L2_PIX_FMT_RGB565X, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_BGR666, TRUE, GST_V4L2_RAW},
   {V4L2_PIX_FMT_BGR24, TRUE, GST_V4L2_RAW},
   {V4L2_PIX_FMT_RGB24, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_ABGR32, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_XBGR32, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_ARGB32, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_XRGB32, TRUE, GST_V4L2_RAW},
+
+  /* Deprecated Packed RGB Image Formats (alpha ambiguity) */
+  {V4L2_PIX_FMT_RGB444, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_RGB555, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_RGB555X, TRUE, GST_V4L2_RAW},
   {V4L2_PIX_FMT_BGR32, TRUE, GST_V4L2_RAW},
   {V4L2_PIX_FMT_RGB32, TRUE, GST_V4L2_RAW},
+
+  /* Grey formats */
   {V4L2_PIX_FMT_GREY, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_Y4, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_Y6, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_Y10, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_Y12, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_Y16, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_Y16_BE, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_Y10BPACK, TRUE, GST_V4L2_RAW},
+
+  /* Palette formats */
+  {V4L2_PIX_FMT_PAL8, TRUE, GST_V4L2_RAW},
+
+  /* Chrominance formats */
+  {V4L2_PIX_FMT_UV8, TRUE, GST_V4L2_RAW},
+
+  /* Luminance+Chrominance formats */
   {V4L2_PIX_FMT_YVU410, TRUE, GST_V4L2_RAW},
   {V4L2_PIX_FMT_YVU420, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_YVU420M, TRUE, GST_V4L2_RAW},
   {V4L2_PIX_FMT_YUYV, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_YYUV, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_YVYU, TRUE, GST_V4L2_RAW},
   {V4L2_PIX_FMT_UYVY, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_VYUY, TRUE, GST_V4L2_RAW},
   {V4L2_PIX_FMT_YUV422P, TRUE, GST_V4L2_RAW},
   {V4L2_PIX_FMT_YUV411P, TRUE, GST_V4L2_RAW},
   {V4L2_PIX_FMT_Y41P, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_YUV444, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_YUV555, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_YUV565, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_YUV32, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_YUV410, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_YUV420, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_YUV420M, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_HI240, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_HM12, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_M420, TRUE, GST_V4L2_RAW},
 
   /* two planes -- one Y, one Cr + Cb interleaved  */
   {V4L2_PIX_FMT_NV12, TRUE, GST_V4L2_RAW},
   {V4L2_PIX_FMT_NV12M, TRUE, GST_V4L2_RAW},
   {V4L2_PIX_FMT_NV12MT, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_NV12MT_16X16, TRUE, GST_V4L2_RAW},
   {V4L2_PIX_FMT_NV21, TRUE, GST_V4L2_RAW},
   {V4L2_PIX_FMT_NV21M, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_NV16, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_NV16M, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_NV61, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_NV61M, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_NV24, TRUE, GST_V4L2_RAW},
+  {V4L2_PIX_FMT_NV42, TRUE, GST_V4L2_RAW},
 
-  /*  The following formats are not defined in the V4L2 specification */
-  {V4L2_PIX_FMT_YUV410, TRUE, GST_V4L2_RAW},
-  {V4L2_PIX_FMT_YUV420, TRUE, GST_V4L2_RAW},
-  {V4L2_PIX_FMT_YYUV, TRUE, GST_V4L2_RAW},
-  {V4L2_PIX_FMT_HI240, TRUE, GST_V4L2_RAW},
-
-  /* see http://www.siliconimaging.com/RGB%20Bayer.htm */
+  /* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
   {V4L2_PIX_FMT_SBGGR8, TRUE, GST_V4L2_CODEC},
   {V4L2_PIX_FMT_SGBRG8, TRUE, GST_V4L2_CODEC},
   {V4L2_PIX_FMT_SGRBG8, TRUE, GST_V4L2_CODEC},
@@ -127,12 +171,16 @@
   {V4L2_PIX_FMT_PJPG, FALSE, GST_V4L2_CODEC},
   {V4L2_PIX_FMT_DV, FALSE, GST_V4L2_TRANSPORT},
   {V4L2_PIX_FMT_MPEG, FALSE, GST_V4L2_TRANSPORT},
+  {V4L2_PIX_FMT_H264, FALSE, GST_V4L2_CODEC},
+  {V4L2_PIX_FMT_H264_NO_SC, FALSE, GST_V4L2_CODEC},
+  {V4L2_PIX_FMT_H264_MVC, FALSE, GST_V4L2_CODEC},
+  {V4L2_PIX_FMT_H263, FALSE, GST_V4L2_CODEC},
   {V4L2_PIX_FMT_MPEG1, FALSE, GST_V4L2_CODEC},
   {V4L2_PIX_FMT_MPEG2, FALSE, GST_V4L2_CODEC},
   {V4L2_PIX_FMT_MPEG4, FALSE, GST_V4L2_CODEC},
-  {V4L2_PIX_FMT_H263, FALSE, GST_V4L2_CODEC},
-  {V4L2_PIX_FMT_H264, FALSE, GST_V4L2_CODEC},
-  /* VP8 not parseable */
+  {V4L2_PIX_FMT_XVID, FALSE, GST_V4L2_CODEC},
+  {V4L2_PIX_FMT_VC1_ANNEX_G, FALSE, GST_V4L2_CODEC},
+  {V4L2_PIX_FMT_VC1_ANNEX_L, FALSE, GST_V4L2_CODEC},
   {V4L2_PIX_FMT_VP8, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
 
   /*  Vendor-specific formats   */
@@ -140,7 +188,6 @@
   {V4L2_PIX_FMT_SN9C10X, TRUE, GST_V4L2_CODEC},
   {V4L2_PIX_FMT_PWC1, TRUE, GST_V4L2_CODEC},
   {V4L2_PIX_FMT_PWC2, TRUE, GST_V4L2_CODEC},
-  {V4L2_PIX_FMT_YVYU, TRUE, GST_V4L2_RAW},
 };
 
 #define GST_V4L2_FORMAT_COUNT (G_N_ELEMENTS (gst_v4l2_formats))
@@ -460,11 +507,9 @@
 {
   g_return_if_fail (v4l2object != NULL);
 
-  if (v4l2object->videodev)
-    g_free (v4l2object->videodev);
+  g_free (v4l2object->videodev);
 
-  if (v4l2object->channel)
-    g_free (v4l2object->channel);
+  g_free (v4l2object->channel);
 
   if (v4l2object->formats) {
     gst_v4l2_object_clear_format_list (v4l2object);
@@ -901,10 +946,27 @@
       break;
 
     case V4L2_PIX_FMT_RGB332:
+    case V4L2_PIX_FMT_ARGB555:
+    case V4L2_PIX_FMT_XRGB555:
     case V4L2_PIX_FMT_RGB555:
+    case V4L2_PIX_FMT_ARGB555X:
+    case V4L2_PIX_FMT_XRGB555X:
     case V4L2_PIX_FMT_RGB555X:
+    case V4L2_PIX_FMT_BGR666:
     case V4L2_PIX_FMT_RGB565:
     case V4L2_PIX_FMT_RGB565X:
+    case V4L2_PIX_FMT_RGB444:
+    case V4L2_PIX_FMT_Y4:
+    case V4L2_PIX_FMT_Y6:
+    case V4L2_PIX_FMT_Y10:
+    case V4L2_PIX_FMT_Y12:
+    case V4L2_PIX_FMT_Y10BPACK:
+    case V4L2_PIX_FMT_YUV555:
+    case V4L2_PIX_FMT_YUV565:
+    case V4L2_PIX_FMT_YUV32:
+    case V4L2_PIX_FMT_NV12MT_16X16:
+    case V4L2_PIX_FMT_NV42:
+    case V4L2_PIX_FMT_H264_MVC:
       rank = RGB_ODD_BASE_RANK;
       break;
 
@@ -915,6 +977,10 @@
 
     case V4L2_PIX_FMT_RGB32:
     case V4L2_PIX_FMT_BGR32:
+    case V4L2_PIX_FMT_ABGR32:
+    case V4L2_PIX_FMT_XBGR32:
+    case V4L2_PIX_FMT_ARGB32:
+    case V4L2_PIX_FMT_XRGB32:
       rank = RGB_BASE_RANK;
       break;
 
@@ -929,6 +995,11 @@
     case V4L2_PIX_FMT_NV21M:   /* Same as NV21      */
     case V4L2_PIX_FMT_YYUV:    /* 16  YUV 4:2:2     */
     case V4L2_PIX_FMT_HI240:   /*  8  8-bit color   */
+    case V4L2_PIX_FMT_NV16:    /* 16  Y/CbCr 4:2:2  */
+    case V4L2_PIX_FMT_NV16M:   /* Same as NV16      */
+    case V4L2_PIX_FMT_NV61:    /* 16  Y/CrCb 4:2:2  */
+    case V4L2_PIX_FMT_NV61M:   /* Same as NV61      */
+    case V4L2_PIX_FMT_NV24:    /* 24  Y/CrCb 4:4:4  */
       rank = YUV_ODD_BASE_RANK;
       break;
 
@@ -939,6 +1010,7 @@
       rank = YUV_BASE_RANK + 2;
       break;
     case V4L2_PIX_FMT_YUV420:  /* I420, 12 bits per pixel */
+    case V4L2_PIX_FMT_YUV420M:
       rank = YUV_BASE_RANK + 7;
       break;
     case V4L2_PIX_FMT_YUYV:    /* YUY2, 16 bits per pixel */
@@ -950,6 +1022,9 @@
     case V4L2_PIX_FMT_UYVY:    /* UYVY, 16 bits per pixel */
       rank = YUV_BASE_RANK + 9;
       break;
+    case V4L2_PIX_FMT_YUV444:
+      rank = YUV_BASE_RANK + 6;
+      break;
     case V4L2_PIX_FMT_Y41P:    /* Y41P, 12 bits per pixel */
       rank = YUV_BASE_RANK + 5;
       break;
@@ -1133,9 +1208,20 @@
     case V4L2_PIX_FMT_GREY:    /*  8  Greyscale     */
       format = GST_VIDEO_FORMAT_GRAY8;
       break;
+    case V4L2_PIX_FMT_Y16:
+      format = GST_VIDEO_FORMAT_GRAY16_LE;
+      break;
+    case V4L2_PIX_FMT_Y16_BE:
+      format = GST_VIDEO_FORMAT_GRAY16_BE;
+      break;
+    case V4L2_PIX_FMT_XRGB555:
     case V4L2_PIX_FMT_RGB555:
       format = GST_VIDEO_FORMAT_RGB15;
       break;
+    case V4L2_PIX_FMT_XRGB555X:
+    case V4L2_PIX_FMT_RGB555X:
+      format = GST_VIDEO_FORMAT_BGR15;
+      break;
     case V4L2_PIX_FMT_RGB565:
       format = GST_VIDEO_FORMAT_RGB16;
       break;
@@ -1145,12 +1231,20 @@
     case V4L2_PIX_FMT_BGR24:
       format = GST_VIDEO_FORMAT_BGR;
       break;
+    case V4L2_PIX_FMT_XRGB32:
     case V4L2_PIX_FMT_RGB32:
       format = GST_VIDEO_FORMAT_xRGB;
       break;
+    case V4L2_PIX_FMT_XBGR32:
     case V4L2_PIX_FMT_BGR32:
       format = GST_VIDEO_FORMAT_BGRx;
       break;
+    case V4L2_PIX_FMT_ABGR32:
+      format = GST_VIDEO_FORMAT_BGRA;
+      break;
+    case V4L2_PIX_FMT_ARGB32:
+      format = GST_VIDEO_FORMAT_ARGB;
+      break;
     case V4L2_PIX_FMT_NV12:
     case V4L2_PIX_FMT_NV12M:
       format = GST_VIDEO_FORMAT_NV12;
@@ -1169,6 +1263,7 @@
       format = GST_VIDEO_FORMAT_YUV9;
       break;
     case V4L2_PIX_FMT_YUV420:
+    case V4L2_PIX_FMT_YUV420M:
       format = GST_VIDEO_FORMAT_I420;
       break;
     case V4L2_PIX_FMT_YUYV:
@@ -1180,11 +1275,6 @@
     case V4L2_PIX_FMT_UYVY:
       format = GST_VIDEO_FORMAT_UYVY;
       break;
-#if 0
-    case V4L2_PIX_FMT_Y41P:
-      format = GST_VIDEO_FORMAT_Y41P;
-      break;
-#endif
     case V4L2_PIX_FMT_YUV411P:
       format = GST_VIDEO_FORMAT_Y41B;
       break;
@@ -1194,6 +1284,17 @@
     case V4L2_PIX_FMT_YVYU:
       format = GST_VIDEO_FORMAT_YVYU;
       break;
+    case V4L2_PIX_FMT_NV16:
+    case V4L2_PIX_FMT_NV16M:
+      format = GST_VIDEO_FORMAT_NV16;
+      break;
+    case V4L2_PIX_FMT_NV61:
+    case V4L2_PIX_FMT_NV61M:
+      format = GST_VIDEO_FORMAT_NV61;
+      break;
+    case V4L2_PIX_FMT_NV24:
+      format = GST_VIDEO_FORMAT_NV24;
+      break;
     default:
       format = GST_VIDEO_FORMAT_UNKNOWN;
       break;
@@ -1213,10 +1314,6 @@
     case V4L2_PIX_FMT_JPEG:    /* JFIF JPEG */
       structure = gst_structure_new_empty ("image/jpeg");
       break;
-    case V4L2_PIX_FMT_YYUV:    /* 16  YUV 4:2:2     */
-    case V4L2_PIX_FMT_HI240:   /*  8  8-bit color   */
-      /* FIXME: get correct fourccs here */
-      break;
     case V4L2_PIX_FMT_MPEG1:
       structure = gst_structure_new ("video/mpeg",
           "mpegversion", G_TYPE_INT, 2, NULL);
@@ -1226,6 +1323,7 @@
           "mpegversion", G_TYPE_INT, 2, NULL);
       break;
     case V4L2_PIX_FMT_MPEG4:
+    case V4L2_PIX_FMT_XVID:
       structure = gst_structure_new ("video/mpeg",
           "mpegversion", G_TYPE_INT, 4, "systemstream",
           G_TYPE_BOOLEAN, FALSE, NULL);
@@ -1239,35 +1337,52 @@
           "stream-format", G_TYPE_STRING, "byte-stream", "alignment",
           G_TYPE_STRING, "au", NULL);
       break;
+    case V4L2_PIX_FMT_H264_NO_SC:
+      structure = gst_structure_new ("video/x-h264",
+          "stream-format", G_TYPE_STRING, "avc", "alignment",
+          G_TYPE_STRING, "au", NULL);
+      break;
+    case V4L2_PIX_FMT_VC1_ANNEX_G:
+    case V4L2_PIX_FMT_VC1_ANNEX_L:
+      structure = gst_structure_new ("video/x-wmv",
+          "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "WVC1", NULL);
+      break;
     case V4L2_PIX_FMT_VP8:
       structure = gst_structure_new_empty ("video/x-vp8");
       break;
-    case V4L2_PIX_FMT_RGB332:
-    case V4L2_PIX_FMT_RGB555X:
-    case V4L2_PIX_FMT_RGB565X:
-      /* FIXME: get correct fourccs here */
-      break;
     case V4L2_PIX_FMT_GREY:    /*  8  Greyscale     */
+    case V4L2_PIX_FMT_Y16:
+    case V4L2_PIX_FMT_Y16_BE:
+    case V4L2_PIX_FMT_XRGB555:
     case V4L2_PIX_FMT_RGB555:
+    case V4L2_PIX_FMT_XRGB555X:
+    case V4L2_PIX_FMT_RGB555X:
     case V4L2_PIX_FMT_RGB565:
     case V4L2_PIX_FMT_RGB24:
     case V4L2_PIX_FMT_BGR24:
     case V4L2_PIX_FMT_RGB32:
+    case V4L2_PIX_FMT_XRGB32:
+    case V4L2_PIX_FMT_ARGB32:
     case V4L2_PIX_FMT_BGR32:
+    case V4L2_PIX_FMT_XBGR32:
+    case V4L2_PIX_FMT_ABGR32:
     case V4L2_PIX_FMT_NV12:    /* 12  Y/CbCr 4:2:0  */
     case V4L2_PIX_FMT_NV12M:
     case V4L2_PIX_FMT_NV12MT:
     case V4L2_PIX_FMT_NV21:    /* 12  Y/CrCb 4:2:0  */
     case V4L2_PIX_FMT_NV21M:
+    case V4L2_PIX_FMT_NV16:    /* 16  Y/CbCr 4:2:2  */
+    case V4L2_PIX_FMT_NV16M:
+    case V4L2_PIX_FMT_NV61:    /* 16  Y/CrCb 4:2:2  */
+    case V4L2_PIX_FMT_NV61M:
+    case V4L2_PIX_FMT_NV24:    /* 24  Y/CrCb 4:4:4  */
     case V4L2_PIX_FMT_YVU410:
     case V4L2_PIX_FMT_YUV410:
     case V4L2_PIX_FMT_YUV420:  /* I420/IYUV */
+    case V4L2_PIX_FMT_YUV420M:
     case V4L2_PIX_FMT_YUYV:
     case V4L2_PIX_FMT_YVU420:
     case V4L2_PIX_FMT_UYVY:
-#if 0
-    case V4L2_PIX_FMT_Y41P:
-#endif
     case V4L2_PIX_FMT_YUV422P:
     case V4L2_PIX_FMT_YVYU:
     case V4L2_PIX_FMT_YUV411P:{
@@ -1308,8 +1423,28 @@
     case V4L2_PIX_FMT_PWC2:
       structure = gst_structure_new_empty ("video/x-pwc2");
       break;
+    case V4L2_PIX_FMT_RGB332:
+    case V4L2_PIX_FMT_BGR666:
+    case V4L2_PIX_FMT_ARGB555X:
+    case V4L2_PIX_FMT_RGB565X:
+    case V4L2_PIX_FMT_RGB444:
+    case V4L2_PIX_FMT_YYUV:    /* 16  YUV 4:2:2     */
+    case V4L2_PIX_FMT_HI240:   /*  8  8-bit color   */
+    case V4L2_PIX_FMT_Y4:
+    case V4L2_PIX_FMT_Y6:
+    case V4L2_PIX_FMT_Y10:
+    case V4L2_PIX_FMT_Y12:
+    case V4L2_PIX_FMT_Y10BPACK:
+    case V4L2_PIX_FMT_YUV444:
+    case V4L2_PIX_FMT_YUV555:
+    case V4L2_PIX_FMT_YUV565:
+    case V4L2_PIX_FMT_Y41P:
+    case V4L2_PIX_FMT_YUV32:
+    case V4L2_PIX_FMT_NV12MT_16X16:
+    case V4L2_PIX_FMT_NV42:
+    case V4L2_PIX_FMT_H264_MVC:
     default:
-      GST_DEBUG ("Unknown fourcc 0x%08x %" GST_FOURCC_FORMAT,
+      GST_DEBUG ("Unsupported fourcc 0x%08x %" GST_FOURCC_FORMAT,
           fourcc, GST_FOURCC_ARGS (fourcc));
       break;
   }
@@ -1454,15 +1589,11 @@
     switch (GST_VIDEO_INFO_FORMAT (info)) {
       case GST_VIDEO_FORMAT_I420:
         fourcc = V4L2_PIX_FMT_YUV420;
+        fourcc_nc = V4L2_PIX_FMT_YUV420M;
         break;
       case GST_VIDEO_FORMAT_YUY2:
         fourcc = V4L2_PIX_FMT_YUYV;
         break;
-#if 0
-      case GST_VIDEO_FORMAT_Y41P:
-        fourcc = V4L2_PIX_FMT_Y41P;
-        break;
-#endif
       case GST_VIDEO_FORMAT_UYVY:
         fourcc = V4L2_PIX_FMT_UYVY;
         break;
@@ -1486,6 +1617,17 @@
         fourcc = V4L2_PIX_FMT_NV21;
         fourcc_nc = V4L2_PIX_FMT_NV21M;
         break;
+      case GST_VIDEO_FORMAT_NV16:
+        fourcc = V4L2_PIX_FMT_NV16;
+        fourcc_nc = V4L2_PIX_FMT_NV16M;
+        break;
+      case GST_VIDEO_FORMAT_NV61:
+        fourcc = V4L2_PIX_FMT_NV61;
+        fourcc_nc = V4L2_PIX_FMT_NV61M;
+        break;
+      case GST_VIDEO_FORMAT_NV24:
+        fourcc = V4L2_PIX_FMT_NV24;
+        break;
       case GST_VIDEO_FORMAT_YVYU:
         fourcc = V4L2_PIX_FMT_YVYU;
         break;
@@ -1502,15 +1644,30 @@
         fourcc = V4L2_PIX_FMT_BGR24;
         break;
       case GST_VIDEO_FORMAT_xRGB:
+        fourcc = V4L2_PIX_FMT_RGB32;
+        fourcc_nc = V4L2_PIX_FMT_XRGB32;
+        break;
       case GST_VIDEO_FORMAT_ARGB:
         fourcc = V4L2_PIX_FMT_RGB32;
+        fourcc_nc = V4L2_PIX_FMT_ARGB32;
         break;
       case GST_VIDEO_FORMAT_BGRx:
+        fourcc = V4L2_PIX_FMT_BGR32;
+        fourcc_nc = V4L2_PIX_FMT_XBGR32;
+        break;
       case GST_VIDEO_FORMAT_BGRA:
         fourcc = V4L2_PIX_FMT_BGR32;
+        fourcc_nc = V4L2_PIX_FMT_ABGR32;
         break;
       case GST_VIDEO_FORMAT_GRAY8:
         fourcc = V4L2_PIX_FMT_GREY;
+        break;
+      case GST_VIDEO_FORMAT_GRAY16_LE:
+        fourcc = V4L2_PIX_FMT_Y16;
+        break;
+      case GST_VIDEO_FORMAT_GRAY16_BE:
+        fourcc = V4L2_PIX_FMT_Y16_BE;
+        break;
       default:
         break;
     }
@@ -1533,6 +1690,7 @@
             break;
           case 4:
             fourcc = V4L2_PIX_FMT_MPEG4;
+            fourcc_nc = V4L2_PIX_FMT_XVID;
             break;
           default:
             break;
@@ -1541,7 +1699,12 @@
     } else if (g_str_equal (mimetype, "video/x-h263")) {
       fourcc = V4L2_PIX_FMT_H263;
     } else if (g_str_equal (mimetype, "video/x-h264")) {
-      fourcc = V4L2_PIX_FMT_H264;
+      const gchar *stream_format =
+          gst_structure_get_string (structure, "stream-format");
+      if (g_str_equal (stream_format, "avc"))
+        fourcc = V4L2_PIX_FMT_H264_NO_SC;
+      else
+        fourcc = V4L2_PIX_FMT_H264;
     } else if (g_str_equal (mimetype, "video/x-vp8")) {
       fourcc = V4L2_PIX_FMT_VP8;
     } else if (g_str_equal (mimetype, "video/x-bayer")) {
@@ -2788,6 +2951,7 @@
     case GST_VIDEO_FORMAT_NV12_64Z32:
     case GST_VIDEO_FORMAT_NV21:
     case GST_VIDEO_FORMAT_NV16:
+    case GST_VIDEO_FORMAT_NV61:
     case GST_VIDEO_FORMAT_NV24:
       estride = (plane == 0 ? 1 : 2) *
           GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (finfo, plane, stride);
@@ -3524,44 +3688,57 @@
 }
 
 GstCaps *
-gst_v4l2_object_get_caps (GstV4l2Object * v4l2object, GstCaps * filter)
+gst_v4l2_object_probe_caps (GstV4l2Object * v4l2object, GstCaps * filter)
 {
   GstCaps *ret;
   GSList *walk;
   GSList *formats;
 
-  if (v4l2object->probed_caps == NULL) {
-    formats = gst_v4l2_object_get_format_list (v4l2object);
+  formats = gst_v4l2_object_get_format_list (v4l2object);
 
-    ret = gst_caps_new_empty ();
+  ret = gst_caps_new_empty ();
 
-    for (walk = formats; walk; walk = walk->next) {
-      struct v4l2_fmtdesc *format;
-      GstStructure *template;
+  for (walk = formats; walk; walk = walk->next) {
+    struct v4l2_fmtdesc *format;
+    GstStructure *template;
 
-      format = (struct v4l2_fmtdesc *) walk->data;
+    format = (struct v4l2_fmtdesc *) walk->data;
 
-      template =
-          gst_v4l2_object_v4l2fourcc_to_bare_struct (format->pixelformat);
+    template = gst_v4l2_object_v4l2fourcc_to_bare_struct (format->pixelformat);
 
-      if (template) {
-        GstCaps *tmp;
+    if (template) {
+      GstCaps *tmp;
 
-        tmp = gst_v4l2_object_probe_caps_for_format (v4l2object,
-            format->pixelformat, template);
-        if (tmp)
-          gst_caps_append (ret, tmp);
+      tmp = gst_v4l2_object_probe_caps_for_format (v4l2object,
+          format->pixelformat, template);
+      if (tmp)
+        gst_caps_append (ret, tmp);
 
-        gst_structure_free (template);
-      } else {
-        GST_DEBUG_OBJECT (v4l2object->element, "unknown format %u",
-            format->pixelformat);
-      }
+      gst_structure_free (template);
+    } else {
+      GST_DEBUG_OBJECT (v4l2object->element, "unknown format %u",
+          format->pixelformat);
     }
-    v4l2object->probed_caps = ret;
   }
 
   if (filter) {
+    ret = gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
+  } else {
+    ret = gst_caps_ref (ret);
+  }
+
+  return ret;
+}
+
+GstCaps *
+gst_v4l2_object_get_caps (GstV4l2Object * v4l2object, GstCaps * filter)
+{
+  GstCaps *ret;
+
+  if (v4l2object->probed_caps == NULL)
+    v4l2object->probed_caps = gst_v4l2_object_probe_caps (v4l2object, NULL);
+
+  if (filter) {
     ret = gst_caps_intersect_full (filter, v4l2object->probed_caps,
         GST_CAPS_INTERSECT_FIRST);
   } else {
diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h
index 177a86b..e3728c4 100644
--- a/sys/v4l2/gstv4l2object.h
+++ b/sys/v4l2/gstv4l2object.h
@@ -260,6 +260,8 @@
 
 gboolean      gst_v4l2_object_stop        (GstV4l2Object * v4l2object);
 
+GstCaps *     gst_v4l2_object_probe_caps  (GstV4l2Object * v4l2object,
+                                           GstCaps * filter);
 GstCaps *     gst_v4l2_object_get_caps    (GstV4l2Object * v4l2object,
                                            GstCaps * filter);
 
diff --git a/sys/v4l2/gstv4l2transform.c b/sys/v4l2/gstv4l2transform.c
index 42aeb13..f617ac4 100644
--- a/sys/v4l2/gstv4l2transform.c
+++ b/sys/v4l2/gstv4l2transform.c
@@ -73,8 +73,8 @@
           pspec);
       break;
     case PROP_CAPTURE_IO_MODE:
-      gst_v4l2_object_set_property_helper (self->v4l2capture, PROP_IO_MODE,
-          value, pspec);
+      gst_v4l2_object_set_property_helper (self->v4l2capture, prop_id, value,
+          pspec);
       break;
 
       /* By default, only set on output */
diff --git a/sys/v4l2/gstv4l2videodec.c b/sys/v4l2/gstv4l2videodec.c
index f06e4f6..dc09a60 100644
--- a/sys/v4l2/gstv4l2videodec.c
+++ b/sys/v4l2/gstv4l2videodec.c
@@ -90,13 +90,13 @@
   GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (object);
 
   switch (prop_id) {
-    case PROP_IO_MODE:
+    case PROP_OUTPUT_IO_MODE:
       gst_v4l2_object_get_property_helper (self->v4l2output, prop_id, value,
           pspec);
       break;
     case PROP_CAPTURE_IO_MODE:
-      gst_v4l2_object_get_property_helper (self->v4l2output, PROP_IO_MODE,
-          value, pspec);
+      gst_v4l2_object_get_property_helper (self->v4l2capture, prop_id, value,
+          pspec);
       break;
 
       /* By default read from output */
@@ -465,6 +465,8 @@
     GstVideoInfo info;
     GstVideoCodecState *output_state;
     GstBuffer *codec_data;
+    GstCaps *acquired_caps, *caps, *filter;
+    GstStructure *st;
 
     GST_DEBUG_OBJECT (self, "Sending header");
 
@@ -506,6 +508,34 @@
     if (!gst_v4l2_object_acquire_format (self->v4l2capture, &info))
       goto not_negotiated;
 
+    /* Create caps from the acquired format, remove the format field */
+    acquired_caps = gst_video_info_to_caps (&info);
+    st = gst_caps_get_structure (acquired_caps, 0);
+    gst_structure_remove_field (st, "format");
+
+    /* Probe currently available pixel formats */
+    filter = gst_v4l2_object_probe_caps (self->v4l2capture, acquired_caps);
+    gst_caps_unref (acquired_caps);
+    caps = gst_pad_peer_query_caps (decoder->srcpad, filter);
+    gst_caps_unref (filter);
+
+    GST_DEBUG_OBJECT (self, "Possible decoded caps: %" GST_PTR_FORMAT,
+        caps);
+    if (gst_caps_is_empty (caps)) {
+      gst_caps_unref (caps);
+      goto not_negotiated;
+    }
+
+    /* Fixate pixel format */
+    caps = gst_caps_fixate(caps);
+
+    GST_DEBUG_OBJECT (self, "Chosen decoded caps: %" GST_PTR_FORMAT, caps);
+
+    /* Try to set negotiated format, on success replace acquired format */
+    if (gst_v4l2_object_set_format (self->v4l2capture, caps))
+      gst_video_info_from_caps (&info, caps);
+    gst_caps_unref (caps);
+
     output_state = gst_video_decoder_set_output_state (decoder,
         info.finfo->format, info.width, info.height, self->input_state);
 
diff --git a/sys/waveform/Makefile.in b/sys/waveform/Makefile.in
index caaebce..8f16b69 100644
--- a/sys/waveform/Makefile.in
+++ b/sys/waveform/Makefile.in
@@ -478,6 +478,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/sys/ximage/Makefile.in b/sys/ximage/Makefile.in
index 016b76e..2de449d 100644
--- a/sys/ximage/Makefile.in
+++ b/sys/ximage/Makefile.in
@@ -479,6 +479,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/sys/ximage/gstximagesrc.c b/sys/ximage/gstximagesrc.c
index f193194..93f8f47 100644
--- a/sys/ximage/gstximagesrc.c
+++ b/sys/ximage/gstximagesrc.c
@@ -536,6 +536,7 @@
   if (ximagesrc->have_xdamage && ximagesrc->use_damage &&
       ximagesrc->last_ximage != NULL) {
     XEvent ev;
+    gboolean have_damage = FALSE;
 
     /* have_frame is TRUE when either the entire screen has been
      * grabbed or when the last image has been copied */
@@ -544,83 +545,91 @@
     GST_DEBUG_OBJECT (ximagesrc, "Retrieving screen using XDamage");
 
     do {
+      XDamageNotifyEvent *damage_ev = (XDamageNotifyEvent *) (&ev);
+
       XNextEvent (ximagesrc->xcontext->disp, &ev);
 
-      if (ev.type == ximagesrc->damage_event_base + XDamageNotify) {
-        XserverRegion parts;
-        XRectangle *rects;
-        int nrects;
+      if (ev.type == ximagesrc->damage_event_base + XDamageNotify &&
+          damage_ev->level == XDamageReportNonEmpty) {
 
-        parts = XFixesCreateRegion (ximagesrc->xcontext->disp, 0, 0);
         XDamageSubtract (ximagesrc->xcontext->disp, ximagesrc->damage, None,
-            parts);
-        /* Now copy out all of the damaged rectangles. */
-        rects = XFixesFetchRegion (ximagesrc->xcontext->disp, parts, &nrects);
-        if (rects != NULL) {
-          int i;
-
-          if (!have_frame) {
-            GST_LOG_OBJECT (ximagesrc,
-                "Copying from last frame ximage->size: %" G_GSIZE_FORMAT,
-                gst_buffer_get_size (ximage));
-            copy_buffer (ximage, ximagesrc->last_ximage);
-            have_frame = TRUE;
-          }
-          for (i = 0; i < nrects; i++) {
-            GST_LOG_OBJECT (ximagesrc,
-                "Damaged sub-region @ %d,%d size %dx%d reported",
-                rects[i].x, rects[i].y, rects[i].width, rects[i].height);
-
-            /* if we only want a small area, clip this damage region to
-             * area we want */
-            if (ximagesrc->endx > ximagesrc->startx &&
-                ximagesrc->endy > ximagesrc->starty) {
-              /* see if damage area intersects */
-              if (rects[i].x + rects[i].width - 1 < ximagesrc->startx ||
-                  rects[i].x > ximagesrc->endx) {
-                /* trivial reject */
-              } else if (rects[i].y + rects[i].height - 1 < ximagesrc->starty ||
-                  rects[i].y > ximagesrc->endy) {
-                /* trivial reject */
-              } else {
-                /* find intersect region */
-                int startx, starty, width, height;
-
-                startx = (rects[i].x < ximagesrc->startx) ? ximagesrc->startx :
-                    rects[i].x;
-                starty = (rects[i].y < ximagesrc->starty) ? ximagesrc->starty :
-                    rects[i].y;
-                width = (rects[i].x + rects[i].width - 1 < ximagesrc->endx) ?
-                    rects[i].x + rects[i].width - startx :
-                    ximagesrc->endx - startx + 1;
-                height = (rects[i].y + rects[i].height - 1 < ximagesrc->endy) ?
-                    rects[i].y + rects[i].height - starty : ximagesrc->endy -
-                    starty + 1;
-
-                GST_LOG_OBJECT (ximagesrc,
-                    "Retrieving damaged sub-region @ %d,%d size %dx%d as intersect region",
-                    startx, starty, width, height);
-                XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
-                    startx, starty, width, height, AllPlanes, ZPixmap,
-                    meta->ximage, startx - ximagesrc->startx,
-                    starty - ximagesrc->starty);
-              }
-            } else {
-
-              GST_LOG_OBJECT (ximagesrc,
-                  "Retrieving damaged sub-region @ %d,%d size %dx%d",
-                  rects[i].x, rects[i].y, rects[i].width, rects[i].height);
-
-              XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
-                  rects[i].x, rects[i].y,
-                  rects[i].width, rects[i].height,
-                  AllPlanes, ZPixmap, meta->ximage, rects[i].x, rects[i].y);
-            }
-          }
-          free (rects);
-        }
+            ximagesrc->damage_region);
+        have_damage = TRUE;
       }
     } while (XPending (ximagesrc->xcontext->disp));
+
+    if (have_damage) {
+      XRectangle *rects;
+      int nrects;
+
+      /* Now copy out all of the damaged rectangles. */
+      rects =
+          XFixesFetchRegion (ximagesrc->xcontext->disp,
+          ximagesrc->damage_region, &nrects);
+      if (rects != NULL) {
+        int i;
+
+        if (!have_frame) {
+          GST_LOG_OBJECT (ximagesrc,
+              "Copying from last frame ximage->size: %" G_GSIZE_FORMAT,
+              gst_buffer_get_size (ximage));
+          copy_buffer (ximage, ximagesrc->last_ximage);
+          have_frame = TRUE;
+        }
+        for (i = 0; i < nrects; i++) {
+          GST_LOG_OBJECT (ximagesrc,
+              "Damaged sub-region @ %d,%d size %dx%d reported",
+              rects[i].x, rects[i].y, rects[i].width, rects[i].height);
+
+          /* if we only want a small area, clip this damage region to
+           * area we want */
+          if (ximagesrc->endx > ximagesrc->startx &&
+              ximagesrc->endy > ximagesrc->starty) {
+            /* see if damage area intersects */
+            if (rects[i].x + rects[i].width - 1 < ximagesrc->startx ||
+                rects[i].x > ximagesrc->endx) {
+              /* trivial reject */
+            } else if (rects[i].y + rects[i].height - 1 < ximagesrc->starty ||
+                rects[i].y > ximagesrc->endy) {
+              /* trivial reject */
+            } else {
+              /* find intersect region */
+              int startx, starty, width, height;
+
+              startx = (rects[i].x < ximagesrc->startx) ? ximagesrc->startx :
+                  rects[i].x;
+              starty = (rects[i].y < ximagesrc->starty) ? ximagesrc->starty :
+                  rects[i].y;
+              width = (rects[i].x + rects[i].width - 1 < ximagesrc->endx) ?
+                  rects[i].x + rects[i].width - startx :
+                  ximagesrc->endx - startx + 1;
+              height = (rects[i].y + rects[i].height - 1 < ximagesrc->endy) ?
+                  rects[i].y + rects[i].height - starty : ximagesrc->endy -
+                  starty + 1;
+
+              GST_LOG_OBJECT (ximagesrc,
+                  "Retrieving damaged sub-region @ %d,%d size %dx%d as intersect region",
+                  startx, starty, width, height);
+              XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
+                  startx, starty, width, height, AllPlanes, ZPixmap,
+                  meta->ximage, startx - ximagesrc->startx,
+                  starty - ximagesrc->starty);
+            }
+          } else {
+
+            GST_LOG_OBJECT (ximagesrc,
+                "Retrieving damaged sub-region @ %d,%d size %dx%d",
+                rects[i].x, rects[i].y, rects[i].width, rects[i].height);
+
+            XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
+                rects[i].x, rects[i].y,
+                rects[i].width, rects[i].height,
+                AllPlanes, ZPixmap, meta->ximage, rects[i].x, rects[i].y);
+          }
+        }
+        XFree (rects);
+      }
+    }
     if (!have_frame) {
       GST_LOG_OBJECT (ximagesrc,
           "Copying from last frame ximage->size: %" G_GSIZE_FORMAT,
@@ -757,9 +766,10 @@
           iwidth = (cx + ximagesrc->cursor_image->width < ximagesrc->endx) ?
               cx + ximagesrc->cursor_image->width - startx :
               ximagesrc->endx - startx;
-          iheight = (cy + ximagesrc->cursor_image->height < ximagesrc->endy) ?
-              cy + ximagesrc->cursor_image->height - starty :
-              ximagesrc->endy - starty;
+          iheight =
+              (cy + ximagesrc->cursor_image->height <
+              ximagesrc->endy) ? cy + ximagesrc->cursor_image->height -
+              starty : ximagesrc->endy - starty;
         }
       } else {
         startx = cx;
@@ -775,11 +785,11 @@
               GUINT_TO_LE (ximagesrc->cursor_image->pixels[i]);
         /* copy those pixels across */
         for (j = starty;
-            j < starty + iheight && j < ximagesrc->starty + ximagesrc->height;
-            j++) {
+            j < starty + iheight
+            && j < ximagesrc->starty + ximagesrc->height; j++) {
           for (i = startx;
-              i < startx + iwidth && i < ximagesrc->startx + ximagesrc->width;
-              i++) {
+              i < startx + iwidth
+              && i < ximagesrc->startx + ximagesrc->width; i++) {
             guint8 *src, *dest;
 
             src =
@@ -788,8 +798,8 @@
             dest =
                 (guint8 *) & (meta->ximage->data[((j -
                             ximagesrc->starty) * ximagesrc->width + (i -
-                            ximagesrc->startx)) * (ximagesrc->xcontext->bpp /
-                        8)]);
+                            ximagesrc->startx)) *
+                    (ximagesrc->xcontext->bpp / 8)]);
 
             composite_pixel (ximagesrc->xcontext, (guint8 *) dest,
                 (guint8 *) src);
@@ -963,8 +973,8 @@
 }
 
 static void
-gst_ximage_src_get_property (GObject * object, guint prop_id, GValue * value,
-    GParamSpec * pspec)
+gst_ximage_src_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
 {
   GstXImageSrc *src = GST_XIMAGE_SRC (object);
 
@@ -1116,16 +1126,16 @@
 
   format =
       gst_video_format_from_masks (xcontext->depth, xcontext->bpp,
-      xcontext->endianness, xcontext->r_mask_output, xcontext->g_mask_output,
-      xcontext->b_mask_output, alpha_mask);
+      xcontext->endianness, xcontext->r_mask_output,
+      xcontext->g_mask_output, xcontext->b_mask_output, alpha_mask);
 
   return gst_caps_new_simple ("video/x-raw",
       "format", G_TYPE_STRING, gst_video_format_to_string (format),
       "width", G_TYPE_INT, width,
       "height", G_TYPE_INT, height,
       "framerate", GST_TYPE_FRACTION_RANGE, 1, G_MAXINT, G_MAXINT, 1,
-      "pixel-aspect-ratio", GST_TYPE_FRACTION, xcontext->par_n, xcontext->par_d,
-      NULL);
+      "pixel-aspect-ratio", GST_TYPE_FRACTION, xcontext->par_n,
+      xcontext->par_d, NULL);
 }
 
 static gboolean
@@ -1186,8 +1196,8 @@
   gc->finalize = gst_ximage_src_finalize;
 
   g_object_class_install_property (gc, PROP_DISPLAY_NAME,
-      g_param_spec_string ("display-name", "Display", "X Display Name", NULL,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+      g_param_spec_string ("display-name", "Display", "X Display Name",
+          NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (gc, PROP_SHOW_POINTER,
       g_param_spec_boolean ("show-pointer", "Show Mouse Pointer",
           "Show mouse pointer (if XFixes extension enabled)", TRUE,
diff --git a/tests/Makefile.in b/tests/Makefile.in
index ff4e317..aa822e5 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -449,6 +449,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am
index e577979..5184e24 100644
--- a/tests/check/Makefile.am
+++ b/tests/check/Makefile.am
@@ -146,7 +146,7 @@
 endif
 
 if USE_GDK_PIXBUF
-check_gdkpixbuf = elements/gdkpixbufsink
+check_gdkpixbuf = elements/gdkpixbufsink elements/gdkpixbufoverlay
 else
 check_gdkpixbuf =
 endif
@@ -424,6 +424,9 @@
 
 elements_flacparse_LDADD = libparser.la $(LDADD)
 
+elements_flvdemux_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS)
+elements_flvdemux_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgsttag-$(GST_API_VERSION) $(LDADD)
+
 elements_mpegaudioparse_LDADD = libparser.la $(LDADD)
 
 elements_aspectratiocrop_LDADD = $(LDADD)
diff --git a/tests/check/Makefile.in b/tests/check/Makefile.in
index 214ce8d..063a2b2 100644
--- a/tests/check/Makefile.in
+++ b/tests/check/Makefile.in
@@ -195,7 +195,8 @@
 @USE_FLAC_TRUE@am__EXEEXT_11 = pipelines/flacdec$(EXEEXT)
 @USE_PLUGIN_FLV_TRUE@am__EXEEXT_12 = elements/flvdemux$(EXEEXT) \
 @USE_PLUGIN_FLV_TRUE@	elements/flvmux$(EXEEXT)
-@USE_GDK_PIXBUF_TRUE@am__EXEEXT_13 = elements/gdkpixbufsink$(EXEEXT)
+@USE_GDK_PIXBUF_TRUE@am__EXEEXT_13 = elements/gdkpixbufsink$(EXEEXT) \
+@USE_GDK_PIXBUF_TRUE@	elements/gdkpixbufoverlay$(EXEEXT)
 @USE_PLUGIN_ISOMP4_TRUE@am__EXEEXT_14 = elements/qtmux$(EXEEXT)
 @USE_PLUGIN_ICYDEMUX_TRUE@am__EXEEXT_15 = elements/icydemux$(EXEEXT)
 @USE_PLUGIN_ID3DEMUX_TRUE@am__EXEEXT_16 = elements/id3demux$(EXEEXT)
@@ -447,13 +448,23 @@
 elements_flacparse_OBJECTS = elements/flacparse.$(OBJEXT)
 elements_flacparse_DEPENDENCIES = libparser.la $(am__DEPENDENCIES_2)
 elements_flvdemux_SOURCES = elements/flvdemux.c
-elements_flvdemux_OBJECTS = elements/flvdemux.$(OBJEXT)
-elements_flvdemux_LDADD = $(LDADD)
-elements_flvdemux_DEPENDENCIES = $(am__DEPENDENCIES_1)
+elements_flvdemux_OBJECTS =  \
+	elements/elements_flvdemux-flvdemux.$(OBJEXT)
+elements_flvdemux_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_2)
+elements_flvdemux_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(elements_flvdemux_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+	-o $@
 elements_flvmux_SOURCES = elements/flvmux.c
 elements_flvmux_OBJECTS = elements/flvmux.$(OBJEXT)
 elements_flvmux_LDADD = $(LDADD)
 elements_flvmux_DEPENDENCIES = $(am__DEPENDENCIES_1)
+elements_gdkpixbufoverlay_SOURCES = elements/gdkpixbufoverlay.c
+elements_gdkpixbufoverlay_OBJECTS =  \
+	elements/gdkpixbufoverlay.$(OBJEXT)
+elements_gdkpixbufoverlay_LDADD = $(LDADD)
+elements_gdkpixbufoverlay_DEPENDENCIES = $(am__DEPENDENCIES_1)
 elements_gdkpixbufsink_SOURCES = elements/gdkpixbufsink.c
 elements_gdkpixbufsink_OBJECTS =  \
 	elements/elements_gdkpixbufsink-gdkpixbufsink.$(OBJEXT)
@@ -898,15 +909,16 @@
 	elements/capssetter.c elements/deinterlace.c \
 	elements/deinterleave.c elements/dtmf.c elements/equalizer.c \
 	elements/flacparse.c elements/flvdemux.c elements/flvmux.c \
-	elements/gdkpixbufsink.c elements/icydemux.c \
-	elements/id3demux.c elements/id3v2mux.c elements/imagefreeze.c \
-	elements/interleave.c elements/jpegdec.c elements/jpegenc.c \
-	elements/level.c elements/matroskademux.c \
-	elements/matroskamux.c elements/matroskaparse.c \
-	elements/mpegaudioparse.c elements/mulawdec.c \
-	elements/mulawenc.c elements/multifile.c elements/qtmux.c \
-	elements/rganalysis.c elements/rglimiter.c elements/rgvolume.c \
-	elements/rtp-payloading.c elements/rtpaux.c elements/rtpbin.c \
+	elements/gdkpixbufoverlay.c elements/gdkpixbufsink.c \
+	elements/icydemux.c elements/id3demux.c elements/id3v2mux.c \
+	elements/imagefreeze.c elements/interleave.c \
+	elements/jpegdec.c elements/jpegenc.c elements/level.c \
+	elements/matroskademux.c elements/matroskamux.c \
+	elements/matroskaparse.c elements/mpegaudioparse.c \
+	elements/mulawdec.c elements/mulawenc.c elements/multifile.c \
+	elements/qtmux.c elements/rganalysis.c elements/rglimiter.c \
+	elements/rgvolume.c elements/rtp-payloading.c \
+	elements/rtpaux.c elements/rtpbin.c \
 	$(elements_rtpbin_buffer_list_SOURCES) elements/rtpcollision.c \
 	elements/rtph263.c elements/rtpjitterbuffer.c \
 	elements/rtpmux.c elements/rtprtx.c elements/rtpsession.c \
@@ -936,15 +948,16 @@
 	elements/capssetter.c elements/deinterlace.c \
 	elements/deinterleave.c elements/dtmf.c elements/equalizer.c \
 	elements/flacparse.c elements/flvdemux.c elements/flvmux.c \
-	elements/gdkpixbufsink.c elements/icydemux.c \
-	elements/id3demux.c elements/id3v2mux.c elements/imagefreeze.c \
-	elements/interleave.c elements/jpegdec.c elements/jpegenc.c \
-	elements/level.c elements/matroskademux.c \
-	elements/matroskamux.c elements/matroskaparse.c \
-	elements/mpegaudioparse.c elements/mulawdec.c \
-	elements/mulawenc.c elements/multifile.c elements/qtmux.c \
-	elements/rganalysis.c elements/rglimiter.c elements/rgvolume.c \
-	elements/rtp-payloading.c elements/rtpaux.c elements/rtpbin.c \
+	elements/gdkpixbufoverlay.c elements/gdkpixbufsink.c \
+	elements/icydemux.c elements/id3demux.c elements/id3v2mux.c \
+	elements/imagefreeze.c elements/interleave.c \
+	elements/jpegdec.c elements/jpegenc.c elements/level.c \
+	elements/matroskademux.c elements/matroskamux.c \
+	elements/matroskaparse.c elements/mpegaudioparse.c \
+	elements/mulawdec.c elements/mulawenc.c elements/multifile.c \
+	elements/qtmux.c elements/rganalysis.c elements/rglimiter.c \
+	elements/rgvolume.c elements/rtp-payloading.c \
+	elements/rtpaux.c elements/rtpbin.c \
 	$(elements_rtpbin_buffer_list_SOURCES) elements/rtpcollision.c \
 	elements/rtph263.c elements/rtpjitterbuffer.c \
 	elements/rtpmux.c elements/rtprtx.c elements/rtpsession.c \
@@ -1428,6 +1441,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
@@ -1608,7 +1623,7 @@
 @USE_PLUGIN_LAW_TRUE@	elements/mulawenc
 
 @USE_GDK_PIXBUF_FALSE@check_gdkpixbuf = 
-@USE_GDK_PIXBUF_TRUE@check_gdkpixbuf = elements/gdkpixbufsink
+@USE_GDK_PIXBUF_TRUE@check_gdkpixbuf = elements/gdkpixbufsink elements/gdkpixbufoverlay
 @USE_PLUGIN_ICYDEMUX_FALSE@check_icydemux = 
 @USE_PLUGIN_ICYDEMUX_TRUE@check_icydemux = elements/icydemux
 @USE_PLUGIN_ID3DEMUX_FALSE@check_id3demux = 
@@ -1732,6 +1747,8 @@
 elements_ac3parse_LDADD = libparser.la $(LDADD)
 elements_amrparse_LDADD = libparser.la $(LDADD)
 elements_flacparse_LDADD = libparser.la $(LDADD)
+elements_flvdemux_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS)
+elements_flvdemux_LDADD = $(GST_PLUGINS_BASE_LIBS) -lgsttag-$(GST_API_VERSION) $(LDADD)
 elements_mpegaudioparse_LDADD = libparser.la $(LDADD)
 elements_aspectratiocrop_LDADD = $(LDADD)
 elements_aspectratiocrop_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS)
@@ -2094,18 +2111,24 @@
 elements/flacparse$(EXEEXT): $(elements_flacparse_OBJECTS) $(elements_flacparse_DEPENDENCIES) $(EXTRA_elements_flacparse_DEPENDENCIES) elements/$(am__dirstamp)
 	@rm -f elements/flacparse$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(elements_flacparse_OBJECTS) $(elements_flacparse_LDADD) $(LIBS)
-elements/flvdemux.$(OBJEXT): elements/$(am__dirstamp) \
-	elements/$(DEPDIR)/$(am__dirstamp)
+elements/elements_flvdemux-flvdemux.$(OBJEXT):  \
+	elements/$(am__dirstamp) elements/$(DEPDIR)/$(am__dirstamp)
 
 elements/flvdemux$(EXEEXT): $(elements_flvdemux_OBJECTS) $(elements_flvdemux_DEPENDENCIES) $(EXTRA_elements_flvdemux_DEPENDENCIES) elements/$(am__dirstamp)
 	@rm -f elements/flvdemux$(EXEEXT)
-	$(AM_V_CCLD)$(LINK) $(elements_flvdemux_OBJECTS) $(elements_flvdemux_LDADD) $(LIBS)
+	$(AM_V_CCLD)$(elements_flvdemux_LINK) $(elements_flvdemux_OBJECTS) $(elements_flvdemux_LDADD) $(LIBS)
 elements/flvmux.$(OBJEXT): elements/$(am__dirstamp) \
 	elements/$(DEPDIR)/$(am__dirstamp)
 
 elements/flvmux$(EXEEXT): $(elements_flvmux_OBJECTS) $(elements_flvmux_DEPENDENCIES) $(EXTRA_elements_flvmux_DEPENDENCIES) elements/$(am__dirstamp)
 	@rm -f elements/flvmux$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(elements_flvmux_OBJECTS) $(elements_flvmux_LDADD) $(LIBS)
+elements/gdkpixbufoverlay.$(OBJEXT): elements/$(am__dirstamp) \
+	elements/$(DEPDIR)/$(am__dirstamp)
+
+elements/gdkpixbufoverlay$(EXEEXT): $(elements_gdkpixbufoverlay_OBJECTS) $(elements_gdkpixbufoverlay_DEPENDENCIES) $(EXTRA_elements_gdkpixbufoverlay_DEPENDENCIES) elements/$(am__dirstamp)
+	@rm -f elements/gdkpixbufoverlay$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(elements_gdkpixbufoverlay_OBJECTS) $(elements_gdkpixbufoverlay_LDADD) $(LIBS)
 elements/elements_gdkpixbufsink-gdkpixbufsink.$(OBJEXT):  \
 	elements/$(am__dirstamp) elements/$(DEPDIR)/$(am__dirstamp)
 
@@ -2510,6 +2533,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_deinterleave-deinterleave.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_dtmf-dtmf.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_equalizer-equalizer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_flvdemux-flvdemux.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_gdkpixbufsink-gdkpixbufsink.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_imagefreeze-imagefreeze.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_interleave-interleave.Po@am__quote@
@@ -2539,8 +2563,8 @@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_videofilter-videofilter.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_videomixer-videomixer.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/flacparse.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/flvdemux.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/flvmux.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/gdkpixbufoverlay.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/icydemux.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/id3demux.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/id3v2mux.Po@am__quote@
@@ -2842,6 +2866,20 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_equalizer_CFLAGS) $(CFLAGS) -c -o elements/elements_equalizer-equalizer.obj `if test -f 'elements/equalizer.c'; then $(CYGPATH_W) 'elements/equalizer.c'; else $(CYGPATH_W) '$(srcdir)/elements/equalizer.c'; fi`
 
+elements/elements_flvdemux-flvdemux.o: elements/flvdemux.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_flvdemux_CFLAGS) $(CFLAGS) -MT elements/elements_flvdemux-flvdemux.o -MD -MP -MF elements/$(DEPDIR)/elements_flvdemux-flvdemux.Tpo -c -o elements/elements_flvdemux-flvdemux.o `test -f 'elements/flvdemux.c' || echo '$(srcdir)/'`elements/flvdemux.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) elements/$(DEPDIR)/elements_flvdemux-flvdemux.Tpo elements/$(DEPDIR)/elements_flvdemux-flvdemux.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='elements/flvdemux.c' object='elements/elements_flvdemux-flvdemux.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_flvdemux_CFLAGS) $(CFLAGS) -c -o elements/elements_flvdemux-flvdemux.o `test -f 'elements/flvdemux.c' || echo '$(srcdir)/'`elements/flvdemux.c
+
+elements/elements_flvdemux-flvdemux.obj: elements/flvdemux.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_flvdemux_CFLAGS) $(CFLAGS) -MT elements/elements_flvdemux-flvdemux.obj -MD -MP -MF elements/$(DEPDIR)/elements_flvdemux-flvdemux.Tpo -c -o elements/elements_flvdemux-flvdemux.obj `if test -f 'elements/flvdemux.c'; then $(CYGPATH_W) 'elements/flvdemux.c'; else $(CYGPATH_W) '$(srcdir)/elements/flvdemux.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) elements/$(DEPDIR)/elements_flvdemux-flvdemux.Tpo elements/$(DEPDIR)/elements_flvdemux-flvdemux.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='elements/flvdemux.c' object='elements/elements_flvdemux-flvdemux.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_flvdemux_CFLAGS) $(CFLAGS) -c -o elements/elements_flvdemux-flvdemux.obj `if test -f 'elements/flvdemux.c'; then $(CYGPATH_W) 'elements/flvdemux.c'; else $(CYGPATH_W) '$(srcdir)/elements/flvdemux.c'; fi`
+
 elements/elements_gdkpixbufsink-gdkpixbufsink.o: elements/gdkpixbufsink.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_gdkpixbufsink_CFLAGS) $(CFLAGS) -MT elements/elements_gdkpixbufsink-gdkpixbufsink.o -MD -MP -MF elements/$(DEPDIR)/elements_gdkpixbufsink-gdkpixbufsink.Tpo -c -o elements/elements_gdkpixbufsink-gdkpixbufsink.o `test -f 'elements/gdkpixbufsink.c' || echo '$(srcdir)/'`elements/gdkpixbufsink.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) elements/$(DEPDIR)/elements_gdkpixbufsink-gdkpixbufsink.Tpo elements/$(DEPDIR)/elements_gdkpixbufsink-gdkpixbufsink.Po
@@ -3759,6 +3797,13 @@
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+elements/gdkpixbufoverlay.log: elements/gdkpixbufoverlay$(EXEEXT)
+	@p='elements/gdkpixbufoverlay$(EXEEXT)'; \
+	b='elements/gdkpixbufoverlay'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 elements/qtmux.log: elements/qtmux$(EXEEXT)
 	@p='elements/qtmux$(EXEEXT)'; \
 	b='elements/qtmux'; \
@@ -4370,7 +4415,7 @@
 	--show-possibly-lost=no                                 \
 	--leak-resolution=high --num-callers=20			\
 	./$* 2>&1 | tee $$valgrind_log ;			\
-	if grep "==" $$valgrind_log > /dev/null 2>&1; then	\
+	if grep "^==" $$valgrind_log > /dev/null 2>&1; then	\
 	    rm $$valgrind_log;					\
 	    exit 1;						\
 	fi ;							\
diff --git a/tests/check/elements/deinterlace.c b/tests/check/elements/deinterlace.c
index c9da2dd..72e64cf 100644
--- a/tests/check/elements/deinterlace.c
+++ b/tests/check/elements/deinterlace.c
@@ -223,7 +223,7 @@
 
 /*
  * Utility function that sets up a pipeline with deinterlace for
- * validanting that it operates in passthrough mode when receiving
+ * validating that it operates in passthrough mode when receiving
  * data with 'infiltercaps' as the input caps and operating in 'mode' mode
  */
 static void
diff --git a/tests/check/elements/deinterleave.c b/tests/check/elements/deinterleave.c
index 2ad17b3..f81fddb 100644
--- a/tests/check/elements/deinterleave.c
+++ b/tests/check/elements/deinterleave.c
@@ -272,6 +272,7 @@
 {
   GstPad *sinkpad;
   GstCaps *caps, *caps2;
+  GstCaps *ret_caps;
   gint i;
   GstBuffer *inbuf;
   gfloat *indata;
@@ -297,13 +298,18 @@
       G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
   gst_caps_set_simple (caps, "channel-mask", GST_TYPE_BITMASK, channel_mask,
       NULL);
-  gst_check_setup_events (mysrcpad, deinterleave, caps, GST_FORMAT_TIME);
 
   sinkpad = gst_element_get_static_pad (deinterleave, "sink");
   fail_unless (sinkpad != NULL);
   fail_unless (gst_pad_link (mysrcpad, sinkpad) == GST_PAD_LINK_OK);
   g_object_unref (sinkpad);
 
+  ret_caps = gst_pad_peer_query_caps (mysrcpad, caps);
+  fail_if (gst_caps_is_empty (ret_caps));
+  fail_unless (gst_pad_peer_query_accept_caps (mysrcpad, caps));
+  gst_caps_unref (ret_caps);
+  gst_check_setup_events (mysrcpad, deinterleave, caps, GST_FORMAT_TIME);
+
   g_signal_connect (deinterleave, "pad-added",
       G_CALLBACK (deinterleave_pad_added), GINT_TO_POINTER (2));
 
@@ -333,6 +339,10 @@
       G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
   gst_caps_set_simple (caps2, "channel-mask", GST_TYPE_BITMASK, channel_mask,
       NULL);
+  ret_caps = gst_pad_peer_query_caps (mysrcpad, caps2);
+  fail_if (gst_caps_is_empty (ret_caps));
+  fail_unless (gst_pad_peer_query_accept_caps (mysrcpad, caps2));
+  gst_caps_unref (ret_caps);
   gst_pad_set_caps (mysrcpad, caps2);
 
   inbuf = gst_buffer_new_and_alloc (2 * 48000 * sizeof (gfloat));
@@ -360,6 +370,10 @@
       G_GUINT64_CONSTANT (1) << GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
   gst_caps_set_simple (caps2, "channel-mask", GST_TYPE_BITMASK, channel_mask,
       NULL);
+  ret_caps = gst_pad_peer_query_caps (mysrcpad, caps2);
+  fail_unless (gst_caps_is_empty (ret_caps));
+  gst_caps_unref (ret_caps);
+  fail_if (gst_pad_peer_query_accept_caps (mysrcpad, caps2));
   gst_pad_set_caps (mysrcpad, caps2);
 
   inbuf = gst_buffer_new_and_alloc (3 * 48000 * sizeof (gfloat));
diff --git a/tests/check/elements/flvdemux.c b/tests/check/elements/flvdemux.c
index c9d156d..2d8d1a7 100644
--- a/tests/check/elements/flvdemux.c
+++ b/tests/check/elements/flvdemux.c
@@ -19,8 +19,10 @@
  */
 
 #include <gst/check/gstcheck.h>
+#include <gst/check/gstharness.h>
 
 #include <gst/gst.h>
+#include <gst/tag/tag.h>
 
 static void
 pad_added_cb (GstElement * flvdemux, GstPad * pad, GstBin * pipeline)
@@ -166,6 +168,156 @@
 
 GST_END_TEST;
 
+static GstBuffer *
+create_buffer (guint8 * data, gsize size)
+{
+  GstBuffer * buf = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
+    data, size, 0, size, NULL, NULL);
+  GST_BUFFER_PTS (buf) = GST_CLOCK_TIME_NONE;
+  GST_BUFFER_DTS (buf) = GST_CLOCK_TIME_NONE;
+  GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
+  GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
+  GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
+  return buf;
+}
+
+static void
+flvdemux_pad_added (GstElement * flvdemux, GstPad * srcpad, GstHarness * h)
+{
+  (void)flvdemux;
+  gst_harness_add_element_src_pad (h, srcpad);
+}
+
+GST_START_TEST (test_speex)
+{
+  guint8 flv_header0[] = {
+      0x46, 0x4c, 0x56, 0x01, 0x04, 0x00, 0x00, 0x00,
+      0x09, 0x00, 0x00, 0x00, 0x00
+  };
+
+  guint8 flv_header1[] = {
+      0x12, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x02, 0x00, 0x0a, 0x6f, 0x6e,
+      0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61,
+      0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x61,
+      0x75, 0x64, 0x69, 0x6f, 0x63, 0x6f, 0x64, 0x65,
+      0x63, 0x69, 0x64, 0x00, 0x40, 0x26, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x6d, 0x65,
+      0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x63, 0x72,
+      0x65, 0x61, 0x74, 0x6f, 0x72, 0x02, 0x00, 0x13,
+      0x47, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x65,
+      0x72, 0x20, 0x46, 0x4c, 0x56, 0x20, 0x6d, 0x75,
+      0x78, 0x65, 0x72, 0x00, 0x0c, 0x63, 0x72, 0x65,
+      0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74,
+      0x65, 0x02, 0x00, 0x18, 0x57, 0x65, 0x64, 0x20,
+      0x53, 0x65, 0x70, 0x20, 0x32, 0x33, 0x20, 0x31,
+      0x30, 0x3a, 0x34, 0x39, 0x3a, 0x35, 0x36, 0x20,
+      0x32, 0x30, 0x31, 0x35, 0x00, 0x00, 0x09, 0x00,
+      0x00, 0x00, 0x87,
+  };
+
+  guint8 speex_header0[] = {
+      0x08, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0xb2, 0x53, 0x70, 0x65, 0x65,
+      0x78, 0x20, 0x20, 0x20, 0x31, 0x2e, 0x32, 0x72,
+      0x63, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
+      0x80, 0x3e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+      0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+      0xff, 0xff, 0xff, 0xff, 0x40, 0x01, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
+  };
+
+  guint8 speex_header1[] = {
+      0x08, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0xb2, 0x1f, 0x00, 0x00, 0x00,
+      0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20,
+      0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x53, 0x74,
+      0x72, 0x65, 0x61, 0x6d, 0x65, 0x72, 0x20, 0x53,
+      0x70, 0x65, 0x65, 0x78, 0x65, 0x6e, 0x63, 0x00,
+      0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x34,
+  };
+
+  guint8 buffer[] = {
+      0x08, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0xb2, 0x36, 0x9d, 0x1b, 0x9a,
+      0x20, 0x00, 0x01, 0x68, 0xe8, 0xe8, 0xe8, 0xe8,
+      0xe8, 0xe8, 0xe8, 0x84, 0x00, 0xb4, 0x74, 0x74,
+      0x74, 0x74, 0x74, 0x74, 0x74, 0x42, 0x00, 0x5a,
+      0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x21,
+      0x00, 0x2d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
+      0x1d, 0x1b, 0x3b, 0x60, 0xab, 0xab, 0xab, 0xab,
+      0xab, 0x0a, 0xba, 0xba, 0xba, 0xba, 0xb0, 0xab,
+      0xab, 0xab, 0xab, 0xab, 0x0a, 0xba, 0xba, 0xba,
+      0xba, 0xb7, 0x00, 0x00, 0x00, 0x52,
+  };
+
+  GstHarness * h = gst_harness_new_with_padnames ("flvdemux", "sink", NULL);
+  gst_harness_set_src_caps_str (h, "video/x-flv");
+
+  g_signal_connect (h->element, "pad-added",
+      G_CALLBACK (flvdemux_pad_added), h);
+
+  gst_harness_push (h, create_buffer (flv_header0,   sizeof (flv_header0)));
+  gst_harness_push (h, create_buffer (flv_header1,   sizeof (flv_header1)));
+  gst_harness_push (h, create_buffer (speex_header0, sizeof (speex_header0)));
+  gst_harness_push (h, create_buffer (speex_header1, sizeof (speex_header1)));
+  gst_harness_push (h, create_buffer (buffer,        sizeof (buffer)));
+
+  {
+    GstCaps * caps;
+    const GstStructure * s;
+    const GValue *streamheader;
+    const GValue *header;
+    const GValue *vorbiscomment;
+    GstBuffer *buf;
+    GstTagList *list;
+    gint rate;
+    gint channels;
+
+    caps = gst_pad_get_current_caps (h->sinkpad);
+    s = gst_caps_get_structure (caps, 0);
+
+    fail_unless (gst_structure_has_name (s, "audio/x-speex"));
+
+    streamheader = gst_structure_get_value (s, "streamheader");
+    fail_unless (streamheader != NULL);
+    fail_unless (G_VALUE_HOLDS (streamheader, GST_TYPE_ARRAY));
+    fail_unless_equals_int (2, gst_value_array_get_size (streamheader));
+
+    header = gst_value_array_get_value (streamheader, 0);
+    fail_unless (header != NULL);
+    fail_unless (G_VALUE_HOLDS (header, GST_TYPE_BUFFER));
+    buf = gst_value_get_buffer (header);
+
+    vorbiscomment = gst_value_array_get_value (streamheader, 1);
+    fail_unless (header != NULL);
+    fail_unless (G_VALUE_HOLDS (header, GST_TYPE_BUFFER));
+    buf = gst_value_get_buffer (vorbiscomment);
+    list = gst_tag_list_from_vorbiscomment_buffer (buf, NULL, 0, NULL);
+    fail_unless (list != NULL);
+    gst_tag_list_unref (list);
+
+    gst_structure_get_int (s, "rate", &rate);
+    fail_unless_equals_int (16000, rate);
+
+    gst_structure_get_int (s, "channels", &channels);
+    fail_unless_equals_int (1, channels);
+
+    gst_caps_unref (caps);
+  }
+
+  /* we should have gotten 2x speex-headers, and one encoded buffer */
+  fail_unless_equals_int (3, gst_harness_buffers_in_queue (h));
+
+  gst_harness_teardown (h);
+}
+
+GST_END_TEST;
+
 static Suite *
 flvdemux_suite (void)
 {
@@ -176,6 +328,8 @@
   tcase_add_test (tc_chain, test_reuse_push);
   tcase_add_test (tc_chain, test_reuse_pull);
 
+  tcase_add_test (tc_chain, test_speex);
+
   return s;
 }
 
diff --git a/tests/check/elements/gdkpixbufoverlay.c b/tests/check/elements/gdkpixbufoverlay.c
new file mode 100644
index 0000000..bc45554
--- /dev/null
+++ b/tests/check/elements/gdkpixbufoverlay.c
@@ -0,0 +1,80 @@
+/* GStreamer unit test for the gdkpixbufoverlay element
+ * Copyright (C) 2015 Tim-Philipp Müller <tim centricular com>
+ *
+ * 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., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gst/check/gstcheck.h>
+
+GST_START_TEST (test_simple_overlay)
+{
+  GstElement *pipeline, *src, *overlay, *sink;
+  GstMessage *msg;
+  GstBus *bus;
+
+  src = gst_element_factory_make ("videotestsrc", NULL);
+  fail_unless (src != NULL);
+  g_object_set (src, "num-buffers", 3, NULL);
+
+  overlay = gst_element_factory_make ("gdkpixbufoverlay", NULL);
+  fail_unless (overlay != NULL);
+
+#define IMAGE_PATH GST_TEST_FILES_PATH G_DIR_SEPARATOR_S "image.jpg"
+  g_object_set (overlay, "location", IMAGE_PATH, NULL);
+
+  sink = gst_element_factory_make ("fakesink", NULL);
+  fail_unless (sink != NULL);
+
+  pipeline = gst_pipeline_new (NULL);
+  gst_bin_add_many (GST_BIN (pipeline), src, overlay, sink, NULL);
+  gst_element_link_many (src, overlay, sink, NULL);
+
+  /* start prerolling */
+  fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
+      GST_STATE_CHANGE_ASYNC);
+
+  bus = gst_element_get_bus (pipeline);
+
+  /* wait for EOS */
+  msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_EOS);
+  gst_message_unref (msg);
+
+  fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL),
+      GST_STATE_CHANGE_SUCCESS);
+
+  gst_object_unref (bus);
+  gst_object_unref (pipeline);
+}
+
+GST_END_TEST;
+
+static Suite *
+gdkpixbufoverlay_suite (void)
+{
+  Suite *s = suite_create ("gdkpixbufoverlay");
+  TCase *tc_chain = tcase_create ("general");
+
+  suite_add_tcase (s, tc_chain);
+  tcase_add_test (tc_chain, test_simple_overlay);
+
+  return s;
+}
+
+GST_CHECK_MAIN (gdkpixbufoverlay);
diff --git a/tests/check/elements/rtp-payloading.c b/tests/check/elements/rtp-payloading.c
index f19306b..3af1d6c 100644
--- a/tests/check/elements/rtp-payloading.c
+++ b/tests/check/elements/rtp-payloading.c
@@ -615,6 +615,31 @@
       rtp_h264_frame_count,
       "video/x-h264,stream-format=(string)byte-stream,alignment=(string)nal",
       "rtph264pay", "rtph264depay", 0, 0, FALSE);
+
+  /* config-interval property used to be of uint type, was changed to int,
+   * make sure old GValue stuff still works */
+  {
+    GValue val = G_VALUE_INIT;
+    GstElement *rtph264pay;
+    GParamSpec *pspec;
+
+
+    rtph264pay = gst_element_factory_make ("rtph264pay", NULL);
+    pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (rtph264pay),
+        "config-interval");
+    fail_unless (pspec->value_type == G_TYPE_INT);
+    g_value_init (&val, G_TYPE_UINT);
+    g_value_set_uint (&val, 10);
+    g_object_set_property (G_OBJECT (rtph264pay), "config-interval", &val);
+    g_value_set_uint (&val, 0);
+    g_object_get_property (G_OBJECT (rtph264pay), "config-interval", &val);
+    fail_unless_equals_int (10, g_value_get_uint (&val));
+    g_object_set (G_OBJECT (rtph264pay), "config-interval", -1, NULL);
+    g_object_get_property (G_OBJECT (rtph264pay), "config-interval", &val);
+    fail_unless (g_value_get_uint (&val) == G_MAXUINT);
+    g_value_unset (&val);
+    gst_object_unref (rtph264pay);
+  }
 }
 
 GST_END_TEST;
diff --git a/tests/check/elements/rtpmux.c b/tests/check/elements/rtpmux.c
index 36b58e6..6f83c08 100644
--- a/tests/check/elements/rtpmux.c
+++ b/tests/check/elements/rtpmux.c
@@ -61,6 +61,15 @@
   return TRUE;
 }
 
+static GstCaps *
+remove_ssrc_from_caps (GstCaps * caps)
+{
+  GstCaps *copy = gst_caps_copy (caps);
+  GstStructure *s = gst_caps_get_structure (copy, 0);
+  gst_structure_remove_field (s, "ssrc");
+  return copy;
+}
+
 static gboolean
 event_func (GstPad * pad, GstObject * noparent, GstEvent * event)
 {
@@ -69,12 +78,20 @@
     {
       GstCaps *caps;
       GstCaps **caps2 = g_object_get_data (G_OBJECT (pad), "caps");
+      GstCaps *caps_no_ssrc;
+      GstCaps *caps2_no_ssrc;
 
       gst_event_parse_caps (event, &caps);
+      caps_no_ssrc = remove_ssrc_from_caps (caps);
+      caps2_no_ssrc = remove_ssrc_from_caps (*caps2);
+
       fail_unless (caps2 != NULL && *caps2 != NULL);
       fail_unless (gst_caps_is_fixed (caps));
       fail_unless (gst_caps_is_fixed (*caps2));
-      fail_unless (gst_caps_is_equal_fixed (caps, *caps2));
+
+      fail_unless (gst_caps_is_equal_fixed (caps_no_ssrc, caps2_no_ssrc));
+      gst_caps_unref (caps_no_ssrc);
+      gst_caps_unref (caps2_no_ssrc);
       break;
     }
     default:
@@ -137,7 +154,6 @@
 
   gst_caps_set_simple (src2caps, "clock-rate", G_TYPE_INT, 3, NULL);
   caps = gst_pad_peer_query_caps (src1, NULL);
-  fail_unless (gst_caps_is_equal (caps, sinkcaps));
   gst_caps_unref (caps);
 
   g_object_set (rtpmux, "seqnum-offset", 100, "timestamp-offset", 1000,
@@ -231,10 +247,10 @@
   fail_unless (buffers && g_list_length (buffers) == 1);
 
   gst_rtp_buffer_map (buffers->data, GST_MAP_READ, &rtpbuffer);
-  fail_unless (gst_rtp_buffer_get_ssrc (&rtpbuffer) == 66);
-  fail_unless (gst_rtp_buffer_get_timestamp (&rtpbuffer) ==
-      200 - 57 + 1000 + i);
-  fail_unless (gst_rtp_buffer_get_seq (&rtpbuffer) == 100 + 1 + i);
+  fail_unless_equals_int (66, gst_rtp_buffer_get_ssrc (&rtpbuffer));
+  fail_unless_equals_int64 (200 - 57 + 1000 + i,
+      gst_rtp_buffer_get_timestamp (&rtpbuffer));
+  fail_unless_equals_int (100 + 1 + i, gst_rtp_buffer_get_seq (&rtpbuffer));
   gst_rtp_buffer_unmap (&rtpbuffer);
 }
 
@@ -265,10 +281,10 @@
 
     fail_unless (buffers && g_list_length (buffers) == 1);
     gst_rtp_buffer_map (buffers->data, GST_MAP_READ, &rtpbuffer);
-    fail_unless (gst_rtp_buffer_get_ssrc (&rtpbuffer) == 66);
-    fail_unless (gst_rtp_buffer_get_timestamp (&rtpbuffer) ==
-        200 - 57 + 1000 + i);
-    fail_unless (gst_rtp_buffer_get_seq (&rtpbuffer) == 100 + 1 + i);
+    fail_unless_equals_int (66, gst_rtp_buffer_get_ssrc (&rtpbuffer));
+    fail_unless_equals_int64 (200 - 57 + 1000 + i,
+        gst_rtp_buffer_get_timestamp (&rtpbuffer));
+    fail_unless_equals_int (100 + 1 + i, gst_rtp_buffer_get_seq (&rtpbuffer));
     gst_rtp_buffer_unmap (&rtpbuffer);
 
     inbuf = gst_rtp_buffer_new_allocate (10, 0, 0);
@@ -325,16 +341,63 @@
   return buf;
 }
 
-GST_START_TEST (test_rtpmux_ssrc)
+static guint32
+_rtp_buffer_get_ssrc (GstBuffer * buf)
 {
-  GstHarness * h = gst_harness_new_with_padnames ("rtpdtmfmux", NULL, "src");
-  GstHarness * h0 = gst_harness_new_with_element (
-      h->element, "sink_0", NULL);
-  GstHarness * h1 = gst_harness_new_with_element (
-      h->element, "sink_1", NULL);
+  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
+  guint32 ret;
+  g_assert (gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp));
+  ret = gst_rtp_buffer_get_ssrc (&rtp);
+  gst_rtp_buffer_unmap (&rtp);
+  return ret;
+}
 
+GST_START_TEST (test_rtpmux_ssrc_property)
+{
+  GstHarness *h = gst_harness_new_with_padnames ("rtpmux", NULL, "src");
+  GstHarness *h0 = gst_harness_new_with_element (h->element, "sink_0", NULL);
+  GstHarness *h1 = gst_harness_new_with_element (h->element, "sink_1", NULL);
+  GstBuffer *buf0;
+  GstBuffer *buf1;
+
+  /* set ssrc to 111111 */
   g_object_set (h->element, "ssrc", 111111, NULL);
 
+  /* both sinkpads have their own idea of what the ssrc should be */
+  gst_harness_set_src_caps_str (h0, "application/x-rtp, ssrc=(uint)222222");
+  gst_harness_set_src_caps_str (h1, "application/x-rtp, ssrc=(uint)333333");
+
+  /* push on both sinkpads with different ssrc */
+  fail_unless_equals_int (GST_FLOW_OK,
+      gst_harness_push (h0, generate_test_buffer (0, 222222)));
+  fail_unless_equals_int (GST_FLOW_OK,
+      gst_harness_push (h1, generate_test_buffer (0, 333333)));
+
+  buf0 = gst_harness_pull (h);
+  buf1 = gst_harness_pull (h);
+
+  /* we expect the ssrc to be what we specified in the property */
+  fail_unless_equals_int (111111, _rtp_buffer_get_ssrc (buf0));
+  fail_unless_equals_int (111111, _rtp_buffer_get_ssrc (buf1));
+
+  gst_buffer_unref (buf0);
+  gst_buffer_unref (buf1);
+
+  gst_harness_teardown (h0);
+  gst_harness_teardown (h1);
+  gst_harness_teardown (h);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_rtpmux_ssrc_property_not_set)
+{
+  GstHarness *h = gst_harness_new_with_padnames ("rtpmux", NULL, "src");
+  GstHarness *h0 = gst_harness_new_with_element (h->element, "sink_0", NULL);
+  GstHarness *h1 = gst_harness_new_with_element (h->element, "sink_1", NULL);
+  GstBuffer *buf0;
+  GstBuffer *buf1;
+
   gst_harness_set_src_caps_str (h0, "application/x-rtp, ssrc=(uint)222222");
   gst_harness_set_src_caps_str (h1, "application/x-rtp, ssrc=(uint)333333");
 
@@ -343,10 +406,121 @@
   fail_unless_equals_int (GST_FLOW_OK,
       gst_harness_push (h1, generate_test_buffer (0, 333333)));
 
+  buf0 = gst_harness_pull (h);
+  buf1 = gst_harness_pull (h);
+
+  /* we expect the ssrc to be the first ssrc that came in */
+  fail_unless_equals_int (222222, _rtp_buffer_get_ssrc (buf0));
+  fail_unless_equals_int (222222, _rtp_buffer_get_ssrc (buf1));
+
+  gst_buffer_unref (buf0);
+  gst_buffer_unref (buf1);
+
   gst_harness_teardown (h0);
   gst_harness_teardown (h1);
   gst_harness_teardown (h);
 }
+
+GST_END_TEST;
+
+GST_START_TEST (test_rtpmux_ssrc_downstream_can_overrule)
+{
+  GstHarness *h = gst_harness_new_with_padnames ("rtpmux", NULL, "src");
+  GstHarness *h0 = gst_harness_new_with_element (h->element, "sink_0", NULL);
+  GstHarness *h1 = gst_harness_new_with_element (h->element, "sink_1", NULL);
+  GstBuffer *buf0;
+  GstBuffer *buf1;
+
+  /* downstream is specifying 444444 as ssrc */
+  gst_harness_set_sink_caps_str (h, "application/x-rtp, ssrc=(uint)444444");
+
+  /* rtpmux ssrc is set to 111111 */
+  g_object_set (h->element, "ssrc", 111111, NULL);
+
+  /* while upstream ssrc is 222222 and 333333 */
+  gst_harness_set_src_caps_str (h0, "application/x-rtp, ssrc=(uint)222222");
+  gst_harness_set_src_caps_str (h1, "application/x-rtp, ssrc=(uint)333333");
+
+  fail_unless_equals_int (GST_FLOW_OK,
+      gst_harness_push (h0, generate_test_buffer (0, 222222)));
+  fail_unless_equals_int (GST_FLOW_OK,
+      gst_harness_push (h1, generate_test_buffer (0, 333333)));
+
+  buf0 = gst_harness_pull (h);
+  buf1 = gst_harness_pull (h);
+
+  /* we expect the ssrc to be downstream ssrc */
+  fail_unless_equals_int (444444, _rtp_buffer_get_ssrc (buf0));
+  fail_unless_equals_int (444444, _rtp_buffer_get_ssrc (buf1));
+
+  gst_buffer_unref (buf0);
+  gst_buffer_unref (buf1);
+
+  gst_harness_teardown (h0);
+  gst_harness_teardown (h1);
+  gst_harness_teardown (h);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_rtpmux_ssrc_downstream_dynamic)
+{
+  GstHarness *h = gst_harness_new_parse ("rtpmux ! capsfilter");
+  GstElement *rtpmux = gst_harness_find_element (h, "rtpmux");
+  GstElement *capsfilter = gst_harness_find_element (h, "capsfilter");
+
+  GstHarness *h0 = gst_harness_new_with_element (rtpmux, "sink_0", NULL);
+  GstHarness *h1 = gst_harness_new_with_element (rtpmux, "sink_1", NULL);
+  GstCaps *caps;
+  GstBuffer *buf0;
+  GstBuffer *buf1;
+
+  gst_harness_play (h);
+
+  caps = gst_caps_from_string ("application/x-rtp, ssrc=(uint)444444");
+  g_object_set (capsfilter, "caps", caps, NULL);
+  gst_caps_unref (caps);
+
+  /* while upstream ssrc is 222222 and 333333 */
+  gst_harness_set_src_caps_str (h0, "application/x-rtp, ssrc=(uint)222222");
+  gst_harness_set_src_caps_str (h1, "application/x-rtp, ssrc=(uint)333333");
+
+  fail_unless_equals_int (GST_FLOW_OK,
+      gst_harness_push (h0, generate_test_buffer (0, 222222)));
+  fail_unless_equals_int (GST_FLOW_OK,
+      gst_harness_push (h1, generate_test_buffer (0, 333333)));
+
+  /* we expect the ssrc to be downstream ssrc (444444) */
+  buf0 = gst_harness_pull (h);
+  buf1 = gst_harness_pull (h);
+  fail_unless_equals_int (444444, _rtp_buffer_get_ssrc (buf0));
+  fail_unless_equals_int (444444, _rtp_buffer_get_ssrc (buf1));
+  gst_buffer_unref (buf0);
+  gst_buffer_unref (buf1);
+
+  caps = gst_caps_from_string ("application/x-rtp, ssrc=(uint)555555");
+  g_object_set (capsfilter, "caps", caps, NULL);
+  gst_caps_unref (caps);
+
+  fail_unless_equals_int (GST_FLOW_OK,
+      gst_harness_push (h0, generate_test_buffer (0, 222222)));
+  fail_unless_equals_int (GST_FLOW_OK,
+      gst_harness_push (h1, generate_test_buffer (0, 333333)));
+
+  /* we expect the ssrc to be the new downstream ssrc (555555) */
+  buf0 = gst_harness_pull (h);
+  buf1 = gst_harness_pull (h);
+  fail_unless_equals_int (555555, _rtp_buffer_get_ssrc (buf0));
+  fail_unless_equals_int (555555, _rtp_buffer_get_ssrc (buf1));
+  gst_buffer_unref (buf0);
+  gst_buffer_unref (buf1);
+
+  gst_object_unref (rtpmux);
+  gst_harness_teardown (h0);
+  gst_harness_teardown (h1);
+  gst_harness_teardown (h);
+}
+
 GST_END_TEST;
 
 static Suite *
@@ -358,7 +532,10 @@
   tc_chain = tcase_create ("rtpmux_basic");
   suite_add_tcase (s, tc_chain);
   tcase_add_test (tc_chain, test_rtpmux_basic);
-  tcase_add_test (tc_chain, test_rtpmux_ssrc);
+  tcase_add_test (tc_chain, test_rtpmux_ssrc_property);
+  tcase_add_test (tc_chain, test_rtpmux_ssrc_property_not_set);
+  tcase_add_test (tc_chain, test_rtpmux_ssrc_downstream_can_overrule);
+  tcase_add_test (tc_chain, test_rtpmux_ssrc_downstream_dynamic);
 
   tc_chain = tcase_create ("rtpdtmfmux_basic");
   tcase_add_test (tc_chain, test_rtpdtmfmux_basic);
diff --git a/tests/check/elements/souphttpsrc.c b/tests/check/elements/souphttpsrc.c
index c2a7c57..8eeb318 100644
--- a/tests/check/elements/souphttpsrc.c
+++ b/tests/check/elements/souphttpsrc.c
@@ -163,7 +163,7 @@
       rc = 302;
     GST_INFO ("debug: %s", debug);
     /* should not've gotten any output in case of a 40x error. Wait a bit
-     * to give streaming thread a chance to push out a buffer and triggering
+     * to give the streaming thread a chance to push out a buffer and trigger
      * our callback before shutting down the pipeline */
     g_usleep (G_USEC_PER_SEC / 2);
     fail_unless (buf == NULL);
@@ -387,8 +387,9 @@
   gst_bin_add (GST_BIN (pipe), sink);
   fail_unless (gst_element_link (src, sink));
 
-  /* Virgin Radio 32kbps mp3 shoutcast stream */
-  g_object_set (src, "location", "http://mp3-vr-32.smgradio.com:80/", NULL);
+  /* Radionomy Hot40Music shoutcast stream */
+  g_object_set (src, "location",
+      "http://streaming.radionomy.com:80/Hot40Music", NULL);
 
   /* EOS after the first buffer */
   g_object_set (src, "num-buffers", 1, NULL);
diff --git a/tests/examples/Makefile.in b/tests/examples/Makefile.in
index 5f08740..70e8f15 100644
--- a/tests/examples/Makefile.in
+++ b/tests/examples/Makefile.in
@@ -455,6 +455,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/tests/examples/audiofx/Makefile.in b/tests/examples/audiofx/Makefile.in
index e4df352..eb24548 100644
--- a/tests/examples/audiofx/Makefile.in
+++ b/tests/examples/audiofx/Makefile.in
@@ -459,6 +459,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/tests/examples/cairo/Makefile.in b/tests/examples/cairo/Makefile.in
index ec4cae5..23ee96e 100644
--- a/tests/examples/cairo/Makefile.in
+++ b/tests/examples/cairo/Makefile.in
@@ -445,6 +445,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/tests/examples/equalizer/Makefile.in b/tests/examples/equalizer/Makefile.in
index bbb5c96..a93dbe3 100644
--- a/tests/examples/equalizer/Makefile.in
+++ b/tests/examples/equalizer/Makefile.in
@@ -445,6 +445,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/tests/examples/equalizer/demo.c b/tests/examples/equalizer/demo.c
index 387544d..03b4ff6 100644
--- a/tests/examples/equalizer/demo.c
+++ b/tests/examples/equalizer/demo.c
@@ -180,8 +180,11 @@
 
   if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
     g_print ("Error initializing: %s\n", err->message);
+    g_option_context_free (ctx);
+    g_clear_error (&err);
     exit (1);
   }
+  g_option_context_free (ctx);
 
   if (argc < 2) {
     g_print ("Usage: %s <uri to play>\n", argv[0]);
diff --git a/tests/examples/jack/Makefile.in b/tests/examples/jack/Makefile.in
index 493bf25..d9b0f9e 100644
--- a/tests/examples/jack/Makefile.in
+++ b/tests/examples/jack/Makefile.in
@@ -444,6 +444,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/tests/examples/level/Makefile.in b/tests/examples/level/Makefile.in
index 9e28758..2fbbb34 100644
--- a/tests/examples/level/Makefile.in
+++ b/tests/examples/level/Makefile.in
@@ -445,6 +445,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/tests/examples/pulse/Makefile.in b/tests/examples/pulse/Makefile.in
index a2650e0..6a2846c 100644
--- a/tests/examples/pulse/Makefile.in
+++ b/tests/examples/pulse/Makefile.in
@@ -445,6 +445,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/tests/examples/rtp/Makefile.in b/tests/examples/rtp/Makefile.in
index bc7c58c..4f2ec24 100644
--- a/tests/examples/rtp/Makefile.in
+++ b/tests/examples/rtp/Makefile.in
@@ -472,6 +472,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/tests/examples/shapewipe/Makefile.in b/tests/examples/shapewipe/Makefile.in
index d3faa67..49d71d4 100644
--- a/tests/examples/shapewipe/Makefile.in
+++ b/tests/examples/shapewipe/Makefile.in
@@ -450,6 +450,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/tests/examples/spectrum/Makefile.in b/tests/examples/spectrum/Makefile.in
index 77a3e19..5239b8b 100644
--- a/tests/examples/spectrum/Makefile.in
+++ b/tests/examples/spectrum/Makefile.in
@@ -467,6 +467,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/tests/examples/v4l2/Makefile.in b/tests/examples/v4l2/Makefile.in
index e3f152b..e393bae 100644
--- a/tests/examples/v4l2/Makefile.in
+++ b/tests/examples/v4l2/Makefile.in
@@ -445,6 +445,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/tests/files/Makefile.in b/tests/files/Makefile.in
index 71621bd..ad00ca3 100644
--- a/tests/files/Makefile.in
+++ b/tests/files/Makefile.in
@@ -390,6 +390,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/tests/icles/Makefile.in b/tests/icles/Makefile.in
index 3b216ac..6d87ab0 100644
--- a/tests/icles/Makefile.in
+++ b/tests/icles/Makefile.in
@@ -545,6 +545,8 @@
 VERSION = @VERSION@
 VPX_130_CFLAGS = @VPX_130_CFLAGS@
 VPX_130_LIBS = @VPX_130_LIBS@
+VPX_140_CFLAGS = @VPX_140_CFLAGS@
+VPX_140_LIBS = @VPX_140_LIBS@
 VPX_CFLAGS = @VPX_CFLAGS@
 VPX_LIBS = @VPX_LIBS@
 WARNING_CFLAGS = @WARNING_CFLAGS@
diff --git a/tests/icles/equalizer-test.c b/tests/icles/equalizer-test.c
index 3f9e50e..883ba33 100644
--- a/tests/icles/equalizer-test.c
+++ b/tests/icles/equalizer-test.c
@@ -55,7 +55,7 @@
     gst_message_parse_error (msg, &err, &debug);
     GST_ERROR ("ERROR: %s [%s]", err->message, debug);
     g_print ("\n===========> ERROR: %s\n%s\n\n", err->message, debug);
-    g_error_free (err);
+    g_clear_error (&err);
     g_free (debug);
   }
 
@@ -186,8 +186,11 @@
 
   if (!g_option_context_parse (ctx, &argc, &argv, &opt_err)) {
     g_error ("Error parsing command line options: %s", opt_err->message);
+    g_option_context_free (ctx);
+    g_clear_error (&opt_err);
     return -1;
   }
+  g_option_context_free (ctx);
 
   GST_DEBUG_CATEGORY_INIT (equalizer_test_debug, "equalizertest", 0, "eqtest");
 
diff --git a/tests/icles/gdkpixbufoverlay-test.c b/tests/icles/gdkpixbufoverlay-test.c
index efbb972..45276ee 100644
--- a/tests/icles/gdkpixbufoverlay-test.c
+++ b/tests/icles/gdkpixbufoverlay-test.c
@@ -151,7 +151,7 @@
 
       gst_message_parse_error (msg, &err, &dbg);
       gst_object_default_error (msg->src, err, dbg);
-      g_error_free (err);
+      g_clear_error (&err);
       g_free (dbg);
       g_main_loop_quit (loop);
       break;
@@ -218,6 +218,8 @@
   g_option_context_add_group (ctx, gst_init_get_option_group ());
   if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
     g_print ("Error initializing: %s\n", err->message);
+    g_option_context_free (ctx);
+    g_clear_error (&err);
     return 1;
   }
   g_option_context_free (ctx);
diff --git a/tests/icles/gdkpixbufsink-test.c b/tests/icles/gdkpixbufsink-test.c
index fbcb13a..6c2825a 100644
--- a/tests/icles/gdkpixbufsink-test.c
+++ b/tests/icles/gdkpixbufsink-test.c
@@ -175,7 +175,7 @@
 
       gst_message_parse_error (msg, &err, &dbg);
       g_error ("Error: %s\n%s\n", err->message, (dbg) ? dbg : "");
-      g_error_free (err);
+      g_clear_error (&err);
       g_free (dbg);
       break;
     }
@@ -345,6 +345,8 @@
 
   if (!g_option_context_parse (ctx, &argc, &argv, &opt_err)) {
     g_error ("Error parsing command line options: %s", opt_err->message);
+    g_option_context_free (ctx);
+    g_clear_error (&opt_err);
     return -1;
   }
 
diff --git a/tests/icles/test-oss4.c b/tests/icles/test-oss4.c
index b2e4b96..adbe442 100644
--- a/tests/icles/test-oss4.c
+++ b/tests/icles/test-oss4.c
@@ -115,6 +115,8 @@
   g_option_context_add_group (ctx, gst_init_get_option_group ());
   if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
     g_print ("Error initializing: %s\n", err->message);
+    g_option_context_free (ctx);
+    g_clear_error (&err);
     exit (1);
   }
   g_option_context_free (ctx);
diff --git a/tests/icles/videocrop-test.c b/tests/icles/videocrop-test.c
index 081fa60..2acfa33 100644
--- a/tests/icles/videocrop-test.c
+++ b/tests/icles/videocrop-test.c
@@ -53,7 +53,7 @@
     gst_message_parse_error (msg, &err, &debug);
     GST_ERROR ("ERROR: %s [%s]", err->message, debug);
     g_print ("\n===========> ERROR: %s\n%s\n\n", err->message, debug);
-    g_error_free (err);
+    g_clear_error (&err);
     g_free (debug);
     gst_message_unref (msg);
   }
@@ -201,8 +201,11 @@
 
   if (!g_option_context_parse (ctx, &argc, &argv, &opt_err)) {
     g_error ("Error parsing command line options: %s", opt_err->message);
+    g_option_context_free (ctx);
+    g_clear_error (&opt_err);
     return -1;
   }
+  g_option_context_free (ctx);
 
   GST_DEBUG_CATEGORY_INIT (videocrop_test_debug, "videocroptest", 0, "vctest");
 
diff --git a/win32/common/config.h b/win32/common/config.h
index f5ab678..027a27e 100644
--- a/win32/common/config.h
+++ b/win32/common/config.h
@@ -45,6 +45,9 @@
 /* GStreamer API Version */
 #define GST_API_VERSION "1.0"
 
+/* Define if extra runtime checks should be enabled */
+#undef GST_ENABLE_EXTRA_CHECKS
+
 /* Defined if gcov is enabled to force a rebuild due to config.h changing */
 #undef GST_GCOV_ENABLED
 
@@ -61,11 +64,14 @@
 #define GST_PACKAGE_ORIGIN "Unknown package origin"
 
 /* GStreamer package release date/time for plugins as YYYY-MM-DD */
-#define GST_PACKAGE_RELEASE_DATETIME "2015-12-14"
+#define GST_PACKAGE_RELEASE_DATETIME "2015-12-24"
 
 /* Define if static plugins should be built */
 #undef GST_PLUGIN_BUILD_STATIC
 
+/* Define if Video4Linux probe shall be run at plugin load */
+#undef GST_V4L2_ENABLE_PROBE
+
 /* Define to enable aalib ASCII Art library (used by aasink). */
 #undef HAVE_AALIB
 
@@ -346,6 +352,9 @@
 /* Define to enable VPX decoder (used by vpx). */
 #undef HAVE_VPX
 
+/* Defined if the VPX library version is 1.4 or bigger */
+#undef HAVE_VPX_1_4
+
 /* Define to enable Win32 WaveForm (used by waveformsink). */
 #undef HAVE_WAVEFORM
 
@@ -387,7 +396,7 @@
 #define PACKAGE_NAME "GStreamer Good Plug-ins"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "GStreamer Good Plug-ins 1.6.2"
+#define PACKAGE_STRING "GStreamer Good Plug-ins 1.7.1"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "gst-plugins-good"
@@ -396,7 +405,7 @@
 #undef PACKAGE_URL
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "1.6.2"
+#define PACKAGE_VERSION "1.7.1"
 
 /* directory where plugins are located */
 #ifdef _DEBUG
@@ -427,7 +436,7 @@
 #undef TARGET_CPU
 
 /* Version number of package */
-#define VERSION "1.6.2"
+#define VERSION "1.7.1"
 
 /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
    significant byte first (like Motorola and SPARC, unlike Intel). */