Merge branch 'upstream'
diff --git a/ChangeLog b/ChangeLog
index 4b85486..c6f423a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,261 +1,306 @@
-=== release 1.8.3 ===
+=== release 1.9.90 ===
 
-2016-08-19  Sebastian Dröge <slomo@coaxion.net>
+2016-09-30  Sebastian Dröge <slomo@coaxion.net>
 
 	* configure.ac:
-	  releasing 1.8.3
+	  releasing 1.9.90
 
-2016-08-19 11:54:35 +0300  Sebastian Dröge <sebastian@centricular.com>
+2016-09-30 11:42:21 +0300  Sebastian Dröge <sebastian@centricular.com>
 
-	* po/af.po:
-	* po/az.po:
-	* po/bg.po:
-	* po/ca.po:
-	* po/cs.po:
-	* po/da.po:
 	* po/de.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/nb.po:
-	* po/nl.po:
-	* po/or.po:
-	* po/pl.po:
-	* po/pt_BR.po:
-	* po/ro.po:
-	* po/ru.po:
-	* po/sk.po:
-	* po/sl.po:
-	* po/sq.po:
-	* po/sr.po:
-	* po/sv.po:
-	* po/tr.po:
-	* po/uk.po:
-	* po/vi.po:
-	* po/zh_CN.po:
-	  Update .po files
+	  po: Update translations
 
-2016-06-16 10:01:50 +0100  Vincent Penquerc'h <vincent.penquerch@collabora.co.uk>
+2016-09-29 19:54:52 +0530  Arun Raghavan <arun@osg.samsung.com>
 
-	* ext/ogg/gstoggdemux.c:
-	  oggdemux: remove eos avoidance workaround
-	  This workaround tried to avoid an EOS event when seeking to the
-	  end of an Ogg stream in order to find its duration. At some point,
-	  an EOS event there would cause any queue2 upstream to pause and
-	  not restart on a seek back to the beginning. This now appears to
-	  not be the case anymore, and so the workaround can be removed.
-	  https://bugzilla.gnome.org/show_bug.cgi?id=767689
-
-2016-05-24 00:44:21 +0100  Tim-Philipp Müller <tim@centricular.com>
-
-	* gst-libs/gst/allocators/Makefile.am:
-	* gst-libs/gst/app/Makefile.am:
 	* gst-libs/gst/audio/Makefile.am:
-	* gst-libs/gst/fft/Makefile.am:
-	* gst-libs/gst/pbutils/Makefile.am:
-	* gst-libs/gst/riff/Makefile.am:
-	* gst-libs/gst/rtp/Makefile.am:
-	* gst-libs/gst/rtsp/Makefile.am:
-	* gst-libs/gst/sdp/Makefile.am:
-	* gst-libs/gst/tag/Makefile.am:
-	* gst-libs/gst/video/Makefile.am:
-	  g-i: pass compiler env to g-ir-scanner
-	  It's what introspection.mak does as well. Should
-	  fix spurious build failures on gnome-continuous.
+	  audio-resampler: Add a missing header to noinst_HEADERS
 
-2016-07-20 11:47:48 +0100  Vincent Penquerc'h <vincent.penquerch@collabora.co.uk>
+2016-09-29 19:45:16 +0530  Arun Raghavan <arun@osg.samsung.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86-sse41.c:
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	  audiorsample: Fix build on 32-bit x86
+	  Turns out _mm_cvtsi128_si64() isn't available on 32-bit, so only build
+	  SSE 4.1 optimisations on x86-64 for now.
+
+2016-09-28 17:37:38 +0530  Arun Raghavan <arun@osg.samsung.com>
+
+	* configure.ac:
+	* gst-libs/gst/audio/Makefile.am:
+	* gst-libs/gst/audio/audio-resampler-macros.h:
+	* gst-libs/gst/audio/audio-resampler-neon.h:
+	* gst-libs/gst/audio/audio-resampler-private.h:
+	* gst-libs/gst/audio/audio-resampler-x86-sse.c:
+	* gst-libs/gst/audio/audio-resampler-x86-sse.h:
+	* gst-libs/gst/audio/audio-resampler-x86-sse2.c:
+	* gst-libs/gst/audio/audio-resampler-x86-sse2.h:
+	* gst-libs/gst/audio/audio-resampler-x86-sse41.c:
+	* gst-libs/gst/audio/audio-resampler-x86-sse41.h:
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audioresample: Separate out CFLAGS used for SSE* code
+	  This makes sure that we only build files that need explicit SIMD support
+	  with the relevant CFLAGS. This allows the rest of the code to be built
+	  without, and specific SSE* code is only called after runtime checks for
+	  CPU features.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=729276
+
+2016-09-28 19:08:52 +0530  Arun Raghavan <arun@osg.samsung.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audioresample: Fix some gobject introspection warnings
+
+2016-09-26 10:01:08 +0200  Edward Hervey <edward@centricular.com>
+
+	* gst/playback/gstplaybin3.c:
+	  playbin3: Remove fallback properties/signals
+	  These can all be used via the GstStream API
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769079
+
+2016-09-25 22:02:22 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* tests/check/meson.build:
+	  tests: playbin-complex test needs oggdemux
+
+2016-09-24 21:11:32 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* tests/check/libs/videotimecode.c:
+	  tests: videotimecode: fix floating point comparisons
+	  Comparing floats for equality is not necessarily going to
+	  work reliably, so use fail_unless_equals_float() for this.
+	  Test would fail on x86 (Intel Atom x5-Z8300).
+
+2016-09-25 16:22:16 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* tests/check/elements/adder.c:
+	  tests: adder: disable racy flush_start_flush_stop test
+	  It's been broken for years, and it's unlikely it will ever
+	  be fixed for collectpads/adder now that there's audiomixer
+	  which works fine. So let's disable it, since all it does
+	  is that it creates noise that distracts from other failures.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=708891
+
+2016-09-22 16:15:54 +0200  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/video/video-scaler.c:
+	  video-scaler: take number of bits into account when copying
+	  Copy twice the amount of pixels for 16 bits formats.
+	  Fixes https://bugzilla.gnome.org/show_bug.cgi?id=747225
+
+2016-09-20 15:12:22 -0400  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/playback/gststreamsynchronizer.c:
+	  streamsynchronizer: Correctly calculate group start times in reverse playback mode
+	  We have to calculate from the segment.stop, not the segment.start, as
+	  playback goes from stop to start. This fix works around another race
+	  condition in streamsynchronizer in my testcase.
+	  See https://bugzilla.gnome.org/show_bug.cgi?id=771479
+
+2016-09-20 17:31:55 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* tests/examples/seek/stepping.c:
+	* tests/examples/seek/stepping2.c:
+	  examples: seek: fix build with MSVC
+	  Use G_PI instead of M_PI. Could also have defined
+	  _USE_MATH_DEFINES or included gst/math-compat.h but
+	  this seems simplest.
+
+2016-09-19 11:27:10 -0400  Nicolas Dufresne <nicolas.dufresne@collabora.com>
+
+	* gst-libs/gst/video/video-frame.c:
+	  doc: Add missing map flag to gst_video_frame_map()
+	  Add missing map flag, and also add unmap call.
+
+2016-09-17 12:42:46 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/audiotestsrc/gstaudiotestsrc.c:
+	  audiotestsrc: Fix segment boundary checking for reverse playback
+
+2016-09-14 16:51:30 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/audiotestsrc/gstaudiotestsrc.c:
+	  audiotestsrc: Don't adjust segment time in seek handler
+	  basesrc already did that very well for us, adjusting it again on top of
+	  that just breaks various non-standard seeks.
+
+2016-09-14 11:29:59 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* configure.ac:
+	  configure: Depend on gstreamer 1.9.2.1
+
+2016-09-14 10:14:18 +0200  Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
+
+	* gst-libs/gst/video/video-overlay-composition.c:
+	  videooverlaycomposition: document required map flags
+	  Fix documentation for gst_video_overlay_composition_blend(). The video frame
+	  needs to be mapped with GST_MAP_READWRITE flag.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=771382
+
+2016-09-12 18:37:21 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/playback/gstplaysink.c:
+	* gst/playback/gsturidecodebin.c:
+	* gst/playback/gsturisourcebin.c:
+	  playback: Use new gst_bin_set_suppressed_flags() API instead of worrying about the flags in multiple places
+
+2016-09-10 20:50:56 +1000  Jan Schmidt <jan@centricular.com>
+
+	* autogen.sh:
+	* common:
+	  Automatic update of common submodule
+	  From b18d820 to f980fd9
+
+2016-09-10 10:05:28 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* tests/check/Makefile.am:
+	* tests/check/elements/.gitignore:
+	* tests/check/elements/videoscale.c:
+	* tests/check/meson.build:
+	  tests: videoscale: split test into multiple ones
+	  The videoscale test takes eternities to run, that's not
+	  great. Split the test into multiple ones. That way they
+	  can be run in parallel. Reduces time to run all tests in
+	  -base from 29 secs to 12 secs when using meson/ninja.
+
+2016-09-10 09:53:49 +1000  Jan Schmidt <jan@centricular.com>
+
+	* autogen.sh:
+	* common:
+	  Automatic update of common submodule
+	  From f49c55e to b18d820
+
+2016-09-07 17:02:23 -0300  Thibault Saunier <thibault.saunier@osg.samsung.com>
+
+	* tests/check/meson.build:
+	  meson: Raise test timeout to 3 minutes
+	  The videoscale testsuite (with 50 tests) last almost 2 minutes here
+
+2016-09-07 14:24:54 -0400  Nicolas Dufresne <nicolas.dufresne@collabora.com>
+
+	* tests/check/libs/video.c:
+	  video/test: Coding style fix
+
+2016-09-05 19:55:58 -0300  Thibault Saunier <thibault.saunier@osg.samsung.com>
+
+	* tests/examples/overlay/meson.build:
+	  meson: Workaround the qt5 module not letting us now the preprocessor is not avalaible
+	  If moc-qt5 is not avalaible, meson breaks:
+	  https://github.com/mesonbuild/meson/issues/758
+
+2016-09-05 18:40:19 -0300  Thibault Saunier <thibault.saunier@osg.samsung.com>
+
+	* tests/examples/overlay/meson.build:
+	  meson: tests: Do not pull qt5 as a hard dependency
+
+2016-09-05 17:43:13 -0300  Thibault Saunier <thibault.saunier@osg.samsung.com>
+
+	* meson.build:
+	* tests/check/getpluginsdir:
+	* tests/check/meson.build:
+	  meson: Properly find where GStreamer plugins are when using subprojects
+	  And fix building with meson 0.34
+
+2016-09-05 12:22:36 -0300  Thibault Saunier <thibault.saunier@osg.samsung.com>
+
+	* meson.build:
+	  meson: Bump version to 1.9.2
+
+2016-08-26 11:30:16 +0100  Vincent Penquerc'h <vincent.penquerch@collabora.co.uk>
 
 	* ext/ogg/gstoggdemux.c:
-	  oggdemux: fix unknown duration playing Ogg over HTTP
-	  If the duration is not known from the chain, it might be known
-	  by the startup seek.
-	  This fixes failure to seek.
-	  Merged with a patch from Tim-Philipp Müller <tim@centricular.com>
-	  https://bugzilla.gnome.org/show_bug.cgi?id=768991
+	  oggdemux: safety for failing to determine time length in push mode
+	  If we can't find a valid granule near the end of the file, we
+	  disable seeking. This guards against the whole file being then
+	  read and never going to PLAYING.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=770314
 
-2016-07-18 19:59:23 +1000  Duncan Palmer <dpalmer@digisoft.tv>
+2016-08-26 11:27:17 +0100  Vincent Penquerc'h <vincent.penquerch@collabora.co.uk>
 
-	* sys/xvimage/xvimageallocator.c:
-	* sys/xvimage/xvimageallocator.h:
-	  xvimageallocator: const correctness in gst_xvimage_allocator_alloc().
-	  https://bugzilla.gnome.org/show_bug.cgi?id=767712
+	* ext/ogg/gstoggdemux.c:
+	  oggdemux: increase EOS granpos detection chunk size
+	  This can be too small on some files to find a valid granule.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=770314
 
-2016-07-18 14:20:11 +0100  Tim-Philipp Müller <tim@centricular.com>
+2016-09-04 21:41:04 +0100  Tim-Philipp Müller <tim@centricular.com>
 
-	* sys/xvimage/xvimageallocator.c:
-	  xvimagesink: only error out if the allocated memory is too small
-	  https://bugzilla.gnome.org/show_bug.cgi?id=767712
+	* tests/examples/seek/meson.build:
+	  meson: fix joystick header check for jseek example
 
-2016-07-07 22:27:15 +1000  Duncan Palmer <dpalmer@digisoft.tv>
-
-	* sys/xvimage/xvimageallocator.c:
-	* sys/xvimage/xvimageallocator.h:
-	* sys/xvimage/xvimagepool.c:
-	  xvimagesink: error out on buffer size sanity check failure.
-	  If sanity checks on the buffer size allocated by XvShmCreateImage() fail,
-	  call on g_set_error(), rather than just logging a warning, as this
-	  failure is fatal.
-	  Add a sanity check on buffer size when the video format is RGB. This adds to
-	  existing checks on various YUV pixel formats.
-	  https://bugzilla.gnome.org/show_bug.cgi?id=767712
-
-2016-07-08 16:43:05 +0300  Sebastian Dröge <sebastian@centricular.com>
-
-	* gst-libs/gst/pbutils/encoding-profile.c:
-	  encoding-profile: Remove some more fields from the caps when creating from discoverer info
-	  parsed, framed, stream-format and alignment are only relevant for parsers and
-	  should not matter here. We still want to be able to use an encoder that can
-	  only output byte-stream if the input was avc.
-	  https://bugzilla.gnome.org/show_bug.cgi?id=768566
-
-2016-07-08 15:45:25 +0300  Sebastian Dröge <sebastian@centricular.com>
-
-	* gst-libs/gst/pbutils/missing-plugins.c:
-	  missing-plugins: Remove some other fields when cleaning up caps
-	  Caps are cleaned up for missing plugins, and for creating encoding profiles
-	  and caps descriptions.
-	  Fields like streamheader, parsed, framed, stream-format and alignment are not
-	  relevant here. The last ones all because a parser will take care of them.
-	  https://bugzilla.gnome.org/show_bug.cgi?id=768566
-
-2016-07-04 17:19:08 +0100  Sergio Torres Soldado <torres.soldado@gmail.com>
-
-	* gst-libs/gst/rtsp/gstrtspconnection.c:
-	  rtspconnection: Fix potential deadlock caused by blocking read forever
-	  Reset the connection "may_cancel" property to avoid a potential deadlock
-	  if there is no data to read and the socket stays blocked forever.
-	  https://bugzilla.gnome.org/show_bug.cgi?id=768249
-
-2016-07-04 11:16:55 +0200  Sebastian Dröge <sebastian@centricular.com>
-
-	* gst-libs/gst/video/gstvideodecoder.c:
-	  videodecoder: fix criticals fixating a non existent field
-	  https://bugzilla.gnome.org/show_bug.cgi?id=766970
-
-2016-07-04 11:07:54 +0200  Sebastian Dröge <sebastian@centricular.com>
-
-	* gst-libs/gst/audio/gstaudioencoder.c:
-	  audioencoder: Protect samples_in/bytes_out and audio info with object lock
-	  It might cause invalid calculations during the CONVERT query otherwise.
-
-2016-07-04 11:12:25 +0200  Sebastian Dröge <sebastian@centricular.com>
-
-	* gst-libs/gst/audio/gstaudiodecoder.c:
-	  audiodecoder: Protect samples_in/bytes_out and audio info with object lock
-	  It might cause invalid calculations during the CONVERT query otherwise.
-
-2016-07-04 11:00:51 +0200  Sebastian Dröge <sebastian@centricular.com>
-
-	* gst-libs/gst/audio/gstaudiodecoder.c:
-	* gst-libs/gst/audio/gstaudioencoder.c:
-	* gst-libs/gst/audio/gstaudioutilsprivate.c:
-	* gst-libs/gst/audio/gstaudioutilsprivate.h:
-	  audioencoder/decoder: Move encoded audio conversion function to a common place
-	  No need to duplicate this non-trivial function.
-
-2016-07-04 09:15:03 +0100  Vincent Penquerc'h <vincent.penquerch@collabora.co.uk>
-
-	* gst-libs/gst/audio/gstaudiodecoder.c:
-	  audiodecoder: fix criticals fixating a non existent field
-	  https://bugzilla.gnome.org/show_bug.cgi?id=766970
-
-2016-07-04 10:55:07 +0200  Sebastian Dröge <sebastian@centricular.com>
-
-	* gst-libs/gst/video/gstvideodecoder.c:
-	  videodecoder: Use the object lock to protect bytes/time tracking
-	  And especially don't use the stream lock for that, as otherwise non-serialized
-	  queries (CONVERT) will cause the stream lock to be taken and easily causes the
-	  application to deadlock.
-	  https://bugzilla.gnome.org/show_bug.cgi?id=768361
-
-2016-07-04 10:47:36 +0200  Sebastian Dröge <sebastian@centricular.com>
-
-	* gst-libs/gst/video/gstvideodecoder.c:
-	* gst-libs/gst/video/gstvideoencoder.c:
-	* gst-libs/gst/video/gstvideoutilsprivate.c:
-	* gst-libs/gst/video/gstvideoutilsprivate.h:
-	  videoencoder/decoder: Move conversion utility functions to a common header and use consistently in encoder/decoder
-
-2016-07-04 10:52:24 +0200  Sebastian Dröge <sebastian@centricular.com>
-
-	* gst-libs/gst/video/gstvideoencoder.c:
-	  videoencoder: Use the object lock to protect bytes/time tracking
-
-2016-06-30 18:53:07 +0100  Tim-Philipp Müller <tim@centricular.com>
-
-	* gst-libs/gst/tag/gsttagdemux.c:
-	  tagdemux: fix handling of very short files in push mode
-	  By default we'll wait for a certain amount of data before
-	  attempting typefinding. However, if the stream is fairly
-	  short, we might get EOS before we ever attempted any
-	  typefinding, so at this point we should force typefinding
-	  and output any pending data if we manage to detect the
-	  type.
-	  https://bugzilla.gnome.org//show_bug.cgi?id=768178
-
-2016-06-30 17:30:34 +0100  Tim-Philipp Müller <tim@centricular.com>
-
-	* gst-libs/gst/tag/gsttagdemux.c:
-	  tagdemux: fix erroring out if we reach EOS without detecting type
-	  In 0.10 the source pad was a dynamic pad that was only added once
-	  the type had been detected, but in 1.x it's an always source pad,
-	  so checking whether it's still NULL won't work to detect if the
-	  type has been detected.
-	  Makes tagdemux error out when we get EOS but haven't managed to
-	  identify the format of the data after the tag.
-	  https://bugzilla.gnome.org//show_bug.cgi?id=768178
-
-2016-06-29 18:14:51 +0200  Sebastian Dröge <sebastian@centricular.com>
-
-	* gst-libs/gst/audio/audio-channels.c:
-	* gst/audioconvert/gstaudioconvert.c:
-	  audioconvert: Handle fallback channel mask for mono correctly
-	  It's 0 and no mask should be set for mono at all.
-	  https://bugzilla.gnome.org/show_bug.cgi?id=757472
-
-2016-06-27 20:49:38 +0300  Sebastian Dröge <sebastian@centricular.com>
-
-	* gst/playback/gstplaysink.c:
-	  playsink: Force STEP events on the video-sink for GST_FORMAT_BUFFERS
-	  It does not make much sense for audio sinks.
-
-2016-06-27 20:53:37 +0300  Sebastian Dröge <sebastian@centricular.com>
-
-	* gst/playback/gstplaysink.c:
-	  playsink: Don't send another step event to the audio-sink if we got step-done from there
-	  Otherwise we would end up with a deadlock as the audio-sink emits step-done
-	  from its streaming thread.
-
-2016-06-21 10:24:15 +0300  Sebastian Dröge <sebastian@centricular.com>
+2016-09-03 11:57:22 +1000  Jonathan Matthew <jonathan@d14n.org>
 
 	* gst-libs/gst/pbutils/gstdiscoverer.c:
-	* tests/check/libs/discoverer.c:
-	  discoverer: Only allow serializing OK discoverer infos to GVariants
-	  They will be incomplete otherwise and we can't generate the full serialized
-	  information, and instead will crash somewhere on the way.
-	  https://bugzilla.gnome.org/show_bug.cgi?id=767859
+	  pbutils: store missing-plugin structure in current_info->misc again
+	  This allows gst_discoverer_info_get_misc to work again, until it
+	  finally gets removed.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=770643
 
-=== release 1.8.2 ===
+2016-09-04 16:04:00 +0100  Tim-Philipp Müller <tim@centricular.com>
 
-2016-06-09 11:50:43 +0300  Sebastian Dröge <sebastian@centricular.com>
+	* tools/gst-play.c:
+	  tools: gst-play: cycle between video tracks without disabling video
+
+2016-09-01 17:56:24 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* win32/common/libgstrtp.def:
+	  win32: Update exports
+
+2016-09-01 22:48:40 +1000  Jan Schmidt <jan@centricular.com>
+
+	* gst-libs/gst/video/video-frame.h:
+	  video-frame: Expand the range of caps for extended buffer flags
+	  The video buffer flags can be applied to encoded video streams,
+	  such as video/x-h264 marked up by a demuxer or parser.
+
+2016-09-01 13:07:07 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/playback/gstplaybackutils.h:
+	  playback: Mark internal functions as G_GNUC_INTERNAL
+
+2016-09-01 14:47:02 +0900  Wonchul Lee <wonchul.lee@collabora.com>
+
+	* gst/playback/gstdecodebin2.c:
+	* gst/playback/gstplaybackutils.c:
+	* gst/playback/gstplaybackutils.h:
+	* gst/playback/gsturidecodebin.c:
+	* gst/playback/gsturisourcebin.c:
+	  playbackutils: Move compare_factories_func
+	  Move _decode_bin_compare_factories_func function to playbackutils
+	  https://bugzilla.gnome.org/show_bug.cgi?id=770692
+
+2016-09-01 09:59:06 +0200  Havard Graff <havard.graff@gmail.com>
+
+	* gst-libs/gst/video/video-frame.h:
+	  video-frame: GST_VIDEO_BUFFER_FLAG are only valid for video/x-raw caps
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769771
+
+2016-09-01 09:57:33 +0200  Havard Graff <havard.graff@gmail.com>
+
+	* gst-libs/gst/rtp/gstrtpbuffer.h:
+	  rtpbuffer: Add buffer flag RETRANSMISSION
+	  Useful for elements to know if a buffer is a retransmitted RTP packet.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769771
+
+2016-09-01 12:38:14 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* configure.ac:
+	  configure: Require orc >= 0.4.24
+	  Needed for being able to compile video.orc
+	  https://bugzilla.gnome.org/show_bug.cgi?id=770698
+
+2016-09-01 12:26:40 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* configure.ac:
+	  Back to development
+
+=== release 1.9.2 ===
+
+2016-09-01 12:26:20 +0300  Sebastian Dröge <sebastian@centricular.com>
 
 	* ChangeLog:
 	* NEWS:
 	* RELEASE:
 	* configure.ac:
-	* docs/plugins/gst-plugins-base-plugins.args:
+	* docs/plugins/gst-plugins-base-plugins.signals:
 	* docs/plugins/inspect/plugin-adder.xml:
 	* docs/plugins/inspect/plugin-alsa.xml:
 	* docs/plugins/inspect/plugin-app.xml:
@@ -286,9 +331,858 @@
 	* gst-plugins-base.doap:
 	* win32/common/_stdint.h:
 	* win32/common/config.h:
-	  Release 1.8.2
+	* win32/common/video-enumtypes.c:
+	* win32/common/video-enumtypes.h:
+	  Release 1.9.2
 
-2016-06-09 11:17:28 +0300  Sebastian Dröge <sebastian@centricular.com>
+2016-09-01 11:23:10 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* po/af.po:
+	* po/az.po:
+	* po/bg.po:
+	* po/ca.po:
+	* po/cs.po:
+	* po/da.po:
+	* po/de.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/nb.po:
+	* po/nl.po:
+	* po/or.po:
+	* po/pl.po:
+	* po/pt_BR.po:
+	* po/ro.po:
+	* po/ru.po:
+	* po/sk.po:
+	* po/sl.po:
+	* po/sq.po:
+	* po/sr.po:
+	* po/sv.po:
+	* po/tr.po:
+	* po/uk.po:
+	* po/vi.po:
+	* po/zh_CN.po:
+	  po: Update translations
+
+2016-09-01 10:53:35 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* tests/icles/test-colorkey.c:
+	  test-colorkey: #define GDK_DISABLE_DEPRECATION_WARNINGS
+	  We use gdk_cairo_create() which is deprecated since 3.22.
+
+2016-08-27 11:22:11 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* meson_options.txt:
+	* tests/examples/app/meson.build:
+	* tests/examples/audio/meson.build:
+	* tests/examples/decodebin_next/meson.build:
+	* tests/examples/dynamic/meson.build:
+	* tests/examples/encoding/meson.build:
+	* tests/examples/fft/meson.build:
+	* tests/examples/gio/meson.build:
+	* tests/examples/meson.build:
+	* tests/examples/overlay/meson.build:
+	* tests/examples/playback/meson.build:
+	* tests/examples/playrec/meson.build:
+	* tests/examples/seek/meson.build:
+	* tests/examples/snapshot/meson.build:
+	* tests/meson.build:
+	  meson: build examples
+
+2016-08-27 01:17:25 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* tests/meson.build:
+	  meson: enable tests
+	  At least on non-Windows platforms.
+
+2016-08-19 11:09:27 -0700  Thibault Saunier <thibault.saunier@osg.samsung.com>
+
+	* ext/ogg/gstoggdemux.c:
+	* gst-libs/gst/tag/gsttagdemux.c:
+	  Use the new API to post flow ERROR messages on the bus
+	  https://bugzilla.gnome.org/show_bug.cgi?id=770158
+
+2016-08-26 20:48:05 +0200  Josep Torra <n770galaxy@gmail.com>
+
+	* configure.ac:
+	* tests/check/Makefile.am:
+	  build: silence error about pthread for 'make check' in osx
+	  Fixes "clang: error: argument unused during compilation: '-pthread'"
+
+2016-08-25 12:19:52 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst-libs/gst/video/meson.build:
+	  meson: update for new files in video lib
+
+2016-08-09 11:39:53 +0200  Josep Torra <n770galaxy@gmail.com>
+
+	* gst/playback/gstdecodebin2.c:
+	  decodebin: forward sticky events on multiqueue
+	  When connecting a demuxer through a multiqueue ensure to copy sticky
+	  events in order to allow the following factory being properly
+	  checked that it is functional.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769580
+
+2016-08-25 11:56:11 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* win32/common/libgstvideo.def:
+	  win32: Update libgstvideo.def
+
+2016-07-26 19:14:40 +0200  Xabier Rodriguez Calvar <calvaris@igalia.com>
+
+	* docs/libs/gst-plugins-base-libs-docs.sgml:
+	* docs/libs/gst-plugins-base-libs-sections.txt:
+	* docs/libs/gst-plugins-base-libs.types:
+	* gst-libs/gst/video/Makefile.am:
+	* gst-libs/gst/video/video.h:
+	* gst-libs/gst/video/videodirection.c:
+	* gst-libs/gst/video/videodirection.h:
+	* gst-plugins-base.spec.in:
+	* tests/check/libs/gstlibscpp.cc:
+	* tests/check/libs/libsabi.c:
+	* tests/icles/test-header-compile:
+	  videodirection: interface for rotation and flip
+	  A GstVideoOrientationMethod enumeration is also provided for the
+	  admitted property values.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768687
+
+2016-08-17 23:49:02 +0200  Matej Knopp <matej.knopp@gmail.com>
+
+	* gst/playback/gstparsebin.c:
+	  parsebin: do not set global tags to stream
+	  https://bugzilla.gnome.org/show_bug.cgi?id=770053
+
+2016-08-12 20:56:31 +0530  Nirbheek Chauhan <nirbheek@centricular.com>
+
+	* .gitignore:
+	* config.h.meson:
+	* ext/alsa/meson.build:
+	* ext/cdparanoia/meson.build:
+	* ext/libvisual/meson.build:
+	* ext/meson.build:
+	* ext/ogg/meson.build:
+	* ext/opus/meson.build:
+	* ext/pango/meson.build:
+	* ext/theora/meson.build:
+	* ext/vorbis/meson.build:
+	* gst-libs/gst/allocators/meson.build:
+	* gst-libs/gst/app/meson.build:
+	* gst-libs/gst/audio/audio_mkenum.py:
+	* gst-libs/gst/audio/meson.build:
+	* gst-libs/gst/fft/meson.build:
+	* gst-libs/gst/meson.build:
+	* gst-libs/gst/pbutils/meson.build:
+	* gst-libs/gst/pbutils/pbutils_mkenum.py:
+	* gst-libs/gst/riff/meson.build:
+	* gst-libs/gst/rtp/meson.build:
+	* gst-libs/gst/rtp/rtp_mkenum.py:
+	* gst-libs/gst/rtsp/meson.build:
+	* gst-libs/gst/rtsp/rtsp_mkenum.py:
+	* gst-libs/gst/sdp/meson.build:
+	* gst-libs/gst/tag/meson.build:
+	* gst-libs/gst/video/meson.build:
+	* gst-libs/gst/video/video_mkenum.py:
+	* gst-libs/meson.build:
+	* gst/adder/meson.build:
+	* gst/app/meson.build:
+	* gst/audioconvert/meson.build:
+	* gst/audiorate/meson.build:
+	* gst/audioresample/meson.build:
+	* gst/audiotestsrc/meson.build:
+	* gst/encoding/meson.build:
+	* gst/gio/meson.build:
+	* gst/meson.build:
+	* gst/playback/meson.build:
+	* gst/subparse/meson.build:
+	* gst/tcp/meson.build:
+	* gst/typefind/meson.build:
+	* gst/videoconvert/meson.build:
+	* gst/videorate/meson.build:
+	* gst/videoscale/meson.build:
+	* gst/videotestsrc/meson.build:
+	* gst/volume/meson.build:
+	* meson.build:
+	* meson_options.txt:
+	* pkgconfig/meson.build:
+	* sys/meson.build:
+	* sys/ximage/meson.build:
+	* sys/xvimage/meson.build:
+	* tests/check/meson.build:
+	* tests/meson.build:
+	* tools/meson.build:
+	  Add support for Meson as alternative/parallel build system
+	  https://github.com/mesonbuild/meson
+	  With contributions from:
+	  Tim-Philipp Müller <tim@centricular.com>
+	  Jussi Pakkanen <jpakkane@gmail.com> (original port)
+	  Highlights of the features provided are:
+	  * Faster builds on Linux (~40-50% faster)
+	  * The ability to build with MSVC on Windows
+	  * Generate Visual Studio project files
+	  * Generate XCode project files
+	  * Much faster builds on Windows (on-par with Linux)
+	  * Seriously fast configure and building on embedded
+	  ... and many more. For more details see:
+	  http://blog.nirbheek.in/2016/05/gstreamer-and-meson-new-hope.html
+	  http://blog.nirbheek.in/2016/07/building-and-developing-gstreamer-using.html
+	  Building with Meson should work on both Linux and Windows, but may
+	  need a few more tweaks on other operating systems.
+
+2016-08-20 11:01:04 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* tests/check/libs/.gitignore:
+	  tests: ignore new videotimecode test binary
+
+2016-08-19 15:29:13 +0300  Vivia Nikolaidou <vivia@ahiru.eu>
+
+	* gst-libs/gst/video/gstvideotimecode.c:
+	  videotimecode: Fix false positive coverity issues
+	  They are false positive overflows, because coverity doesn't realize that
+	  hours <= 24, minutes < 60 and seconds < 60 in all functions. Also casting the
+	  number 60 (seconds in minute, minutes in hour) to guint64 for the
+	  calculations, in order to avoid overflowing once we allow more than 24-hour
+	  timecodes.
+	  CIDs #1371459, #1371458
+
+2016-08-18 12:03:39 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/videorate/gstvideorate.c:
+	  videorate: Implement basic support for reverse playback
+	  This is enough for making it work in GES, but it's unclear if all the various
+	  property combinations are working correctly. It's an improvement over what was
+	  there before in any case, which was to just drop all buffers if rate < 0.0.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769624
+
+2016-08-12 21:04:03 +0530  Nirbheek Chauhan <nirbheek@centricular.com>
+
+	* gst-libs/gst/fft/kiss_fft_s16.h:
+	* gst-libs/gst/fft/kiss_fft_s32.h:
+	  gstfft: Use stdint.h instead of _stdint.h
+	  _stdint.h is generated by Autotools and we don't really need it.
+	  stdint.h is now available on all supported platforms.
+	  This really only makes a difference for MSVC, which has it starting from
+	  Visual Studio 2015.
+
+2016-08-19 09:27:01 +0200  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/allocators/gstfdmemory.c:
+	* gst-libs/gst/allocators/gstfdmemory.h:
+	  fdmemory: add flag to avoid close of the fd
+	  Add GST_FD_MEMORY_FLAG_DONT_CLOSE to avoid closing the fd when the
+	  memory is freed. When you can guarantee the lifetime of the fd is
+	  longer than the memory, this can save a dup() call.
+
+2016-08-17 13:03:43 +0300  Vivia Nikolaidou <vivia@toolsonair.com>
+
+	* gst-libs/gst/video/gstvideotimecode.c:
+	  videotimecode: Fix various coverity issues
+	  Most of them are overflow related and false positives, but coverity can't know
+	  that these can't overflow without us giving it more information. Add some
+	  assertions for this.
+	  One was an actual issue with flags comparison.
+	  CIDs #1369051, #1369050, #1369049, #1369048, #1369045
+
+2016-08-08 20:04:11 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst/playback/gstplaybin3.c:
+	  playbin3: add "element-setup" signal
+	  Allows configuration of plugged elements.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=578933
+
+2016-06-16 10:01:50 +0100  Vincent Penquerc'h <vincent.penquerch@collabora.co.uk>
+
+	* ext/ogg/gstoggdemux.c:
+	  oggdemux: remove eos avoidance workaround
+	  This workaround tried to avoid an EOS event when seeking to the
+	  end of an Ogg stream in order to find its duration. At some point,
+	  an EOS event there would cause any queue2 upstream to pause and
+	  not restart on a seek back to the beginning. This now appears to
+	  not be the case anymore, and so the workaround can be removed.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767689
+
+2016-08-04 19:06:45 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* docs/libs/gst-plugins-base-libs-sections.txt:
+	* win32/common/libgstvideo.def:
+	  videotimecode: Add to docs and exports list
+
+2016-05-18 19:30:52 +0300  Vivia Nikolaidou <vivia@toolsonair.com>
+
+	* ext/pango/gsttimeoverlay.c:
+	* ext/pango/gsttimeoverlay.h:
+	  timeoverlay: Add support to display timecode
+	  Choosing time-mode=time-code will display the time code attached to the
+	  buffer, or 00:00:00:00 if no time code is found.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=766419
+
+2016-05-14 17:59:20 +0300  Vivia Nikolaidou <vivia@toolsonair.com>
+
+	* gst-libs/gst/video/gstvideometa.c:
+	* gst-libs/gst/video/gstvideometa.h:
+	  videometa: Added video time code meta
+	  It attaches a GstVideoTimeCodeMeta (SMPTE timecode) as metadata to a buffer.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=766419
+
+2016-05-14 12:20:38 +0300  Vivia Nikolaidou <vivia@toolsonair.com>
+
+	* gst-libs/gst/video/Makefile.am:
+	* gst-libs/gst/video/gstvideotimecode.c:
+	* gst-libs/gst/video/gstvideotimecode.h:
+	* gst-libs/gst/video/video.h:
+	* tests/check/Makefile.am:
+	* tests/check/libs/videotimecode.c:
+	  videotimecode: Added support for SMPTE time code metadata
+	  Can be attached as GstMeta into a video frame.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=766419
+
+2016-07-28 15:04:01 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst/playback/gstdecodebin3.c:
+	  decodebin3: don't leak alternate inputs
+	  Fix leaks (including parsebin elements) with this pipeline:
+	  playbin3
+	  uri=http://127.0.0.1:8079/defaults/exMPD_BIP_TC1/exMPD_BIP_TC1.mpd
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769270
+
+2016-08-01 16:00:29 +0100  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* ext/ogg/gstoggparse.c:
+	  ogg: check return values in gst_ogg_parse_new_stream
+	  Return NULL in gst_ogg_parse_new_stream when either ogg_stream_pagein() or
+	  gst_ogg_stream_setup_map() failed.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769299
+
+2016-08-01 15:52:11 +0100  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* ext/ogg/gstoggparse.c:
+	  ogg: fix memory leak in gst_ogg_parse_new_stream
+	  Avoid leaking the stream object
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769299
+
+2016-08-01 13:35:16 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst/playback/gstdecodebin3.c:
+	  decodebin3: fix output->decoder_{sink,src} leak
+	  output->decoder_sink and output->decoder_src are both going to be
+	  replaced in the 2 branches of the following 'if'.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769270
+
+2016-08-01 12:37:43 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst/playback/gstdecodebin3.c:
+	  decodebin3: fix tag list leak
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769270
+
+2016-08-01 12:28:20 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst/playback/gstdecodebin3.c:
+	  decodebin3: consume select-streams event
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769270
+
+2016-07-28 15:44:27 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* tests/examples/decodebin_next/decodebin3.c:
+	* tests/examples/decodebin_next/playbin-test.c:
+	  decodebin_next: fix caps and tags leaks
+	  The getters are (transfer full).
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769270
+
+2016-07-28 14:46:34 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst/playback/gstdecodebin3.c:
+	  decodebin3: fix collection ref handling
+	  gst_stream_collection_add_stream() consumes the collection reference
+	  passed to it but gst_stream_collection_get_stream() is (transfer none).
+	  Fix this pipeline:
+	  playbin3
+	  uri=http://127.0.0.1:8079/defaults/exMPD_BIP_TC1/exMPD_BIP_TC1.mpd
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769270
+
+2016-07-29 11:38:44 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst/playback/gstdecodebin3.c:
+	  decodebin3: handle full removal of streams
+	  Fix the
+	  validate.file.playback.disable_subtitle_track_while_paused.* validate
+	  scenarios when using playbin3.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769298
+
+2016-08-02 12:03:18 +0200  Carlos Rafael Giani <dv@pseudoterminal.org>
+
+	* gst-libs/gst/riff/riff-media.c:
+	  riff: Remove sample rate and channel count boundaries in caps
+	  WAV is too generic to impose more-or-less arbitrary boundaries on the
+	  sample rate and channel count caps. For example, there are 384 kHz WAV
+	  files. Another example: it is in theory possible that somebody puts DSD
+	  data into a WAV file, which will then have a sample rate of ~2.8 MHz.
+	  For this reason, get rid of the rate and channel caps unless they are
+	  fixed values. Downstream anyway usually knows the limitations better.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=761514
+
+2016-07-29 15:51:35 +0300  Sreerenj Balachandran <sreerenj.balachandran@intel.com>
+
+	* gst-libs/gst/pbutils/codec-utils.c:
+	  pbutils: Add more h264 scalable profiles
+	  Adding Scalable Constrained High (G.10.1.2.1) and
+	  Scalable High Intra(G.10.1.3) profiles to the profile list
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769303
+
+2016-07-26 17:46:02 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/rtp/gstrtpbuffer.c:
+	* gst-libs/gst/rtp/gstrtpbuffer.h:
+	  rtpbuffer: Add some const qualifiers
+	  gst_rtp_buffer_add_extension_onebyte_header() and
+	  gst_rtp_buffer_add_extension_twobytes_header() can have a const argument for
+	  the actual extension data.
+
+2015-12-26 13:19:01 +0000  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst/playback/gstparsebin.c:
+	  parsebin: maintain original order when creating fallback stream collection
+
+2016-03-20 14:37:03 +1100  Jan Schmidt <jan@centricular.com>
+
+	* gst/playback/gstdecodebin2.c:
+	  decodebin: Send stream-group-done to unblock downstream
+	  When processing EOS for a pad, send a stream-group-done
+	  for the pad in case downstream is waiting for more
+	  data on this stream before it can process related
+	  streams from the group.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768995
+
+2016-07-22 14:40:25 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst/playback/gstplaybin3.c:
+	  playbin3: fix collection leak
+	  The collection referenced owned by playbin3 was not released when it was
+	  destroyed.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769080
+
+2016-07-22 14:35:17 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst/playback/gstdecodebin3.c:
+	  decodebin3: fix collection refcounting
+	  My collection leak fix 83f30627cd9460157935e7e9603c60a15555967e
+	  introduced a crash in this scenario: audiotestsrc ! decodebin3 ! fakesink
+	  The reference handling of collection in decodebin3 wasn't very clear and
+	  my attempt to fix the leak introduced a regression where we went one
+	  reference short in some other scenarios.
+	  Fixing this by:
+	  - Giving a strong reference to DecodebinInput making things clearer
+	  - Fixing get_merged_collection() which was sometimes returning an
+	  existing reference and sometimes a new one.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=769080
+
+2016-07-23 14:42:30 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* docs/plugins/.gitignore:
+	* tests/check/libs/.gitignore:
+	  Add more files to .gitignore
+
+2016-07-22 14:42:31 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst/playback/gsturisourcebin.c:
+	  docs: urisourcebin: fix typo
+
+2016-07-22 23:21:36 +1000  Jan Schmidt <jan@centricular.com>
+
+	* gst/playback/gstdecodebin3.c:
+	* gst/playback/gstparsebin.c:
+	* gst/playback/gstplaybin3.c:
+	* gst/playback/gsturisourcebin.c:
+	  playback: Flesh out docs a bit for new elements
+	  Add some more text to the docs for urisourcebin,
+	  parsebin, decodebin3 and playbin3, including a warning
+	  that they are unstable API for now
+
+2016-07-22 12:52:12 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* docs/plugins/gst-plugins-base-plugins-docs.sgml:
+	* docs/plugins/gst-plugins-base-plugins-sections.txt:
+	* docs/plugins/gst-plugins-base-plugins.signals:
+	* gst/playback/gstparsebin.c:
+	* gst/playback/gstplaybin3.c:
+	  docs: add playbin3, decodebin3, parsebin, urisourcebin to docs
+	  Docs still need some fleshing out though.
+
+2016-07-13 18:29:52 +0900  Arun Raghavan <arun@arunraghavan.net>
+
+	* ext/vorbis/gstvorbisenc.c:
+	  Revert "vorbisenc: push an updated segment stop time when we know it"
+	  This reverts commit a16cd5d2a5cbdf084163ead68b59d537d7db99f7.
+	  Setting the stop time on the segment breaks reconfiguration, as the
+	  encoder signals an EOS, but we reconfigure it an continue to produce
+	  buffers.
+	  This information  should not be required via the segment downstream
+	  since we already have the sample count being used to generate buffer
+	  durations.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768763
+
+2016-07-20 11:47:48 +0100  Vincent Penquerc'h <vincent.penquerch@collabora.co.uk>
+
+	* ext/ogg/gstoggdemux.c:
+	  oggdemux: fix unknown duration playing Ogg over HTTP
+	  If the duration is not known from the chain, it might be known
+	  by the startup seek.
+	  This fixes failure to seek.
+	  Merged with a patch from Tim-Philipp Müller <tim@centricular.com>
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768991
+
+2016-07-20 12:17:57 +0200  Michael Olbrich <m.olbrich@pengutronix.de>
+
+	* gst-libs/gst/audio/gstaudioclock.c:
+	  audioclock: use GST_STIME_FORMAT for the correct argument
+	  GST_STIME_ARGS is used for time_offset not for last_time.
+	  This fixes the format string accordingly.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768990
+
+2016-07-19 18:20:57 +0200  Wim Taymans <wtaymans@redhat.com>
+
+	* gst/audioresample/gstaudioresample.c:
+	  audioresample: after a reset, recalculate the ouput size
+	  After we reset the resampler, there is no history anymore in the resampler
+	  and the previously calculated output size is no longer valid.
+	  Recalculate the new output size after a reset to make sure we don't try
+	  to convert too much.
+
+2016-07-19 13:26:06 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst/subparse/gstsubparse.c:
+	  subparse: fix some leaks
+	  Fixes check-valgrind for subparse test.
+
+2016-07-18 17:26:26 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* tests/check/elements/appsink.c:
+	  tests: appsink: add minimal test for new pull with timeout functions
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768852
+
+2016-07-15 13:20:29 +0200  Joan Pau Beltran <joanpau.beltran@socib.cat>
+
+	* docs/libs/gst-plugins-base-libs-sections.txt:
+	* gst-libs/gst/app/gstappsink.c:
+	* gst-libs/gst/app/gstappsink.h:
+	* win32/common/libgstapp.def:
+	  appsink: add _pull_sample/preroll() variants with timeout
+	  The _pull_sample() and _pull_preroll() functions block
+	  until a sample is available, EOS happens or the pipeline
+	  is shut down (returning NULL in the last two cases).
+	  This adds _try_pull_sample() and _try_pull_preroll()
+	  functions with a timeout argument to specify the maximum
+	  amount of time to wait for a new sample.
+	  To avoid code duplication, wait forever if the timeout is
+	  GST_CLOCK_TIME_NONE and use that to implement
+	  _pull_sample/_pull_preroll with the original behavior.
+	  Add also corresponding action signals "try-pull-sample"
+	  and "try-pull-preroll".
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768852
+
+2016-07-13 14:17:25 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst/playback/gstdecodebin3.c:
+	  decodebin3: actually check result of accept caps query
+	  We were just checking if the query was handled, not its result.
+	  Also fix a leak as gst_pad_query() was not consuming the query.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768811
+
+2016-07-18 14:20:11 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* sys/xvimage/xvimageallocator.c:
+	  xvimagesink: only error out if the allocated memory is too small
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767712
+
+2016-07-18 19:59:23 +1000  Duncan Palmer <dpalmer@digisoft.tv>
+
+	* sys/xvimage/xvimageallocator.c:
+	* sys/xvimage/xvimageallocator.h:
+	  xvimageallocator: const correctness in gst_xvimage_allocator_alloc().
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767712
+
+2016-07-07 22:27:15 +1000  Duncan Palmer <dpalmer@digisoft.tv>
+
+	* sys/xvimage/xvimageallocator.c:
+	* sys/xvimage/xvimageallocator.h:
+	* sys/xvimage/xvimagepool.c:
+	  xvimagesink: error out on buffer size sanity check failure.
+	  If sanity checks on the buffer size allocated by XvShmCreateImage() fail,
+	  call on g_set_error(), rather than just logging a warning, as this
+	  failure is fatal.
+	  Add a sanity check on buffer size when the video format is RGB. This adds to
+	  existing checks on various YUV pixel formats.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767712
+
+2016-07-14 10:33:38 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst/playback/gstplaybin3.c:
+	  playbin3: fix stream leak
+	  The stream returned by gst_message_streams_selected_get_stream() is
+	  reffed.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768811
+
+2016-07-13 16:16:21 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst/playback/gstdecodebin3.c:
+	* gst/playback/gstparsebin.c:
+	  decodebin3: fix collection leak
+	  The collection owned by GstDecodebin3 has to be unreffed when disposing.
+	  gst_event_new_stream_collection() doesn't consume the collection passed
+	  to it so no need to give it an extra ref.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768811
+
+2016-07-14 10:34:30 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst/playback/gstdecodebin3-parse.c:
+	* gst/playback/gstdecodebin3.c:
+	  decodebin3: fix stream leaks
+	  MultiQueueSlot owns a ref on the active stream so it should release it
+	  when being freed.
+	  DecodebinInputStream owns ref on the active and pending stream so they
+	  should be dropped when being freed.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768811
+
+2016-07-14 14:24:23 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst/playback/gstdecodebin3.c:
+	* gst/playback/gstparsebin.c:
+	  decodebin3: fix event leaks
+	  Returning GST_PAD_PROBE_HANDLED means we are taking care of unreffing
+	  the probe info.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768811
+
+2016-07-14 16:29:39 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst/playback/gstdecodebin3.c:
+	* gst/playback/gstparsebin.c:
+	  decodebin3: fix caps leaks
+	  gst_stream_get_caps() returns a reffed caps.
+	  The caps passed to gst_query_set_caps_result() are not transfered.
+	  The caps in gst_parse_pad_stream_start_event() was either acquired
+	  using gst_pad_get_current_caps() which returns a new ref or
+	  explicitly reffed.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768811
+
+2016-07-15 19:48:02 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst-libs/gst/rtp/gstrtpbasedepayload.c:
+	  rtp: rtpbasedepayload: simplify code
+	  Remove unnecessary helper struct for callbacks. The bclass
+	  member of the helper struct was not used, so we can just
+	  remove it and the GET_CLASS() call and simplify the whole
+	  affair by passing the depayloader directly to the callback.
+
+2016-07-13 16:02:25 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst/playback/gstdecodebin3.c:
+	* gst/playback/gstplaybin3.c:
+	* tests/examples/decodebin_next/decodebin3.c:
+	* tests/examples/decodebin_next/playbin-test.c:
+	  playbin3: fix leaks of collection returned by message parse API
+	  gst_message_parse_stream_collection() and
+	  gst_message_parse_streams_selected() actually return a reffed
+	  GstStreamCollection.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768776
+
+2016-07-15 22:47:02 +1000  Jan Schmidt <jan@centricular.com>
+
+	* tools/gst-play.c:
+	  gst-play: Allow disabling audio/video/subtitle tracks
+	  When cycling through tracks, add 'disable' to the set
+	  of states.
+
+2016-06-24 12:25:30 +1000  Jan Schmidt <jan@centricular.com>
+
+	* ext/alsa/gstalsasink.h:
+	  alsasink: Remove unused hwparam/swparam pointers
+	  The ALSA params structures aren't kept. The pointers
+	  aren't used anywhere, so remove them from the struct.
+
+2016-07-13 15:45:33 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* tools/gst-device-monitor.c:
+	  tools: fix device leaks in gst-device-monitor
+	  gst_message_parse_device_{added,removed} is actually returning a new ref
+	  on the device.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768776
+
+2016-07-12 12:03:53 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* tests/check/elements/videoscale.c:
+	  videoscale: fix bus leak in test
+	  gst_bus_add_signal_watch() takes a ref on the bus which should be
+	  released using gst_bus_remove_signal_watch().
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768718
+
+2016-07-11 19:17:41 +0200  Xabier Rodriguez Calvar <calvaris@igalia.com>
+
+	* gst-libs/gst/video/videoorientation.c:
+	  videoorientation: Use G_DEFINE_INTERFACE instead of a manually written get_type()
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768687
+
+2016-07-12 00:13:32 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/video/video-color.c:
+	* gst-libs/gst/video/video-format.c:
+	  video: Fix some compiler warnings for out-of-range enum values
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767816
+
+2016-07-11 21:13:37 +0200  Stefan Sauer <ensonic@users.sf.net>
+
+	* common:
+	  Automatic update of common submodule
+	  From f363b32 to f49c55e
+
+2016-07-10 10:28:44 +0900  Seungha Yang <sh.yang@lge.com>
+
+	* gst-libs/gst/app/gstappsrc.c:
+	* gst-libs/gst/app/gstappsrc.h:
+	* tests/check/elements/appsrc.c:
+	  appsrc: Remove trailing whitespace
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768510
+
+2016-07-08 16:43:05 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/pbutils/encoding-profile.c:
+	  encoding-profile: Remove some more fields from the caps when creating from discoverer info
+	  parsed, framed, stream-format and alignment are only relevant for parsers and
+	  should not matter here. We still want to be able to use an encoder that can
+	  only output byte-stream if the input was avc.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768566
+
+2016-07-08 15:45:25 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/pbutils/missing-plugins.c:
+	  missing-plugins: Remove some other fields when cleaning up caps
+	  Caps are cleaned up for missing plugins, and for creating encoding profiles
+	  and caps descriptions.
+	  Fields like streamheader, parsed, framed, stream-format and alignment are not
+	  relevant here. The last ones all because a parser will take care of them.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768566
+
+2016-07-08 15:44:26 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/pbutils/pbutils-private.h:
+	  pbutils: Mark private functions as G_GNUC_INTERNAL
+
+2016-07-07 17:37:51 +0200  Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
+
+	* gst/subparse/gstsubparse.c:
+	  subparse: don't reset allowed tags
+	  When a discont buffer is processed, the state is re-initialized, which
+	  nullifies the allowed_tags.
+	  The problem is when a subrip string with tags is processed and allowed_tags is
+	  NULL. The function subrip_unescape_formatting() calls g_strjoinv with a
+	  str_array as NULL, leading to a GLib-CRITICAL.
+	  This patch removes the allowed_tags resetting, in parser_state_init(), but
+	  move it into gst_sub_parse_format_autodetect().
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768525
+
+2016-07-04 17:19:08 +0100  Sergio Torres Soldado <torres.soldado@gmail.com>
+
+	* gst-libs/gst/rtsp/gstrtspconnection.c:
+	  rtspconnection: Fix potential deadlock caused by blocking read forever
+	  Reset the connection "may_cancel" property to avoid a potential deadlock
+	  if there is no data to read and the socket stays blocked forever.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768249
+
+2016-07-07 17:29:34 +0200  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/video/video-converter.c:
+	  video-converter: fix compilation on big-endian
+
+2016-07-07 17:10:17 +0200  Edward Hervey <edward@centricular.com>
+
+	* gst-libs/gst/video/gstvideodecoder.c:
+	  videodecoder: More trickmode fix
+	  We need to take into account the input segment flags to know whether
+	  we should drain the decoder after a new keyframe in trick mode.
+	  Otherwise we would have to wait for the next frame to be outputted (and
+	  the segment to be activated) which ... well ... kind of beats the whole
+	  point of this draining :)
+
+2016-07-06 21:13:19 +0200  Piotr Drąg <piotrdrag@gmail.com>
+
+	* po/POTFILES.in:
+	  po: update POTFILES
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768495
+
+2016-07-07 00:27:00 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/audio/Makefile.am:
+	  audio: Ship audio-resampler-neon.h
+
+2016-07-06 16:14:32 +0200  Thijs Vermeir <thijsvermeir@gmail.com>
+
+	* tests/examples/playback/playback-test.c:
+	  tests: correctly print guintptr on mac
+
+2016-07-06 13:51:00 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* configure.ac:
+	  Back to development
+
+=== release 1.9.1 ===
+
+2016-07-06 13:06:06 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* ChangeLog:
+	* NEWS:
+	* RELEASE:
+	* configure.ac:
+	* docs/plugins/gst-plugins-base-plugins.args:
+	* docs/plugins/gst-plugins-base-plugins.hierarchy:
+	* docs/plugins/gst-plugins-base-plugins.interfaces:
+	* docs/plugins/gst-plugins-base-plugins.signals:
+	* docs/plugins/inspect/plugin-adder.xml:
+	* docs/plugins/inspect/plugin-alsa.xml:
+	* docs/plugins/inspect/plugin-app.xml:
+	* docs/plugins/inspect/plugin-audioconvert.xml:
+	* docs/plugins/inspect/plugin-audiorate.xml:
+	* docs/plugins/inspect/plugin-audioresample.xml:
+	* docs/plugins/inspect/plugin-audiotestsrc.xml:
+	* docs/plugins/inspect/plugin-cdparanoia.xml:
+	* docs/plugins/inspect/plugin-encoding.xml:
+	* docs/plugins/inspect/plugin-gio.xml:
+	* docs/plugins/inspect/plugin-libvisual.xml:
+	* docs/plugins/inspect/plugin-ogg.xml:
+	* docs/plugins/inspect/plugin-opus.xml:
+	* docs/plugins/inspect/plugin-pango.xml:
+	* docs/plugins/inspect/plugin-playback.xml:
+	* docs/plugins/inspect/plugin-subparse.xml:
+	* docs/plugins/inspect/plugin-tcp.xml:
+	* docs/plugins/inspect/plugin-theora.xml:
+	* docs/plugins/inspect/plugin-typefindfunctions.xml:
+	* docs/plugins/inspect/plugin-videoconvert.xml:
+	* docs/plugins/inspect/plugin-videorate.xml:
+	* docs/plugins/inspect/plugin-videoscale.xml:
+	* docs/plugins/inspect/plugin-videotestsrc.xml:
+	* docs/plugins/inspect/plugin-volume.xml:
+	* docs/plugins/inspect/plugin-vorbis.xml:
+	* docs/plugins/inspect/plugin-ximagesink.xml:
+	* docs/plugins/inspect/plugin-xvimagesink.xml:
+	* gst-libs/gst/video/video-orc-dist.c:
+	* gst-plugins-base.doap:
+	* win32/common/_stdint.h:
+	* win32/common/audio-enumtypes.c:
+	* win32/common/audio-enumtypes.h:
+	* win32/common/config.h:
+	* win32/common/video-enumtypes.c:
+	  Release 1.9.1
+
+2016-07-06 11:42:29 +0300  Sebastian Dröge <sebastian@centricular.com>
 
 	* po/af.po:
 	* po/az.po:
@@ -330,13 +1224,474 @@
 	* po/zh_CN.po:
 	  Update .po files
 
-2016-06-09 10:05:03 +0300  Sebastian Dröge <sebastian@centricular.com>
+2016-07-06 10:18:00 +0300  Sebastian Dröge <sebastian@centricular.com>
 
+	* po/af.po:
+	* po/az.po:
+	* po/bg.po:
+	* po/ca.po:
+	* po/cs.po:
+	* po/da.po:
+	* po/de.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/nb.po:
+	* po/nl.po:
+	* po/or.po:
+	* po/pl.po:
 	* po/pt_BR.po:
+	* po/ro.po:
+	* po/ru.po:
 	* po/sk.po:
+	* po/sl.po:
+	* po/sq.po:
+	* po/sr.po:
+	* po/sv.po:
+	* po/tr.po:
+	* po/uk.po:
+	* po/vi.po:
+	* po/zh_CN.po:
 	  po: Update translations
 
+2016-06-30 16:36:27 +0200  Philippe Normand <philn@igalia.com>
+
+	* gst-libs/gst/video/gstvideodecoder.c:
+	  videodecoder: Take stream lock one time only on drain
+	  When the drain is triggered from the chain function the lock is already
+	  taken so there is no need to take it one more time.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767641
+
+2016-07-04 11:16:55 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/video/gstvideodecoder.c:
+	  videodecoder: fix criticals fixating a non existent field
+	  https://bugzilla.gnome.org/show_bug.cgi?id=766970
+
+2016-07-04 11:12:25 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/audio/gstaudiodecoder.c:
+	  audiodecoder: Protect samples_in/bytes_out and audio info with object lock
+	  It might cause invalid calculations during the CONVERT query otherwise.
+
+2016-07-04 11:07:54 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/audio/gstaudioencoder.c:
+	  audioencoder: Protect samples_in/bytes_out and audio info with object lock
+	  It might cause invalid calculations during the CONVERT query otherwise.
+
+2016-07-04 11:00:51 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/audio/gstaudiodecoder.c:
+	* gst-libs/gst/audio/gstaudioencoder.c:
+	* gst-libs/gst/audio/gstaudioutilsprivate.c:
+	* gst-libs/gst/audio/gstaudioutilsprivate.h:
+	  audioencoder/decoder: Move encoded audio conversion function to a common place
+	  No need to duplicate this non-trivial function.
+
+2016-07-04 09:15:03 +0100  Vincent Penquerc'h <vincent.penquerch@collabora.co.uk>
+
+	* gst-libs/gst/audio/gstaudiodecoder.c:
+	  audiodecoder: fix criticals fixating a non existent field
+	  https://bugzilla.gnome.org/show_bug.cgi?id=766970
+
+2016-07-04 10:55:07 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/video/gstvideodecoder.c:
+	  videodecoder: Use the object lock to protect bytes/time tracking
+	  And especially don't use the stream lock for that, as otherwise non-serialized
+	  queries (CONVERT) will cause the stream lock to be taken and easily causes the
+	  application to deadlock.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=768361
+
+2016-07-04 10:52:24 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/video/gstvideoencoder.c:
+	  videoencoder: Use the object lock to protect bytes/time tracking
+
+2016-07-04 10:47:36 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/video/gstvideodecoder.c:
+	* gst-libs/gst/video/gstvideoencoder.c:
+	* gst-libs/gst/video/gstvideoutilsprivate.c:
+	* gst-libs/gst/video/gstvideoutilsprivate.h:
+	  videoencoder/decoder: Move conversion utility functions to a common header and use consistently in encoder/decoder
+
+2016-03-17 00:19:18 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/app/gstappsrc.c:
+	  appsrc: If do-timestamp=TRUE, capture the time when the buffer was pushed to the source
+	  ... instead of the time when it was pushed further downstream.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=763630
+
+2016-04-29 00:59:42 -0700  Zaheer Abbas Merali <zaheermerali@gmail.com>
+
+	* gst-libs/gst/rtp/gstrtpbasedepayload.c:
+	  basertpdepayload: create valid segment when given non-time segment
+	  This will become an error in 1.10.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=765796
+
+2016-06-30 18:53:07 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst-libs/gst/tag/gsttagdemux.c:
+	  tagdemux: fix handling of very short files in push mode
+	  By default we'll wait for a certain amount of data before
+	  attempting typefinding. However, if the stream is fairly
+	  short, we might get EOS before we ever attempted any
+	  typefinding, so at this point we should force typefinding
+	  and output any pending data if we manage to detect the
+	  type.
+	  https://bugzilla.gnome.org//show_bug.cgi?id=768178
+
+2016-06-30 17:30:34 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst-libs/gst/tag/gsttagdemux.c:
+	  tagdemux: fix erroring out if we reach EOS without detecting type
+	  In 0.10 the source pad was a dynamic pad that was only added once
+	  the type had been detected, but in 1.x it's an always source pad,
+	  so checking whether it's still NULL won't work to detect if the
+	  type has been detected.
+	  Makes tagdemux error out when we get EOS but haven't managed to
+	  identify the format of the data after the tag.
+	  https://bugzilla.gnome.org//show_bug.cgi?id=768178
+
+2016-06-30 17:26:56 +0200  Edward Hervey <edward@centricular.com>
+
+	* gst/playback/gstparsebin.c:
+	  parsebin: Fix authors and description
+
+2016-06-30 17:26:14 +0200  Edward Hervey <edward@centricular.com>
+
+	* gst/playback/Makefile.am:
+	* gst/playback/gstplayback.c:
+	* gst/playback/gstplayback.h:
+	* gst/playback/gsturidecodebin3.c:
+	  playback: Remove uridecodebin3
+	  This was committed by mistake. The solution forward is to use the
+	  appropriate combination of urisourcebin and decodebin3
+
+2016-06-29 18:14:51 +0200  Edward Hervey <edward@centricular.com>
+
+	* configure.ac:
+	* gst/playback/Makefile.am:
+	* gst/playback/gstdecodebin3-parse.c:
+	* gst/playback/gstdecodebin3.c:
+	* gst/playback/gstparsebin.c:
+	* gst/playback/gstplayback.c:
+	* gst/playback/gstplayback.h:
+	* gst/playback/gstplaybin3.c:
+	* gst/playback/gsturidecodebin3.c:
+	* gst/playback/gsturisourcebin.c:
+	* tests/examples/Makefile.am:
+	* tests/examples/decodebin_next/.gitignore:
+	* tests/examples/decodebin_next/Makefile.am:
+	* tests/examples/decodebin_next/decodebin3.c:
+	* tests/examples/decodebin_next/playbin-test.c:
+	  playback: New elements
+	  With contributions from Jan Schmidt <jan@centricular.com>
+	  * decodebin3 and playbin3 have the same purpose as the decodebin and
+	  playbin elements, except make usage of more 1.x features and the new
+	  GstStream API. This allows them to be more memory/cpu efficient.
+	  * parsebin is a new element that demuxers/depayloads/parses an incoming
+	  stream and exposes elementary streams. It is used by decodebin3.
+	  It also automatically creates GstStream and GstStreamCollection for
+	  elements that don't natively create them and sends the corresponding
+	  events and messages
+	  * Any application using playbin can use playbin3 by setting the env
+	  variable USE_PLAYBIN3=1 without reconfiguration/recompilation.
+
+2016-06-29 18:14:51 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/audio/audio-channels.c:
+	* gst/audioconvert/gstaudioconvert.c:
+	  audioconvert: Handle fallback channel mask for mono correctly
+	  It's 0 and no mask should be set for mono at all.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=757472
+
+2016-06-27 20:53:37 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/playback/gstplaysink.c:
+	  playsink: Don't send another step event to the audio-sink if we got step-done from there
+	  Otherwise we would end up with a deadlock as the audio-sink emits step-done
+	  from its streaming thread.
+
+2016-06-27 20:49:38 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/playback/gstplaysink.c:
+	  playsink: Force STEP events on the video-sink for GST_FORMAT_BUFFERS
+	  It does not make much sense for audio sinks.
+
+2016-06-24 01:56:11 +0530  Nirbheek Chauhan <nirbheek@centricular.com>
+
+	* configure.ac:
+	  configure: Need to add -DGST_STATIC_COMPILATION when building only statically
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767463
+
+2016-06-23 10:22:35 +0100  Vincent Penquerc'h <vincent.penquerch@collabora.co.uk>
+
+	* ext/ogg/gstoggdemux.c:
+	  oggdemux: demote an expected error to debug
+	  Dropping a buffer because we have a seek pending is normal,
+	  and will now happen when we trigger a seek while going through
+	  the packets in a page. So this should not be an error.
+
+2016-06-22 16:02:37 +0200  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/video/video-converter.c:
+	* gst-libs/gst/video/video-resampler.c:
+	* gst-libs/gst/video/video-resampler.h:
+	* gst-libs/gst/video/video-scaler.c:
+	  video-converter: fix interlaced scaling some more
+	  Fix problem with the line cache where it would forget the first line in
+	  the cache in some cases.
+	  Keep as much backlog as we have taps. This generally works better and we
+	  could do even better by calculating the overlap in all taps.
+	  Allocated enough lines for the line cache.
+	  Use only half the number of taps for the interlaced lines because we
+	  only have half the number of lines.
+	  The pixel shift should be relative to the new output pixel size so scale
+	  it.
+	  Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=767921
+
+2016-06-21 14:53:36 -0400  Nicolas Dufresne <nicolas.dufresne@collabora.com>
+
+	* docs/plugins/gst-plugins-base-plugins-docs.sgml:
+	  plugin-doc: Minor re-order
+
+2016-06-21 14:40:17 -0400  Nicolas Dufresne <nicolas.dufresne@collabora.com>
+
+	* docs/plugins/Makefile.am:
+	* docs/plugins/gst-plugins-base-plugins-sections.txt:
+	* docs/plugins/gst-plugins-base-plugins.signals:
+	* docs/plugins/inspect/plugin-pango.xml:
+	* docs/plugins/inspect/plugin-videoconvert.xml:
+	* docs/plugins/inspect/plugin-videoscale.xml:
+	* docs/plugins/inspect/plugin-videotestsrc.xml:
+	  Automatic update of plugins doc files
+
+2016-06-21 18:04:23 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* tests/check/libs/discoverer.c:
+	  tests: discoverer: handle missing ogg/codec plugins gracefully
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767859
+
+2016-06-21 11:45:49 -0400  Nicolas Dufresne <nicolas.dufresne@collabora.com>
+
+	* common:
+	  Automatic update of common submodule
+	  From ac2f647 to f363b32
+
+2016-06-20 12:42:28 +0100  Vincent Penquerc'h <vincent.penquerch@collabora.co.uk>
+
+	* ext/opus/gstopusdec.c:
+	* ext/opus/gstopusdec.h:
+	  opusdec: handle missing buffers with no duration
+	  If buffer duration is missing, it is parsed from the packet data.
+	  This is not foolproof, since Opus can change durations on the
+	  fly.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767826
+
+2016-06-17 15:11:20 +0200  Michael Olbrich <m.olbrich@pengutronix.de>
+
+	* gst-libs/gst/tag/gsttagdemux.c:
+	  tagdemux: preserve duration when skipping a tag at the beginning of a buffer
+	  gst_buffer_copy_region() does not copy the duration if it doesn't start
+	  with the first byte. We just skip the tag here, so the duration is still
+	  valid.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767791
+
+2016-06-21 10:24:15 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/pbutils/gstdiscoverer.c:
+	* tests/check/libs/discoverer.c:
+	  discoverer: Only allow serializing OK discoverer infos to GVariants
+	  They will be incomplete otherwise and we can't generate the full serialized
+	  information, and instead will crash somewhere on the way.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767859
+
+2016-04-14 14:02:27 +0100  Vincent Penquerc'h <vincent.penquerch@collabora.co.uk>
+
+	* ext/ogg/gstoggdemux.c:
+	  oggdemux: fix audio glitches with low bitrate vorbis
+	  A low bitrate stream which can pack more than 2 seconds of audio
+	  in a page would cause the stream's position to be updated not
+	  often enough, and would trigger a spurious "jump" via a GAP
+	  event. Instead, we update the stream position after calculating
+	  the new overall segment position.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=764966
+
+2016-06-16 10:55:52 +0100  Mikhail Fludkov <misha@pexip.com>
+
+	* tests/check/elements/opus.c:
+	  opusdec: test for PLC timestamp when FEC is enabled.
+
+2016-04-05 12:41:45 +0200  Mikhail Fludkov <misha@pexip.com>
+
+	* gst-libs/gst/audio/gstaudiodecoder.c:
+	* tests/check/libs/audiodecoder.c:
+	  audiodecoder: fix invalid timestamps when PLC and delay
+	  Elements inherited from GstAudioDecoder, supporting PLC and introducing
+	  delay produce invalid timestamps. Good example is opusdec with in-band FEC
+	  enabled. After receiving GAP event it delays the audio concealment until
+	  the next buffer arrives. The next buffer will have DISCONT flag set which
+	  will make GstAudioDecoder to reset it's internal state, thus forgetting
+	  the timestamp of GAP event. As a result the concealed audio will have the
+	  timestamp of the next buffer (with DISCONT flag) but not the timestamp
+	  from the event.
+
+2016-06-11 17:11:30 +0200  Paulo Neves <pneves@airborneprojects.com>
+
+	* gst-libs/gst/tag/gstexiftag.c:
+	* tests/check/libs/tag.c:
+	  exiftag: Increase serialized geo precision
+	  The serialization of double typed geographical
+	  coordinates to DMS system supported by the exif
+	  standards was previously truncated without need.
+	  The previous code truncated the seconds part of
+	  the coordinate to a fraction with denominator
+	  equal to 1 causing a bug on the deserialization
+	  when the test for the coordinate to be serialized
+	  was more precise.
+	  This patch applies a 10E6 multiplier to the numerator
+	  equal to the denominator of the rational number.
+	  Eg. Latitude = 89.5688643 Serialization
+	  DMS Old code = 89/1 deg, 34/1 min, 7/1 sec
+	  DMS New code = 89/1 deg, 34/1 min, 79114800UL/10000000UL
+	  Deserialization
+	  DMS Old code = 89.5686111111
+	  DMS New code = 89.5688643
+	  The new test tries to serialize a higher precision
+	  coordinate.
+	  The types of the coordinates are also guint32 instead
+	  of gint like previously. guint32 is the type of the
+	  fraction components in the exif.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767537
+
+2016-06-10 22:36:32 -0400  Thomas Jones <thomas.jones@utoronto.ca>
+
+	* gst-libs/gst/pbutils/gstaudiovisualizer.c:
+	  audiovisualizer: Fix calculations for bytes<->samples conversions
+	  Use bpf instead of channels * sizeof(gint16).
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767505
+
+2016-06-10 14:04:36 -0400  Thomas Jones <thomas.jones@utoronto.ca>
+
+	* gst-libs/gst/pbutils/gstaudiovisualizer.c:
+	  audiovisualizer: Use GST_BUFFER_PTS() instead of GST_BUFFER_TIMESTAMP()
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767506
+
+2016-06-10 22:50:41 -0400  Thomas Jones <thomas.jones@utoronto.ca>
+
+	* gst-libs/gst/pbutils/gstaudiovisualizer.c:
+	  audiovisualizer: fix timestamp calculation for audio channels > 1
+	  We have to use bps*channels instead of just bps, which is exactly what bpf is for.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767507
+
+2015-04-09 19:09:17 +0200  Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
+
+	* gst-libs/gst/video/gstvideodecoder.c:
+	  videodecoder: handle buffer's flags at offset
+	  For reverse playback it is important to handle correctly the frame sync
+	  points, which is set when the input buffer doesn't have the DELTA_UNIT flag.
+	  This is handled correctly when decoder is packetized, but when it is not the
+	  frame's sync point is not copied, and the reverse playback never decodes frame
+	  batches.
+	  The current patch adds the buffer's flags to the Timestamp list, where the
+	  timestamp and duration of the input buffers are hold.
+
+2015-04-09 19:18:58 +0200  Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
+
+	* gst-libs/gst/video/gstvideodecoder.c:
+	  videodecoder: squash two message logs into one
+	  There were two consecutive log messages in gst_video_decoder_decode_frame().
+	  Given the information they provide, it is more efficient to squash them into a
+	  single one.
+
+2015-04-09 19:16:10 +0200  Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
+
+	* gst-libs/gst/video/gstvideodecoder.c:
+	  videodecoder: playback rate is in input_segment
+	  The playback rate is hold in the input_segment member variable, not in the
+	  output_segment, and the parse_gather list was never filled because of that.
+	  This patch changes the comparison with input_segment.
+
+2016-06-09 19:02:49 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/video/gstvideodecoder.c:
+	  videodecoder: Use input segment rate instead of output segment rate to decide whether the drain on keyframes
+	  The output segment is only set up after data is output, which might be far in
+	  the future for reverse playback. Also we are here interested in the state at
+	  the current *input* frame (which is the keyframe), not any possible output.
+
+2016-06-09 18:53:54 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/video/gstvideodecoder.c:
+	  videodecoder: Only drain in KEY_UNITS trick mode after a keyframe in forwards playback mode
+	  For reverse playback the same behaviour was already implemented in
+	  flush_parse().
+	  For reverse playback, chain_forward() is only used to gather frames and not
+	  for decoding, and it is actually called by the draining logic, causing an
+	  infinite recursion.
+
+2016-06-07 09:48:35 +0200  Edward Hervey <edward@centricular.com>
+
+	* gst-libs/gst/video/gstvideodecoder.c:
+	  videodecoder: Don't push late frames
+	  While it's a bit tricky to discard frames *before* decoding (because
+	  we might not be sure which data is needed or not by the decoder), we
+	  can discard them after decoding if they are too late anyway.
+	  Any following basetransform based element or similar would drop the frame too.
+
+2016-06-07 10:31:59 +0200  Edward Hervey <edward@centricular.com>
+
+	* gst-libs/gst/video/gstvideodecoder.c:
+	  videodecoder: Avoid recursive drain/flush calls
+	  _chain_forward() can also be called with reverse playback. Blindly
+	  calling drain_out() on DISCONT buffers would end up in a recursive
+	  call.
+
+2016-06-04 09:51:17 +0200  Edward Hervey <edward@centricular.com>
+
+	* gst-libs/gst/video/gstvideodecoder.c:
+	  videodecoder: Drain out keyframes in TRICK_MODE_KEY_UNITS
+	  When asked to just decode keyframe, if we got a keyframe drain out
+	  the decoder straight away.
+	  This avoids having to wait for the next frame and reduces delay even
+	  more.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767232
+
+2016-06-04 09:49:00 +0200  Edward Hervey <edward@centricular.com>
+
+	* gst-libs/gst/video/gstvideodecoder.c:
+	  videodecoder: Drain decoder on DISCONT buffers
+	  This ensures the decoder is properly drained out when receiving a
+	  DISCONT buffer. The optimal way of doing this would have been to
+	  receive a GAP event before hand but it is not always possible.
+	  Fixes big delays with some decoders (ex gst-libav) that will not
+	  drain out data when only decoding keyframes.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767232
+
+2016-06-01 11:02:12 +0200  Michael Olbrich <m.olbrich@pengutronix.de>
+
+	* gst-libs/gst/tag/gsttagdemux.c:
+	  tagdemux: preserve timestamp when skipping a tag at the beginning of a buffer
+	  gst_buffer_copy_region() does not copy the timestamp if it doesn't start
+	  with the first byte. We just skip the tag here, so the timestamp is still
+	  valid.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767173
+
 2016-05-10 13:56:13 +0200  Stian Selnes <stian@pexip.com>
 
 	* gst-libs/gst/video/video-color.c:
@@ -346,6 +1701,100 @@
 	  actual table causing IS_UNKNOWN() to sometimes fail.
 	  https://bugzilla.gnome.org/show_bug.cgi?id=767163
 
+2016-06-02 13:07:01 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* ext/opus/gstopusenc.c:
+	* gst/playback/gstsubtitleoverlay.c:
+	  opusenc, subtitleoverlay: use MAY_BE_LEAKED flag
+	  Flag caps that are cached locally and will never be freed.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767155
+
+2016-06-01 16:56:13 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/playback/gstdecodebin2.c:
+	  decodebin: Create a new decode element with the parser/convert capsfilter if there is a multiqueue after the parser
+	  https://bugzilla.gnome.org/show_bug.cgi?id=767102
+
+2016-05-23 15:11:53 +0200  Edward Hervey <edward@centricular.com>
+
+	* gst-libs/gst/video/gstvideodecoder.c:
+	  videodecoder: Make sure the DISCONT flag is set on the outgoing buffer
+	  The base class was setting the DISCONT flag before checking whether the buffer
+	  would be in segment or not.
+	  Fix issues with DISCONT flags not being properly propagated downstream when
+	  decoders buffers were out of segment.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=766800
+
+2016-06-01 15:31:52 +0200  Joan Pau Beltran <joanpau.beltran@socib.cat>
+
+	* docs/design/part-mediatype-video-raw.txt:
+	  docs: design: add IYU2 raw video format description
+	  https://bugzilla.gnome.org/show_bug.cgi?id=763026
+
+2016-06-01 12:36:38 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* ext/pango/gstbasetextoverlay.c:
+	  textoverlay: enable shaded background drawing for new IYU2 format
+
+2016-05-30 16:40:26 +0200  Joan Pau Beltran <joanpau.beltran@socib.cat>
+
+	* gst-libs/gst/video/video-converter.c:
+	* gst-libs/gst/video/video-format.c:
+	* gst-libs/gst/video/video-format.h:
+	* gst-libs/gst/video/video-info.c:
+	* gst-libs/gst/video/video-scaler.c:
+	* tests/check/libs/video.c:
+	  video: add IYU2 format
+	  This existed in 0.10 and is needed by dc1394src.
+	  IYU2 format is a YUV fully-sampled packed format similar to v308
+	  but with different component order (U-Y-V instead of Y-U-V).
+	  http://www.fourcc.org/yuv.php#IYU2
+	  https://bugzilla.gnome.org/show_bug.cgi?id=763026#c5
+
+2016-03-17 23:47:48 +0530  Nirbheek Chauhan <nirbheek.chauhan@gmail.com>
+
+	* ext/libvisual/visual.c:
+	  libvisual: Factor out endian-order RGB formats
+	  MSVC seems to ignore preprocessor conditionals inside static
+	  pad templates. Also remove unnecessary quotes inside caps strings.
+
+2016-05-24 00:44:21 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst-libs/gst/allocators/Makefile.am:
+	* gst-libs/gst/app/Makefile.am:
+	* gst-libs/gst/audio/Makefile.am:
+	* gst-libs/gst/fft/Makefile.am:
+	* gst-libs/gst/pbutils/Makefile.am:
+	* gst-libs/gst/riff/Makefile.am:
+	* gst-libs/gst/rtp/Makefile.am:
+	* gst-libs/gst/rtsp/Makefile.am:
+	* gst-libs/gst/sdp/Makefile.am:
+	* gst-libs/gst/tag/Makefile.am:
+	* gst-libs/gst/video/Makefile.am:
+	  g-i: pass compiler env to g-ir-scanner
+	  It's what introspection.mak does as well. Should
+	  fix spurious build failures on gnome-continuous.
+
+2016-05-23 19:28:39 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* ext/opus/gstopusdec.c:
+	* ext/opus/gstopusenc.c:
+	  opus: use default error messages in some more cases
+
+2016-05-23 15:35:39 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* ext/opus/gstopusdec.c:
+	  opusdec: use default error message strings in more cases
+	  Details should go into the debug message. We should probably
+	  make up new codes for encoder/decoder lib init failures too.
+
+2016-05-19 12:26:05 -0400  Olivier Crête <olivier.crete@collabora.com>
+
+	* ext/opus/gstopusdec.c:
+	* ext/opus/gstopusenc.c:
+	  opus: Post error message on GST_FLOW_ERROR
+	  https://bugzilla.gnome.org/show_bug.cgi?id=766265
+
 2016-05-14 14:41:28 +0200  Olivier Crête <olivier.crete@collabora.com>
 
 	* ext/opus/gstopusdec.c:
@@ -374,37 +1823,168 @@
 	  Fix a leak with the 'test_suburi_error_wrongproto' test.
 	  https://bugzilla.gnome.org/show_bug.cgi?id=766515
 
+2016-05-16 09:52:35 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* tests/check/elements/playbin.c:
+	  tests: playbin: add test for new "element-setup" signal
+	  https://bugzilla.gnome.org/show_bug.cgi?id=578933
+
+2016-05-14 11:28:01 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst/playback/gstplaybin2.c:
+	  playbin: add "element-setup" signal
+	  Allows configuration of plugged elements.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=578933
+
+2016-05-15 14:43:11 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* Makefile.am:
+	* gst-libs/gst/app/.gitignore:
+	* gst-libs/gst/app/gstapp-marshal.list:
+	  app: remove marshaller files from git
+
+2016-05-15 14:37:41 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst-libs/gst/app/Makefile.am:
+	* gst-libs/gst/app/gstappsink.c:
+	* gst-libs/gst/app/gstappsrc.c:
+	  app: use generic marshallers
+
+2016-05-15 12:01:17 +0200  Edward Hervey <bilboed@bilboed.com>
+
+	* ext/ogg/gstoggdemux.c:
+	  oggdemux: Reset keyframe_granule when needed
+	  This avoids ending up with bogus values when doing flushing seeks
+	  in push-mode.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=766467
+
+2016-05-15 13:31:03 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* docs/plugins/gst-plugins-base-plugins.args:
+	* docs/plugins/inspect/plugin-adder.xml:
+	* docs/plugins/inspect/plugin-alsa.xml:
+	* docs/plugins/inspect/plugin-app.xml:
+	* docs/plugins/inspect/plugin-audioconvert.xml:
+	* docs/plugins/inspect/plugin-audiorate.xml:
+	* docs/plugins/inspect/plugin-audioresample.xml:
+	* docs/plugins/inspect/plugin-audiotestsrc.xml:
+	* docs/plugins/inspect/plugin-cdparanoia.xml:
+	* docs/plugins/inspect/plugin-encoding.xml:
+	* docs/plugins/inspect/plugin-gio.xml:
+	* docs/plugins/inspect/plugin-libvisual.xml:
+	* docs/plugins/inspect/plugin-ogg.xml:
+	* docs/plugins/inspect/plugin-opus.xml:
+	* docs/plugins/inspect/plugin-pango.xml:
+	* docs/plugins/inspect/plugin-playback.xml:
+	* docs/plugins/inspect/plugin-subparse.xml:
+	* docs/plugins/inspect/plugin-tcp.xml:
+	* docs/plugins/inspect/plugin-theora.xml:
+	* docs/plugins/inspect/plugin-typefindfunctions.xml:
+	* docs/plugins/inspect/plugin-videoconvert.xml:
+	* docs/plugins/inspect/plugin-videorate.xml:
+	* docs/plugins/inspect/plugin-videoscale.xml:
+	* docs/plugins/inspect/plugin-videotestsrc.xml:
+	* docs/plugins/inspect/plugin-volume.xml:
+	* docs/plugins/inspect/plugin-vorbis.xml:
+	* docs/plugins/inspect/plugin-ximagesink.xml:
+	* docs/plugins/inspect/plugin-xvimagesink.xml:
+	  docs: Update for git master
+
+2016-05-14 15:43:24 +0300  Matthew Waters <matthew@centricular.com>
+
+	* gst-libs/gst/video/gstvideoaffinetransformationmeta.h:
+	  video/affinetransformationmeta: define the coordinate space used
+	  Based on the expected output from the already existing usage by androidmedia
+	  and the opengl plugins.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=764667
+
+2015-12-17 19:38:33 +0000  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst-libs/gst/pbutils/descriptions.c:
+	  pbutils: add description for WebVTT
+
+2015-09-30 17:55:22 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* tests/check/Makefile.am:
+	* tests/check/elements/playsink.c:
+	  tests: playsink: add minimal test for playsink element
+	  Attempt to reproduce leak.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=755867
+
+2016-05-10 12:17:34 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* tests/check/elements/vorbistag.c:
+	  vorbistag: fix buffer leaks in tests
+	  It internally uses gst_check_chain_func() so we
+	  should call gst_check_drop_buffers() when tearing down tests to free
+	  the buffers which have been exchanged through the pipeline.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=766226
+
+2016-05-10 12:17:34 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* tests/check/elements/appsrc.c:
+	  appsrc: fix buffer leaks in tests
+	  It internally uses gst_check_chain_func() so we
+	  should call gst_check_drop_buffers() when tearing down tests to free
+	  the buffers which have been exchanged through the pipeline.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=766226
+
+2016-05-10 12:17:34 +0200  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* tests/check/elements/audiorate.c:
+	  audiorate: fix buffer leaks in tests
+	  It internally uses gst_check_chain_func() so we
+	  should call gst_check_drop_buffers() when tearing down tests to free
+	  the buffers which have been exchanged through the pipeline.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=766226
+
 2016-05-10 21:34:53 +0900  Hyunjun Ko <zzoon@igalia.com>
 
 	* gst-libs/gst/sdp/gstsdpmessage.c:
 	  sdp: parse sdp attributes in case that sdp message doesn't contain mikey message
 	  https://bugzilla.gnome.org/show_bug.cgi?id=766204
 
-2016-04-29 11:06:49 +0300  Sebastian Dröge <sebastian@centricular.com>
+2016-05-10 16:44:04 +0300  Sebastian Dröge <sebastian@centricular.com>
 
-	* gst-libs/gst/pbutils/encoding-profile.c:
-	  encoding-profile: Fix caps memory leak
+	* docs/libs/gst-plugins-base-libs-sections.txt:
+	* gst-libs/gst/app/gstappsrc.c:
+	* gst-libs/gst/app/gstappsrc.h:
+	* win32/common/libgstapp.def:
+	  appsrc: Add duration property for providing a duration in TIME format
+	  https://bugzilla.gnome.org/show_bug.cgi?id=766229
 
-2016-04-28 11:18:23 +0300  Sebastian Dröge <sebastian@centricular.com>
+2016-05-10 10:01:12 +0300  Sebastian Dröge <sebastian@centricular.com>
 
-	* gst-libs/gst/pbutils/encoding-profile.c:
-	  encoding-profile: Fail to create encoding profile from discoverer info if no streams could be added
-	  https://bugzilla.gnome.org/show_bug.cgi?id=765708
+	* gst-libs/gst/video/gstvideodecoder.h:
+	* gst-libs/gst/video/gstvideoencoder.h:
+	  videodecoder/encoder: Correct GST_IS_*CODER_CLASS macros
+	  They are currently not used, but would result in a compiler error due to wrong
+	  variable name usage.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=766203
 
-2016-04-28 11:21:47 +0300  Sebastian Dröge <sebastian@centricular.com>
+2016-05-05 13:16:57 +0300  Sebastian Dröge <sebastian@centricular.com>
 
-	* gst-libs/gst/pbutils/encoding-profile.c:
-	  encoding-profile: Recurse into nested container profiles and only add the final audio/video streams
-	  If we e.g. have AVI with DV container with video/audio inside the DV
-	  container, we can't handle this at this point with an encoding profile.
-	  Instead of erroring out, flatten the container hierarchy.
-	  https://bugzilla.gnome.org/show_bug.cgi?id=765708
+	* gst/tcp/gstmultihandlesink.c:
+	  multihandlesink: Warn if trying to change the state from the streaming thread
+	  Instead of silently returning GST_STATE_CHANGE_FAILURE.
 
-2016-04-28 11:15:53 +0300  Sebastian Dröge <sebastian@centricular.com>
+2016-05-04 11:33:50 +1000  Alessandro Decina <alessandro.d@gmail.com>
 
-	* gst-libs/gst/pbutils/encoding-profile.c:
-	  encoding-profile: Move adding of each stream to a helper function
-	  https://bugzilla.gnome.org/show_bug.cgi?id=765708
+	* gst/playback/gstdecodebin2.c:
+	  decodebin: an element can negotiate before we block it
+	  When we initialize an element in decodebin, we 1) set it to PAUSED and
+	  push sticky events on its sinkpad to trigger negotiation 2) block its
+	  src pad(s) to detect CAPS events. We can't block before 1) as that
+	  would lead to a deadlock.
+	  It's possible (and common) tho that an element configures its srcpad
+	  during 1) and before 2). Therefore before this change we would
+	  typically block and expose an element's pad only once the element
+	  output its first buffer, triggering sticky events to be resent. One
+	  consequence of this behaviour is that it sometimes broke
+	  renegotiation.
+	  With this change now we consider a pad ready to be exposed when it's
+	  ->blocked or has fixed caps (which were set before we could block it).
+	  https://bugzilla.gnome.org/show_bug.cgi?id=765456
 
 2016-05-02 14:21:55 -0300  Thiago Santos <thiagoss@osg.samsung.com>
 
@@ -443,6 +2023,52 @@
 	* tests/check/elements/opus.c:
 	  tests: opus: remove apparently useless macro in tests
 
+2016-04-29 11:06:49 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/pbutils/encoding-profile.c:
+	  encoding-profile: Fix caps memory leak
+
+2016-04-28 11:21:47 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/pbutils/encoding-profile.c:
+	  encoding-profile: Recurse into nested container profiles and only add the final audio/video streams
+	  If we e.g. have AVI with DV container with video/audio inside the DV
+	  container, we can't handle this at this point with an encoding profile.
+	  Instead of erroring out, flatten the container hierarchy.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=765708
+
+2016-04-28 11:18:23 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/pbutils/encoding-profile.c:
+	  encoding-profile: Fail to create encoding profile from discoverer info if no streams could be added
+	  https://bugzilla.gnome.org/show_bug.cgi?id=765708
+
+2016-04-28 11:15:53 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/pbutils/encoding-profile.c:
+	  encoding-profile: Move adding of each stream to a helper function
+	  https://bugzilla.gnome.org/show_bug.cgi?id=765708
+
+2015-08-21 10:40:33 +0200  Aurélien Zanelli <aurelien.zanelli@darkosphere.fr>
+
+	* gst-libs/gst/tag/gstexiftag.c:
+	* tests/check/libs/tag.c:
+	  exiftag: handle GST_TAG_CAPTURING_FOCAL_LENGTH_35_MM tag
+	  This tag match the EXIF_TAG_FOCAL_LENGTH_IN_35_MM_FILM exif tag and is
+	  stored on a short. Hence there is a precision loss compared to the
+	  GstTag which is a double value.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=753930
+
+2015-08-21 10:39:36 +0200  Aurélien Zanelli <aurelien.zanelli@darkosphere.fr>
+
+	* gst-libs/gst/tag/tag.h:
+	* gst-libs/gst/tag/tags.c:
+	  tag: add GST_TAG_CAPTURING_FOCAL_LENGTH_35_MM tag
+	  It is the 35 mm equivalent focal length of the lens, mainly used in
+	  photography. Tag value is stored in a double value to be consistent with
+	  GST_TAG_CAPTURING_FOCAL_LENGTH.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=753930
+
 2016-04-28 09:59:25 +0300  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
 
 	* ext/opus/gstopusdec.c:
@@ -450,6 +2076,29 @@
 	  The caps returned by gst_pad_get_allowed_caps() was leaked.
 	  https://bugzilla.gnome.org/show_bug.cgi?id=765706
 
+2016-04-27 18:08:46 +0900  Kipp Cannon <kipp.cannon@ligo.org>
+
+	* gst-libs/gst/audio/audio.c:
+	* gst-libs/gst/audio/audio.h:
+	  audio: Add const to segment parameter of gst_audio_buffer_clip()
+	  e.g., allows this to be used with the reference retrieved by
+	  gst_event_parse_segment().
+	  https://bugzilla.gnome.org/show_bug.cgi?id=765663
+
+2016-04-21 08:45:40 +0200  Jakub Adam <jakub.adam@ktknet.cz>
+
+	* sys/ximage/ximagesink.c:
+	  ximagesink: generate reconfigure on window handle change
+	  When ximagesink is given a new window handle, it should check
+	  its geometry and if the size of the new window differs from
+	  the previous one, create reconfigure event in order to get
+	  a chance to negotiate a more suitable image resolution with
+	  the upstream elements.
+	  We can't rely on receiving Expose or ConfigureNotify from
+	  the X server for the newly assigned window, which would also
+	  generate reconfigure.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=765424
+
 2016-04-25 17:16:04 +0300  Sebastian Dröge <sebastian@centricular.com>
 
 	* gst/encoding/gstsmartencoder.c:
@@ -458,13 +2107,6 @@
 	  event before EOS
 	  https://bugzilla.gnome.org/show_bug.cgi?id=765541
 
-2016-04-25 16:47:00 +0300  Sebastian Dröge <sebastian@centricular.com>
-
-	* gst-libs/gst/pbutils/codec-utils.c:
-	  codec-utils: H264 level idc 0 is not valid
-	  Don't put level=0 into the caps, it confuses other elements.
-	  https://bugzilla.gnome.org/show_bug.cgi?id=765538
-
 2016-04-25 16:48:36 +0300  Sebastian Dröge <sebastian@centricular.com>
 
 	* gst-libs/gst/pbutils/codec-utils.c:
@@ -472,6 +2114,13 @@
 	  Don't put level=0 into the caps, it confuses other elements.
 	  https://bugzilla.gnome.org/show_bug.cgi?id=765538
 
+2016-04-25 16:47:00 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/pbutils/codec-utils.c:
+	  codec-utils: H264 level idc 0 is not valid
+	  Don't put level=0 into the caps, it confuses other elements.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=765538
+
 2016-04-25 16:06:39 +0300  Sebastian Dröge <sebastian@centricular.com>
 
 	* gst-libs/gst/pbutils/encoding-profile.c:
@@ -487,96 +2136,15 @@
 	  encoding-profile: Don't put G_BEGIN_DECLS around #include statements
 	  It should only be around our own declarations.
 
-=== release 1.8.1 ===
+2016-04-22 15:07:10 +0200  Wim Taymans <wtaymans@redhat.com>
 
-2016-04-20 18:15:39 +0300  Sebastian Dröge <sebastian@centricular.com>
-
-	* ChangeLog:
-	* NEWS:
-	* RELEASE:
-	* configure.ac:
-	* docs/plugins/inspect/plugin-adder.xml:
-	* docs/plugins/inspect/plugin-alsa.xml:
-	* docs/plugins/inspect/plugin-app.xml:
-	* docs/plugins/inspect/plugin-audioconvert.xml:
-	* docs/plugins/inspect/plugin-audiorate.xml:
-	* docs/plugins/inspect/plugin-audioresample.xml:
-	* docs/plugins/inspect/plugin-audiotestsrc.xml:
-	* docs/plugins/inspect/plugin-cdparanoia.xml:
-	* docs/plugins/inspect/plugin-encoding.xml:
-	* docs/plugins/inspect/plugin-gio.xml:
-	* docs/plugins/inspect/plugin-libvisual.xml:
-	* docs/plugins/inspect/plugin-ogg.xml:
-	* docs/plugins/inspect/plugin-opus.xml:
-	* docs/plugins/inspect/plugin-pango.xml:
-	* docs/plugins/inspect/plugin-playback.xml:
-	* docs/plugins/inspect/plugin-subparse.xml:
-	* docs/plugins/inspect/plugin-tcp.xml:
-	* docs/plugins/inspect/plugin-theora.xml:
-	* docs/plugins/inspect/plugin-typefindfunctions.xml:
-	* docs/plugins/inspect/plugin-videoconvert.xml:
-	* docs/plugins/inspect/plugin-videorate.xml:
-	* docs/plugins/inspect/plugin-videoscale.xml:
-	* docs/plugins/inspect/plugin-videotestsrc.xml:
-	* docs/plugins/inspect/plugin-volume.xml:
-	* docs/plugins/inspect/plugin-vorbis.xml:
-	* docs/plugins/inspect/plugin-ximagesink.xml:
-	* docs/plugins/inspect/plugin-xvimagesink.xml:
-	* gst-plugins-base.doap:
-	* win32/common/_stdint.h:
-	* win32/common/config.h:
-	  Release 1.8.1
-
-2016-04-20 18:02:22 +0300  Sebastian Dröge <sebastian@centricular.com>
-
-	* po/af.po:
-	* po/az.po:
-	* po/bg.po:
-	* po/ca.po:
-	* po/cs.po:
-	* po/de.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/nb.po:
-	* po/nl.po:
-	* po/or.po:
-	* po/pl.po:
-	* po/pt_BR.po:
-	* po/ro.po:
-	* po/ru.po:
-	* po/sk.po:
-	* po/sl.po:
-	* po/sq.po:
-	* po/sr.po:
-	* po/sv.po:
-	* po/tr.po:
-	* po/uk.po:
-	* po/vi.po:
-	* po/zh_CN.po:
-	  Update .po files
-
-2016-04-15 17:48:26 +0100  Tim-Philipp Müller <tim@centricular.com>
-
-	* win32/common/libgstsdp.def:
-	  win32: update .def for new API
-
-2016-04-20 15:30:04 +0300  Sebastian Dröge <sebastian@centricular.com>
-
-	* po/da.po:
-	  po: Update translations
+	* gst-libs/gst/video/video-converter.c:
+	* gst-libs/gst/video/video-orc-dist.c:
+	* gst-libs/gst/video/video-orc-dist.h:
+	* gst-libs/gst/video/video-orc.orc:
+	  video-converter: add more fastpaths for I420 -> RGB
+	  Use the I420->BGRA and a new I420->ARGB to speed up any I420 to RGB
+	  operation.
 
 2016-04-19 17:36:20 +0200  Josep Torra <n770galaxy@gmail.com>
 
@@ -585,6 +2153,42 @@
 	  sdp: update since markers to 1.8.1 for some new APIs
 	  As we decided to backport some fixes we update the since markers.
 
+2016-04-17 16:21:32 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* tests/check/pipelines/vorbisenc.c:
+	  tests: vorbisenc: fix with CK_FORK=no
+
+2016-04-12 16:32:20 +0300  Vivia Nikolaidou <vivia@toolsonair.com>
+
+	* gst/playback/gstdecodebin2.c:
+	  decodebin: Always add a multiqueue in single-stream use-buffering pipelines
+	  If we are configured to use buffering and there is no demuxer in the chain, we
+	  still want a multiqueue, otherwise we will ignore the use-buffering property.
+	  In that case, we will insert a multiqueue after the parser or decoder - not
+	  elsewhere, otherwise we won't have timestamps.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=764948
+
+2016-04-18 17:39:02 +0300  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* tools/gst-play.c:
+	  gst-play: call gst_deinit()
+	  So we can use gst-play to track memory leaks.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=765216
+
+2016-04-15 17:48:26 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* win32/common/libgstsdp.def:
+	  win32: update .def for new API
+
+2016-04-16 02:11:59 +1000  Jan Schmidt <jan@centricular.com>
+
+	* gst-libs/gst/audio/gstaudioringbuffer.c:
+	  Revert "audioringbuffer: start ringbuffer if needed upon commit"
+	  This reverts commit 13ee94ef1091f8a8a90dbd395b39876c26c5188e.
+	  Causes audio glitches at startup by starting to output segments
+	  from the ringbuffer before it has been filled / fully prerolled.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=657076
+
 2016-04-15 00:18:50 -0700  Aleix Conchillo Flaqué <aconchillo@gmail.com>
 
 	* gst-libs/gst/sdp/gstsdpmessage.c:
@@ -602,14 +2206,19 @@
 	* gst-libs/gst/sdp/gstsdpmessage.c:
 	  mikey: add new function gst_mikey_message_to_caps
 
-2016-04-16 02:11:59 +1000  Jan Schmidt <jan@centricular.com>
+2016-04-15 12:54:32 +0100  Vincent Penquerc'h <vincent.penquerch@collabora.co.uk>
 
-	* gst-libs/gst/audio/gstaudioringbuffer.c:
-	  Revert "audioringbuffer: start ringbuffer if needed upon commit"
-	  This reverts commit 13ee94ef1091f8a8a90dbd395b39876c26c5188e.
-	  Causes audio glitches at startup by starting to output segments
-	  from the ringbuffer before it has been filled / fully prerolled.
-	  https://bugzilla.gnome.org/show_bug.cgi?id=657076
+	* gst/subparse/gstsubparse.c:
+	  subparse: fix build with GCC 4.6.3
+	  gstsubparse.c: In function ‘parse_subrip’:
+	  gstsubparse.c:988:7: error: ignoring return value of ‘strtol’, declared with attribute warn_unused_result [-Werror=unused-result]
+	  cc1: all warnings being treated as errors
+	  https://bugzilla.gnome.org/show_bug.cgi?id=765042
+
+2016-04-15 13:08:38 +0200  Josep Torra <n770galaxy@gmail.com>
+
+	* tests/icles/.gitignore:
+	  .gitignore: add test-resample binary
 
 2016-04-14 17:26:54 -0700  Aleix Conchillo Flaqué <aconchillo@gmail.com>
 
@@ -621,6 +2230,112 @@
 	  both are given srtp parametres will be preferred.
 	  https://bugzilla.gnome.org/show_bug.cgi?id=765027
 
+2016-04-14 10:00:06 +0100  Julien Isorce <j.isorce@samsung.com>
+
+	* README:
+	* common:
+	  Automatic update of common submodule
+	  From 6f2d209 to ac2f647
+
+2016-04-13 10:07:33 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/video/gstvideometa.c:
+	* gst-libs/gst/video/video-multiview.c:
+	* gst-libs/gst/video/video-overlay-composition.c:
+	  videometa: Initialize all fields of all metas with default values
+	  The metas are not allocated with all fields initialized to zeroes.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=764902
+
+2016-04-11 15:28:00 +0000  Arjen Veenhuizen <arjen.veenhuizen@tno.nl>
+
+	* gst-libs/gst/video/gstvideometa.c:
+	  videometa: Explicitly initialize GstVideoCropMeta on init
+	  It is not allocated with all fields initialized to 0.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=764902
+
+2016-03-21 16:34:37 +0100  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* ext/alsa/gstalsa.c:
+	  alsa: properly convert position-less channels from ALSA
+	  The only way for ALSA to expose a position-less multi channels is to
+	  return an array full of SND_CHMAP_MONO. Converting this to a
+	  GST_AUDIO_CHANNEL_POSITION_MONO array would be invalid as
+	  GST_AUDIO_CHANNEL_POSITION_MONO is meant to be used only with one
+	  channel.
+	  Fix this by using GST_AUDIO_CHANNEL_POSITION_NONE which is meant to be
+	  used for position-less channels.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=763799
+
+2016-03-21 16:29:39 +0100  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst-libs/gst/audio/gstaudioringbuffer.c:
+	  audioringbuffer: don't attempt to reorder position-less channels
+	  As said in its doc GST_AUDIO_CHANNEL_POSITION_NONE is meant to be used
+	  for "position-less channels, e.g. from a sound card that records 1024
+	  channels; mutually exclusive with any other channel position".
+	  But at the moment using such positions would raise a
+	  'g_return_if_reached' warning as gst_audio_get_channel_reorder_map()
+	  would reject it.
+	  Fix this by preventing any attempt to reorder in such case as that's not
+	  what we want anyway.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=763799
+
+2016-03-21 07:26:50 -0400  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* gst-libs/gst/audio/gstaudioringbuffer.c:
+	  audio: add debug output if channels mapping does not match
+	  https://bugzilla.gnome.org/show_bug.cgi?id=763985
+
+2016-03-21 11:58:13 +0100  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* ext/alsa/gstalsa.c:
+	  alsa: add some debugging output to alsa_detect_channels_mapping()
+	  https://bugzilla.gnome.org/show_bug.cgi?id=763985
+
+2016-03-21 11:46:45 +0100  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* docs/libs/gst-plugins-base-libs-sections.txt:
+	* gst-libs/gst/audio/audio-channels.c:
+	* gst-libs/gst/audio/audio-channels.h:
+	* win32/common/libgstaudio.def:
+	  gst-audio: add gst_audio_channel_positions_to_string()
+	  We currently don't log much about channel positions making debugging
+	  harder as it should be. This is the first step in my attempt to improve
+	  this.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=763985
+
+2016-03-21 05:09:10 -0400  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* ext/alsa/gstalsa.c:
+	* ext/alsa/gstalsa.h:
+	* ext/alsa/gstalsasink.c:
+	* ext/alsa/gstalsasrc.c:
+	  alsa: factor out alsa_detect_channels_mapping()
+	  This code was duplicated in alsasrc and alsasink.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=763985
+
+2016-03-21 05:06:18 -0400  Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
+
+	* ext/alsa/gstalsa.h:
+	  alsa: coding style fix
+	  Was using tabs instead of spaces.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=763985
+
+2016-04-12 16:34:00 +0300  Vivia Nikolaidou <vivia@ahiru.eu>
+
+	* gst-libs/gst/allocators/gstfdmemory.c:
+	* gst-libs/gst/rtp/gstrtpbasedepayload.c:
+	  fdmemory, rtpbasedepayload: Ran gst-indent
+	  https://bugzilla.gnome.org/show_bug.cgi?id=764948
+
+2016-04-12 16:25:12 +0300  Vivia Nikolaidou <vivia@ahiru.eu>
+
+	* gst/playback/gstdecodebin2.c:
+	  decodebin: Rename misleading variable is_parser_converter into is_parser
+	  In that place, the variable isn't checking whether the element is a
+	  converter, only if it is a parser.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=764948
+
 2016-04-11 11:28:09 +0200  Fabrice Bellet <fabrice@bellet.info>
 
 	* gst-libs/gst/audio/gstaudiosink.c:
@@ -632,6 +2347,735 @@
 	  g_thread_self().
 	  https://bugzilla.gnome.org/show_bug.cgi?id=764865
 
+2016-04-06 17:57:28 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* tests/check/libs/gstlibscpp.cc:
+	  tests: libscpp: test RTP/RTCP buffer init macros with C++ compiler
+
+2016-04-06 21:03:19 +1000  Jan Schmidt <jan@centricular.com>
+
+	* gst/playback/gstsubtitleoverlay.c:
+	  subtitleoverlay: Don't complain when stream-start is the first event.
+	  When blocking the subtitle pad, it's expected that stream-start
+	  is the first event, and that it can precede caps arriving on the
+	  peer pad - in fact the caps can only have arrived on the peer
+	  pad when it was pre-primed with sticky events previously.
+	  Instead, just pass the stream-start and don't block, because
+	  stream-start is sticky anyway.
+
+2016-04-06 21:00:10 +1000  Jan Schmidt <jan@centricular.com>
+
+	* gst/subparse/gstsubparse.c:
+	  subparse: WebVTT Cue identifiers are optional
+	  Don't require a cue identifier preceding the time range line
+	  when parsing WebVTT. We could also store the CueID, but it's
+	  not using anywhere, so just ignore it for now.
+
+2016-04-05 14:26:55 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* win32/common/libgstaudio.def:
+	  win32: Add new libgstaudio symbols
+
+2016-04-01 12:25:14 +0200  Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
+
+	* gst-libs/gst/audio/gstaudiodecoder.c:
+	* gst-libs/gst/audio/gstaudiodecoder.h:
+	* gst-libs/gst/audio/gstaudioencoder.c:
+	* gst-libs/gst/audio/gstaudioencoder.h:
+	  libs: audio: split allocation query caps and pad caps
+	  Since the allocation query caps contains memory size and the pad's caps
+	  contains the display size, an audio encoder or decoder might need to allocate
+	  a different buffer size than the size negotiated in the caps.
+	  This patch splits this logic distinction for audiodecoder and audioencoder.
+	  Thus the user, if needs a different allocation caps, should set it through
+	  gst_audio_{encoder,decoder}_set_allocation_cap() before calling the negotiate()
+	  vmethod. Otherwise the allocation_caps will be the same as the caps in the
+	  src pad.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=764421
+
+2016-03-31 15:31:31 +0200  Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
+
+	* gst-libs/gst/video/gstvideodecoder.c:
+	* gst-libs/gst/video/gstvideoencoder.c:
+	* gst-libs/gst/video/gstvideoutils.c:
+	* gst-libs/gst/video/gstvideoutils.h:
+	  libs: video: split allocation query caos and pad caps
+	  Since the allocation query caps contains memory size and the pad's caps
+	  contains the display size, a video encoder or decoder might need to allocate
+	  a different frame size than the size negotiated in the caps.
+	  This patch splits this logic distinction for videodecoder and videoencoder.
+	  The user if needs a different allocation caps, should set the allocation_caps
+	  in the GstVideoCodecState before calling negotiate() vmethod. Otherwise the
+	  allocation_caps will be the same as the caps set in the src pad.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=764421
+
+2016-04-04 16:39:21 +0200  Víctor Manuel Jáquez Leal <vjaquez@igalia.com>
+
+	* gst-libs/gst/audio/gstaudioencoder.c:
+	  audioencoder: fix gtk-doc comment format
+
+2016-04-02 10:37:55 +0200  Mikhail Fludkov <misha@pexip.com>
+
+	* gst-libs/gst/rtp/gstrtpbasedepayload.c:
+	* tests/check/libs/rtpbasedepayload.c:
+	  rtpbasedepayload: look at ssrc before sequence numbers
+	  Doing so prevents us dropping buffers in the rare, but possible, situations,
+	  when the stream changes SSRC and new sequence numbers does not differ
+	  much from the last sequence number from previous SSRC. For example:
+	  ssrc - 0xaaaa 101,102,103,104 ssrc - 0xbbbb 102, 103, 104, 105...
+	  In the scenario above we don't want to drop the first 3 packets of
+	  0xbbbb stream.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=764459
+
+2016-04-03 11:40:50 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/videorate/gstvideorate.c:
+	  videorate: Don't fill up the segment with duplicate buffers if drop_only==TRUE
+
+2016-04-03 11:38:28 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst/videorate/gstvideorate.c:
+	  videorate: Remove dead code
+	  We never get into this code path at all if drop_only==TRUE.
+
+2016-03-29 17:19:41 +0200  Frédéric Bertolus <frederic.bertolus@parrot.com>
+
+	* gst/videorate/gstvideorate.c:
+	  videorate: avoid useless buffer copy in drop-only mode
+	  Make writable the buffer before pushing it lead to a buffer copy. It's
+	  because a reference is keep for the previous buffer.
+	  The previous buffer reference is only need to duplicate the buffer. In
+	  drop-only mode, the previous buffer is release just after pushing the
+	  buffer so a copy is done but it's useless.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=764319
+
+2016-04-02 15:19:44 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst-libs/gst/video/video-frame.c:
+	  video: fix example code in gst_video_frame_map() docs
+	  GST_VIDEO_FRAME_PLANE_PSTRIDE() does not exist.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=764414
+
+2016-04-02 10:09:07 +0100  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst-libs/gst/pbutils/gstdiscoverer-types.c:
+	  discoverer: copy over result and seekable fields when copying a discoverer info
+	  The function gst_discoverer_info_copy doesn't copy the data members seekable
+	  and result of the source GstDiscovererInfo.
+	  In the case of copying a GstDiscovererInfo for later use, the seekbale will be
+	  undefined, which in practice usually will be false, even though the seekable of
+	  the original GstDiscovererInfo is true.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=762710
+
+2016-03-31 13:32:32 -0400  Nicolas Dufresne <nicolas.dufresne@collabora.com>
+
+	* gst-libs/gst/video/video-format.h:
+	  video-format: Fix macro documentation
+	  The parameter type was wrongly documenting that a GstVideoInfo structure
+	  pointer was needed, while it needs a GstVideoFormatInfo structure
+	  pointer.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=764414
+
+2016-03-26 20:53:08 +0000  Tim-Philipp Müller <tim@centricular.com>
+
+	* tests/check/elements/subparse.c:
+	* tests/check/libs/rtp.c:
+	  test: fix indentation
+
+2016-03-26 20:52:16 +0000  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst-libs/gst/rtp/gstrtcpbuffer.c:
+	  rtp: rtcpbuffer: fix indentation
+	  https://bugzilla.gnome.org/show_bug.cgi?id=761944
+
+2016-03-26 20:50:31 +0000  Tim-Philipp Müller <tim@centricular.com>
+
+	* gst-libs/gst/rtp/gstrtcpbuffer.c:
+	  rtp: rtpcbuffer: fix Since markers
+	  https://bugzilla.gnome.org/show_bug.cgi?id=761944
+
+2016-03-30 11:16:49 +1100  Alessandro Decina <alessandro.d@gmail.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: disable neon on arm64
+	  Fix the build on arm64 by using HAVE_ARM_NEON instead of __ARM_NEON__.
+
+2016-03-29 22:16:38 +1100  Jan Schmidt <jan@centricular.com>
+
+	* gst/subparse/gstsubparse.c:
+	  subparse: Add more parsing guards
+	  Insert extra checks for the validity of the incoming
+	  data when parsing subrip/webvtt content and debug log
+	  output for invalid content.
+	  Should fix Coverity warnings.
+
+2016-03-29 10:23:08 +0100  Luis de Bethencourt <luisbg@osg.samsung.com>
+
+	* gst/subparse/gstsubparse.c:
+	  subparse: add missing break between formats
+	  A break is missing at the end of case GST_SUB_PARSE_FORMAT_LRC or it will
+	  fallthrough to WebVTT. This fixes commit fd2a14144a7a.
+
+2016-03-29 12:11:22 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	  audio-resampler: Use _mm_set_epi64x(0, x) instead of _mm_cvtsi64_si128(x) in more places
+
+2016-03-29 11:25:15 +0300  Sreerenj Balachandran <sreerenj.balachandran@intel.com>
+
+	* win32/common/video-enumtypes.c:
+	  win32: Update exports for new video formats
+	  Update win32 exports for P010_10BE and P010_10LE
+	  video formats.
+
+2016-03-29 11:16:42 +0300  Scott D Phillips <scott.d.phillips@intel.com>
+
+	* gst-libs/gst/video/video-converter.c:
+	* gst-libs/gst/video/video-format.c:
+	* gst-libs/gst/video/video-format.h:
+	* gst-libs/gst/video/video-info.c:
+	  video: add P010 format support
+	  P010 is a YUV420 format with an interleaved U-V plane and 2-bytes per
+	  component with the the color value stored in the 10 most significant
+	  bits.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=761607
+	  ---
+	  Changes since v2:
+	  - Set bits=16 in DPTH10_10_10_HI
+	  Changes since v1:
+	  - Fixed x-offset calculation in uv.
+	  - Added 6-bit shifts to FormatInfo.
+
+2016-03-29 10:15:07 +0300  Sebastian Dröge <sebastian@centricular.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	  resampler: Use _mm_set_epi64x(0, x) instead of _mm_cvtsi64_si128(x)
+	  The latter is only available on x86-64 for some reason.
+
+2016-03-29 08:21:54 +0200  Edward Hervey <bilboed@bilboed.com>
+
+	* gst-libs/gst/audio/Makefile.am:
+	  audio: Fix distcheck
+	  Don't forget to dist the needed files (which don't need to be installed)
+
+2016-03-28 15:37:36 +0200  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: estimate memory usage in auto mode
+	  Estimate the memory usage and use this to decide between full or
+	  interpolated filter.
+
+2016-03-28 12:51:26 +0200  Wim Taymans <wtaymans@redhat.com>
+
+	* gst/audioresample/Makefile.am:
+	* gst/audioresample/README:
+	* gst/audioresample/gstaudioresample.c:
+	  audioresample: remove last ORC remains
+
+2016-03-16 12:55:56 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: small optimizations
+
+2016-03-04 17:15:44 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-converter.c:
+	* gst-libs/gst/audio/audio-resampler.c:
+	* gst-libs/gst/audio/audio-resampler.h:
+	  audio-resampler: improve non-interleaved flags
+	  Make it possible to have different interleaving on input and output
+	  because we can quite trivially do that.
+
+2016-03-02 11:40:15 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: unroll some more loops
+	  Unroll some loops.
+
+2016-03-01 16:31:18 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	  audio-resampler: keep precision
+	  Transpose and add before applying the cubic interpolation to avoid
+	  overflows when using full precision.
+
+2016-03-01 16:26:15 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: small cleanups
+
+2016-02-25 15:38:46 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: optimize no resampling
+	  Switch to the faster nearest resample method when are doing no rate
+	  conversion.
+
+2016-02-25 14:09:44 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-converter.c:
+	* gst-libs/gst/audio/audio-resampler.c:
+	* gst-libs/gst/audio/audio-resampler.h:
+	  audio-resampler: add VARIABLE_RATE flag
+	  Add a VARIABLE rate flag that selects an interpolating filter.
+	  Move some function setup code in the _new function.
+
+2016-02-23 04:46:55 -0500  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-neon.h:
+	  audio-resampler: more neon optimizations
+
+2016-02-24 12:57:26 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	  audio-resampler: avoid overflow in cubic interpolation
+	  Shift out an extra bit to have some more headroom when doing cubic
+	  interpolation.
+
+2016-02-24 12:56:39 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: overread only 8 taps
+	  We only need 8 taps of zeroes as headroom for the SIMD optimized
+	  functions.
+
+2016-02-24 12:55:28 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-converter.c:
+	  audio-converter: use helper to check intermediate format
+
+2016-02-23 15:37:37 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: fix phase
+
+2016-02-22 11:16:28 -0500  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-neon.h:
+	  audio-resampler: fix neon assembler
+
+2016-02-22 13:19:02 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: avoid some format conversion
+	  Store the filter in the desired sample format so that we can simply do a
+	  linear or cubic interpolation to get the new filter instead of having to
+	  go through gdouble and then convert.
+
+2016-02-22 03:28:21 -0500  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-neon.h:
+	  audio-resampler: fix neon linear float interpolation
+
+2016-02-19 16:39:43 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-neon.h:
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: reorder filter coefficients for more speed
+	  Reorder the filter coefficients to make it easier to use SIMD for
+	  interpolation.
+	  Fix orc flags a little.
+	  Add specialized nearest resampling function.
+
+2016-02-19 10:40:03 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-neon.h:
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: remove stereo optimizations
+	  The stereo optimizations don't give enough benefit.
+	  Rename none to full to make it clear that we use a full filter instead
+	  of an interpolated one
+
+2016-02-18 12:48:45 -0500  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-neon.h:
+	  audio-resample: remove neon double stubs
+	  NEON does not have double types.
+
+2016-02-18 12:38:49 -0500  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-neon.h:
+	  audio-resampler: add more neon optimizations
+
+2016-02-18 11:05:18 -0500  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-neon.h:
+	  audio-resampler: add more neon optimizations
+
+2016-02-17 11:20:06 -0500  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-neon.h:
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: add neon optimizations
+	  Unroll some more loops in the fallback code that seems to work fine
+	  for ARM.
+	  Add some simple ARM optimizations taken from speex.
+
+2016-02-17 13:12:31 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: give better hints about the precision
+	  Give better hints to the compiler about the precision we expect from
+	  the multiplications.
+
+2016-02-17 12:05:58 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resample: small optimizations
+	  Remove some inline functions that are called in the slow path.
+	  Unroll C fallback functions a little.
+
+2016-02-16 09:18:13 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: Use n_phases when calculating taps offset
+	  Tweak linear interpolation oversampling.
+	  Clear filter cache on rate changes when using a full filter.
+
+2016-02-15 18:06:19 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-converter.c:
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	* gst/audioresample/gstaudioresample.c:
+	* gst/audioresample/gstaudioresample.h:
+	  audio-resampler: improve filter construction
+	  Remove some unused variables from the inner product functions.
+	  Make filter coefficients by interpolating if required.
+	  Rename some fields.
+	  Try hard to not recalculate filters when just chaging the rate.
+	  Add more proprties to audioresample.
+
+2016-02-12 10:00:22 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: avoid overflow in fraction calculation
+
+2016-02-11 19:42:31 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: increase precision
+
+2016-02-11 17:40:56 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	  audio-resampler: add more optimizations
+
+2016-02-11 13:23:07 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resample: fix taps conversion
+	  We do taps conversion in place so make sure we don't overwrite the
+	  input with temporary data.
+	  Optimize some more gint16 functions.
+
+2016-02-11 11:57:26 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: Improve taps memory layout
+	  Rearrange the oversampled taps in memory to make it easier to use
+	  SIMD instructions on them. this simplifies some sse code.
+	  Add some more optimizations
+
+2016-02-10 17:28:24 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: add cubic interpolation
+
+2016-02-10 13:31:11 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	* win32/common/libgstaudio.def:
+	  audio-resampler: add more functions
+	  Use some macros to generate more functions
+
+2016-02-10 12:04:12 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	* gst-libs/gst/audio/audio-resampler.h:
+	  audio-resampler: add linear interpolation method
+	  Make more functions into macros.
+	  Add linear interpolation of filter coefficients.
+
+2016-02-04 15:22:39 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* tests/icles/Makefile.am:
+	* tests/icles/test-resample.c:
+	  tests: add resample test
+
+2016-02-04 15:21:40 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	* gst-libs/gst/audio/audio-resampler.h:
+	  audio-resampler: add max-phase-error config
+
+2016-02-04 15:19:53 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: improve tap calculation
+	  Return the taps from make_taps, this makes it possible to not actually
+	  have to cache the taps when we want to.
+	  Fix overflow in phase calculation.
+
+2016-02-02 12:06:44 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	* gst-libs/gst/audio/audio-resampler.h:
+	  audio-resampler: fix guint -> gint
+
+2016-02-02 11:48:16 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: improve phase error
+	  Accept a phase error of maximum 10%, which turns out to be inaudible.
+
+2016-02-01 17:18:32 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: improve phase calculation
+	  Also calculate the GCD with the current phase so that we can accurately
+	  represent the current phase with the new resample rates.
+
+2016-01-26 22:53:33 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: fix history after buffer resize
+	  When we resize the temp buffer, move the history in its new place.
+
+2016-01-26 16:42:16 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-converter.c:
+	* gst-libs/gst/audio/audio-resampler.c:
+	* gst-libs/gst/audio/audio-resampler.h:
+	* gst/audioresample/gstaudioresample.c:
+	* win32/common/libgstaudio.def:
+	  audio-resampler: add reset function
+	  Add a function to reset the audio-resampler.
+	  Use new function in audio-converter
+	  Use the new functions in gstaudioresample and fixup drain functions.
+
+2016-01-26 16:40:57 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: Small fixes
+	  Fix the phase.
+	  Reset the new sample buffer with 0.
+	  Move samples around when we change the filter size.
+
+2016-01-26 16:38:50 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: Rework make_taps
+	  Make it return a pointer to the generated taps. That way we can later
+	  decide to actually cache it or not.
+
+2016-01-26 09:57:03 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	* gst/audioresample/gstaudioresample.c:
+	  audio-resampler: handle filter length changes
+	  Update the buffer with history samples when the filter length changes
+	  because of an update of the parameters or sample rates.
+
+2016-01-22 17:34:39 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: fix samples_avail
+	  We only know the taps after we calculate them.
+
+2016-01-22 16:45:28 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: work on dynamically changing the samplerate
+	  Calculate the new phase for the new sample rate.
+	  Fix some docs.
+
+2016-01-22 10:28:13 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-converter.c:
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: small cleanups
+
+2016-01-21 10:38:17 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: add fallback to mono function
+	  Remove stereo implementations. Implement fall back to mono functions
+	  when the stereo function is missing.
+
+2016-01-18 12:52:41 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: add float stereo SSE function
+
+2016-01-15 12:45:47 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* configure.ac:
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	  audio-resampler: Fix compilation of intrinsics
+	  Only compile intrinsics when we are building for the selected
+	  architecture.
+	  Add sse4.1 optimized int32 resampler code.
+
+2016-01-15 11:43:13 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-converter.c:
+	  audioconvert: only resample on supported formats
+
+2016-01-15 11:20:29 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-converter.c:
+	* gst-libs/gst/audio/audio-resampler.c:
+	* gst/audioresample/gstaudioresample.c:
+	  audio-converter: make some optimized functions
+	  Make an optimized function that just calls the resampler when possible.
+	  Optimize the resampler transform_size function a little.
+
+2016-01-15 10:26:02 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: remove mirror function
+	  We don't need to mirror the input, just assume 0 samples.
+	  Always move the processed samples to the start of the buffer.
+	  Add some G_LIKELY
+
+2016-01-13 17:50:38 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	  audio-resampler: also enable sse when sse2 is available
+
+2016-01-13 17:44:39 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: optimizations
+	  Improve int16 resampling by using pmaddwd
+	  Use intrinsics to scale and pack int16 samples
+	  Align the coefficients so that we can use aligned loads
+	  Add padding to taps and samples so that we don't have to use partial
+	  loads for the remainder of the loops.
+	  Remove copy_n, we can reuse the plain copy function with some new
+	  parameters.
+	  Align and pad the sample array.
+
+2016-01-12 18:55:19 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-x86.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: make pluggable optimized functions
+	  Add support for x86 specialized functions and select them at runtime.
+
+2016-01-12 10:23:53 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-resampler-core.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	  audio-resampler: combine functions
+
+2016-01-11 16:25:02 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* win32/common/libgstaudio.def:
+	  defs: update
+
+2016-01-05 16:06:22 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-converter.c:
+	* gst-libs/gst/audio/audio-converter.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	* gst-libs/gst/audio/audio-resampler.h:
+	* gst/audioresample/gstaudioresample.c:
+	  audio-converter: simplify API
+	  Remove the consumed/produced output fields from the resampler and
+	  converter. Let the caler specify the right number of input/output
+	  samples so we can be more optimal.
+	  Use just one function to update the converter configuration.
+	  Simplify some things internally.
+	  Make it possible to use writable input as temp space in audioconvert.
+
+2016-01-04 18:28:38 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/audio-converter.c:
+	* gst-libs/gst/audio/audio-converter.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	* gst-libs/gst/audio/audio-resampler.h:
+	* gst/audioresample/gstaudioresample.c:
+	* gst/audioresample/gstaudioresample.h:
+	  audio-converter: more work on resampling
+	  - Fix the resampler in the audio converter
+	  - fix memory leaks
+
+2015-11-13 15:32:29 +0100  Wim Taymans <wtaymans@redhat.com>
+
+	* gst-libs/gst/audio/Makefile.am:
+	* gst-libs/gst/audio/audio-converter.c:
+	* gst-libs/gst/audio/audio-converter.h:
+	* gst-libs/gst/audio/audio-resampler-core.h:
+	* gst-libs/gst/audio/audio-resampler.c:
+	* gst-libs/gst/audio/audio-resampler.h:
+	* gst-libs/gst/audio/audio.h:
+	* gst-libs/gst/audio/dbesi0.c:
+	* gst/audioresample/Makefile.am:
+	* gst/audioresample/arch.h:
+	* gst/audioresample/fixed_arm4.h:
+	* gst/audioresample/fixed_arm5e.h:
+	* gst/audioresample/fixed_bfin.h:
+	* gst/audioresample/fixed_debug.h:
+	* gst/audioresample/fixed_generic.h:
+	* gst/audioresample/gstaudioresample.c:
+	* gst/audioresample/gstaudioresample.h:
+	* gst/audioresample/resample.c:
+	* gst/audioresample/resample_neon.h:
+	* gst/audioresample/resample_sse.h:
+	* gst/audioresample/speex_resampler.h:
+	* gst/audioresample/speex_resampler_double.c:
+	* gst/audioresample/speex_resampler_float.c:
+	* gst/audioresample/speex_resampler_int.c:
+	* gst/audioresample/speex_resampler_wrapper.h:
+	  audio-converter: add resampler
+	  Add a resampler to the processing chain when needed.
+	  port the audio resampler to the new audioconverter library
+
+2016-03-25 01:13:54 +1100  Jan Schmidt <jan@centricular.com>
+
+	* win32/common/libgstpbutils.def:
+	* win32/common/libgstrtp.def:
+	  win32: update win32 exports for new API
+
+2016-03-07 23:29:43 +1100  Jan Schmidt <jan@centricular.com>
+
+	* gst/subparse/gstsubparse.c:
+	* gst/subparse/gstsubparse.h:
+	* tests/check/elements/subparse.c:
+	  subparse: WebVTT parsing support
+	  WebVTT is a new subtitle format for HTML5 video. In this first
+	  version of the parser the cue settings are parsed but only stored in
+	  the internal parser state structure. Later on these settings could be
+	  part of the GstBuffer metadata.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=629764
+
+2016-02-26 02:58:26 +1100  Jan Schmidt <jan@centricular.com>
+
+	* gst/typefind/gsttypefindfunctions.c:
+	  typefind: Add a typefinder for WebVTT files
+
+2016-02-26 02:56:15 +1100  Jan Schmidt <jan@centricular.com>
+
+	* gst/typefind/gsttypefindfunctions.c:
+	  typefind: Reduce URI typefinder from MAX to LIKELY
+	  Don't claim maximum likelihood for anything that starts
+	  with text that looks like a uri, it's too broad.
+
 2016-03-24 14:59:48 +1100  Jan Schmidt <jan@centricular.com>
 
 	* gst/playback/gstdecodebin2.c:
@@ -643,12 +3087,124 @@
 	  in multiqueue.
 	  https://bugzilla.gnome.org/show_bug.cgi?id=764020
 
-2016-02-26 02:56:15 +1100  Jan Schmidt <jan@centricular.com>
+2016-03-08 19:22:18 +0000  Tim-Philipp Müller <tim@centricular.com>
 
-	* gst/typefind/gsttypefindfunctions.c:
-	  typefind: Reduce URI typefinder from MAX to LIKELY
-	  Don't claim maximum likelihood for anything that starts
-	  with text that looks like a uri, it's too broad.
+	* gst-libs/gst/audio/gstaudiodecoder.c:
+	  audiodecoder: avoid unnecessary gst_pad_has_current_caps() checks
+	  No need to do this for each input buffer, we have the input caps
+	  stored somewhere already.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=763337
+
+2016-03-22 11:25:49 +0900  Jimmy Ohn <yongjin.ohn@lge.com>
+
+	* docs/libs/gst-plugins-base-libs-sections.txt:
+	* gst-libs/gst/pbutils/codec-utils.c:
+	* gst-libs/gst/pbutils/codec-utils.h:
+	* win32/common/libgstpbutils.def:
+	  codec-utils: Add utilities for AAC and the AACHead header
+	  Add utilities about the channels and sample rate for AAC.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=749110
+
+2016-03-21 16:06:20 +0900  Jimmy Ohn <yongjin.ohn@lge.com>
+
+	* gst/playback/gstdecodebin2.c:
+	  decodebin: Modify result of seekable in check_upstream_seekable function
+	  In check_upstream_seekable function, it returns FALSE value even though
+	  we already declare about the seekable variable. So, This patch return
+	  result of seekable in check_upstream_seekable function.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=763975
+
+2016-03-03 16:46:24 +0900  Vineeth TM <vineeth.tm@samsung.com>
+
+	* ext/alsa/gstalsamidisrc.c:
+	* ext/alsa/gstalsasink.c:
+	* ext/alsa/gstalsasrc.c:
+	* ext/libvisual/visual.c:
+	* ext/ogg/gstoggaviparse.c:
+	* ext/ogg/gstoggdemux.c:
+	* ext/ogg/gstoggmux.c:
+	* ext/ogg/gstoggparse.c:
+	* ext/ogg/gstogmparse.c:
+	* ext/opus/gstopusdec.c:
+	* ext/opus/gstopusenc.c:
+	* ext/pango/gstbasetextoverlay.c:
+	* ext/pango/gsttextoverlay.c:
+	* ext/pango/gsttextrender.c:
+	* ext/theora/gsttheoradec.c:
+	* ext/theora/gsttheoraenc.c:
+	* ext/theora/gsttheoraparse.c:
+	* ext/vorbis/gstvorbisdec.c:
+	* ext/vorbis/gstvorbisenc.c:
+	* ext/vorbis/gstvorbisparse.c:
+	* gst-libs/gst/app/gstappsink.c:
+	* gst-libs/gst/app/gstappsrc.c:
+	* gst-libs/gst/audio/gstaudiocdsrc.c:
+	* gst-libs/gst/tag/gsttagdemux.c:
+	* gst/adder/gstadder.c:
+	* gst/audioconvert/gstaudioconvert.c:
+	* gst/audiorate/gstaudiorate.c:
+	* gst/audioresample/gstaudioresample.c:
+	* gst/audiotestsrc/gstaudiotestsrc.c:
+	* gst/encoding/gstencodebin.c:
+	* gst/encoding/gstsmartencoder.c:
+	* gst/encoding/gststreamcombiner.c:
+	* gst/encoding/gststreamsplitter.c:
+	* gst/gio/gstgiobasesink.c:
+	* gst/gio/gstgiobasesrc.c:
+	* gst/playback/gstdecodebin2.c:
+	* gst/playback/gstplaysink.c:
+	* gst/playback/gstplaysinkconvertbin.c:
+	* gst/playback/gststreamsynchronizer.c:
+	* gst/playback/gstsubtitleoverlay.c:
+	* gst/playback/gsturidecodebin.c:
+	* gst/subparse/gstssaparse.c:
+	* gst/subparse/gstsubparse.c:
+	* gst/tcp/gstmultihandlesink.c:
+	* gst/tcp/gstsocketsrc.c:
+	* gst/tcp/gsttcpclientsink.c:
+	* gst/tcp/gsttcpclientsrc.c:
+	* gst/tcp/gsttcpserversrc.c:
+	* gst/videoconvert/gstvideoconvert.c:
+	* gst/videorate/gstvideorate.c:
+	* gst/videotestsrc/gstvideotestsrc.c:
+	* sys/ximage/ximagesink.c:
+	* sys/xvimage/xvimagesink.c:
+	* tests/check/elements/audiorate.c:
+	* tests/check/elements/decodebin.c:
+	* tests/check/elements/playbin-complex.c:
+	* tests/check/elements/playbin.c:
+	* tests/check/elements/videoscale.c:
+	* tests/check/libs/audiodecoder.c:
+	* tests/check/libs/audioencoder.c:
+	* tests/check/libs/baseaudiovisualizer.c:
+	* tests/check/libs/rtpbasedepayload.c:
+	* tests/check/libs/rtpbasepayload.c:
+	* tests/check/libs/videodecoder.c:
+	* tests/check/libs/videoencoder.c:
+	  base: use new gst_element_class_add_static_pad_template()
+	  https://bugzilla.gnome.org/show_bug.cgi?id=763075
+
+2015-10-06 17:02:03 +0200  Stian Selnes <stian@pexip.com>
+
+	* gst-libs/gst/rtp/gstrtcpbuffer.c:
+	* gst-libs/gst/rtp/gstrtcpbuffer.h:
+	* tests/check/libs/rtp.c:
+	  rtcpbuffer: Add API for APP packets
+	  https://bugzilla.gnome.org/show_bug.cgi?id=761944
+
+2014-07-29 15:37:12 +0200  Haakon Sporsheim <haakon@pexip.com>
+
+	* gst-libs/gst/rtp/gstrtcpbuffer.c:
+	* gst-libs/gst/rtp/gstrtcpbuffer.h:
+	* tests/check/libs/rtp.c:
+	* win32/common/libgstrtp.def:
+	  rtcpbuffer: Add profile-specific extension API.
+	  https://bugzilla.gnome.org/show_bug.cgi?id=761950
+
+2016-03-24 13:32:52 +0200  Sebastian Dröge <sebastian@centricular.com>
+
+	* configure.ac:
+	  Back to development
 
 === release 1.8.0 ===
 
diff --git a/Makefile.am b/Makefile.am
index 5fc3e10..fc34e1d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -81,6 +81,8 @@
 	$(top_builddir)/common/shave \
 	$(top_builddir)/common/shave-libtool \
 	$(top_builddir)/gst-libs/gst/audio/testchannels \
+        $(top_builddir)/gst-libs/gst/app/gstapp-marshal.c \
+        $(top_builddir)/gst-libs/gst/app/gstapp-marshal.h \
 	$(top_builddir)/tests/check/elements/gdppay \
 	$(top_builddir)/tests/check/elements/gdpdepay \
 	$(top_builddir)/tests/check/pipelines/streamheader \
diff --git a/Makefile.in b/Makefile.in
index d1e8f1f..4eaa664 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -107,6 +107,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -443,6 +444,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -456,6 +460,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -493,6 +500,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -597,6 +605,8 @@
 	$(top_builddir)/common/shave \
 	$(top_builddir)/common/shave-libtool \
 	$(top_builddir)/gst-libs/gst/audio/testchannels \
+        $(top_builddir)/gst-libs/gst/app/gstapp-marshal.c \
+        $(top_builddir)/gst-libs/gst/app/gstapp-marshal.h \
 	$(top_builddir)/tests/check/elements/gdppay \
 	$(top_builddir)/tests/check/elements/gdpdepay \
 	$(top_builddir)/tests/check/pipelines/streamheader \
@@ -1151,8 +1161,11 @@
 
 update-exports:
 	make check-exports 2>&1 | patch -p1
-	git add win32/common/libgst*.def
-	git diff --cached -- win32/common/
+	if test -f "$(top_srcdir)/win32/common/libgstgl.def"; then \
+	  git checkout "$(top_srcdir)/win32/common/libgstgl.def";  \
+	fi
+	git add $(top_srcdir)/win32/common/libgst*.def
+	git diff --cached -- $(top_srcdir)/win32/common/
 	echo '^^^--- updated and staged changes above'
 
 # complain about nonportable printf format strings (%lld, %llu, %zu etc.)
diff --git a/NEWS b/NEWS
index 0ebfe94..072b2df 100644
--- a/NEWS
+++ b/NEWS
@@ -1,28 +1 @@
-### 1.8.3
-
-The third 1.8 bug-fix release (1.8.3) was released on 19 August 2016.
-This release only contains bugfixes and it should be safe to update from 1.8.x.
-
-#### Major bugfixes in 1.8.3
-
- - Fix Android build scripts on OS X and Windows
- - Fix stepping in PAUSED state in certain circumstances
- - Fix jackaudiosink hang when exiting
- - Fix udpsrc receiving multicast packets not only from the selected
-   multicast group
- - Fix unnecessary decoding of unselected streams in GES
- - Fix (multi)udpsink randomly not sending to clients
- - Fix ALL\_BOTH probes not considering EVENT\_FLUSH
- - Fix average input rate calculations in queue2
- - Fix various locking issues causing deadlock in adaptivedemux
- - Fix gst-libav encoders to correctly produce codec\_data in caps
- - Add Wayland, Windows and Rasberry Pi support to the QML GL video sink
- - Add support for building with OpenH264 1.6
- - Add support for controlling deinterlacing in GES video sources
- - ... and many, many more!
-
-For a full list of bugfixes see [Bugzilla][buglist-1.8.3]. Note that this is
-not the full list of changes. For the full list of changes please refer to the
-GIT logs or ChangeLogs of the particular modules.
-
-[buglist-1.8.3]: https://bugzilla.gnome.org/buglist.cgi?bug_status=RESOLVED&bug_status=VERIFIED&classification=Platform&limit=0&list_id=145400&order=bug_id&product=GStreamer&query_format=advanced&resolution=FIXED&target_milestone=1.8.3
+This is GStreamer 1.9.90
diff --git a/README b/README
index fa53f95..48e2c9f 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-GStreamer 1.7.x development series
+GStreamer 1.9.x development series
 
 WHAT IT IS
 ----------
diff --git a/RELEASE b/RELEASE
index c7687ff..32a0af3 100644
--- a/RELEASE
+++ b/RELEASE
@@ -1,15 +1,13 @@
 
-Release notes for GStreamer Base Plugins 1.8.3
+Release notes for GStreamer Base Plugins 1.9.90
 
-The GStreamer team is proud to announce the third bugfix release in the stable
-1.8 release series of your favourite cross-platform multimedia framework!
+The GStreamer team is pleased to announce the first release candidate of the
+stable 1.10 release series. The 1.10 release series is adding new features on
+top of the 1.0, 1.2, 1.4, 1.6 and 1.8 series and is part of the API and
+ABI-stable 1.x release series of the GStreamer multimedia framework.
 
 
-This release only contains bugfixes and it is safe to update from 1.8.x. For a
-full list of bugfixes see Bugzilla.
-
-
-See /releases/1.8/ for the full release notes.
+Binaries for Android, iOS, Mac OS X and Windows will be provided in the next days.
 
 
 This module contains a set of reference plugins, base classes for other
@@ -58,13 +56,12 @@
 
 Bugs fixed in this release
      
-      * 767689 : oggdemux: re-enable the seek on EOS when determining stream length
-      * 767712 : xvimage: Missing sanity checking for allocation sizes for various video formats
-      * 767859 : discoverer: Don't crash when trying to serialize non-OK discoverer infos to a GVariant
-      * 768178 : tagdemux: Drops data of too small files in PUSH mode
-      * 768249 : rtspsrc lockup on gst_rtspsrc_stop
-      * 768361 : videodecoder: Takes stream lock for non-serialized queries
-      * 768991 : oggdemux: fix unknown duration playing Ogg from HTTP
+      * 729276 : audioresample: Misdetected and/or misused intrinsics headers
+      * 769771 : rtpbuffer: Add buffer flag RETRANSMISSION
+      * 770314 : oggdemux: Does not go back to beginning point on EOS when determining stream length
+      * 770446 : pulsesrc, audiosrc: No audio captured with new GStreamer 1.8.2
+      * 770692 : playbackutils: Move compare_factories_func
+      * 770698 : video-orc.orc doesn't compile with orc 0.4.23
 
 ==== Download ====
 
@@ -101,9 +98,17 @@
         
 Contributors to this release
     
-      * Duncan Palmer
+      * Arun Raghavan
+      * Edward Hervey
+      * Havard Graff
+      * Jan Schmidt
+      * Jonathan Matthew
+      * Nicolas Dufresne
       * Sebastian Dröge
-      * Sergio Torres Soldado
+      * Thibault Saunier
       * Tim-Philipp Müller
       * Vincent Penquerc'h
+      * Víctor Manuel Jáquez Leal
+      * Wim Taymans
+      * Wonchul Lee
  
\ No newline at end of file
diff --git a/aclocal.m4 b/aclocal.m4
index 02ca342..959ed1d 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1459,6 +1459,7 @@
 m4_include([common/m4/as-libtool.m4])
 m4_include([common/m4/as-version.m4])
 m4_include([common/m4/ax_create_stdint_h.m4])
+m4_include([common/m4/ax_pthread.m4])
 m4_include([common/m4/gst-arch.m4])
 m4_include([common/m4/gst-args.m4])
 m4_include([common/m4/gst-check.m4])
diff --git a/common/Makefile.in b/common/Makefile.in
index 4686176..ef5dca8 100644
--- a/common/Makefile.in
+++ b/common/Makefile.in
@@ -96,6 +96,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -405,6 +406,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -418,6 +422,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -455,6 +462,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/common/gst.supp b/common/gst.supp
index 2740e9a..f85cd69 100644
--- a/common/gst.supp
+++ b/common/gst.supp
@@ -4024,5 +4024,4 @@
    fun:malloc
    ...
    fun:g_quark_init
-   fun:glib_init_ctor
 }
diff --git a/common/gtk-doc-plugins.mak b/common/gtk-doc-plugins.mak
index fe0977c..4b5dd1b 100644
--- a/common/gtk-doc-plugins.mak
+++ b/common/gtk-doc-plugins.mak
@@ -179,9 +179,13 @@
 		$(top_srcdir)/common/plugins.xsl $$a > xml/`basename $$a`; done
 	@for f in $(EXAMPLE_CFILES); do \
 		$(PYTHON) $(top_srcdir)/common/c-to-xml.py $$f > xml/element-`basename $$f .c`.xml; done
-	@gtkdoc-mkdb \
+	@_source_dir='' ;						\
+	for i in $(DOC_SOURCE_DIR) ; do					\
+	    _source_dir="$${_source_dir} --source-dir=$$i" ;	        \
+	done ;								\
+	gtkdoc-mkdb \
 		--module=$(DOC_MODULE) \
-		--source-dir=$(DOC_SOURCE_DIR) \
+		$${_source_dir} \
 		 --expand-content-files="$(expand_content_files)" \
 		--main-sgml-file=$(srcdir)/$(DOC_MAIN_SGML_FILE) \
 		--output-format=xml \
diff --git a/common/gtk-doc.mak b/common/gtk-doc.mak
index 2aab3a9..3f83491 100644
--- a/common/gtk-doc.mak
+++ b/common/gtk-doc.mak
@@ -121,7 +121,11 @@
 
 sgml-build.stamp: setup-build.stamp $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(expand_content_files)
 	@echo '  DOC   Building XML'
-	@gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR)  --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) --output-format=xml $(MKDB_OPTIONS)
+	@_source_dir='' ;						\
+	for i in $(DOC_SOURCE_DIR) ; do					\
+	    _source_dir="$${_source_dir} --source-dir=$$i" ;	        \
+	done ;							        \
+	gtkdoc-mkdb --module=$(DOC_MODULE) $${_source_dir}  --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) --output-format=xml $(MKDB_OPTIONS)
 	@cp ../version.entities xml
 	@touch sgml-build.stamp
 
diff --git a/common/m4/Makefile.in b/common/m4/Makefile.in
index 881a961..65ddad5 100644
--- a/common/m4/Makefile.in
+++ b/common/m4/Makefile.in
@@ -96,6 +96,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -345,6 +346,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -358,6 +362,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -395,6 +402,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/common/m4/ax_pthread.m4 b/common/m4/ax_pthread.m4
index d383ad5..4c4051e 100644
--- a/common/m4/ax_pthread.m4
+++ b/common/m4/ax_pthread.m4
@@ -19,10 +19,10 @@
 #   is necessary on AIX to use the special cc_r compiler alias.)
 #
 #   NOTE: You are assumed to not only compile your program with these flags,
-#   but also link it with them as well. e.g. you should link with
+#   but also to link with them as well. For example, you might link with
 #   $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
 #
-#   If you are only building threads programs, you may wish to use these
+#   If you are only building threaded programs, you may wish to use these
 #   variables in your default LIBS, CFLAGS, and CC:
 #
 #     LIBS="$PTHREAD_LIBS $LIBS"
@@ -30,8 +30,8 @@
 #     CC="$PTHREAD_CC"
 #
 #   In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
-#   has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
-#   (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#   has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
+#   that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
 #
 #   Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
 #   PTHREAD_PRIO_INHERIT symbol is defined when compiling with
@@ -82,35 +82,40 @@
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 21
+#serial 23
 
 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
 AC_DEFUN([AX_PTHREAD], [
 AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AC_PROG_SED])
 AC_LANG_PUSH([C])
 ax_pthread_ok=no
 
 # We used to check for pthread.h first, but this fails if pthread.h
-# requires special compiler flags (e.g. on True64 or Sequent).
+# requires special compiler flags (e.g. on Tru64 or Sequent).
 # It gets checked for in the link test anyway.
 
 # First of all, check if the user has set any of the PTHREAD_LIBS,
 # etcetera environment variables, and if threads linking works using
 # them:
-if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
-        save_CFLAGS="$CFLAGS"
+if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
+        ax_pthread_save_CC="$CC"
+        ax_pthread_save_CFLAGS="$CFLAGS"
+        ax_pthread_save_LIBS="$LIBS"
+        AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
         CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-        save_LIBS="$LIBS"
         LIBS="$PTHREAD_LIBS $LIBS"
-        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
-        AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes])
+        AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
+        AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
         AC_MSG_RESULT([$ax_pthread_ok])
-        if test x"$ax_pthread_ok" = xno; then
+        if test "x$ax_pthread_ok" = "xno"; then
                 PTHREAD_LIBS=""
                 PTHREAD_CFLAGS=""
         fi
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
+        CC="$ax_pthread_save_CC"
+        CFLAGS="$ax_pthread_save_CFLAGS"
+        LIBS="$ax_pthread_save_LIBS"
 fi
 
 # We must check for the threads library under a number of different
@@ -123,7 +128,7 @@
 # which indicates that we try without any flags at all, and "pthread-config"
 # which is a program returning the flags for the Pth emulation library.
 
-ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
 
 # The ordering *is* (sometimes) important.  Some notes on the
 # individual items follow:
@@ -132,82 +137,225 @@
 # none: in case threads are in libc; should be tried before -Kthread and
 #       other compiler flags to prevent continual compiler warnings
 # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
-# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
-# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
-# -pthreads: Solaris/gcc
-# -mthreads: Mingw32/gcc, Lynx/gcc
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
+#           (Note: HP C rejects this with "bad form for `-t' option")
+# -pthreads: Solaris/gcc (Note: HP C also rejects)
 # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
-#      doesn't hurt to check since this sometimes defines pthreads too;
-#      also defines -D_REENTRANT)
-#      ... -mt is also the pthreads flag for HP/aCC
+#      doesn't hurt to check since this sometimes defines pthreads and
+#      -D_REENTRANT too), HP C (must be checked before -lpthread, which
+#      is present but should not be used directly; and before -mthreads,
+#      because the compiler interprets this as "-mt" + "-hreads")
+# -mthreads: Mingw32/gcc, Lynx/gcc
 # pthread: Linux, etcetera
 # --thread-safe: KAI C++
 # pthread-config: use pthread-config program (for GNU Pth library)
 
-case ${host_os} in
+case $host_os in
+
+        freebsd*)
+
+        # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+        # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+
+        ax_pthread_flags="-kthread lthread $ax_pthread_flags"
+        ;;
+
+        hpux*)
+
+        # From the cc(1) man page: "[-mt] Sets various -D flags to enable
+        # multi-threading and also sets -lpthread."
+
+        ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
+        ;;
+
+        openedition*)
+
+        # IBM z/OS requires a feature-test macro to be defined in order to
+        # enable POSIX threads at all, so give the user a hint if this is
+        # not set. (We don't define these ourselves, as they can affect
+        # other portions of the system API in unpredictable ways.)
+
+        AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
+            [
+#            if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
+             AX_PTHREAD_ZOS_MISSING
+#            endif
+            ],
+            [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
+        ;;
+
         solaris*)
 
         # On Solaris (at least, for some versions), libc contains stubbed
         # (non-functional) versions of the pthreads routines, so link-based
-        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
-        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
-        # a function called by this macro, so we could check for that, but
-        # who knows whether they'll stub that too in a future libc.)  So,
-        # we'll just look for -pthreads and -lpthread first:
+        # tests will erroneously succeed. (N.B.: The stubs are missing
+        # pthread_cleanup_push, or rather a function called by this macro,
+        # so we could check for that, but who knows whether they'll stub
+        # that too in a future libc.)  So we'll check first for the
+        # standard Solaris way of linking pthreads (-mt -lpthread).
 
-        ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
-        ;;
-
-        darwin*)
-        ax_pthread_flags="-pthread $ax_pthread_flags"
+        ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags"
         ;;
 esac
 
-# Clang doesn't consider unrecognized options an error unless we specify
-# -Werror. We throw in some extra Clang-specific options to ensure that
-# this doesn't happen for GCC, which also accepts -Werror.
+# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
 
-AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags])
-save_CFLAGS="$CFLAGS"
-ax_pthread_extra_flags="-Werror"
-CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])],
-                  [AC_MSG_RESULT([yes])],
-                  [ax_pthread_extra_flags=
-                   AC_MSG_RESULT([no])])
-CFLAGS="$save_CFLAGS"
+AS_IF([test "x$GCC" = "xyes"],
+      [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"])
 
-if test x"$ax_pthread_ok" = xno; then
-for flag in $ax_pthread_flags; do
+# The presence of a feature test macro requesting re-entrant function
+# definitions is, on some systems, a strong hint that pthreads support is
+# correctly enabled
 
-        case $flag in
+case $host_os in
+        darwin* | hpux* | linux* | osf* | solaris*)
+        ax_pthread_check_macro="_REENTRANT"
+        ;;
+
+        aix*)
+        ax_pthread_check_macro="_THREAD_SAFE"
+        ;;
+
+        *)
+        ax_pthread_check_macro="--"
+        ;;
+esac
+AS_IF([test "x$ax_pthread_check_macro" = "x--"],
+      [ax_pthread_check_cond=0],
+      [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
+
+# Are we compiling with Clang?
+
+AC_CACHE_CHECK([whether $CC is Clang],
+    [ax_cv_PTHREAD_CLANG],
+    [ax_cv_PTHREAD_CLANG=no
+     # Note that Autoconf sets GCC=yes for Clang as well as GCC
+     if test "x$GCC" = "xyes"; then
+        AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
+            [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
+#            if defined(__clang__) && defined(__llvm__)
+             AX_PTHREAD_CC_IS_CLANG
+#            endif
+            ],
+            [ax_cv_PTHREAD_CLANG=yes])
+     fi
+    ])
+ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
+
+ax_pthread_clang_warning=no
+
+# Clang needs special handling, because older versions handle the -pthread
+# option in a rather... idiosyncratic way
+
+if test "x$ax_pthread_clang" = "xyes"; then
+
+        # Clang takes -pthread; it has never supported any other flag
+
+        # (Note 1: This will need to be revisited if a system that Clang
+        # supports has POSIX threads in a separate library.  This tends not
+        # to be the way of modern systems, but it's conceivable.)
+
+        # (Note 2: On some systems, notably Darwin, -pthread is not needed
+        # to get POSIX threads support; the API is always present and
+        # active.  We could reasonably leave PTHREAD_CFLAGS empty.  But
+        # -pthread does define _REENTRANT, and while the Darwin headers
+        # ignore this macro, third-party headers might not.)
+
+        PTHREAD_CFLAGS="-pthread"
+        PTHREAD_LIBS=
+
+        ax_pthread_ok=yes
+
+        # However, older versions of Clang make a point of warning the user
+        # that, in an invocation where only linking and no compilation is
+        # taking place, the -pthread option has no effect ("argument unused
+        # during compilation").  They expect -pthread to be passed in only
+        # when source code is being compiled.
+        #
+        # Problem is, this is at odds with the way Automake and most other
+        # C build frameworks function, which is that the same flags used in
+        # compilation (CFLAGS) are also used in linking.  Many systems
+        # supported by AX_PTHREAD require exactly this for POSIX threads
+        # support, and in fact it is often not straightforward to specify a
+        # flag that is used only in the compilation phase and not in
+        # linking.  Such a scenario is extremely rare in practice.
+        #
+        # Even though use of the -pthread flag in linking would only print
+        # a warning, this can be a nuisance for well-run software projects
+        # that build with -Werror.  So if the active version of Clang has
+        # this misfeature, we search for an option to squash it.
+
+        AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
+            [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
+            [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
+             # Create an alternate version of $ac_link that compiles and
+             # links in two steps (.c -> .o, .o -> exe) instead of one
+             # (.c -> exe), because the warning occurs only in the second
+             # step
+             ax_pthread_save_ac_link="$ac_link"
+             ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
+             ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
+             ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
+             ax_pthread_save_CFLAGS="$CFLAGS"
+             for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
+                AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
+                CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
+                ac_link="$ax_pthread_save_ac_link"
+                AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
+                    [ac_link="$ax_pthread_2step_ac_link"
+                     AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
+                         [break])
+                    ])
+             done
+             ac_link="$ax_pthread_save_ac_link"
+             CFLAGS="$ax_pthread_save_CFLAGS"
+             AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
+             ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
+            ])
+
+        case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
+                no | unknown) ;;
+                *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
+        esac
+
+fi # $ax_pthread_clang = yes
+
+if test "x$ax_pthread_ok" = "xno"; then
+for ax_pthread_try_flag in $ax_pthread_flags; do
+
+        case $ax_pthread_try_flag in
                 none)
                 AC_MSG_CHECKING([whether pthreads work without any flags])
                 ;;
 
+                -mt,pthread)
+                AC_MSG_CHECKING([whether pthreads work with -mt -lpthread])
+                PTHREAD_CFLAGS="-mt"
+                PTHREAD_LIBS="-lpthread"
+                ;;
+
                 -*)
-                AC_MSG_CHECKING([whether pthreads work with $flag])
-                PTHREAD_CFLAGS="$flag"
+                AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
+                PTHREAD_CFLAGS="$ax_pthread_try_flag"
                 ;;
 
                 pthread-config)
                 AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
-                if test x"$ax_pthread_config" = xno; then continue; fi
+                AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
                 PTHREAD_CFLAGS="`pthread-config --cflags`"
                 PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
                 ;;
 
                 *)
-                AC_MSG_CHECKING([for the pthreads library -l$flag])
-                PTHREAD_LIBS="-l$flag"
+                AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
+                PTHREAD_LIBS="-l$ax_pthread_try_flag"
                 ;;
         esac
 
-        save_LIBS="$LIBS"
-        save_CFLAGS="$CFLAGS"
+        ax_pthread_save_CFLAGS="$CFLAGS"
+        ax_pthread_save_LIBS="$LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
         LIBS="$PTHREAD_LIBS $LIBS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags"
 
         # Check for various functions.  We must include pthread.h,
         # since some functions may be macros.  (On the Sequent, we
@@ -218,7 +366,11 @@
         # pthread_cleanup_push because it is one of the few pthread
         # functions on Solaris that doesn't have a non-functional libc stub.
         # We try pthread_create on general principles.
+
         AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+#                       if $ax_pthread_check_cond
+#                        error "$ax_pthread_check_macro must be defined"
+#                       endif
                         static void routine(void *a) { a = 0; }
                         static void *start_routine(void *a) { return a; }],
                        [pthread_t th; pthread_attr_t attr;
@@ -227,16 +379,14 @@
                         pthread_attr_init(&attr);
                         pthread_cleanup_push(routine, 0);
                         pthread_cleanup_pop(0) /* ; */])],
-                [ax_pthread_ok=yes],
-                [])
+            [ax_pthread_ok=yes],
+            [])
 
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
+        CFLAGS="$ax_pthread_save_CFLAGS"
+        LIBS="$ax_pthread_save_LIBS"
 
         AC_MSG_RESULT([$ax_pthread_ok])
-        if test "x$ax_pthread_ok" = xyes; then
-                break;
-        fi
+        AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
 
         PTHREAD_LIBS=""
         PTHREAD_CFLAGS=""
@@ -244,71 +394,74 @@
 fi
 
 # Various other checks:
-if test "x$ax_pthread_ok" = xyes; then
-        save_LIBS="$LIBS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        save_CFLAGS="$CFLAGS"
+if test "x$ax_pthread_ok" = "xyes"; then
+        ax_pthread_save_CFLAGS="$CFLAGS"
+        ax_pthread_save_LIBS="$LIBS"
         CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
 
         # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
-        AC_MSG_CHECKING([for joinable pthread attribute])
-        attr_name=unknown
-        for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
-            AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
-                           [int attr = $attr; return attr /* ; */])],
-                [attr_name=$attr; break],
-                [])
-        done
-        AC_MSG_RESULT([$attr_name])
-        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
-            AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name],
-                               [Define to necessary symbol if this constant
-                                uses a non-standard name on your system.])
-        fi
+        AC_CACHE_CHECK([for joinable pthread attribute],
+            [ax_cv_PTHREAD_JOINABLE_ATTR],
+            [ax_cv_PTHREAD_JOINABLE_ATTR=unknown
+             for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+                 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
+                                                 [int attr = $ax_pthread_attr; return attr /* ; */])],
+                                [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
+                                [])
+             done
+            ])
+        AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
+               test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
+               test "x$ax_pthread_joinable_attr_defined" != "xyes"],
+              [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
+                                  [$ax_cv_PTHREAD_JOINABLE_ATTR],
+                                  [Define to necessary symbol if this constant
+                                   uses a non-standard name on your system.])
+               ax_pthread_joinable_attr_defined=yes
+              ])
 
-        AC_MSG_CHECKING([if more special flags are required for pthreads])
-        flag=no
-        case ${host_os} in
-            aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
-            osf* | hpux*) flag="-D_REENTRANT";;
-            solaris*)
-            if test "$GCC" = "yes"; then
-                flag="-D_REENTRANT"
-            else
-                # TODO: What about Clang on Solaris?
-                flag="-mt -D_REENTRANT"
-            fi
-            ;;
-        esac
-        AC_MSG_RESULT([$flag])
-        if test "x$flag" != xno; then
-            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
-        fi
+        AC_CACHE_CHECK([whether more special flags are required for pthreads],
+            [ax_cv_PTHREAD_SPECIAL_FLAGS],
+            [ax_cv_PTHREAD_SPECIAL_FLAGS=no
+             case $host_os in
+             solaris*)
+             ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
+             ;;
+             esac
+            ])
+        AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
+               test "x$ax_pthread_special_flags_added" != "xyes"],
+              [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
+               ax_pthread_special_flags_added=yes])
 
         AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
-            [ax_cv_PTHREAD_PRIO_INHERIT], [
-                AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
-                                                [[int i = PTHREAD_PRIO_INHERIT;]])],
-                    [ax_cv_PTHREAD_PRIO_INHERIT=yes],
-                    [ax_cv_PTHREAD_PRIO_INHERIT=no])
+            [ax_cv_PTHREAD_PRIO_INHERIT],
+            [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
+                                             [[int i = PTHREAD_PRIO_INHERIT;]])],
+                            [ax_cv_PTHREAD_PRIO_INHERIT=yes],
+                            [ax_cv_PTHREAD_PRIO_INHERIT=no])
             ])
-        AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
-            [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])])
+        AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
+               test "x$ax_pthread_prio_inherit_defined" != "xyes"],
+              [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
+               ax_pthread_prio_inherit_defined=yes
+              ])
 
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
+        CFLAGS="$ax_pthread_save_CFLAGS"
+        LIBS="$ax_pthread_save_LIBS"
 
         # More AIX lossage: compile with *_r variant
-        if test "x$GCC" != xyes; then
+        if test "x$GCC" != "xyes"; then
             case $host_os in
                 aix*)
                 AS_CASE(["x/$CC"],
-                  [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
-                  [#handle absolute path differently from PATH based program lookup
-                   AS_CASE(["x$CC"],
-                     [x/*],
-                     [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
-                     [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
+                    [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
+                    [#handle absolute path differently from PATH based program lookup
+                     AS_CASE(["x$CC"],
+                         [x/*],
+                         [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
+                         [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
                 ;;
             esac
         fi
@@ -321,7 +474,7 @@
 AC_SUBST([PTHREAD_CC])
 
 # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
-if test x"$ax_pthread_ok" = xyes; then
+if test "x$ax_pthread_ok" = "xyes"; then
         ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
         :
 else
diff --git a/common/win32.mak b/common/win32.mak
index 87cd346..6060532 100644
--- a/common/win32.mak
+++ b/common/win32.mak
@@ -61,8 +61,11 @@
 
 update-exports:
 	make check-exports 2>&1 | patch -p1
-	git add win32/common/libgst*.def
-	git diff --cached -- win32/common/
+	if test -f "$(top_srcdir)/win32/common/libgstgl.def"; then \
+	  git checkout "$(top_srcdir)/win32/common/libgstgl.def";  \
+	fi
+	git add $(top_srcdir)/win32/common/libgst*.def
+	git diff --cached -- $(top_srcdir)/win32/common/
 	echo '^^^--- updated and staged changes above'
 
 # complain about nonportable printf format strings (%lld, %llu, %zu etc.)
diff --git a/config.h.in b/config.h.in
index d433b89..91a3a5b 100644
--- a/config.h.in
+++ b/config.h.in
@@ -161,6 +161,14 @@
    */
 #undef HAVE_DCGETTEXT
 
+/* Define to 1 if you have the declaration of `__i386__', and to 0 if you
+   don't. */
+#undef HAVE_DECL___I386__
+
+/* Define to 1 if you have the declaration of `__x86_64__', and to 0 if you
+   don't. */
+#undef HAVE_DECL___X86_64__
+
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
@@ -245,9 +253,27 @@
 /* Define to 1 if you have the <process.h> header file. */
 #undef HAVE_PROCESS_H
 
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Have PTHREAD_PRIO_INHERIT. */
+#undef HAVE_PTHREAD_PRIO_INHERIT
+
 /* Define if RDTSC is available */
 #undef HAVE_RDTSC
 
+/* Define to 1 if you have the <smmintrin.h> header file. */
+#undef HAVE_SMMINTRIN_H
+
+/* SSE support is enabled */
+#undef HAVE_SSE
+
+/* SSE2 support is enabled */
+#undef HAVE_SSE2
+
+/* SSE4.1 support is enabled */
+#undef HAVE_SSE41
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
@@ -350,6 +376,10 @@
 /* directory where plugins are located */
 #undef PLUGINDIR
 
+/* Define to necessary symbol if this constant uses a non-standard name on
+   your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
 /* The size of `char', as computed by sizeof. */
 #undef SIZEOF_CHAR
 
diff --git a/configure b/configure
index b6e0979..2c3f00f 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 Base Plug-ins 1.8.3.
+# Generated by GNU Autoconf 2.69 for GStreamer Base Plug-ins 1.9.90.
 #
 # Report bugs to <http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer>.
 #
@@ -591,8 +591,8 @@
 # Identity of this package.
 PACKAGE_NAME='GStreamer Base Plug-ins'
 PACKAGE_TARNAME='gst-plugins-base'
-PACKAGE_VERSION='1.8.3'
-PACKAGE_STRING='GStreamer Base Plug-ins 1.8.3'
+PACKAGE_VERSION='1.9.90'
+PACKAGE_STRING='GStreamer Base Plug-ins 1.9.90'
 PACKAGE_BUGREPORT='http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer'
 PACKAGE_URL=''
 
@@ -821,6 +821,15 @@
 HAVE_WINSOCK2_H_TRUE
 HAVE_SYS_SOCKET_H_FALSE
 HAVE_SYS_SOCKET_H_TRUE
+SSE41_CFLAGS
+SSE2_CFLAGS
+SSE_CFLAGS
+HAVE_X86_FALSE
+HAVE_X86_TRUE
+PTHREAD_CFLAGS
+PTHREAD_LIBS
+PTHREAD_CC
+ax_pthread_config
 LIBM
 ENABLE_PLUGIN_DOCS_FALSE
 ENABLE_PLUGIN_DOCS_TRUE
@@ -1789,7 +1798,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 Base Plug-ins 1.8.3 to adapt to many kinds of systems.
+\`configure' configures GStreamer Base Plug-ins 1.9.90 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1862,7 +1871,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of GStreamer Base Plug-ins 1.8.3:";;
+     short | recursive ) echo "Configuration of GStreamer Base Plug-ins 1.9.90:";;
    esac
   cat <<\_ACEOF
 
@@ -2157,7 +2166,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-GStreamer Base Plug-ins configure 1.8.3
+GStreamer Base Plug-ins configure 1.9.90
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2930,7 +2939,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 Base Plug-ins $as_me 1.8.3, which was
+It was created by GStreamer Base Plug-ins $as_me 1.9.90, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3909,7 +3918,7 @@
 
 # Define the identity of the package.
  PACKAGE='gst-plugins-base'
- VERSION='1.8.3'
+ VERSION='1.9.90'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -4120,9 +4129,9 @@
 
 
 
-  PACKAGE_VERSION_MAJOR=$(echo 1.8.3 | cut -d'.' -f1)
-  PACKAGE_VERSION_MINOR=$(echo 1.8.3 | cut -d'.' -f2)
-  PACKAGE_VERSION_MICRO=$(echo 1.8.3 | cut -d'.' -f3)
+  PACKAGE_VERSION_MAJOR=$(echo 1.9.90 | cut -d'.' -f1)
+  PACKAGE_VERSION_MINOR=$(echo 1.9.90 | cut -d'.' -f2)
+  PACKAGE_VERSION_MICRO=$(echo 1.9.90 | cut -d'.' -f3)
 
 
 
@@ -4133,7 +4142,7 @@
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking nano version" >&5
 $as_echo_n "checking nano version... " >&6; }
 
-  NANO=$(echo 1.8.3 | cut -d'.' -f4)
+  NANO=$(echo 1.9.90 | cut -d'.' -f4)
 
   if test x"$NANO" = x || test "x$NANO" = "x0" ; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: 0 (release)" >&5
@@ -8967,10 +8976,10 @@
 done
 
 
-  GST_CURRENT=803
+  GST_CURRENT=990
   GST_REVISION=0
-  GST_AGE=803
-  GST_LIBVERSION=803:0:803
+  GST_AGE=990
+  GST_LIBVERSION=990:0:990
 
 
 
@@ -13598,7 +13607,7 @@
 
 
 
-GST_REQ=1.8.0
+GST_REQ=1.9.90
 
 
 
@@ -22891,6 +22900,648 @@
 
 
 
+
+
+
+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
+
+ax_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on Tru64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
+        ax_pthread_save_CC="$CC"
+        ax_pthread_save_CFLAGS="$CFLAGS"
+        ax_pthread_save_LIBS="$LIBS"
+        if test "x$PTHREAD_CC" != "x"; then :
+  CC="$PTHREAD_CC"
+fi
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS" >&5
+$as_echo_n "checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS... " >&6; }
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_join ();
+int
+main ()
+{
+return pthread_join ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
+$as_echo "$ax_pthread_ok" >&6; }
+        if test "x$ax_pthread_ok" = "xno"; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        CC="$ax_pthread_save_CC"
+        CFLAGS="$ax_pthread_save_CFLAGS"
+        LIBS="$ax_pthread_save_LIBS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
+#           (Note: HP C rejects this with "bad form for `-t' option")
+# -pthreads: Solaris/gcc (Note: HP C also rejects)
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads and
+#      -D_REENTRANT too), HP C (must be checked before -lpthread, which
+#      is present but should not be used directly; and before -mthreads,
+#      because the compiler interprets this as "-mt" + "-hreads")
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case $host_os in
+
+        freebsd*)
+
+        # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+        # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+
+        ax_pthread_flags="-kthread lthread $ax_pthread_flags"
+        ;;
+
+        hpux*)
+
+        # From the cc(1) man page: "[-mt] Sets various -D flags to enable
+        # multi-threading and also sets -lpthread."
+
+        ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
+        ;;
+
+        openedition*)
+
+        # IBM z/OS requires a feature-test macro to be defined in order to
+        # enable POSIX threads at all, so give the user a hint if this is
+        # not set. (We don't define these ourselves, as they can affect
+        # other portions of the system API in unpredictable ways.)
+
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#            if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
+             AX_PTHREAD_ZOS_MISSING
+#            endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "AX_PTHREAD_ZOS_MISSING" >/dev/null 2>&1; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&5
+$as_echo "$as_me: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&2;}
+fi
+rm -f conftest*
+
+        ;;
+
+        solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed. (N.B.: The stubs are missing
+        # pthread_cleanup_push, or rather a function called by this macro,
+        # so we could check for that, but who knows whether they'll stub
+        # that too in a future libc.)  So we'll check first for the
+        # standard Solaris way of linking pthreads (-mt -lpthread).
+
+        ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags"
+        ;;
+esac
+
+# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
+
+if test "x$GCC" = "xyes"; then :
+  ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"
+fi
+
+# The presence of a feature test macro requesting re-entrant function
+# definitions is, on some systems, a strong hint that pthreads support is
+# correctly enabled
+
+case $host_os in
+        darwin* | hpux* | linux* | osf* | solaris*)
+        ax_pthread_check_macro="_REENTRANT"
+        ;;
+
+        aix*)
+        ax_pthread_check_macro="_THREAD_SAFE"
+        ;;
+
+        *)
+        ax_pthread_check_macro="--"
+        ;;
+esac
+if test "x$ax_pthread_check_macro" = "x--"; then :
+  ax_pthread_check_cond=0
+else
+  ax_pthread_check_cond="!defined($ax_pthread_check_macro)"
+fi
+
+# Are we compiling with Clang?
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC is Clang" >&5
+$as_echo_n "checking whether $CC is Clang... " >&6; }
+if ${ax_cv_PTHREAD_CLANG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ax_cv_PTHREAD_CLANG=no
+     # Note that Autoconf sets GCC=yes for Clang as well as GCC
+     if test "x$GCC" = "xyes"; then
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
+#            if defined(__clang__) && defined(__llvm__)
+             AX_PTHREAD_CC_IS_CLANG
+#            endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "AX_PTHREAD_CC_IS_CLANG" >/dev/null 2>&1; then :
+  ax_cv_PTHREAD_CLANG=yes
+fi
+rm -f conftest*
+
+     fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG" >&5
+$as_echo "$ax_cv_PTHREAD_CLANG" >&6; }
+ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
+
+ax_pthread_clang_warning=no
+
+# Clang needs special handling, because older versions handle the -pthread
+# option in a rather... idiosyncratic way
+
+if test "x$ax_pthread_clang" = "xyes"; then
+
+        # Clang takes -pthread; it has never supported any other flag
+
+        # (Note 1: This will need to be revisited if a system that Clang
+        # supports has POSIX threads in a separate library.  This tends not
+        # to be the way of modern systems, but it's conceivable.)
+
+        # (Note 2: On some systems, notably Darwin, -pthread is not needed
+        # to get POSIX threads support; the API is always present and
+        # active.  We could reasonably leave PTHREAD_CFLAGS empty.  But
+        # -pthread does define _REENTRANT, and while the Darwin headers
+        # ignore this macro, third-party headers might not.)
+
+        PTHREAD_CFLAGS="-pthread"
+        PTHREAD_LIBS=
+
+        ax_pthread_ok=yes
+
+        # However, older versions of Clang make a point of warning the user
+        # that, in an invocation where only linking and no compilation is
+        # taking place, the -pthread option has no effect ("argument unused
+        # during compilation").  They expect -pthread to be passed in only
+        # when source code is being compiled.
+        #
+        # Problem is, this is at odds with the way Automake and most other
+        # C build frameworks function, which is that the same flags used in
+        # compilation (CFLAGS) are also used in linking.  Many systems
+        # supported by AX_PTHREAD require exactly this for POSIX threads
+        # support, and in fact it is often not straightforward to specify a
+        # flag that is used only in the compilation phase and not in
+        # linking.  Such a scenario is extremely rare in practice.
+        #
+        # Even though use of the -pthread flag in linking would only print
+        # a warning, this can be a nuisance for well-run software projects
+        # that build with -Werror.  So if the active version of Clang has
+        # this misfeature, we search for an option to squash it.
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread" >&5
+$as_echo_n "checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread... " >&6; }
+if ${ax_cv_PTHREAD_CLANG_NO_WARN_FLAG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
+             # Create an alternate version of $ac_link that compiles and
+             # links in two steps (.c -> .o, .o -> exe) instead of one
+             # (.c -> exe), because the warning occurs only in the second
+             # step
+             ax_pthread_save_ac_link="$ac_link"
+             ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
+             ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
+             ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
+             ax_pthread_save_CFLAGS="$CFLAGS"
+             for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
+                if test "x$ax_pthread_try" = "xunknown"; then :
+  break
+fi
+                CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
+                ac_link="$ax_pthread_save_ac_link"
+                cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int main(void){return 0;}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_link="$ax_pthread_2step_ac_link"
+                     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int main(void){return 0;}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+             done
+             ac_link="$ax_pthread_save_ac_link"
+             CFLAGS="$ax_pthread_save_CFLAGS"
+             if test "x$ax_pthread_try" = "x"; then :
+  ax_pthread_try=no
+fi
+             ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&5
+$as_echo "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&6; }
+
+        case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
+                no | unknown) ;;
+                *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
+        esac
+
+fi # $ax_pthread_clang = yes
+
+if test "x$ax_pthread_ok" = "xno"; then
+for ax_pthread_try_flag in $ax_pthread_flags; do
+
+        case $ax_pthread_try_flag in
+                none)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
+$as_echo_n "checking whether pthreads work without any flags... " >&6; }
+                ;;
+
+                -mt,pthread)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with -mt -lpthread" >&5
+$as_echo_n "checking whether pthreads work with -mt -lpthread... " >&6; }
+                PTHREAD_CFLAGS="-mt"
+                PTHREAD_LIBS="-lpthread"
+                ;;
+
+                -*)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $ax_pthread_try_flag" >&5
+$as_echo_n "checking whether pthreads work with $ax_pthread_try_flag... " >&6; }
+                PTHREAD_CFLAGS="$ax_pthread_try_flag"
+                ;;
+
+                pthread-config)
+                # Extract the first word of "pthread-config", so it can be a program name with args.
+set dummy pthread-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ax_pthread_config+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ax_pthread_config"; then
+  ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ax_pthread_config="yes"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no"
+fi
+fi
+ax_pthread_config=$ac_cv_prog_ax_pthread_config
+if test -n "$ax_pthread_config"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5
+$as_echo "$ax_pthread_config" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+                if test "x$ax_pthread_config" = "xno"; then :
+  continue
+fi
+                PTHREAD_CFLAGS="`pthread-config --cflags`"
+                PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+                ;;
+
+                *)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$ax_pthread_try_flag" >&5
+$as_echo_n "checking for the pthreads library -l$ax_pthread_try_flag... " >&6; }
+                PTHREAD_LIBS="-l$ax_pthread_try_flag"
+                ;;
+        esac
+
+        ax_pthread_save_CFLAGS="$CFLAGS"
+        ax_pthread_save_LIBS="$LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+#                       if $ax_pthread_check_cond
+#                        error "$ax_pthread_check_macro must be defined"
+#                       endif
+                        static void routine(void *a) { a = 0; }
+                        static void *start_routine(void *a) { return a; }
+int
+main ()
+{
+pthread_t th; pthread_attr_t attr;
+                        pthread_create(&th, 0, start_routine, 0);
+                        pthread_join(th, 0);
+                        pthread_attr_init(&attr);
+                        pthread_cleanup_push(routine, 0);
+                        pthread_cleanup_pop(0) /* ; */
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+        CFLAGS="$ax_pthread_save_CFLAGS"
+        LIBS="$ax_pthread_save_LIBS"
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
+$as_echo "$ax_pthread_ok" >&6; }
+        if test "x$ax_pthread_ok" = "xyes"; then :
+  break
+fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$ax_pthread_ok" = "xyes"; then
+        ax_pthread_save_CFLAGS="$CFLAGS"
+        ax_pthread_save_LIBS="$LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
+$as_echo_n "checking for joinable pthread attribute... " >&6; }
+if ${ax_cv_PTHREAD_JOINABLE_ATTR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ax_cv_PTHREAD_JOINABLE_ATTR=unknown
+             for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+                 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+int attr = $ax_pthread_attr; return attr /* ; */
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+             done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_JOINABLE_ATTR" >&5
+$as_echo "$ax_cv_PTHREAD_JOINABLE_ATTR" >&6; }
+        if test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
+               test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
+               test "x$ax_pthread_joinable_attr_defined" != "xyes"; then :
+
+cat >>confdefs.h <<_ACEOF
+#define PTHREAD_CREATE_JOINABLE $ax_cv_PTHREAD_JOINABLE_ATTR
+_ACEOF
+
+               ax_pthread_joinable_attr_defined=yes
+
+fi
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether more special flags are required for pthreads" >&5
+$as_echo_n "checking whether more special flags are required for pthreads... " >&6; }
+if ${ax_cv_PTHREAD_SPECIAL_FLAGS+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ax_cv_PTHREAD_SPECIAL_FLAGS=no
+             case $host_os in
+             solaris*)
+             ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
+             ;;
+             esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_SPECIAL_FLAGS" >&5
+$as_echo "$ax_cv_PTHREAD_SPECIAL_FLAGS" >&6; }
+        if test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
+               test "x$ax_pthread_special_flags_added" != "xyes"; then :
+  PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
+               ax_pthread_special_flags_added=yes
+fi
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5
+$as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; }
+if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+int i = PTHREAD_PRIO_INHERIT;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_cv_PTHREAD_PRIO_INHERIT=yes
+else
+  ax_cv_PTHREAD_PRIO_INHERIT=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5
+$as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; }
+        if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
+               test "x$ax_pthread_prio_inherit_defined" != "xyes"; then :
+
+$as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h
+
+               ax_pthread_prio_inherit_defined=yes
+
+fi
+
+        CFLAGS="$ax_pthread_save_CFLAGS"
+        LIBS="$ax_pthread_save_LIBS"
+
+        # More AIX lossage: compile with *_r variant
+        if test "x$GCC" != "xyes"; then
+            case $host_os in
+                aix*)
+                case "x/$CC" in #(
+  x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6) :
+    #handle absolute path differently from PATH based program lookup
+                     case "x$CC" in #(
+  x/*) :
+    if as_fn_executable_p ${CC}_r; then :
+  PTHREAD_CC="${CC}_r"
+fi ;; #(
+  *) :
+    for ac_prog in ${CC}_r
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_PTHREAD_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$PTHREAD_CC"; then
+  ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PTHREAD_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
+if test -n "$PTHREAD_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5
+$as_echo "$PTHREAD_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$PTHREAD_CC" && break
+done
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+ ;;
+esac ;; #(
+  *) :
+     ;;
+esac
+                ;;
+            esac
+        fi
+fi
+
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+
+
+
+
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test "x$ax_pthread_ok" = "xyes"; then
+
+$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
+
+        :
+else
+        ax_pthread_ok=no
+
+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}: checking for ANSI C header files" >&5
 $as_echo_n "checking for ANSI C header files... " >&6; }
 if ${ac_cv_header_stdc+:} false; then :
@@ -23004,7 +23655,7 @@
 fi
 
 
-for ac_header in xmmintrin.h emmintrin.h
+for ac_header in xmmintrin.h emmintrin.h smmintrin.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -23018,6 +23669,177 @@
 done
 
 
+ac_fn_c_check_decl "$LINENO" "__i386__" "ac_cv_have_decl___i386__" "$ac_includes_default"
+if test "x$ac_cv_have_decl___i386__" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL___I386__ $ac_have_decl
+_ACEOF
+if test $ac_have_decl = 1; then :
+  HAVE_X86=1
+fi
+
+ac_fn_c_check_decl "$LINENO" "__x86_64__" "ac_cv_have_decl___x86_64__" "$ac_includes_default"
+if test "x$ac_cv_have_decl___x86_64__" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL___X86_64__ $ac_have_decl
+_ACEOF
+if test $ac_have_decl = 1; then :
+  HAVE_X86=1
+fi
+
+
+SSE_CFLAGS="-msse"
+SSE2_CFLAGS="-msse2"
+SSE41_CFLAGS="-msse4.1"
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands $SSE_CFLAGS" >&5
+$as_echo_n "checking to see if compiler understands $SSE_CFLAGS... " >&6; }
+
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $SSE_CFLAGS"
+
+  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
+    HAVE_SSE=1
+    true
+  else
+    HAVE_SSE=0
+    true
+  fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5
+$as_echo "$flag_ok" >&6; }
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands $SSE2_CFLAGS" >&5
+$as_echo_n "checking to see if compiler understands $SSE2_CFLAGS... " >&6; }
+
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $SSE2_CFLAGS"
+
+  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
+    HAVE_SSE2=1
+    true
+  else
+    HAVE_SSE2=0
+    true
+  fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5
+$as_echo "$flag_ok" >&6; }
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking to see if compiler understands $SSE41_CFLAGS" >&5
+$as_echo_n "checking to see if compiler understands $SSE41_CFLAGS... " >&6; }
+
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $SSE41_CFLAGS"
+
+  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
+    HAVE_SSE41=1
+    true
+  else
+    HAVE_SSE41=0
+    true
+  fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag_ok" >&5
+$as_echo "$flag_ok" >&6; }
+
+
+ if test "x${HAVE_X86}" = "x1"; then
+  HAVE_X86_TRUE=
+  HAVE_X86_FALSE='#'
+else
+  HAVE_X86_TRUE='#'
+  HAVE_X86_FALSE=
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SSE $HAVE_SSE
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SSE2 $HAVE_SSE2
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SSE41 $HAVE_SSE41
+_ACEOF
+
+
+
+
+
+
 for ac_header in sys/socket.h
 do :
   ac_fn_c_check_header_compile "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default
@@ -24239,7 +25061,7 @@
 
 
 
-  ORC_REQ=0.4.23
+  ORC_REQ=0.4.24
 
   # Check whether --enable-orc was given.
 if test "${enable_orc+set}" = set; then :
@@ -25830,6 +26652,10 @@
 fi
 
 
+if test x$enable_static = xyes -a x$enable_shared = xno; then
+  GST_STATIC_CFLAGS="-DGST_STATIC_COMPILATION"
+fi
+
 # set by AG_GST_PARSE_SUBSYSTEM_DISABLES above
 NO_WARNINGS=""
 
@@ -31140,7 +31966,7 @@
 GST_PLUGINS_BASE_CFLAGS="-I\$(top_srcdir)/gst-libs -I\$(top_builddir)/gst-libs"
 
 
-GST_CFLAGS="$GST_CFLAGS"
+GST_CFLAGS="$GST_CFLAGS $GST_STATIC_CFLAGS"
 GST_CXXFLAGS="$GLIB_CFLAGS $GST_CFLAGS \$(GLIB_EXTRA_CFLAGS) \$(GST_OPTION_CXXFLAGS)"
 GST_CFLAGS="$GLIB_CFLAGS $GST_CFLAGS \$(GLIB_EXTRA_CFLAGS) \$(GST_OPTION_CFLAGS)"
 
@@ -31163,7 +31989,7 @@
 
 $MKDIR_P tests/check/orc
 
-ac_config_files="$ac_config_files Makefile gst-plugins-base.spec gst/Makefile gst/adder/Makefile gst/app/Makefile gst/audioconvert/Makefile gst/audiorate/Makefile gst/audiotestsrc/Makefile gst/encoding/Makefile gst/videoconvert/Makefile gst/gio/Makefile gst/playback/Makefile gst/audioresample/Makefile gst/subparse/Makefile gst/tcp/Makefile gst/typefind/Makefile gst/videotestsrc/Makefile gst/videorate/Makefile gst/videoscale/Makefile gst/volume/Makefile sys/Makefile sys/ximage/Makefile sys/xvimage/Makefile ext/Makefile ext/alsa/Makefile ext/cdparanoia/Makefile ext/libvisual/Makefile ext/ogg/Makefile ext/opus/Makefile ext/pango/Makefile ext/theora/Makefile ext/vorbis/Makefile gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/allocators/Makefile gst-libs/gst/audio/Makefile gst-libs/gst/app/Makefile gst-libs/gst/fft/Makefile gst-libs/gst/riff/Makefile gst-libs/gst/rtp/Makefile gst-libs/gst/rtsp/Makefile gst-libs/gst/sdp/Makefile gst-libs/gst/tag/Makefile gst-libs/gst/pbutils/Makefile gst-libs/gst/pbutils/gstpluginsbaseversion.h gst-libs/gst/video/Makefile tools/Makefile pkgconfig/Makefile pkgconfig/gstreamer-allocators.pc pkgconfig/gstreamer-allocators-uninstalled.pc pkgconfig/gstreamer-audio.pc pkgconfig/gstreamer-audio-uninstalled.pc pkgconfig/gstreamer-app.pc pkgconfig/gstreamer-app-uninstalled.pc pkgconfig/gstreamer-fft.pc pkgconfig/gstreamer-fft-uninstalled.pc pkgconfig/gstreamer-pbutils.pc pkgconfig/gstreamer-pbutils-uninstalled.pc pkgconfig/gstreamer-riff.pc pkgconfig/gstreamer-riff-uninstalled.pc pkgconfig/gstreamer-rtp.pc pkgconfig/gstreamer-rtp-uninstalled.pc pkgconfig/gstreamer-rtsp.pc pkgconfig/gstreamer-rtsp-uninstalled.pc pkgconfig/gstreamer-sdp.pc pkgconfig/gstreamer-sdp-uninstalled.pc pkgconfig/gstreamer-tag.pc pkgconfig/gstreamer-tag-uninstalled.pc pkgconfig/gstreamer-video.pc pkgconfig/gstreamer-video-uninstalled.pc pkgconfig/gstreamer-plugins-base.pc pkgconfig/gstreamer-plugins-base-uninstalled.pc tests/Makefile tests/check/Makefile tests/examples/Makefile tests/examples/app/Makefile tests/examples/audio/Makefile tests/examples/dynamic/Makefile tests/examples/encoding/Makefile tests/examples/fft/Makefile tests/examples/gio/Makefile tests/examples/overlay/Makefile tests/examples/seek/Makefile tests/examples/snapshot/Makefile tests/examples/playback/Makefile tests/examples/playrec/Makefile tests/files/Makefile tests/icles/Makefile tests/icles/playback/Makefile docs/Makefile docs/design/Makefile docs/libs/Makefile docs/plugins/Makefile docs/version.entities po/Makefile.in common/Makefile common/m4/Makefile m4/Makefile"
+ac_config_files="$ac_config_files Makefile gst-plugins-base.spec gst/Makefile gst/adder/Makefile gst/app/Makefile gst/audioconvert/Makefile gst/audiorate/Makefile gst/audiotestsrc/Makefile gst/encoding/Makefile gst/videoconvert/Makefile gst/gio/Makefile gst/playback/Makefile gst/audioresample/Makefile gst/subparse/Makefile gst/tcp/Makefile gst/typefind/Makefile gst/videotestsrc/Makefile gst/videorate/Makefile gst/videoscale/Makefile gst/volume/Makefile sys/Makefile sys/ximage/Makefile sys/xvimage/Makefile ext/Makefile ext/alsa/Makefile ext/cdparanoia/Makefile ext/libvisual/Makefile ext/ogg/Makefile ext/opus/Makefile ext/pango/Makefile ext/theora/Makefile ext/vorbis/Makefile gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/allocators/Makefile gst-libs/gst/audio/Makefile gst-libs/gst/app/Makefile gst-libs/gst/fft/Makefile gst-libs/gst/riff/Makefile gst-libs/gst/rtp/Makefile gst-libs/gst/rtsp/Makefile gst-libs/gst/sdp/Makefile gst-libs/gst/tag/Makefile gst-libs/gst/pbutils/Makefile gst-libs/gst/pbutils/gstpluginsbaseversion.h gst-libs/gst/video/Makefile tools/Makefile pkgconfig/Makefile pkgconfig/gstreamer-allocators.pc pkgconfig/gstreamer-allocators-uninstalled.pc pkgconfig/gstreamer-audio.pc pkgconfig/gstreamer-audio-uninstalled.pc pkgconfig/gstreamer-app.pc pkgconfig/gstreamer-app-uninstalled.pc pkgconfig/gstreamer-fft.pc pkgconfig/gstreamer-fft-uninstalled.pc pkgconfig/gstreamer-pbutils.pc pkgconfig/gstreamer-pbutils-uninstalled.pc pkgconfig/gstreamer-riff.pc pkgconfig/gstreamer-riff-uninstalled.pc pkgconfig/gstreamer-rtp.pc pkgconfig/gstreamer-rtp-uninstalled.pc pkgconfig/gstreamer-rtsp.pc pkgconfig/gstreamer-rtsp-uninstalled.pc pkgconfig/gstreamer-sdp.pc pkgconfig/gstreamer-sdp-uninstalled.pc pkgconfig/gstreamer-tag.pc pkgconfig/gstreamer-tag-uninstalled.pc pkgconfig/gstreamer-video.pc pkgconfig/gstreamer-video-uninstalled.pc pkgconfig/gstreamer-plugins-base.pc pkgconfig/gstreamer-plugins-base-uninstalled.pc tests/Makefile tests/check/Makefile tests/examples/Makefile tests/examples/app/Makefile tests/examples/audio/Makefile tests/examples/decodebin_next/Makefile tests/examples/dynamic/Makefile tests/examples/encoding/Makefile tests/examples/fft/Makefile tests/examples/gio/Makefile tests/examples/overlay/Makefile tests/examples/seek/Makefile tests/examples/snapshot/Makefile tests/examples/playback/Makefile tests/examples/playrec/Makefile tests/files/Makefile tests/icles/Makefile tests/icles/playback/Makefile docs/Makefile docs/design/Makefile docs/libs/Makefile docs/plugins/Makefile docs/version.entities po/Makefile.in common/Makefile common/m4/Makefile m4/Makefile"
 
 
 sed \
@@ -31470,6 +32296,10 @@
   as_fn_error $? "conditional \"ENABLE_PLUGIN_DOCS\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${HAVE_X86_TRUE}" && test -z "${HAVE_X86_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_X86\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${HAVE_SYS_SOCKET_H_TRUE}" && test -z "${HAVE_SYS_SOCKET_H_FALSE}"; then
   as_fn_error $? "conditional \"HAVE_SYS_SOCKET_H\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -32083,7 +32913,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by GStreamer Base Plug-ins $as_me 1.8.3, which was
+This file was extended by GStreamer Base Plug-ins $as_me 1.9.90, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -32149,7 +32979,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 Base Plug-ins config.status 1.8.3
+GStreamer Base Plug-ins config.status 1.9.90
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -32768,6 +33598,7 @@
     "tests/examples/Makefile") CONFIG_FILES="$CONFIG_FILES tests/examples/Makefile" ;;
     "tests/examples/app/Makefile") CONFIG_FILES="$CONFIG_FILES tests/examples/app/Makefile" ;;
     "tests/examples/audio/Makefile") CONFIG_FILES="$CONFIG_FILES tests/examples/audio/Makefile" ;;
+    "tests/examples/decodebin_next/Makefile") CONFIG_FILES="$CONFIG_FILES tests/examples/decodebin_next/Makefile" ;;
     "tests/examples/dynamic/Makefile") CONFIG_FILES="$CONFIG_FILES tests/examples/dynamic/Makefile" ;;
     "tests/examples/encoding/Makefile") CONFIG_FILES="$CONFIG_FILES tests/examples/encoding/Makefile" ;;
     "tests/examples/fft/Makefile") CONFIG_FILES="$CONFIG_FILES tests/examples/fft/Makefile" ;;
diff --git a/configure.ac b/configure.ac
index b6f8fb8..6e9dc52 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/prerelease
-AC_INIT([GStreamer Base Plug-ins],[1.8.3],[http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer],[gst-plugins-base])
+AC_INIT([GStreamer Base Plug-ins],[1.9.90],[http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer],[gst-plugins-base])
 
 AG_GST_INIT
 
@@ -56,10 +56,10 @@
 dnl      1.10.9 (who knows) => 1009
 dnl
 dnl sets GST_LT_LDFLAGS
-AS_LIBTOOL(GST, 803, 0, 803)
+AS_LIBTOOL(GST, 990, 0, 990)
 
 dnl *** required versions of GStreamer stuff ***
-GST_REQ=1.8.0
+GST_REQ=1.9.90
 
 dnl *** autotools stuff ****
 
@@ -167,6 +167,9 @@
 LT_LIB_M
 AC_SUBST(LIBM)
 
+dnl check for pthreads
+AX_PTHREAD
+
 dnl *** checks for header files ***
 
 dnl check if we have ANSI C header files
@@ -174,7 +177,31 @@
 
 dnl check for GCC specific SSE headers
 dnl these are used by the speex resampler code
-AC_CHECK_HEADERS([xmmintrin.h emmintrin.h])
+AC_CHECK_HEADERS([xmmintrin.h emmintrin.h smmintrin.h])
+
+dnl also check which architecture we're on for building files with intrinsics
+dnl separately
+AC_CHECK_DECLS([__i386__], [HAVE_X86=1])
+AC_CHECK_DECLS([__x86_64__], [HAVE_X86=1])
+
+dnl check for -m* compiler flags too
+SSE_CFLAGS="-msse"
+SSE2_CFLAGS="-msse2"
+SSE41_CFLAGS="-msse4.1"
+
+AS_COMPILER_FLAG([$SSE_CFLAGS], [HAVE_SSE=1], [HAVE_SSE=0])
+AS_COMPILER_FLAG([$SSE2_CFLAGS], [HAVE_SSE2=1], [HAVE_SSE2=0])
+AS_COMPILER_FLAG([$SSE41_CFLAGS], [HAVE_SSE41=1], [HAVE_SSE41=0])
+
+AM_CONDITIONAL(HAVE_X86, [test "x${HAVE_X86}" = "x1"])
+
+AC_DEFINE_UNQUOTED(HAVE_SSE, [$HAVE_SSE], [SSE support is enabled])
+AC_DEFINE_UNQUOTED(HAVE_SSE2, [$HAVE_SSE2], [SSE2 support is enabled])
+AC_DEFINE_UNQUOTED(HAVE_SSE41, [$HAVE_SSE41], [SSE4.1 support is enabled])
+
+AC_SUBST(SSE_CFLAGS)
+AC_SUBST(SSE2_CFLAGS)
+AC_SUBST(SSE41_CFLAGS)
 
 dnl used in gst/tcp
 AC_CHECK_HEADERS([sys/socket.h],
@@ -251,7 +278,7 @@
 GLIB_REQ=2.40.0
 AG_GST_GLIB_CHECK([$GLIB_REQ])
 
-ORC_CHECK([0.4.23])
+ORC_CHECK([0.4.24])
 
 dnl checks for gstreamer
 dnl uninstalled is selected preferentially -- see pkg-config(1)
@@ -396,6 +423,12 @@
 AC_SUBST(GST_PLUGIN_LIBTOOLFLAGS)
 AM_CONDITIONAL(GST_PLUGIN_BUILD_STATIC, test "x$enable_static_plugins" = "xyes")
 
+dnl If only building static libraries, define GST_STATIC_COMPILATION. This is
+dnl needed only on Windows, but it doesn't hurt to have it everywhere.
+if test x$enable_static = xyes -a x$enable_shared = xno; then
+  GST_STATIC_CFLAGS="-DGST_STATIC_COMPILATION"
+fi
+
 # set by AG_GST_PARSE_SUBSYSTEM_DISABLES above
 dnl make sure it doesn't complain about unused variables if debugging is disabled
 NO_WARNINGS=""
@@ -801,7 +834,7 @@
 
 dnl FIXME: do we want to rename to GST_ALL_* ?
 dnl add GST_OPTION_CFLAGS, but overridable
-GST_CFLAGS="$GST_CFLAGS"
+GST_CFLAGS="$GST_CFLAGS $GST_STATIC_CFLAGS"
 GST_CXXFLAGS="$GLIB_CFLAGS $GST_CFLAGS \$(GLIB_EXTRA_CFLAGS) \$(GST_OPTION_CXXFLAGS)"
 GST_CFLAGS="$GLIB_CFLAGS $GST_CFLAGS \$(GLIB_EXTRA_CFLAGS) \$(GST_OPTION_CFLAGS)"
 AC_SUBST(GST_CFLAGS)
@@ -912,6 +945,7 @@
 tests/examples/Makefile
 tests/examples/app/Makefile
 tests/examples/audio/Makefile
+tests/examples/decodebin_next/Makefile
 tests/examples/dynamic/Makefile
 tests/examples/encoding/Makefile
 tests/examples/fft/Makefile
diff --git a/docs/Makefile.in b/docs/Makefile.in
index 1d2265d..94cd2a5 100644
--- a/docs/Makefile.in
+++ b/docs/Makefile.in
@@ -96,6 +96,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -404,6 +405,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -417,6 +421,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -454,6 +461,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/docs/design/Makefile.in b/docs/design/Makefile.in
index 8a8700c..6d9c958 100644
--- a/docs/design/Makefile.in
+++ b/docs/design/Makefile.in
@@ -96,6 +96,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -405,6 +406,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -418,6 +422,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -455,6 +462,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/docs/design/part-mediatype-video-raw.txt b/docs/design/part-mediatype-video-raw.txt
index 541b366..c7fc837 100644
--- a/docs/design/part-mediatype-video-raw.txt
+++ b/docs/design/part-mediatype-video-raw.txt
@@ -754,6 +754,30 @@
           default rstride: RU4 (width * 3)
           default size:    rstride (image) * height
 
+ "IYU2" packed 4:4:4 YUV, U-Y-V order
+
+       +--+--+--+ +--+--+--+
+       |U0|Y0|V0| |U1|Y1|V1| ...
+       +--+--+--+ +--+--+--+
+
+        Component 0: Y
+          depth:           8
+          pstride:         3
+          offset:          1
+
+        Component 1: U
+          depth            8
+          pstride:         3
+          offset:          0
+
+        Component 2: V
+          depth:           8
+          pstride:         3
+          offset:          2
+
+        Image
+          default rstride: RU4 (width * 3)
+          default size:    rstride (image) * height
 
  "RGB16" rgb 5-6-5 bits per component
 
diff --git a/docs/libs/Makefile.in b/docs/libs/Makefile.in
index 433b8d1..b058347 100644
--- a/docs/libs/Makefile.in
+++ b/docs/libs/Makefile.in
@@ -115,6 +115,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -366,6 +367,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -379,6 +383,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -416,6 +423,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -901,7 +909,11 @@
 
 @ENABLE_GTK_DOC_TRUE@sgml-build.stamp: setup-build.stamp $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(expand_content_files)
 @ENABLE_GTK_DOC_TRUE@	@echo '  DOC   Building XML'
-@ENABLE_GTK_DOC_TRUE@	@gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR)  --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) --output-format=xml $(MKDB_OPTIONS)
+@ENABLE_GTK_DOC_TRUE@	@_source_dir='' ;						\
+@ENABLE_GTK_DOC_TRUE@	for i in $(DOC_SOURCE_DIR) ; do					\
+@ENABLE_GTK_DOC_TRUE@	    _source_dir="$${_source_dir} --source-dir=$$i" ;	        \
+@ENABLE_GTK_DOC_TRUE@	done ;							        \
+@ENABLE_GTK_DOC_TRUE@	gtkdoc-mkdb --module=$(DOC_MODULE) $${_source_dir}  --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) --output-format=xml $(MKDB_OPTIONS)
 @ENABLE_GTK_DOC_TRUE@	@cp ../version.entities xml
 @ENABLE_GTK_DOC_TRUE@	@touch sgml-build.stamp
 
diff --git a/docs/libs/gst-plugins-base-libs-docs.sgml b/docs/libs/gst-plugins-base-libs-docs.sgml
index 57e2407..7e7a58c 100644
--- a/docs/libs/gst-plugins-base-libs-docs.sgml
+++ b/docs/libs/gst-plugins-base-libs-docs.sgml
@@ -209,6 +209,7 @@
       <xi:include href="xml/gstvideosink.xml" />
       <xi:include href="xml/gstcolorbalance.xml" />
       <xi:include href="xml/gstcolorbalancechannel.xml" />
+      <xi:include href="xml/gstvideodirection.xml" />
       <xi:include href="xml/gstvideoorientation.xml" />
       <xi:include href="xml/gstvideooverlay.xml" />
       <xi:include href="xml/gstvideodecoder.xml" />
diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt
index d00e67c..33e64f8 100644
--- a/docs/libs/gst-plugins-base-libs-sections.txt
+++ b/docs/libs/gst-plugins-base-libs-sections.txt
@@ -49,6 +49,8 @@
 gst_app_src_set_latency
 gst_app_src_set_size
 gst_app_src_get_size
+gst_app_src_set_duration
+gst_app_src_get_duration
 gst_app_src_set_stream_type
 gst_app_src_get_stream_type
 gst_app_src_set_max_bytes
@@ -102,6 +104,8 @@
 gst_app_sink_get_drop
 gst_app_sink_pull_preroll
 gst_app_sink_pull_sample
+gst_app_sink_try_pull_preroll
+gst_app_sink_try_pull_sample
 GstAppSinkCallbacks
 gst_app_sink_set_callbacks
 <SUBSECTION Standard>
@@ -512,6 +516,7 @@
 gst_audio_buffer_reorder_channels
 gst_audio_reorder_channels
 gst_audio_get_channel_reorder_map
+gst_audio_channel_positions_to_string
 GstAudioChannelMixer
 GstAudioChannelMixerFlags
 gst_audio_channel_mixer_new
@@ -876,6 +881,19 @@
 </SECTION>
 
 <SECTION>
+<FILE>gstvideodirection</FILE>
+<INCLUDE>gst/video/videodirection.h</INCLUDE>
+GstVideoDirection
+GstVideoDirectionInterface
+<SUBSECTION Standard>
+GST_TYPE_VIDEO_DIRECTION
+GST_VIDEO_DIRECTION
+GST_IS_VIDEO_DIRECTION
+GST_VIDEO_DIRECTION_GET_INTERFACE
+gst_video_direction_get_type
+</SECTION>
+
+<SECTION>
 <FILE>gstvideoorientation</FILE>
 <INCLUDE>gst/video/videoorientation.h</INCLUDE>
 GstVideoOrientation
@@ -2217,6 +2235,8 @@
 gst_codec_utils_aac_get_index_from_sample_rate
 gst_codec_utils_aac_get_profile
 gst_codec_utils_aac_get_level
+gst_codec_utils_aac_get_channels
+gst_codec_utils_aac_get_sample_rate
 gst_codec_utils_aac_caps_set_level_and_profile
 <SUBSECTION>
 gst_codec_utils_h264_get_profile
@@ -2358,6 +2378,8 @@
 GST_META_TAG_VIDEO_SIZE_STR
 GST_META_TAG_VIDEO_COLORSPACE_STR
 
+GstVideoOrientationMethod
+
 #video-event.h
 <SUBSECTION>
 gst_video_event_new_still_frame
@@ -2601,6 +2623,30 @@
 gst_video_multiview_guess_half_aspect
 gst_video_multiview_video_info_change_mode
 
+#video-timecode.h
+<SUBSECTION>
+GstVideoTimeCode
+GstVideoTimeCodeConfig
+GstVideoTimeCodeFlags
+gst_video_time_code_new
+gst_video_time_code_new_empty
+gst_video_time_code_free
+gst_video_time_code_copy
+gst_video_time_code_init
+gst_video_time_code_clear
+gst_video_time_code_is_valid
+gst_video_time_code_compare
+gst_video_time_code_increment_frame
+gst_video_time_code_add_frames
+gst_video_time_code_frames_since_daily_jam
+gst_video_time_code_nsec_since_daily_jam
+gst_video_time_code_to_date_time
+gst_video_time_code_to_string
+
+<SUBSECTION Standard>
+gst_video_time_code_get_type
+GST_TYPE_VIDEO_TIME_CODE
+
 #video-enumtypes.h
 <SUBSECTION Standard>
 gst_color_balance_type_get_type
@@ -2662,6 +2708,10 @@
 gst_buffer_add_video_gl_texture_upload_meta
 gst_buffer_get_video_gl_texture_upload_meta
 gst_video_gl_texture_upload_meta_upload
+GstVideoTimeCodeMeta
+gst_buffer_add_video_time_code_meta
+gst_buffer_add_video_time_code_meta_full
+gst_buffer_get_video_time_code_meta
 <SUBSECTION Standard>
 gst_video_crop_meta_api_get_type
 gst_video_meta_api_get_type
@@ -2676,6 +2726,10 @@
 GST_VIDEO_GL_TEXTURE_UPLOAD_META_INFO
 gst_video_gl_texture_upload_meta_api_get_type
 gst_video_gl_texture_upload_meta_get_info
+GST_VIDEO_TIME_CODE_META_API_TYPE
+GST_VIDEO_TIME_CODE_META_INFO
+gst_video_time_code_meta_api_get_type
+gst_video_time_code_meta_get_info
 </SECTION>
 
 <SECTION>
diff --git a/docs/libs/gst-plugins-base-libs.types b/docs/libs/gst-plugins-base-libs.types
index 6ce1f36..031229f 100644
--- a/docs/libs/gst-plugins-base-libs.types
+++ b/docs/libs/gst-plugins-base-libs.types
@@ -43,6 +43,8 @@
 #include <gst/video/colorbalance.h>
 gst_color_balance_get_type
 gst_color_balance_channel_get_type
+#include <gst/video/videodirection.h>
+gst_video_direction_get_type
 #include <gst/video/videoorientation.h>
 gst_video_orientation_get_type
 #include <gst/video/videooverlay.h>
diff --git a/docs/libs/html/api-index-full.html b/docs/libs/html/api-index-full.html
index 2885655..c384151 100644
--- a/docs/libs/html/api-index-full.html
+++ b/docs/libs/html/api-index-full.html
@@ -110,6 +110,14 @@
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="gst-plugins-base-libs-appsink.html#gst-app-sink-try-pull-preroll" title="gst_app_sink_try_pull_preroll ()">gst_app_sink_try_pull_preroll</a>, function in <a class="link" href="gst-plugins-base-libs-appsink.html" title="appsink">appsink</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-appsink.html#gst-app-sink-try-pull-sample" title="gst_app_sink_try_pull_sample ()">gst_app_sink_try_pull_sample</a>, function in <a class="link" href="gst-plugins-base-libs-appsink.html" title="appsink">appsink</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="gst-plugins-base-libs-appsrc.html#gst-app-src-end-of-stream" title="gst_app_src_end_of_stream ()">gst_app_src_end_of_stream</a>, function in <a class="link" href="gst-plugins-base-libs-appsrc.html" title="appsrc">appsrc</a>
 </dt>
 <dd></dd>
@@ -122,6 +130,10 @@
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="gst-plugins-base-libs-appsrc.html#gst-app-src-get-duration" title="gst_app_src_get_duration ()">gst_app_src_get_duration</a>, function in <a class="link" href="gst-plugins-base-libs-appsrc.html" title="appsrc">appsrc</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="gst-plugins-base-libs-appsrc.html#gst-app-src-get-emit-signals" title="gst_app_src_get_emit_signals ()">gst_app_src_get_emit_signals</a>, function in <a class="link" href="gst-plugins-base-libs-appsrc.html" title="appsrc">appsrc</a>
 </dt>
 <dd></dd>
@@ -158,6 +170,10 @@
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="gst-plugins-base-libs-appsrc.html#gst-app-src-set-duration" title="gst_app_src_set_duration ()">gst_app_src_set_duration</a>, function in <a class="link" href="gst-plugins-base-libs-appsrc.html" title="appsrc">appsrc</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="gst-plugins-base-libs-appsrc.html#gst-app-src-set-emit-signals" title="gst_app_src_set_emit_signals ()">gst_app_src_set_emit_signals</a>, function in <a class="link" href="gst-plugins-base-libs-appsrc.html" title="appsrc">appsrc</a>
 </dt>
 <dd></dd>
@@ -610,6 +626,10 @@
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="gst-plugins-base-libs-gstaudiochannels.html#gst-audio-channel-positions-to-string" title="gst_audio_channel_positions_to_string ()">gst_audio_channel_positions_to_string</a>, function in <a class="link" href="gst-plugins-base-libs-gstaudiochannels.html" title="gstaudiochannels">gstaudiochannels</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="gst-plugins-base-libs-gstaudiochannels.html#gst-audio-channel-positions-to-valid-order" title="gst_audio_channel_positions_to_valid_order ()">gst_audio_channel_positions_to_valid_order</a>, function in <a class="link" href="gst-plugins-base-libs-gstaudiochannels.html" title="gstaudiochannels">gstaudiochannels</a>
 </dt>
 <dd></dd>
@@ -1359,6 +1379,14 @@
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="gst-plugins-base-libs-gstvideometa.html#gst-buffer-add-video-time-code-meta" title="gst_buffer_add_video_time_code_meta ()">gst_buffer_add_video_time_code_meta</a>, function in <a class="link" href="gst-plugins-base-libs-gstvideometa.html" title="gstvideometa">gstvideometa</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideometa.html#gst-buffer-add-video-time-code-meta-full" title="gst_buffer_add_video_time_code_meta_full ()">gst_buffer_add_video_time_code_meta_full</a>, function in <a class="link" href="gst-plugins-base-libs-gstvideometa.html" title="gstvideometa">gstvideometa</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="gst-plugins-base-libs-gstaudiometa.html#gst-buffer-get-audio-clipping-meta" title="gst_buffer_get_audio_clipping_meta()">gst_buffer_get_audio_clipping_meta</a>, macro in <a class="link" href="gst-plugins-base-libs-gstaudiometa.html" title="gstaudiometa">gstaudiometa</a>
 </dt>
 <dd></dd>
@@ -1403,6 +1431,10 @@
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="gst-plugins-base-libs-gstvideometa.html#gst-buffer-get-video-time-code-meta" title="gst_buffer_get_video_time_code_meta()">gst_buffer_get_video_time_code_meta</a>, macro in <a class="link" href="gst-plugins-base-libs-gstvideometa.html" title="gstvideometa">gstvideometa</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="gst-plugins-base-libs-GstVideoPool.html#gst-buffer-pool-config-get-video-alignment" title="gst_buffer_pool_config_get_video_alignment ()">gst_buffer_pool_config_get_video_alignment</a>, function in <a class="link" href="gst-plugins-base-libs-GstVideoPool.html" title="GstVideoPool">GstVideoPool</a>
 </dt>
 <dd></dd>
@@ -1440,6 +1472,10 @@
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="gst-plugins-base-libs-gstpbutilscodecutils.html#gst-codec-utils-aac-get-channels" title="gst_codec_utils_aac_get_channels ()">gst_codec_utils_aac_get_channels</a>, function in <a class="link" href="gst-plugins-base-libs-gstpbutilscodecutils.html" title="gstpbutilscodecutils">gstpbutilscodecutils</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="gst-plugins-base-libs-gstpbutilscodecutils.html#gst-codec-utils-aac-get-index-from-sample-rate" title="gst_codec_utils_aac_get_index_from_sample_rate ()">gst_codec_utils_aac_get_index_from_sample_rate</a>, function in <a class="link" href="gst-plugins-base-libs-gstpbutilscodecutils.html" title="gstpbutilscodecutils">gstpbutilscodecutils</a>
 </dt>
 <dd></dd>
@@ -1452,6 +1488,10 @@
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="gst-plugins-base-libs-gstpbutilscodecutils.html#gst-codec-utils-aac-get-sample-rate" title="gst_codec_utils_aac_get_sample_rate ()">gst_codec_utils_aac_get_sample_rate</a>, function in <a class="link" href="gst-plugins-base-libs-gstpbutilscodecutils.html" title="gstpbutilscodecutils">gstpbutilscodecutils</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="gst-plugins-base-libs-gstpbutilscodecutils.html#gst-codec-utils-aac-get-sample-rate-from-index" title="gst_codec_utils_aac_get_sample_rate_from_index ()">gst_codec_utils_aac_get_sample_rate_from_index</a>, function in <a class="link" href="gst-plugins-base-libs-gstpbutilscodecutils.html" title="gstpbutilscodecutils">gstpbutilscodecutils</a>
 </dt>
 <dd></dd>
@@ -5183,6 +5223,18 @@
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="gst-plugins-base-libs-gstvideodirection.html#GstVideoDirection-struct" title="GstVideoDirection">GstVideoDirection</a>, struct in <a class="link" href="gst-plugins-base-libs-gstvideodirection.html" title="gstvideodirection">gstvideodirection</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideodirection.html#GstVideoDirection--video-direction" title="The “video-direction” property">GstVideoDirection:video-direction</a>, object property in <a class="link" href="gst-plugins-base-libs-gstvideodirection.html" title="gstvideodirection">gstvideodirection</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideodirection.html#GstVideoDirectionInterface" title="struct GstVideoDirectionInterface">GstVideoDirectionInterface</a>, struct in <a class="link" href="gst-plugins-base-libs-gstvideodirection.html" title="gstvideodirection">gstvideodirection</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="gst-plugins-base-libs-GstVideoDither.html#GstVideoDither" title="GstVideoDither">GstVideoDither</a>, struct in <a class="link" href="gst-plugins-base-libs-GstVideoDither.html" title="GstVideoDither">GstVideoDither</a>
 </dt>
 <dd></dd>
@@ -5287,6 +5339,10 @@
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoOrientationMethod" title="enum GstVideoOrientationMethod">GstVideoOrientationMethod</a>, enum in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="gst-plugins-base-libs-gstvideooverlay.html#GstVideoOverlay-struct" title="GstVideoOverlay">GstVideoOverlay</a>, struct in <a class="link" href="gst-plugins-base-libs-gstvideooverlay.html" title="gstvideooverlay">gstvideooverlay</a>
 </dt>
 <dd></dd>
@@ -5363,6 +5419,22 @@
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode">GstVideoTimeCode</a>, struct in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeConfig" title="struct GstVideoTimeCodeConfig">GstVideoTimeCodeConfig</a>, struct in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeFlags" title="enum GstVideoTimeCodeFlags">GstVideoTimeCodeFlags</a>, enum in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideometa.html#GstVideoTimeCodeMeta" title="GstVideoTimeCodeMeta">GstVideoTimeCodeMeta</a>, struct in <a class="link" href="gst-plugins-base-libs-gstvideometa.html" title="gstvideometa">gstvideometa</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTransferFunction" title="enum GstVideoTransferFunction">GstVideoTransferFunction</a>, enum in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
 </dt>
 <dd></dd>
@@ -6663,6 +6735,62 @@
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-add-frames" title="gst_video_time_code_add_frames ()">gst_video_time_code_add_frames</a>, function in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-clear" title="gst_video_time_code_clear ()">gst_video_time_code_clear</a>, function in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-compare" title="gst_video_time_code_compare ()">gst_video_time_code_compare</a>, function in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-copy" title="gst_video_time_code_copy ()">gst_video_time_code_copy</a>, function in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-frames-since-daily-jam" title="gst_video_time_code_frames_since_daily_jam ()">gst_video_time_code_frames_since_daily_jam</a>, function in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-free" title="gst_video_time_code_free ()">gst_video_time_code_free</a>, function in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-increment-frame" title="gst_video_time_code_increment_frame ()">gst_video_time_code_increment_frame</a>, function in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-init" title="gst_video_time_code_init ()">gst_video_time_code_init</a>, function in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-is-valid" title="gst_video_time_code_is_valid ()">gst_video_time_code_is_valid</a>, function in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-new" title="gst_video_time_code_new ()">gst_video_time_code_new</a>, function in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-new-empty" title="gst_video_time_code_new_empty ()">gst_video_time_code_new_empty</a>, function in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-nsec-since-daily-jam" title="gst_video_time_code_nsec_since_daily_jam ()">gst_video_time_code_nsec_since_daily_jam</a>, function in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-to-date-time" title="gst_video_time_code_to_date_time ()">gst_video_time_code_to_date_time</a>, function in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-to-string" title="gst_video_time_code_to_string ()">gst_video_time_code_to_string</a>, function in <a class="link" href="gst-plugins-base-libs-gstvideo.html" title="gstvideo">gstvideo</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="gst-plugins-base-libs-gsttagvorbis.html#gst-vorbis-tag-add" title="gst_vorbis_tag_add ()">gst_vorbis_tag_add</a>, function in <a class="link" href="gst-plugins-base-libs-gsttagvorbis.html" title="gsttagvorbis">gsttagvorbis</a>
 </dt>
 <dd></dd>
diff --git a/docs/libs/html/gst-plugins-base-libs-1.0.devhelp2 b/docs/libs/html/gst-plugins-base-libs-1.0.devhelp2
index 5fa911b..4227fda 100644
--- a/docs/libs/html/gst-plugins-base-libs-1.0.devhelp2
+++ b/docs/libs/html/gst-plugins-base-libs-1.0.devhelp2
@@ -99,6 +99,7 @@
         <sub name="gstvideosink" link="gst-plugins-base-libs-gstvideosink.html"/>
         <sub name="gstcolorbalance" link="gst-plugins-base-libs-gstcolorbalance.html"/>
         <sub name="gstcolorbalancechannel" link="gst-plugins-base-libs-gstcolorbalancechannel.html"/>
+        <sub name="gstvideodirection" link="gst-plugins-base-libs-gstvideodirection.html"/>
         <sub name="gstvideoorientation" link="gst-plugins-base-libs-gstvideoorientation.html"/>
         <sub name="gstvideooverlay" link="gst-plugins-base-libs-gstvideooverlay.html"/>
         <sub name="GstVideoDecoder" link="gst-plugins-base-libs-GstVideoDecoder.html"/>
@@ -130,6 +131,8 @@
     <keyword type="function" name="gst_app_src_set_latency ()" link="gst-plugins-base-libs-appsrc.html#gst-app-src-set-latency"/>
     <keyword type="function" name="gst_app_src_set_size ()" link="gst-plugins-base-libs-appsrc.html#gst-app-src-set-size"/>
     <keyword type="function" name="gst_app_src_get_size ()" link="gst-plugins-base-libs-appsrc.html#gst-app-src-get-size"/>
+    <keyword type="function" name="gst_app_src_set_duration ()" link="gst-plugins-base-libs-appsrc.html#gst-app-src-set-duration" since="1.10"/>
+    <keyword type="function" name="gst_app_src_get_duration ()" link="gst-plugins-base-libs-appsrc.html#gst-app-src-get-duration" since="1.10"/>
     <keyword type="function" name="gst_app_src_set_stream_type ()" link="gst-plugins-base-libs-appsrc.html#gst-app-src-set-stream-type"/>
     <keyword type="function" name="gst_app_src_get_stream_type ()" link="gst-plugins-base-libs-appsrc.html#gst-app-src-get-stream-type"/>
     <keyword type="function" name="gst_app_src_set_max_bytes ()" link="gst-plugins-base-libs-appsrc.html#gst-app-src-set-max-bytes"/>
@@ -154,6 +157,8 @@
     <keyword type="function" name="gst_app_sink_get_drop ()" link="gst-plugins-base-libs-appsink.html#gst-app-sink-get-drop"/>
     <keyword type="function" name="gst_app_sink_pull_preroll ()" link="gst-plugins-base-libs-appsink.html#gst-app-sink-pull-preroll"/>
     <keyword type="function" name="gst_app_sink_pull_sample ()" link="gst-plugins-base-libs-appsink.html#gst-app-sink-pull-sample"/>
+    <keyword type="function" name="gst_app_sink_try_pull_preroll ()" link="gst-plugins-base-libs-appsink.html#gst-app-sink-try-pull-preroll" since="1.10"/>
+    <keyword type="function" name="gst_app_sink_try_pull_sample ()" link="gst-plugins-base-libs-appsink.html#gst-app-sink-try-pull-sample" since="1.10"/>
     <keyword type="function" name="gst_app_sink_set_callbacks ()" link="gst-plugins-base-libs-appsink.html#gst-app-sink-set-callbacks"/>
     <keyword type="struct" name="GstAppSinkCallbacks" link="gst-plugins-base-libs-appsink.html#GstAppSinkCallbacks"/>
     <keyword type="function" name="GstAudioFormatPack ()" link="gst-plugins-base-libs-gstaudio.html#GstAudioFormatPack"/>
@@ -385,6 +390,7 @@
     <keyword type="function" name="gst_audio_buffer_reorder_channels ()" link="gst-plugins-base-libs-gstaudiochannels.html#gst-audio-buffer-reorder-channels"/>
     <keyword type="function" name="gst_audio_reorder_channels ()" link="gst-plugins-base-libs-gstaudiochannels.html#gst-audio-reorder-channels"/>
     <keyword type="function" name="gst_audio_get_channel_reorder_map ()" link="gst-plugins-base-libs-gstaudiochannels.html#gst-audio-get-channel-reorder-map"/>
+    <keyword type="function" name="gst_audio_channel_positions_to_string ()" link="gst-plugins-base-libs-gstaudiochannels.html#gst-audio-channel-positions-to-string"/>
     <keyword type="function" name="gst_audio_channel_mixer_new ()" link="gst-plugins-base-libs-gstaudiochannels.html#gst-audio-channel-mixer-new"/>
     <keyword type="function" name="gst_audio_channel_mixer_free ()" link="gst-plugins-base-libs-gstaudiochannels.html#gst-audio-channel-mixer-free"/>
     <keyword type="function" name="gst_audio_channel_mixer_is_passthrough ()" link="gst-plugins-base-libs-gstaudiochannels.html#gst-audio-channel-mixer-is-passthrough"/>
@@ -1118,6 +1124,8 @@
     <keyword type="function" name="gst_codec_utils_aac_get_index_from_sample_rate ()" link="gst-plugins-base-libs-gstpbutilscodecutils.html#gst-codec-utils-aac-get-index-from-sample-rate"/>
     <keyword type="function" name="gst_codec_utils_aac_get_profile ()" link="gst-plugins-base-libs-gstpbutilscodecutils.html#gst-codec-utils-aac-get-profile"/>
     <keyword type="function" name="gst_codec_utils_aac_get_level ()" link="gst-plugins-base-libs-gstpbutilscodecutils.html#gst-codec-utils-aac-get-level"/>
+    <keyword type="function" name="gst_codec_utils_aac_get_channels ()" link="gst-plugins-base-libs-gstpbutilscodecutils.html#gst-codec-utils-aac-get-channels"/>
+    <keyword type="function" name="gst_codec_utils_aac_get_sample_rate ()" link="gst-plugins-base-libs-gstpbutilscodecutils.html#gst-codec-utils-aac-get-sample-rate"/>
     <keyword type="function" name="gst_codec_utils_aac_caps_set_level_and_profile ()" link="gst-plugins-base-libs-gstpbutilscodecutils.html#gst-codec-utils-aac-caps-set-level-and-profile"/>
     <keyword type="function" name="gst_codec_utils_h264_get_profile ()" link="gst-plugins-base-libs-gstpbutilscodecutils.html#gst-codec-utils-h264-get-profile"/>
     <keyword type="function" name="gst_codec_utils_h264_get_level ()" link="gst-plugins-base-libs-gstpbutilscodecutils.html#gst-codec-utils-h264-get-level"/>
@@ -1455,11 +1463,26 @@
     <keyword type="function" name="gst_video_multiview_mode_to_caps_string ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-multiview-mode-to-caps-string" since="1.6"/>
     <keyword type="function" name="gst_video_multiview_guess_half_aspect ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-multiview-guess-half-aspect" since="1.6"/>
     <keyword type="function" name="gst_video_multiview_video_info_change_mode ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-multiview-video-info-change-mode" since="1.6"/>
+    <keyword type="function" name="gst_video_time_code_new ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-new" since="1.10"/>
+    <keyword type="function" name="gst_video_time_code_new_empty ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-new-empty" since="1.10"/>
+    <keyword type="function" name="gst_video_time_code_free ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-free" since="1.10"/>
+    <keyword type="function" name="gst_video_time_code_copy ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-copy" since="1.10"/>
+    <keyword type="function" name="gst_video_time_code_init ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-init" since="1.10"/>
+    <keyword type="function" name="gst_video_time_code_clear ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-clear" since="1.10"/>
+    <keyword type="function" name="gst_video_time_code_is_valid ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-is-valid" since="1.10"/>
+    <keyword type="function" name="gst_video_time_code_compare ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-compare" since="1.10"/>
+    <keyword type="function" name="gst_video_time_code_increment_frame ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-increment-frame" since="1.10"/>
+    <keyword type="function" name="gst_video_time_code_add_frames ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-add-frames" since="1.10"/>
+    <keyword type="function" name="gst_video_time_code_frames_since_daily_jam ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-frames-since-daily-jam" since="1.10"/>
+    <keyword type="function" name="gst_video_time_code_nsec_since_daily_jam ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-nsec-since-daily-jam" since="1.10"/>
+    <keyword type="function" name="gst_video_time_code_to_date_time ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-to-date-time" since="1.10"/>
+    <keyword type="function" name="gst_video_time_code_to_string ()" link="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-to-string" since="1.10"/>
     <keyword type="struct" name="struct GstVideoAlignment" link="gst-plugins-base-libs-gstvideo.html#GstVideoAlignment"/>
     <keyword type="macro" name="GST_META_TAG_VIDEO_STR" link="gst-plugins-base-libs-gstvideo.html#GST-META-TAG-VIDEO-STR:CAPS" since="1.2"/>
     <keyword type="macro" name="GST_META_TAG_VIDEO_ORIENTATION_STR" link="gst-plugins-base-libs-gstvideo.html#GST-META-TAG-VIDEO-ORIENTATION-STR:CAPS" since="1.2"/>
     <keyword type="macro" name="GST_META_TAG_VIDEO_SIZE_STR" link="gst-plugins-base-libs-gstvideo.html#GST-META-TAG-VIDEO-SIZE-STR:CAPS" since="1.2"/>
     <keyword type="macro" name="GST_META_TAG_VIDEO_COLORSPACE_STR" link="gst-plugins-base-libs-gstvideo.html#GST-META-TAG-VIDEO-COLORSPACE-STR:CAPS" since="1.2"/>
+    <keyword type="enum" name="enum GstVideoOrientationMethod" link="gst-plugins-base-libs-gstvideo.html#GstVideoOrientationMethod" since="1.10"/>
     <keyword type="enum" name="enum GstVideoFormat" link="gst-plugins-base-libs-gstvideo.html#GstVideoFormat"/>
     <keyword type="macro" name="GST_VIDEO_MAX_PLANES" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-MAX-PLANES:CAPS"/>
     <keyword type="macro" name="GST_VIDEO_MAX_COMPONENTS" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-MAX-COMPONENTS:CAPS"/>
@@ -1486,6 +1509,9 @@
     <keyword type="enum" name="enum GstVideoTileType" link="gst-plugins-base-libs-gstvideo.html#GstVideoTileType"/>
     <keyword type="enum" name="enum GstVideoTileMode" link="gst-plugins-base-libs-gstvideo.html#GstVideoTileMode"/>
     <keyword type="struct" name="GstVideoConverter" link="gst-plugins-base-libs-gstvideo.html#GstVideoConverter"/>
+    <keyword type="struct" name="struct GstVideoTimeCode" link="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" since="1.10"/>
+    <keyword type="struct" name="struct GstVideoTimeCodeConfig" link="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeConfig" since="1.10"/>
+    <keyword type="enum" name="enum GstVideoTimeCodeFlags" link="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeFlags" since="1.10"/>
     <keyword type="function" name="gst_video_meta_map ()" link="gst-plugins-base-libs-gstvideometa.html#gst-video-meta-map"/>
     <keyword type="function" name="gst_video_meta_unmap ()" link="gst-plugins-base-libs-gstvideometa.html#gst-video-meta-unmap"/>
     <keyword type="function" name="gst_video_meta_get_info ()" link="gst-plugins-base-libs-gstvideometa.html#gst-video-meta-get-info"/>
@@ -1503,12 +1529,16 @@
     <keyword type="function" name="gst_buffer_add_video_gl_texture_upload_meta ()" link="gst-plugins-base-libs-gstvideometa.html#gst-buffer-add-video-gl-texture-upload-meta"/>
     <keyword type="macro" name="gst_buffer_get_video_gl_texture_upload_meta()" link="gst-plugins-base-libs-gstvideometa.html#gst-buffer-get-video-gl-texture-upload-meta"/>
     <keyword type="function" name="gst_video_gl_texture_upload_meta_upload ()" link="gst-plugins-base-libs-gstvideometa.html#gst-video-gl-texture-upload-meta-upload"/>
+    <keyword type="function" name="gst_buffer_add_video_time_code_meta ()" link="gst-plugins-base-libs-gstvideometa.html#gst-buffer-add-video-time-code-meta" since="1.10"/>
+    <keyword type="function" name="gst_buffer_add_video_time_code_meta_full ()" link="gst-plugins-base-libs-gstvideometa.html#gst-buffer-add-video-time-code-meta-full" since="1.10"/>
+    <keyword type="macro" name="gst_buffer_get_video_time_code_meta()" link="gst-plugins-base-libs-gstvideometa.html#gst-buffer-get-video-time-code-meta"/>
     <keyword type="struct" name="struct GstVideoMeta" link="gst-plugins-base-libs-gstvideometa.html#GstVideoMeta"/>
     <keyword type="struct" name="GstVideoMetaTransform" link="gst-plugins-base-libs-gstvideometa.html#GstVideoMetaTransform"/>
     <keyword type="struct" name="struct GstVideoCropMeta" link="gst-plugins-base-libs-gstvideometa.html#GstVideoCropMeta"/>
     <keyword type="struct" name="GstVideoRegionOfInterestMeta" link="gst-plugins-base-libs-gstvideometa.html#GstVideoRegionOfInterestMeta"/>
     <keyword type="macro" name="GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META" link="gst-plugins-base-libs-gstvideometa.html#GST-BUFFER-POOL-OPTION-VIDEO-GL-TEXTURE-UPLOAD-META:CAPS" since="1.2.2"/>
     <keyword type="struct" name="struct GstVideoGLTextureUploadMeta" link="gst-plugins-base-libs-gstvideometa.html#GstVideoGLTextureUploadMeta"/>
+    <keyword type="struct" name="GstVideoTimeCodeMeta" link="gst-plugins-base-libs-gstvideometa.html#GstVideoTimeCodeMeta" since="1.10"/>
     <keyword type="function" name="gst_buffer_add_video_affine_transformation_meta ()" link="gst-plugins-base-libs-gstvideoaffinetransformationmeta.html#gst-buffer-add-video-affine-transformation-meta" since="1.8"/>
     <keyword type="macro" name="gst_buffer_get_video_affine_transformation_meta()" link="gst-plugins-base-libs-gstvideoaffinetransformationmeta.html#gst-buffer-get-video-affine-transformation-meta"/>
     <keyword type="function" name="gst_video_affine_transformation_meta_apply_matrix ()" link="gst-plugins-base-libs-gstvideoaffinetransformationmeta.html#gst-video-affine-transformation-meta-apply-matrix" since="1.8"/>
@@ -1606,6 +1636,9 @@
     <keyword type="struct" name="struct GstColorBalanceChannel" link="gst-plugins-base-libs-gstcolorbalancechannel.html#GstColorBalanceChannel-struct"/>
     <keyword type="struct" name="struct GstColorBalanceChannelClass" link="gst-plugins-base-libs-gstcolorbalancechannel.html#GstColorBalanceChannelClass"/>
     <keyword type="signal" name="The “value-changed” signal" link="gst-plugins-base-libs-gstcolorbalancechannel.html#GstColorBalanceChannel-value-changed"/>
+    <keyword type="struct" name="GstVideoDirection" link="gst-plugins-base-libs-gstvideodirection.html#GstVideoDirection-struct"/>
+    <keyword type="struct" name="struct GstVideoDirectionInterface" link="gst-plugins-base-libs-gstvideodirection.html#GstVideoDirectionInterface" since="1.10"/>
+    <keyword type="property" name="The “video-direction” property" link="gst-plugins-base-libs-gstvideodirection.html#GstVideoDirection--video-direction"/>
     <keyword type="function" name="gst_video_orientation_get_hcenter ()" link="gst-plugins-base-libs-gstvideoorientation.html#gst-video-orientation-get-hcenter"/>
     <keyword type="function" name="gst_video_orientation_get_hflip ()" link="gst-plugins-base-libs-gstvideoorientation.html#gst-video-orientation-get-hflip"/>
     <keyword type="function" name="gst_video_orientation_get_vcenter ()" link="gst-plugins-base-libs-gstvideoorientation.html#gst-video-orientation-get-vcenter"/>
@@ -1768,6 +1801,7 @@
     <keyword type="constant" name="GST_FD_MEMORY_FLAG_NONE" link="gst-plugins-base-libs-fdmemory.html#GST-FD-MEMORY-FLAG-NONE:CAPS"/>
     <keyword type="constant" name="GST_FD_MEMORY_FLAG_KEEP_MAPPED" link="gst-plugins-base-libs-fdmemory.html#GST-FD-MEMORY-FLAG-KEEP-MAPPED:CAPS"/>
     <keyword type="constant" name="GST_FD_MEMORY_FLAG_MAP_PRIVATE" link="gst-plugins-base-libs-fdmemory.html#GST-FD-MEMORY-FLAG-MAP-PRIVATE:CAPS"/>
+    <keyword type="constant" name="GST_FD_MEMORY_FLAG_DONT_CLOSE" link="gst-plugins-base-libs-fdmemory.html#GST-FD-MEMORY-FLAG-DONT-CLOSE:CAPS"/>
     <keyword type="constant" name="GST_APP_STREAM_TYPE_STREAM" link="gst-plugins-base-libs-appsrc.html#GST-APP-STREAM-TYPE-STREAM:CAPS"/>
     <keyword type="constant" name="GST_APP_STREAM_TYPE_SEEKABLE" link="gst-plugins-base-libs-appsrc.html#GST-APP-STREAM-TYPE-SEEKABLE:CAPS"/>
     <keyword type="constant" name="GST_APP_STREAM_TYPE_RANDOM_ACCESS" link="gst-plugins-base-libs-appsrc.html#GST-APP-STREAM-TYPE-RANDOM-ACCESS:CAPS"/>
@@ -2295,6 +2329,16 @@
     <keyword type="constant" name="GST_DISCOVERER_SERIALIZE_TAGS" link="gst-plugins-base-libs-gstdiscoverer.html#GST-DISCOVERER-SERIALIZE-TAGS:CAPS"/>
     <keyword type="constant" name="GST_DISCOVERER_SERIALIZE_MISC" link="gst-plugins-base-libs-gstdiscoverer.html#GST-DISCOVERER-SERIALIZE-MISC:CAPS"/>
     <keyword type="constant" name="GST_DISCOVERER_SERIALIZE_ALL" link="gst-plugins-base-libs-gstdiscoverer.html#GST-DISCOVERER-SERIALIZE-ALL:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_ORIENTATION_IDENTITY" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-ORIENTATION-IDENTITY:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_ORIENTATION_90R" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-ORIENTATION-90R:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_ORIENTATION_180" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-ORIENTATION-180:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_ORIENTATION_90L" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-ORIENTATION-90L:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_ORIENTATION_HORIZ" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-ORIENTATION-HORIZ:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_ORIENTATION_VERT" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-ORIENTATION-VERT:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_ORIENTATION_UL_LR" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-ORIENTATION-UL-LR:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_ORIENTATION_UR_LL" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-ORIENTATION-UR-LL:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_ORIENTATION_AUTO" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-ORIENTATION-AUTO:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_ORIENTATION_CUSTOM" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-ORIENTATION-CUSTOM:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_FORMAT_UNKNOWN" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-FORMAT-UNKNOWN:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_FORMAT_ENCODED" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-FORMAT-ENCODED:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_FORMAT_I420" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-FORMAT-I420:CAPS"/>
@@ -2356,6 +2400,9 @@
     <keyword type="constant" name="GST_VIDEO_FORMAT_A444_10BE" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-FORMAT-A444-10BE:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_FORMAT_A444_10LE" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-FORMAT-A444-10LE:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_FORMAT_NV61" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-FORMAT-NV61:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_FORMAT_P010_10BE" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-FORMAT-P010-10BE:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_FORMAT_P010_10LE" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-FORMAT-P010-10LE:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_FORMAT_IYU2" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-FORMAT-IYU2:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_FORMAT_FLAG_YUV" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-FORMAT-FLAG-YUV:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_FORMAT_FLAG_RGB" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-FORMAT-FLAG-RGB:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_FORMAT_FLAG_GRAY" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-FORMAT-FLAG-GRAY:CAPS"/>
@@ -2455,6 +2502,9 @@
     <keyword type="constant" name="GST_VIDEO_TILE_TYPE_INDEXED" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-TILE-TYPE-INDEXED:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_TILE_MODE_UNKNOWN" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-TILE-MODE-UNKNOWN:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_TILE_MODE_ZFLIPZ_2X2" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-TILE-MODE-ZFLIPZ-2X2:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_TIME_CODE_FLAGS_NONE" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-TIME-CODE-FLAGS-NONE:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-TIME-CODE-FLAGS-DROP-FRAME:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_TIME_CODE_FLAGS_INTERLACED" link="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-TIME-CODE-FLAGS-INTERLACED:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_OVERLAY_FORMAT_FLAG_NONE" link="gst-plugins-base-libs-gstvideooverlaycomposition.html#GST-VIDEO-OVERLAY-FORMAT-FLAG-NONE:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_OVERLAY_FORMAT_FLAG_PREMULTIPLIED_ALPHA" link="gst-plugins-base-libs-gstvideooverlaycomposition.html#GST-VIDEO-OVERLAY-FORMAT-FLAG-PREMULTIPLIED-ALPHA:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_OVERLAY_FORMAT_FLAG_GLOBAL_ALPHA" link="gst-plugins-base-libs-gstvideooverlaycomposition.html#GST-VIDEO-OVERLAY-FORMAT-FLAG-GLOBAL-ALPHA:CAPS"/>
@@ -2480,6 +2530,7 @@
     <keyword type="constant" name="GST_VIDEO_CHROMA_METHOD_NEAREST" link="gst-plugins-base-libs-GstVideoChroma.html#GST-VIDEO-CHROMA-METHOD-NEAREST:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_CHROMA_METHOD_LINEAR" link="gst-plugins-base-libs-GstVideoChroma.html#GST-VIDEO-CHROMA-METHOD-LINEAR:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_RESAMPLER_FLAG_NONE" link="gst-plugins-base-libs-GstVideoResampler.html#GST-VIDEO-RESAMPLER-FLAG-NONE:CAPS"/>
+    <keyword type="constant" name="GST_VIDEO_RESAMPLER_FLAG_HALF_TAPS" link="gst-plugins-base-libs-GstVideoResampler.html#GST-VIDEO-RESAMPLER-FLAG-HALF-TAPS:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_RESAMPLER_METHOD_NEAREST" link="gst-plugins-base-libs-GstVideoResampler.html#GST-VIDEO-RESAMPLER-METHOD-NEAREST:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_RESAMPLER_METHOD_LINEAR" link="gst-plugins-base-libs-GstVideoResampler.html#GST-VIDEO-RESAMPLER-METHOD-LINEAR:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_RESAMPLER_METHOD_CUBIC" link="gst-plugins-base-libs-GstVideoResampler.html#GST-VIDEO-RESAMPLER-METHOD-CUBIC:CAPS"/>
@@ -2876,6 +2927,16 @@
     <keyword type="member" name="GstVideoFrame.id" link="gst-plugins-base-libs-gstvideo.html#GstVideoFrame.id"/>
     <keyword type="member" name="GstVideoFrame.data" link="gst-plugins-base-libs-gstvideo.html#GstVideoFrame.data"/>
     <keyword type="member" name="GstVideoFrame.map" link="gst-plugins-base-libs-gstvideo.html#GstVideoFrame.map"/>
+    <keyword type="member" name="GstVideoTimeCode.config" link="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode.config"/>
+    <keyword type="member" name="GstVideoTimeCode.hours" link="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode.hours"/>
+    <keyword type="member" name="GstVideoTimeCode.minutes" link="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode.minutes"/>
+    <keyword type="member" name="GstVideoTimeCode.seconds" link="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode.seconds"/>
+    <keyword type="member" name="GstVideoTimeCode.frames" link="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode.frames"/>
+    <keyword type="member" name="GstVideoTimeCode.field-count" link="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode.field-count"/>
+    <keyword type="member" name="GstVideoTimeCodeConfig.fps-n" link="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeConfig.fps-n"/>
+    <keyword type="member" name="GstVideoTimeCodeConfig.fps-d" link="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeConfig.fps-d"/>
+    <keyword type="member" name="GstVideoTimeCodeConfig.flags" link="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeConfig.flags"/>
+    <keyword type="member" name="GstVideoTimeCodeConfig.latest-daily-jam" link="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeConfig.latest-daily-jam"/>
     <keyword type="member" name="GstVideoMeta.meta" link="gst-plugins-base-libs-gstvideometa.html#GstVideoMeta.meta"/>
     <keyword type="member" name="GstVideoMeta.buffer" link="gst-plugins-base-libs-gstvideometa.html#GstVideoMeta.buffer"/>
     <keyword type="member" name="GstVideoMeta.flags" link="gst-plugins-base-libs-gstvideometa.html#GstVideoMeta.flags"/>
@@ -2907,6 +2968,8 @@
     <keyword type="member" name="GstVideoGLTextureUploadMeta.texture-orientation" link="gst-plugins-base-libs-gstvideometa.html#GstVideoGLTextureUploadMeta.texture-orientation"/>
     <keyword type="member" name="GstVideoGLTextureUploadMeta.n-textures" link="gst-plugins-base-libs-gstvideometa.html#GstVideoGLTextureUploadMeta.n-textures"/>
     <keyword type="member" name="GstVideoGLTextureUploadMeta.texture-type" link="gst-plugins-base-libs-gstvideometa.html#GstVideoGLTextureUploadMeta.texture-type"/>
+    <keyword type="member" name="GstVideoTimeCodeMeta.meta" link="gst-plugins-base-libs-gstvideometa.html#GstVideoTimeCodeMeta.meta"/>
+    <keyword type="member" name="GstVideoTimeCodeMeta.tc" link="gst-plugins-base-libs-gstvideometa.html#GstVideoTimeCodeMeta.tc"/>
     <keyword type="member" name="GstVideoOverlayCompositionMeta.meta" link="gst-plugins-base-libs-gstvideooverlaycomposition.html#GstVideoOverlayCompositionMeta.meta"/>
     <keyword type="member" name="GstVideoOverlayCompositionMeta.overlay" link="gst-plugins-base-libs-gstvideooverlaycomposition.html#GstVideoOverlayCompositionMeta.overlay"/>
     <keyword type="member" name="GstVideoFilterClass.set-info" link="gst-plugins-base-libs-gstvideofilter.html#GstVideoFilterClass.set-info"/>
@@ -2938,6 +3001,7 @@
     <keyword type="member" name="GstColorBalanceChannel-struct.max-value" link="gst-plugins-base-libs-gstcolorbalancechannel.html#GstColorBalanceChannel-struct.max-value"/>
     <keyword type="member" name="GstColorBalanceChannelClass.parent" link="gst-plugins-base-libs-gstcolorbalancechannel.html#GstColorBalanceChannelClass.parent"/>
     <keyword type="member" name="GstColorBalanceChannelClass.value-changed" link="gst-plugins-base-libs-gstcolorbalancechannel.html#GstColorBalanceChannelClass.value-changed"/>
+    <keyword type="member" name="GstVideoDirectionInterface.iface" link="gst-plugins-base-libs-gstvideodirection.html#GstVideoDirectionInterface.iface"/>
     <keyword type="member" name="GstVideoOrientationInterface.iface" link="gst-plugins-base-libs-gstvideoorientation.html#GstVideoOrientationInterface.iface"/>
     <keyword type="member" name="GstVideoOrientationInterface.get-hflip" link="gst-plugins-base-libs-gstvideoorientation.html#GstVideoOrientationInterface.get-hflip"/>
     <keyword type="member" name="GstVideoOrientationInterface.get-vflip" link="gst-plugins-base-libs-gstvideoorientation.html#GstVideoOrientationInterface.get-vflip"/>
@@ -3004,6 +3068,7 @@
     <keyword type="member" name="GstVideoCodecState.info" link="gst-plugins-base-libs-gstvideoutils.html#GstVideoCodecState.info"/>
     <keyword type="member" name="GstVideoCodecState.caps" link="gst-plugins-base-libs-gstvideoutils.html#GstVideoCodecState.caps"/>
     <keyword type="member" name="GstVideoCodecState.codec-data" link="gst-plugins-base-libs-gstvideoutils.html#GstVideoCodecState.codec-data"/>
+    <keyword type="member" name="GstVideoCodecState.allocation-caps" link="gst-plugins-base-libs-gstvideoutils.html#GstVideoCodecState.allocation-caps"/>
     <keyword type="member" name="GstNavigationInterface.iface" link="gst-plugins-base-libs-gstnavigation.html#GstNavigationInterface.iface"/>
     <keyword type="member" name="GstNavigationInterface.send-event" link="gst-plugins-base-libs-gstnavigation.html#GstNavigationInterface.send-event"/>
   </functions>
diff --git a/docs/libs/html/gst-plugins-base-libs-GstAudioConverter.html b/docs/libs/html/gst-plugins-base-libs-GstAudioConverter.html
index 96dec21..ba0038b 100644
--- a/docs/libs/html/gst-plugins-base-libs-GstAudioConverter.html
+++ b/docs/libs/html/gst-plugins-base-libs-GstAudioConverter.html
@@ -164,7 +164,7 @@
 <tbody>
 <tr>
 <td class="parameter_name"><p>flags</p></td>
-<td class="parameter_description"><p><a class="link" href="gst-plugins-base-libs-GstAudioConverter.html#GstAudioConverterFlags" title="enum GstAudioConverterFlags"><span class="type">GstAudioConverterFlags</span></a></p></td>
+<td class="parameter_description"><p>extra <a class="link" href="gst-plugins-base-libs-GstAudioConverter.html#GstAudioConverterFlags" title="enum GstAudioConverterFlags"><span class="type">GstAudioConverterFlags</span></a></p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
diff --git a/docs/libs/html/gst-plugins-base-libs-GstVideoResampler.html b/docs/libs/html/gst-plugins-base-libs-GstVideoResampler.html
index 16dd037..bddb9a2 100644
--- a/docs/libs/html/gst-plugins-base-libs-GstVideoResampler.html
+++ b/docs/libs/html/gst-plugins-base-libs-GstVideoResampler.html
@@ -237,13 +237,24 @@
 <col class="enum_members_description">
 <col width="200px" class="enum_members_annotations">
 </colgroup>
-<tbody><tr>
+<tbody>
+<tr>
 <td class="enum_member_name"><p><a name="GST-VIDEO-RESAMPLER-FLAG-NONE:CAPS"></a>GST_VIDEO_RESAMPLER_FLAG_NONE</p></td>
 <td class="enum_member_description">
 <p>no flags</p>
 </td>
 <td class="enum_member_annotations"> </td>
-</tr></tbody>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-RESAMPLER-FLAG-HALF-TAPS:CAPS"></a>GST_VIDEO_RESAMPLER_FLAG_HALF_TAPS</p></td>
+<td class="enum_member_description">
+<p>when no taps are given, half the
+             number of calculated taps. This can be used when making scalers
+             for the different fields of an interlaced picture. Since 1.10</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+</tbody>
 </table></div>
 </div>
 <p class="since">Since: 1.6</p>
diff --git a/docs/libs/html/gst-plugins-base-libs-appsink.html b/docs/libs/html/gst-plugins-base-libs-appsink.html
index 1fdc197..2df129e 100644
--- a/docs/libs/html/gst-plugins-base-libs-appsink.html
+++ b/docs/libs/html/gst-plugins-base-libs-appsink.html
@@ -130,6 +130,22 @@
 </tr>
 <tr>
 <td class="function_type">
+<a href="/usr/share/gtk-doc/html/gstreamer-1.0GstSample.html#GstSample-struct"><span class="returnvalue">GstSample</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-appsink.html#gst-app-sink-try-pull-preroll" title="gst_app_sink_try_pull_preroll ()">gst_app_sink_try_pull_preroll</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/gstreamer-1.0GstSample.html#GstSample-struct"><span class="returnvalue">GstSample</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-appsink.html#gst-app-sink-try-pull-sample" title="gst_app_sink_try_pull_sample ()">gst_app_sink_try_pull_sample</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
 <span class="returnvalue">void</span>
 </td>
 <td class="function_name">
@@ -167,7 +183,9 @@
 <p>The normal way of retrieving samples from appsink is by using the
 <a class="link" href="gst-plugins-base-libs-appsink.html#gst-app-sink-pull-sample" title="gst_app_sink_pull_sample ()"><code class="function">gst_app_sink_pull_sample()</code></a> and <a class="link" href="gst-plugins-base-libs-appsink.html#gst-app-sink-pull-preroll" title="gst_app_sink_pull_preroll ()"><code class="function">gst_app_sink_pull_preroll()</code></a> methods.
 These methods block until a sample becomes available in the sink or when the
-sink is shut down or reaches EOS.</p>
+sink is shut down or reaches EOS. There are also timed variants of these
+methods, <a class="link" href="gst-plugins-base-libs-appsink.html#gst-app-sink-try-pull-sample" title="gst_app_sink_try_pull_sample ()"><code class="function">gst_app_sink_try_pull_sample()</code></a> and <a class="link" href="gst-plugins-base-libs-appsink.html#gst-app-sink-try-pull-preroll" title="gst_app_sink_try_pull_preroll ()"><code class="function">gst_app_sink_try_pull_preroll()</code></a>,
+which accept a timeout parameter to limit the amount of time to wait.</p>
 <p>Appsink will internally use a queue to collect buffers from the streaming
 thread. If the application is not pulling samples fast enough, this queue
 will consume a lot of memory over time. The "max-buffers" property can be
@@ -541,6 +559,102 @@
 </div>
 <hr>
 <div class="refsect2">
+<a name="gst-app-sink-try-pull-preroll"></a><h3>gst_app_sink_try_pull_preroll ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstSample.html#GstSample-struct"><span class="returnvalue">GstSample</span></a> *
+gst_app_sink_try_pull_preroll (<em class="parameter"><code><a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-appsink.html#GstAppSink-struct"><span class="type">GstAppSink</span></a> *appsink</code></em>,
+                               <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstClock.html#GstClockTime"><span class="type">GstClockTime</span></a> timeout</code></em>);</pre>
+<p>Get the last preroll sample in <em class="parameter"><code>appsink</code></em>
+. This was the sample that caused the
+appsink to preroll in the PAUSED state. This sample can be pulled many times
+and remains available to the application even after EOS.</p>
+<p>This function is typically used when dealing with a pipeline in the PAUSED
+state. Calling this function after doing a seek will give the sample right
+after the seek position.</p>
+<p>Note that the preroll sample will also be returned as the first sample
+when calling <a class="link" href="gst-plugins-base-libs-appsink.html#gst-app-sink-pull-sample" title="gst_app_sink_pull_sample ()"><code class="function">gst_app_sink_pull_sample()</code></a>.</p>
+<p>If an EOS event was received before any buffers or the timeout expires,
+this function returns <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. Use <a class="link" href="gst-plugins-base-libs-appsink.html#gst-app-sink-is-eos" title="gst_app_sink_is_eos ()"><code class="function">gst_app_sink_is_eos()</code></a> to check for the EOS
+condition.</p>
+<p>This function blocks until a preroll sample or EOS is received, the appsink
+element is set to the READY/NULL state, or the timeout expires.</p>
+<div class="refsect3">
+<a name="gst-app-sink-try-pull-preroll.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>appsink</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-appsink.html#GstAppSink-struct"><span class="type">GstAppSink</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>timeout</p></td>
+<td class="parameter_description"><p>the maximum amount of time to wait for the preroll sample</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-app-sink-try-pull-preroll.returns"></a><h4>Returns</h4>
+<p> a <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstSample.html#GstSample-struct"><span class="type">GstSample</span></a> or NULL when the appsink is stopped or EOS or the timeout expires.
+Call <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstSample.html#gst-sample-unref"><code class="function">gst_sample_unref()</code></a> after usage. </p>
+<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-app-sink-try-pull-sample"></a><h3>gst_app_sink_try_pull_sample ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstSample.html#GstSample-struct"><span class="returnvalue">GstSample</span></a> *
+gst_app_sink_try_pull_sample (<em class="parameter"><code><a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-appsink.html#GstAppSink-struct"><span class="type">GstAppSink</span></a> *appsink</code></em>,
+                              <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstClock.html#GstClockTime"><span class="type">GstClockTime</span></a> timeout</code></em>);</pre>
+<p>This function blocks until a sample or EOS becomes available or the appsink
+element is set to the READY/NULL state or the timeout expires.</p>
+<p>This function will only return samples when the appsink is in the PLAYING
+state. All rendered buffers will be put in a queue so that the application
+can pull samples at its own rate. Note that when the application does not
+pull samples fast enough, the queued buffers could consume a lot of memory,
+especially when dealing with raw video frames.</p>
+<p>If an EOS event was received before any buffers or the timeout expires,
+this function returns <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. Use <a class="link" href="gst-plugins-base-libs-appsink.html#gst-app-sink-is-eos" title="gst_app_sink_is_eos ()"><code class="function">gst_app_sink_is_eos()</code></a> to check for the EOS
+condition.</p>
+<div class="refsect3">
+<a name="gst-app-sink-try-pull-sample.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>appsink</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-appsink.html#GstAppSink-struct"><span class="type">GstAppSink</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>timeout</p></td>
+<td class="parameter_description"><p>the maximum amount of time to wait for a sample</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-app-sink-try-pull-sample.returns"></a><h4>Returns</h4>
+<p> a <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstSample.html#GstSample-struct"><span class="type">GstSample</span></a> or NULL when the appsink is stopped or EOS or the timeout expires.
+Call <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstSample.html#gst-sample-unref"><code class="function">gst_sample_unref()</code></a> after usage. </p>
+<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
 <a name="gst-app-sink-set-callbacks"></a><h3>gst_app_sink_set_callbacks ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 gst_app_sink_set_callbacks (<em class="parameter"><code><a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-appsink.html#GstAppSink-struct"><span class="type">GstAppSink</span></a> *appsink</code></em>,
diff --git a/docs/libs/html/gst-plugins-base-libs-appsrc.html b/docs/libs/html/gst-plugins-base-libs-appsrc.html
index 705b231..9a931b9 100644
--- a/docs/libs/html/gst-plugins-base-libs-appsrc.html
+++ b/docs/libs/html/gst-plugins-base-libs-appsrc.html
@@ -93,6 +93,22 @@
 <span class="returnvalue">void</span>
 </td>
 <td class="function_name">
+<a class="link" href="gst-plugins-base-libs-appsrc.html#gst-app-src-set-duration" title="gst_app_src_set_duration ()">gst_app_src_set_duration</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/gstreamer-1.0GstClock.html#GstClockTime"><span class="returnvalue">GstClockTime</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-appsrc.html#gst-app-src-get-duration" title="gst_app_src_get_duration ()">gst_app_src_get_duration</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
 <a class="link" href="gst-plugins-base-libs-appsrc.html#gst-app-src-set-stream-type" title="gst_app_src_set_stream_type ()">gst_app_src_set_stream_type</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
@@ -240,10 +256,10 @@
 <p>These signals allow the application to operate the appsrc in two different
 ways:</p>
 <p>The push mode, in which the application repeatedly calls the push-buffer/push-sample
-method with a new buffer/sample. Optionally, the queue size in the appsrc 
-can be controlled with the enough-data and need-data signals by respectively 
-stopping/starting the push-buffer/push-sample calls. This is a typical 
-mode of operation for the stream-type "stream" and "seekable". Use this 
+method with a new buffer/sample. Optionally, the queue size in the appsrc
+can be controlled with the enough-data and need-data signals by respectively
+stopping/starting the push-buffer/push-sample calls. This is a typical
+mode of operation for the stream-type "stream" and "seekable". Use this
 mode when implementing various network protocols or hardware devices.</p>
 <p>The pull mode, in which the need-data signal triggers the next push-buffer call.
 This mode is typically used in the "random-access" stream-type. Use this
@@ -461,6 +477,66 @@
 </div>
 <hr>
 <div class="refsect2">
+<a name="gst-app-src-set-duration"></a><h3>gst_app_src_set_duration ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+gst_app_src_set_duration (<em class="parameter"><code><a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-appsrc.html#GstAppSrc-struct"><span class="type">GstAppSrc</span></a> *appsrc</code></em>,
+                          <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstClock.html#GstClockTime"><span class="type">GstClockTime</span></a> duration</code></em>);</pre>
+<p>Set the duration of the stream in nanoseconds. A value of GST_CLOCK_TIME_NONE means that the duration is
+not known.</p>
+<div class="refsect3">
+<a name="gst-app-src-set-duration.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>appsrc</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-appsrc.html#GstAppSrc-struct"><span class="type">GstAppSrc</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>duration</p></td>
+<td class="parameter_description"><p>the duration to set</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-app-src-get-duration"></a><h3>gst_app_src_get_duration ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstClock.html#GstClockTime"><span class="returnvalue">GstClockTime</span></a>
+gst_app_src_get_duration (<em class="parameter"><code><a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-appsrc.html#GstAppSrc-struct"><span class="type">GstAppSrc</span></a> *appsrc</code></em>);</pre>
+<p>Get the duration of the stream in nanoseconds. A value of GST_CLOCK_TIME_NONE means that the duration is
+not known.</p>
+<div class="refsect3">
+<a name="gst-app-src-get-duration.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>appsrc</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-appsrc.html#GstAppSrc-struct"><span class="type">GstAppSrc</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-app-src-get-duration.returns"></a><h4>Returns</h4>
+<p> the duration of the stream previously set with <a class="link" href="gst-plugins-base-libs-appsrc.html#gst-app-src-set-duration" title="gst_app_src_set_duration ()"><code class="function">gst_app_src_set_duration()</code></a>;</p>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
 <a name="gst-app-src-set-stream-type"></a><h3>gst_app_src_set_stream_type ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 gst_app_src_set_stream_type (<em class="parameter"><code><a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-appsrc.html#GstAppSrc-struct"><span class="type">GstAppSrc</span></a> *appsrc</code></em>,
@@ -763,8 +839,8 @@
 <pre class="programlisting"><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstPad.html#GstFlowReturn"><span class="returnvalue">GstFlowReturn</span></a>
 gst_app_src_push_sample (<em class="parameter"><code><a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-appsrc.html#GstAppSrc-struct"><span class="type">GstAppSrc</span></a> *appsrc</code></em>,
                          <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstSample.html#GstSample-struct"><span class="type">GstSample</span></a> *sample</code></em>);</pre>
-<p>Extract a buffer from the provided sample and adds it to the queue of 
-buffers that the appsrc element will push to its source pad. Any 
+<p>Extract a buffer from the provided sample and adds it to the queue of
+buffers that the appsrc element will push to its source pad. Any
 previous caps that were set on appsrc will be replaced by the caps
 associated with the sample if not equal.</p>
 <p>When the block property is TRUE, this function can block until free
diff --git a/docs/libs/html/gst-plugins-base-libs-fdmemory.html b/docs/libs/html/gst-plugins-base-libs-fdmemory.html
index b56b312..510e07d 100644
--- a/docs/libs/html/gst-plugins-base-libs-fdmemory.html
+++ b/docs/libs/html/gst-plugins-base-libs-fdmemory.html
@@ -150,7 +150,8 @@
 <p> a GstMemory based on <em class="parameter"><code>allocator</code></em>
 .
 When the buffer will be released the allocator will close the <em class="parameter"><code>fd</code></em>
-.
+unless
+the <a class="link" href="gst-plugins-base-libs-fdmemory.html#GST-FD-MEMORY-FLAG-DONT-CLOSE:CAPS"><code class="literal">GST_FD_MEMORY_FLAG_DONT_CLOSE</code></a> flag is specified.
 The memory is only mmapped on <code class="function">gst_buffer_mmap()</code> request. </p>
 <p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
 </div>
@@ -277,6 +278,14 @@
 </td>
 <td class="enum_member_annotations"> </td>
 </tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-FD-MEMORY-FLAG-DONT-CLOSE:CAPS"></a>GST_FD_MEMORY_FLAG_DONT_CLOSE</p></td>
+<td class="enum_member_description">
+<p>don't close the file descriptor when
+       the memory is freed. Since: 1.10.</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
 </tbody>
 </table></div>
 </div>
diff --git a/docs/libs/html/gst-plugins-base-libs-gstaudio.html b/docs/libs/html/gst-plugins-base-libs-gstaudio.html
index 75e2948..9c358a3 100644
--- a/docs/libs/html/gst-plugins-base-libs-gstaudio.html
+++ b/docs/libs/html/gst-plugins-base-libs-gstaudio.html
@@ -1334,7 +1334,7 @@
 <a name="gst-audio-buffer-clip"></a><h3>gst_audio_buffer_clip ()</h3>
 <pre class="programlisting"><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstBuffer.html#GstBuffer-struct"><span class="returnvalue">GstBuffer</span></a> *
 gst_audio_buffer_clip (<em class="parameter"><code><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstBuffer.html#GstBuffer-struct"><span class="type">GstBuffer</span></a> *buffer</code></em>,
-                       <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstSegment.html#GstSegment-struct"><span class="type">GstSegment</span></a> *segment</code></em>,
+                       <em class="parameter"><code>const <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstSegment.html#GstSegment-struct"><span class="type">GstSegment</span></a> *segment</code></em>,
                        <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> rate</code></em>,
                        <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> bpf</code></em>);</pre>
 <p>Clip the buffer to the given <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstSegment.html#GstSegment-struct"><code class="literal">GstSegment</code></a>.</p>
diff --git a/docs/libs/html/gst-plugins-base-libs-gstaudiochannels.html b/docs/libs/html/gst-plugins-base-libs-gstaudiochannels.html
index 67025a3..d736de5 100644
--- a/docs/libs/html/gst-plugins-base-libs-gstaudiochannels.html
+++ b/docs/libs/html/gst-plugins-base-libs-gstaudiochannels.html
@@ -111,6 +111,14 @@
 </tr>
 <tr>
 <td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstaudiochannels.html#gst-audio-channel-positions-to-string" title="gst_audio_channel_positions_to_string ()">gst_audio_channel_positions_to_string</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
 <a class="link" href="gst-plugins-base-libs-gstaudiochannels.html#GstAudioChannelMixer" title="GstAudioChannelMixer"><span class="returnvalue">GstAudioChannelMixer</span></a> *
 </td>
 <td class="function_name">
@@ -590,6 +598,47 @@
 </div>
 <hr>
 <div class="refsect2">
+<a name="gst-audio-channel-positions-to-string"></a><h3>gst_audio_channel_positions_to_string ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+gst_audio_channel_positions_to_string (<em class="parameter"><code>const <a class="link" href="gst-plugins-base-libs-gstaudiochannels.html#GstAudioChannelPosition" title="enum GstAudioChannelPosition"><span class="type">GstAudioChannelPosition</span></a> *position</code></em>,
+                                       <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> channels</code></em>);</pre>
+<p>Converts <em class="parameter"><code>position</code></em>
+ to a human-readable string representation for
+debugging purposes.</p>
+<div class="refsect3">
+<a name="gst-audio-channel-positions-to-string.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>position</p></td>
+<td class="parameter_description"><p> The <a href="gst-plugins-base-libs-gstaudiochannels.html#GstAudioChannelPosition"><code class="literal">GstAudioChannelPositions</code></a>
+to convert. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=channels]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>channels</p></td>
+<td class="parameter_description"><p>The number of channels.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-audio-channel-positions-to-string.returns"></a><h4>Returns</h4>
+<p> a newly allocated string representing
+<em class="parameter"><code>position</code></em>
+</p>
+<p>Since 1.10. </p>
+<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
 <a name="gst-audio-channel-mixer-new"></a><h3>gst_audio_channel_mixer_new ()</h3>
 <pre class="programlisting"><a class="link" href="gst-plugins-base-libs-gstaudiochannels.html#GstAudioChannelMixer" title="GstAudioChannelMixer"><span class="returnvalue">GstAudioChannelMixer</span></a> *
 gst_audio_channel_mixer_new (<em class="parameter"><code><a class="link" href="gst-plugins-base-libs-gstaudiochannels.html#GstAudioChannelMixerFlags" title="enum GstAudioChannelMixerFlags"><span class="type">GstAudioChannelMixerFlags</span></a> flags</code></em>,
diff --git a/docs/libs/html/gst-plugins-base-libs-gstaudioencoder.html b/docs/libs/html/gst-plugins-base-libs-gstaudioencoder.html
index c9a13fb..6b2be0e 100644
--- a/docs/libs/html/gst-plugins-base-libs-gstaudioencoder.html
+++ b/docs/libs/html/gst-plugins-base-libs-gstaudioencoder.html
@@ -682,6 +682,34 @@
 <pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
 gst_audio_encoder_set_output_format (<em class="parameter"><code><a class="link" href="gst-plugins-base-libs-gstaudioencoder.html#GstAudioEncoder"><span class="type">GstAudioEncoder</span></a> *enc</code></em>,
                                      <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstCaps.html#GstCaps-struct"><span class="type">GstCaps</span></a> *caps</code></em>);</pre>
+<p>Configure output caps on the srcpad of <em class="parameter"><code>enc</code></em>
+.</p>
+<div class="refsect3">
+<a name="gst-audio-encoder-set-output-format.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>enc</p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstaudioencoder.html#GstAudioEncoder"><span class="type">GstAudioEncoder</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>caps</p></td>
+<td class="parameter_description"><p> <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstCaps.html#GstCaps-struct"><span class="type">GstCaps</span></a>. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-audio-encoder-set-output-format.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> on success.</p>
+</div>
 </div>
 <hr>
 <div class="refsect2">
diff --git a/docs/libs/html/gst-plugins-base-libs-gstcolorbalancechannel.html b/docs/libs/html/gst-plugins-base-libs-gstcolorbalancechannel.html
index 579de2c..fcc83cf 100644
--- a/docs/libs/html/gst-plugins-base-libs-gstcolorbalancechannel.html
+++ b/docs/libs/html/gst-plugins-base-libs-gstcolorbalancechannel.html
@@ -7,7 +7,7 @@
 <link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Library Reference Manual">
 <link rel="up" href="gstreamer-video.html" title="Video Library">
 <link rel="prev" href="gst-plugins-base-libs-gstcolorbalance.html" title="gstcolorbalance">
-<link rel="next" href="gst-plugins-base-libs-gstvideoorientation.html" title="gstvideoorientation">
+<link rel="next" href="gst-plugins-base-libs-gstvideodirection.html" title="gstvideodirection">
 <meta name="generator" content="GTK-Doc V1.25 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
@@ -22,7 +22,7 @@
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="gstreamer-video.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="gst-plugins-base-libs-gstcolorbalance.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="gst-plugins-base-libs-gstvideoorientation.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="n" href="gst-plugins-base-libs-gstvideodirection.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
 <a name="gst-plugins-base-libs-gstcolorbalancechannel"></a><div class="titlepage"></div>
diff --git a/docs/libs/html/gst-plugins-base-libs-gstpbutilscodecutils.html b/docs/libs/html/gst-plugins-base-libs-gstpbutilscodecutils.html
index b310dcc..ed745dd 100644
--- a/docs/libs/html/gst-plugins-base-libs-gstpbutilscodecutils.html
+++ b/docs/libs/html/gst-plugins-base-libs-gstpbutilscodecutils.html
@@ -71,6 +71,22 @@
 </tr>
 <tr>
 <td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="returnvalue">guint</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstpbutilscodecutils.html#gst-codec-utils-aac-get-channels" title="gst_codec_utils_aac_get_channels ()">gst_codec_utils_aac_get_channels</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="returnvalue">guint</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstpbutilscodecutils.html#gst-codec-utils-aac-get-sample-rate" title="gst_codec_utils_aac_get_sample_rate ()">gst_codec_utils_aac_get_sample_rate</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
 <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
 </td>
 <td class="function_name">
@@ -386,6 +402,73 @@
 </div>
 <hr>
 <div class="refsect2">
+<a name="gst-codec-utils-aac-get-channels"></a><h3>gst_codec_utils_aac_get_channels ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="returnvalue">guint</span></a>
+gst_codec_utils_aac_get_channels (<em class="parameter"><code>const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint8"><span class="type">guint8</span></a> *audio_config</code></em>,
+                                  <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> len</code></em>);</pre>
+<p>Returns the channels of the given AAC stream.</p>
+<div class="refsect3">
+<a name="gst-codec-utils-aac-get-channels.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>audio_config</p></td>
+<td class="parameter_description"><p>a pointer to the AudioSpecificConfig as specified in the
+Elementary Stream Descriptor (esds) in ISO/IEC 14496-1.</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-codec-utils-aac-get-channels.returns"></a><h4>Returns</h4>
+<p> The channels or 0 if the channel could not be determined.</p>
+<p>Since 1.10</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-codec-utils-aac-get-sample-rate"></a><h3>gst_codec_utils_aac_get_sample_rate ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="returnvalue">guint</span></a>
+gst_codec_utils_aac_get_sample_rate (<em class="parameter"><code>const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint8"><span class="type">guint8</span></a> *audio_config</code></em>,
+                                     <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> len</code></em>);</pre>
+<p>Translates the sample rate index found in AAC headers to the actual sample
+rate.</p>
+<div class="refsect3">
+<a name="gst-codec-utils-aac-get-sample-rate.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>audio_config</p></td>
+<td class="parameter_description"><p>a pointer to the AudioSpecificConfig as specified in the
+Elementary Stream Descriptor (esds) in ISO/IEC 14496-1.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>len</p></td>
+<td class="parameter_description"><p>Length of <em class="parameter"><code>audio_config</code></em>
+in bytes</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-codec-utils-aac-get-sample-rate.returns"></a><h4>Returns</h4>
+<p> The sample rate if sr_idx is valid, 0 otherwise.</p>
+<p>Since 1.10</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
 <a name="gst-codec-utils-aac-caps-set-level-and-profile"></a><h3>gst_codec_utils_aac_caps_set_level_and_profile ()</h3>
 <pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
 gst_codec_utils_aac_caps_set_level_and_profile
diff --git a/docs/libs/html/gst-plugins-base-libs-gstpluginsbaseversion.html b/docs/libs/html/gst-plugins-base-libs-gstpluginsbaseversion.html
index 5283091..8031929 100644
--- a/docs/libs/html/gst-plugins-base-libs-gstpluginsbaseversion.html
+++ b/docs/libs/html/gst-plugins-base-libs-gstpluginsbaseversion.html
@@ -177,14 +177,14 @@
 <hr>
 <div class="refsect2">
 <a name="GST-PLUGINS-BASE-VERSION-MINOR:CAPS"></a><h3>GST_PLUGINS_BASE_VERSION_MINOR</h3>
-<pre class="programlisting">#define GST_PLUGINS_BASE_VERSION_MINOR (8)
+<pre class="programlisting">#define GST_PLUGINS_BASE_VERSION_MINOR (9)
 </pre>
 <p>The minor version of GStreamer's gst-plugins-base libraries at compile time.</p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="GST-PLUGINS-BASE-VERSION-MICRO:CAPS"></a><h3>GST_PLUGINS_BASE_VERSION_MICRO</h3>
-<pre class="programlisting">#define GST_PLUGINS_BASE_VERSION_MICRO (3)
+<pre class="programlisting">#define GST_PLUGINS_BASE_VERSION_MICRO (90)
 </pre>
 <p>The micro version of GStreamer's gst-plugins-base libraries at compile time.</p>
 </div>
diff --git a/docs/libs/html/gst-plugins-base-libs-gstrtpbuffer.html b/docs/libs/html/gst-plugins-base-libs-gstrtpbuffer.html
index e81fee8..6456231 100644
--- a/docs/libs/html/gst-plugins-base-libs-gstrtpbuffer.html
+++ b/docs/libs/html/gst-plugins-base-libs-gstrtpbuffer.html
@@ -2143,7 +2143,7 @@
 gst_rtp_buffer_add_extension_onebyte_header
                                (<em class="parameter"><code><a class="link" href="gst-plugins-base-libs-gstrtpbuffer.html#GstRTPBuffer" title="struct GstRTPBuffer"><span class="type">GstRTPBuffer</span></a> *rtp</code></em>,
                                 <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint8"><span class="type">guint8</span></a> id</code></em>,
-                                <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> data</code></em>,
+                                <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gconstpointer"><span class="type">gconstpointer</span></a> data</code></em>,
                                 <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> size</code></em>);</pre>
 <p>Adds a RFC 5285 header extension with a one byte header to the end of the
 RTP header. If there is already a RFC 5285 header extension with a one byte
@@ -2197,7 +2197,7 @@
                                (<em class="parameter"><code><a class="link" href="gst-plugins-base-libs-gstrtpbuffer.html#GstRTPBuffer" title="struct GstRTPBuffer"><span class="type">GstRTPBuffer</span></a> *rtp</code></em>,
                                 <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint8"><span class="type">guint8</span></a> appbits</code></em>,
                                 <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint8"><span class="type">guint8</span></a> id</code></em>,
-                                <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> data</code></em>,
+                                <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gconstpointer"><span class="type">gconstpointer</span></a> data</code></em>,
                                 <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> size</code></em>);</pre>
 <p>Adds a RFC 5285 header extension with a two bytes header to the end of the
 RTP header. If there is already a RFC 5285 header extension with a two bytes
diff --git a/docs/libs/html/gst-plugins-base-libs-gstvideo.html b/docs/libs/html/gst-plugins-base-libs-gstvideo.html
index 034bf7f..5baab99 100644
--- a/docs/libs/html/gst-plugins-base-libs-gstvideo.html
+++ b/docs/libs/html/gst-plugins-base-libs-gstvideo.html
@@ -1100,6 +1100,118 @@
 <a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-multiview-video-info-change-mode" title="gst_video_multiview_video_info_change_mode ()">gst_video_multiview_video_info_change_mode</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
+<tr>
+<td class="function_type">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="returnvalue">GstVideoTimeCode</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-new" title="gst_video_time_code_new ()">gst_video_time_code_new</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="returnvalue">GstVideoTimeCode</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-new-empty" title="gst_video_time_code_new_empty ()">gst_video_time_code_new_empty</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-free" title="gst_video_time_code_free ()">gst_video_time_code_free</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="returnvalue">GstVideoTimeCode</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-copy" title="gst_video_time_code_copy ()">gst_video_time_code_copy</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-init" title="gst_video_time_code_init ()">gst_video_time_code_init</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-clear" title="gst_video_time_code_clear ()">gst_video_time_code_clear</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-is-valid" title="gst_video_time_code_is_valid ()">gst_video_time_code_is_valid</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="returnvalue">gint</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-compare" title="gst_video_time_code_compare ()">gst_video_time_code_compare</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-increment-frame" title="gst_video_time_code_increment_frame ()">gst_video_time_code_increment_frame</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-add-frames" title="gst_video_time_code_add_frames ()">gst_video_time_code_add_frames</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="returnvalue">guint64</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-frames-since-daily-jam" title="gst_video_time_code_frames_since_daily_jam ()">gst_video_time_code_frames_since_daily_jam</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="returnvalue">guint64</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-nsec-since-daily-jam" title="gst_video_time_code_nsec_since_daily_jam ()">gst_video_time_code_nsec_since_daily_jam</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-GDateTime.html#GDateTime"><span class="returnvalue">GDateTime</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-to-date-time" title="gst_video_time_code_to_date_time ()">gst_video_time_code_to_date_time</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideo.html#gst-video-time-code-to-string" title="gst_video_time_code_to_string ()">gst_video_time_code_to_string</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -1133,6 +1245,10 @@
 </tr>
 <tr>
 <td class="datatype_keyword">enum</td>
+<td class="function_name"><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoOrientationMethod" title="enum GstVideoOrientationMethod">GstVideoOrientationMethod</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">enum</td>
 <td class="function_name"><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoFormat" title="enum GstVideoFormat">GstVideoFormat</a></td>
 </tr>
 <tr>
@@ -1235,6 +1351,18 @@
 <td class="datatype_keyword"> </td>
 <td class="function_name"><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoConverter" title="GstVideoConverter">GstVideoConverter</a></td>
 </tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode">GstVideoTimeCode</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeConfig" title="struct GstVideoTimeCodeConfig">GstVideoTimeCodeConfig</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">enum</td>
+<td class="function_name"><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeFlags" title="enum GstVideoTimeCodeFlags">GstVideoTimeCodeFlags</a></td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -2124,7 +2252,7 @@
 <tbody>
 <tr>
 <td class="parameter_name"><p>info</p></td>
-<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoInfo" title="struct GstVideoInfo"><span class="type">GstVideoInfo</span></a></p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoFormatInfo" title="struct GstVideoFormatInfo"><span class="type">GstVideoFormatInfo</span></a></p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -2157,7 +2285,7 @@
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>info</p></td>
-<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoInfo" title="struct GstVideoInfo"><span class="type">GstVideoInfo</span></a></p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoFormatInfo" title="struct GstVideoFormatInfo"><span class="type">GstVideoFormatInfo</span></a></p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -2181,7 +2309,7 @@
 <tbody>
 <tr>
 <td class="parameter_name"><p>info</p></td>
-<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoInfo" title="struct GstVideoInfo"><span class="type">GstVideoInfo</span></a></p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoFormatInfo" title="struct GstVideoFormatInfo"><span class="type">GstVideoFormatInfo</span></a></p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -2254,7 +2382,7 @@
 <tbody>
 <tr>
 <td class="parameter_name"><p>info</p></td>
-<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoInfo" title="struct GstVideoInfo"><span class="type">GstVideoInfo</span></a></p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoFormatInfo" title="struct GstVideoFormatInfo"><span class="type">GstVideoFormatInfo</span></a></p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -3580,14 +3708,16 @@
 14
 15
 16
-17</pre></td>
+17
+18
+19</pre></td>
         <td class="listing_code"><pre class="programlisting">GstVideoFrame vframe<span class="gtkdoc opt">;</span>
 <span class="gtkdoc opt">...</span>
 <span class="gtkdoc slc">// set RGB pixels to black one at a time</span>
-<span class="keyword">if</span> <span class="gtkdoc opt">(</span><span class="function"><a href="gst-plugins-base-libs-gstvideo.html#gst-video-frame-map">gst_video_frame_map</a></span> <span class="gtkdoc opt">(&amp;</span>vframe<span class="gtkdoc opt">,</span> video_info<span class="gtkdoc opt">,</span> video_buffer<span class="gtkdoc opt">)) {</span>
+<span class="keyword">if</span> <span class="gtkdoc opt">(</span><span class="function"><a href="gst-plugins-base-libs-gstvideo.html#gst-video-frame-map">gst_video_frame_map</a></span> <span class="gtkdoc opt">(&amp;</span>vframe<span class="gtkdoc opt">,</span> video_info<span class="gtkdoc opt">,</span> video_buffer<span class="gtkdoc opt">,</span> GST_MAP_WRITE<span class="gtkdoc opt">)) {</span>
   guint8 <span class="gtkdoc opt">*</span>pixels <span class="gtkdoc opt">=</span> <span class="function"><a href="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-FRAME-PLANE-DATA:CAPS">GST_VIDEO_FRAME_PLANE_DATA</a></span> <span class="gtkdoc opt">(</span>vframe<span class="gtkdoc opt">,</span> <span class="number">0</span><span class="gtkdoc opt">);</span>
   guint stride <span class="gtkdoc opt">=</span> <span class="function"><a href="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-FRAME-PLANE-STRIDE:CAPS">GST_VIDEO_FRAME_PLANE_STRIDE</a></span> <span class="gtkdoc opt">(</span>vframe<span class="gtkdoc opt">,</span> <span class="number">0</span><span class="gtkdoc opt">);</span>
-  guint pixel_stride <span class="gtkdoc opt">=</span> <span class="function">GST_VIDEO_FRAME_PLANE_PSTRIDE</span> <span class="gtkdoc opt">(</span>vframe<span class="gtkdoc opt">,</span> <span class="number">0</span><span class="gtkdoc opt">);</span>
+  guint pixel_stride <span class="gtkdoc opt">=</span> <span class="function"><a href="gst-plugins-base-libs-gstvideo.html#GST-VIDEO-FRAME-COMP-PSTRIDE:CAPS">GST_VIDEO_FRAME_COMP_PSTRIDE</a></span> <span class="gtkdoc opt">(</span>vframe<span class="gtkdoc opt">,</span> <span class="number">0</span><span class="gtkdoc opt">);</span>
 
   <span class="keyword">for</span> <span class="gtkdoc opt">(</span>h <span class="gtkdoc opt">=</span> <span class="number">0</span><span class="gtkdoc opt">;</span> h <span class="gtkdoc opt">&lt;</span> height<span class="gtkdoc opt">; ++</span>h<span class="gtkdoc opt">) {</span>
     <span class="keyword">for</span> <span class="gtkdoc opt">(</span>w <span class="gtkdoc opt">=</span> <span class="number">0</span><span class="gtkdoc opt">;</span> w <span class="gtkdoc opt">&lt;</span> width<span class="gtkdoc opt">; ++</span>w<span class="gtkdoc opt">) {</span>
@@ -3596,6 +3726,8 @@
       <span class="function">memset</span> <span class="gtkdoc opt">(</span>pixel<span class="gtkdoc opt">,</span> <span class="number">0</span><span class="gtkdoc opt">,</span> pixel_stride<span class="gtkdoc opt">);</span>
     <span class="gtkdoc opt">}</span>
   <span class="gtkdoc opt">}</span>
+
+  <span class="function"><a href="gst-plugins-base-libs-gstvideo.html#gst-video-frame-unmap">gst_video_frame_unmap</a></span> <span class="gtkdoc opt">(&amp;</span>vframe<span class="gtkdoc opt">);</span>
 <span class="gtkdoc opt">}</span>
 <span class="gtkdoc opt">...</span></pre></td>
       </tr>
@@ -4641,6 +4773,506 @@
 </div>
 <p class="since">Since: 1.6</p>
 </div>
+<hr>
+<div class="refsect2">
+<a name="gst-video-time-code-new"></a><h3>gst_video_time_code_new ()</h3>
+<pre class="programlisting"><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="returnvalue">GstVideoTimeCode</span></a> *
+gst_video_time_code_new (<em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> fps_n</code></em>,
+                         <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> fps_d</code></em>,
+                         <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-GDateTime.html#GDateTime"><span class="type">GDateTime</span></a> *latest_daily_jam</code></em>,
+                         <em class="parameter"><code><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeFlags" title="enum GstVideoTimeCodeFlags"><span class="type">GstVideoTimeCodeFlags</span></a> flags</code></em>,
+                         <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> hours</code></em>,
+                         <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> minutes</code></em>,
+                         <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> seconds</code></em>,
+                         <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> frames</code></em>,
+                         <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> field_count</code></em>);</pre>
+<p><em class="parameter"><code>field_count</code></em>
+ is 0 for progressive, 1 or 2 for interlaced.
+<em class="parameter"><code>latest_daiy_jam</code></em>
+ reference is stolen from caller.</p>
+<div class="refsect3">
+<a name="gst-video-time-code-new.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>fps_n</p></td>
+<td class="parameter_description"><p>Numerator of the frame rate</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>fps_d</p></td>
+<td class="parameter_description"><p>Denominator of the frame rate</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>latest_daily_jam</p></td>
+<td class="parameter_description"><p>The latest daily jam of the <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>flags</p></td>
+<td class="parameter_description"><p><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeFlags" title="enum GstVideoTimeCodeFlags"><span class="type">GstVideoTimeCodeFlags</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>hours</p></td>
+<td class="parameter_description"><p>the hours field of <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>minutes</p></td>
+<td class="parameter_description"><p>the minutes field of <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>seconds</p></td>
+<td class="parameter_description"><p>the seconds field of <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>frames</p></td>
+<td class="parameter_description"><p>the frames field of <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>field_count</p></td>
+<td class="parameter_description"><p>Interlaced video field count</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-video-time-code-new.returns"></a><h4>Returns</h4>
+<p> a new <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> with the given values.</p>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-video-time-code-new-empty"></a><h3>gst_video_time_code_new_empty ()</h3>
+<pre class="programlisting"><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="returnvalue">GstVideoTimeCode</span></a> *
+gst_video_time_code_new_empty (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+<div class="refsect3">
+<a name="gst-video-time-code-new-empty.returns"></a><h4>Returns</h4>
+<p> a new empty <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-video-time-code-free"></a><h3>gst_video_time_code_free ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+gst_video_time_code_free (<em class="parameter"><code><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> *tc</code></em>);</pre>
+<p>Frees <em class="parameter"><code>tc</code></em>
+ .</p>
+<div class="refsect3">
+<a name="gst-video-time-code-free.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>tc</p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-video-time-code-copy"></a><h3>gst_video_time_code_copy ()</h3>
+<pre class="programlisting"><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="returnvalue">GstVideoTimeCode</span></a> *
+gst_video_time_code_copy (<em class="parameter"><code>const <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> *tc</code></em>);</pre>
+<div class="refsect3">
+<a name="gst-video-time-code-copy.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>tc</p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-video-time-code-copy.returns"></a><h4>Returns</h4>
+<p> a new <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> with the same values as <em class="parameter"><code>tc</code></em>
+.</p>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-video-time-code-init"></a><h3>gst_video_time_code_init ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+gst_video_time_code_init (<em class="parameter"><code><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> *tc</code></em>,
+                          <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> fps_n</code></em>,
+                          <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> fps_d</code></em>,
+                          <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-GDateTime.html#GDateTime"><span class="type">GDateTime</span></a> *latest_daily_jam</code></em>,
+                          <em class="parameter"><code><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeFlags" title="enum GstVideoTimeCodeFlags"><span class="type">GstVideoTimeCodeFlags</span></a> flags</code></em>,
+                          <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> hours</code></em>,
+                          <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> minutes</code></em>,
+                          <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> seconds</code></em>,
+                          <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> frames</code></em>,
+                          <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> field_count</code></em>);</pre>
+<p><em class="parameter"><code>field_count</code></em>
+ is 0 for progressive, 1 or 2 for interlaced.
+<em class="parameter"><code>latest_daiy_jam</code></em>
+ reference is stolen from caller.</p>
+<p>Initializes <em class="parameter"><code>tc</code></em>
+ with the given values.</p>
+<div class="refsect3">
+<a name="gst-video-time-code-init.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>tc</p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>fps_n</p></td>
+<td class="parameter_description"><p>Numerator of the frame rate</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>fps_d</p></td>
+<td class="parameter_description"><p>Denominator of the frame rate</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>latest_daily_jam</p></td>
+<td class="parameter_description"><p>The latest daily jam of the <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>flags</p></td>
+<td class="parameter_description"><p><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeFlags" title="enum GstVideoTimeCodeFlags"><span class="type">GstVideoTimeCodeFlags</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>hours</p></td>
+<td class="parameter_description"><p>the hours field of <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>minutes</p></td>
+<td class="parameter_description"><p>the minutes field of <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>seconds</p></td>
+<td class="parameter_description"><p>the seconds field of <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>frames</p></td>
+<td class="parameter_description"><p>the frames field of <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>field_count</p></td>
+<td class="parameter_description"><p>Interlaced video field count</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-video-time-code-clear"></a><h3>gst_video_time_code_clear ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+gst_video_time_code_clear (<em class="parameter"><code><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> *tc</code></em>);</pre>
+<p>Initializes <em class="parameter"><code>tc</code></em>
+ with empty/zero/NULL values.</p>
+<div class="refsect3">
+<a name="gst-video-time-code-clear.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>tc</p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-video-time-code-is-valid"></a><h3>gst_video_time_code_is_valid ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+gst_video_time_code_is_valid (<em class="parameter"><code>const <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> *tc</code></em>);</pre>
+<div class="refsect3">
+<a name="gst-video-time-code-is-valid.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>tc</p></td>
+<td class="parameter_description"><p><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> to check</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-video-time-code-is-valid.returns"></a><h4>Returns</h4>
+<p> whether <em class="parameter"><code>tc</code></em>
+is a valid timecode (supported frame rate,
+hours/minutes/seconds/frames not overflowing)</p>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-video-time-code-compare"></a><h3>gst_video_time_code_compare ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="returnvalue">gint</span></a>
+gst_video_time_code_compare (<em class="parameter"><code>const <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> *tc1</code></em>,
+                             <em class="parameter"><code>const <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> *tc2</code></em>);</pre>
+<p>Compares <em class="parameter"><code>tc1</code></em>
+ and <em class="parameter"><code>tc2</code></em>
+ . If both have latest daily jam information, it is
+taken into account. Otherwise, it is assumed that the daily jam of both
+<em class="parameter"><code>tc1</code></em>
+ and <em class="parameter"><code>tc2</code></em>
+ was at the same time.</p>
+<div class="refsect3">
+<a name="gst-video-time-code-compare.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>tc1</p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>tc2</p></td>
+<td class="parameter_description"><p>another <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-video-time-code-compare.returns"></a><h4>Returns</h4>
+<p> 1 if <em class="parameter"><code>tc1</code></em>
+is after <em class="parameter"><code>tc2</code></em>
+, -1 if <em class="parameter"><code>tc1</code></em>
+is before <em class="parameter"><code>tc2</code></em>
+, 0 otherwise.</p>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-video-time-code-increment-frame"></a><h3>gst_video_time_code_increment_frame ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+gst_video_time_code_increment_frame (<em class="parameter"><code><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> *tc</code></em>);</pre>
+<p>Adds one frame to <em class="parameter"><code>tc</code></em>
+ .</p>
+<div class="refsect3">
+<a name="gst-video-time-code-increment-frame.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>tc</p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-video-time-code-add-frames"></a><h3>gst_video_time_code_add_frames ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+gst_video_time_code_add_frames (<em class="parameter"><code><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> *tc</code></em>,
+                                <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint64"><span class="type">gint64</span></a> frames</code></em>);</pre>
+<p>Adds or subtracts <em class="parameter"><code>frames</code></em>
+ amount of frames to <em class="parameter"><code>tc</code></em>
+ .</p>
+<div class="refsect3">
+<a name="gst-video-time-code-add-frames.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>tc</p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>frames</p></td>
+<td class="parameter_description"><p>How many frames to add or subtract</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-video-time-code-frames-since-daily-jam"></a><h3>gst_video_time_code_frames_since_daily_jam ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="returnvalue">guint64</span></a>
+gst_video_time_code_frames_since_daily_jam
+                               (<em class="parameter"><code>const <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> *tc</code></em>);</pre>
+<div class="refsect3">
+<a name="gst-video-time-code-frames-since-daily-jam.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>tc</p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-video-time-code-frames-since-daily-jam.returns"></a><h4>Returns</h4>
+<p> how many frames have passed since the daily jam of <em class="parameter"><code>tc</code></em>
+.</p>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-video-time-code-nsec-since-daily-jam"></a><h3>gst_video_time_code_nsec_since_daily_jam ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="returnvalue">guint64</span></a>
+gst_video_time_code_nsec_since_daily_jam
+                               (<em class="parameter"><code>const <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> *tc</code></em>);</pre>
+<div class="refsect3">
+<a name="gst-video-time-code-nsec-since-daily-jam.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>tc</p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-video-time-code-nsec-since-daily-jam.returns"></a><h4>Returns</h4>
+<p> how many nsec have passed since the daily jam of <em class="parameter"><code>tc</code></em>
+.</p>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-video-time-code-to-date-time"></a><h3>gst_video_time_code_to_date_time ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-GDateTime.html#GDateTime"><span class="returnvalue">GDateTime</span></a> *
+gst_video_time_code_to_date_time (<em class="parameter"><code>const <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> *tc</code></em>);</pre>
+<p>The <em class="parameter"><code>tc.config-&gt;latest_daily_jam</code></em>
+ is required to be non-NULL.</p>
+<div class="refsect3">
+<a name="gst-video-time-code-to-date-time.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>tc</p></td>
+<td class="parameter_description"><p><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> to convert</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-video-time-code-to-date-time.returns"></a><h4>Returns</h4>
+<p> the <a href="/usr/share/gtk-doc/html/glibglib-GDateTime.html#GDateTime"><span class="type">GDateTime</span></a> representation of <em class="parameter"><code>tc</code></em>
+.</p>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-video-time-code-to-string"></a><h3>gst_video_time_code_to_string ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+gst_video_time_code_to_string (<em class="parameter"><code>const <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> *tc</code></em>);</pre>
+<div class="refsect3">
+<a name="gst-video-time-code-to-string.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>tc</p></td>
+<td class="parameter_description"><p><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> to convert</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-video-time-code-to-string.returns"></a><h4>Returns</h4>
+<p> the SMPTE ST 2059-1:2015 string representation of <em class="parameter"><code>tc</code></em>
+. That will
+take the form hh:mm:ss:ff . The last separator (between seconds and frames)
+may vary:</p>
+<p>';' for drop-frame, non-interlaced content and for drop-frame interlaced
+field 2
+',' for drop-frame interlaced field 1
+':' for non-drop-frame, non-interlaced content and for non-drop-frame
+interlaced field 2
+'.' for non-drop-frame interlaced field 1</p>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-libs-gstvideo.other_details"></a><h2>Types and Values</h2>
@@ -4729,6 +5361,94 @@
 </div>
 <hr>
 <div class="refsect2">
+<a name="GstVideoOrientationMethod"></a><h3>enum GstVideoOrientationMethod</h3>
+<p>The different video orientation methods.</p>
+<div class="refsect3">
+<a name="GstVideoOrientationMethod.members"></a><h4>Members</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="300px" class="enum_members_name">
+<col class="enum_members_description">
+<col width="200px" class="enum_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-ORIENTATION-IDENTITY:CAPS"></a>GST_VIDEO_ORIENTATION_IDENTITY</p></td>
+<td class="enum_member_description">
+<p>Identity (no rotation)</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-ORIENTATION-90R:CAPS"></a>GST_VIDEO_ORIENTATION_90R</p></td>
+<td class="enum_member_description">
+<p>Rotate clockwise 90 degrees</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-ORIENTATION-180:CAPS"></a>GST_VIDEO_ORIENTATION_180</p></td>
+<td class="enum_member_description">
+<p>Rotate 180 degrees</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-ORIENTATION-90L:CAPS"></a>GST_VIDEO_ORIENTATION_90L</p></td>
+<td class="enum_member_description">
+<p>Rotate counter-clockwise 90 degrees</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-ORIENTATION-HORIZ:CAPS"></a>GST_VIDEO_ORIENTATION_HORIZ</p></td>
+<td class="enum_member_description">
+<p>Flip horizontally</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-ORIENTATION-VERT:CAPS"></a>GST_VIDEO_ORIENTATION_VERT</p></td>
+<td class="enum_member_description">
+<p>Flip vertically</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-ORIENTATION-UL-LR:CAPS"></a>GST_VIDEO_ORIENTATION_UL_LR</p></td>
+<td class="enum_member_description">
+<p>Flip across upper left/lower right diagonal</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-ORIENTATION-UR-LL:CAPS"></a>GST_VIDEO_ORIENTATION_UR_LL</p></td>
+<td class="enum_member_description">
+<p>Flip across upper right/lower left diagonal</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-ORIENTATION-AUTO:CAPS"></a>GST_VIDEO_ORIENTATION_AUTO</p></td>
+<td class="enum_member_description">
+<p>Select flip method based on image-orientation tag</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-ORIENTATION-CUSTOM:CAPS"></a>GST_VIDEO_ORIENTATION_CUSTOM</p></td>
+<td class="enum_member_description">
+<p>Current status depends on plugin internal setup</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
 <a name="GstVideoFormat"></a><h3>enum GstVideoFormat</h3>
 <p>Enum value describing the most common video formats.</p>
 <div class="refsect3">
@@ -4942,7 +5662,7 @@
 <tr>
 <td class="enum_member_name"><p><a name="GST-VIDEO-FORMAT-v308"></a>GST_VIDEO_FORMAT_v308</p></td>
 <td class="enum_member_description">
-<p>packed 4:4:4 YUV</p>
+<p>packed 4:4:4 YUV (Y-U-V ...)</p>
 </td>
 <td class="enum_member_annotations"> </td>
 </tr>
@@ -5170,6 +5890,27 @@
 </td>
 <td class="enum_member_annotations"> </td>
 </tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-FORMAT-P010-10BE:CAPS"></a>GST_VIDEO_FORMAT_P010_10BE</p></td>
+<td class="enum_member_description">
+<p>planar 4:2:0 YUV with interleaved UV plane, 10 bits per channel</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-FORMAT-P010-10LE:CAPS"></a>GST_VIDEO_FORMAT_P010_10LE</p></td>
+<td class="enum_member_description">
+<p>planar 4:2:0 YUV with interleaved UV plane, 10 bits per channel</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-FORMAT-IYU2:CAPS"></a>GST_VIDEO_FORMAT_IYU2</p></td>
+<td class="enum_member_description">
+<p>packed 4:4:4 YUV (U-Y-V ...) (Since 1.10)</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -6532,6 +7273,8 @@
 <a name="GstVideoBufferFlags"></a><h3>enum GstVideoBufferFlags</h3>
 <p>Additional video buffer flags. These flags can potentially be used on any
 buffers carrying video data - even encoded data.</p>
+<p>Note that these are only valid for <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstCaps.html#GstCaps-struct"><span class="type">GstCaps</span></a> of type: video/...
+They can conflict with other extended buffer flags.</p>
 <div class="refsect3">
 <a name="GstVideoBufferFlags.members"></a><h4>Members</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -6672,6 +7415,163 @@
 <a name="GstVideoConverter"></a><h3>GstVideoConverter</h3>
 <pre class="programlisting">typedef struct _GstVideoConverter GstVideoConverter;</pre>
 </div>
+<hr>
+<div class="refsect2">
+<a name="GstVideoTimeCode"></a><h3>struct GstVideoTimeCode</h3>
+<pre class="programlisting">struct GstVideoTimeCode {
+  GstVideoTimeCodeConfig config;
+
+  guint hours;
+  guint minutes;
+  guint seconds;
+  guint frames;
+  guint field_count;
+};
+</pre>
+<p><em class="parameter"><code>field_count</code></em>
+ must be 0 for progressive video and 1 or 2 for interlaced.</p>
+<p>A representation of a SMPTE time code.</p>
+<p><em class="parameter"><code>hours</code></em>
+ must be positive and less than 24. Will wrap around otherwise.
+<em class="parameter"><code>minutes</code></em>
+ and <em class="parameter"><code>seconds</code></em>
+ must be positive and less than 60.
+<em class="parameter"><code>frames</code></em>
+ must be less than or equal to <em class="parameter"><code>config.fps_n</code></em>
+ / <em class="parameter"><code>config.fps_d</code></em>
+
+These values are *NOT* automatically normalized.</p>
+<div class="refsect3">
+<a name="GstVideoTimeCode.members"></a><h4>Members</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeConfig" title="struct GstVideoTimeCodeConfig"><span class="type">GstVideoTimeCodeConfig</span></a> <em class="structfield"><code><a name="GstVideoTimeCode.config"></a>config</code></em>;</p></td>
+<td class="struct_member_description"><p>the corresponding <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeConfig" title="struct GstVideoTimeCodeConfig"><span class="type">GstVideoTimeCodeConfig</span></a></p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> <em class="structfield"><code><a name="GstVideoTimeCode.hours"></a>hours</code></em>;</p></td>
+<td class="struct_member_description"><p>the hours field of <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> <em class="structfield"><code><a name="GstVideoTimeCode.minutes"></a>minutes</code></em>;</p></td>
+<td class="struct_member_description"><p>the minutes field of <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> <em class="structfield"><code><a name="GstVideoTimeCode.seconds"></a>seconds</code></em>;</p></td>
+<td class="struct_member_description"><p>the seconds field of <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> <em class="structfield"><code><a name="GstVideoTimeCode.frames"></a>frames</code></em>;</p></td>
+<td class="struct_member_description"><p>the frames field of <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> <em class="structfield"><code><a name="GstVideoTimeCode.field-count"></a>field_count</code></em>;</p></td>
+<td class="struct_member_description"><p>Interlaced video field count</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstVideoTimeCodeConfig"></a><h3>struct GstVideoTimeCodeConfig</h3>
+<pre class="programlisting">struct GstVideoTimeCodeConfig {
+  guint fps_n;
+  guint fps_d;
+  GstVideoTimeCodeFlags flags;
+  GDateTime *latest_daily_jam;
+};
+</pre>
+<p>Supported frame rates: 30000/1001, 60000/1001 (both with and without drop
+frame), and integer frame rates e.g. 25/1, 30/1, 50/1, 60/1.</p>
+<p>The configuration of the time code.</p>
+<div class="refsect3">
+<a name="GstVideoTimeCodeConfig.members"></a><h4>Members</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> <em class="structfield"><code><a name="GstVideoTimeCodeConfig.fps-n"></a>fps_n</code></em>;</p></td>
+<td class="struct_member_description"><p>Numerator of the frame rate</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> <em class="structfield"><code><a name="GstVideoTimeCodeConfig.fps-d"></a>fps_d</code></em>;</p></td>
+<td class="struct_member_description"><p>Denominator of the frame rate</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeFlags" title="enum GstVideoTimeCodeFlags"><span class="type">GstVideoTimeCodeFlags</span></a> <em class="structfield"><code><a name="GstVideoTimeCodeConfig.flags"></a>flags</code></em>;</p></td>
+<td class="struct_member_description"><p>the corresponding <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeFlags" title="enum GstVideoTimeCodeFlags"><span class="type">GstVideoTimeCodeFlags</span></a></p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-GDateTime.html#GDateTime"><span class="type">GDateTime</span></a> *<em class="structfield"><code><a name="GstVideoTimeCodeConfig.latest-daily-jam"></a>latest_daily_jam</code></em>;</p></td>
+<td class="struct_member_description"><p>The latest daily jam information, if present, or NULL</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstVideoTimeCodeFlags"></a><h3>enum GstVideoTimeCodeFlags</h3>
+<p>Flags related to the time code information.
+For drop frame, only 30000/1001 and 60000/1001 frame rates are supported.</p>
+<div class="refsect3">
+<a name="GstVideoTimeCodeFlags.members"></a><h4>Members</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="300px" class="enum_members_name">
+<col class="enum_members_description">
+<col width="200px" class="enum_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-TIME-CODE-FLAGS-NONE:CAPS"></a>GST_VIDEO_TIME_CODE_FLAGS_NONE</p></td>
+<td class="enum_member_description">
+<p>No flags</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-TIME-CODE-FLAGS-DROP-FRAME:CAPS"></a>GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME</p></td>
+<td class="enum_member_description">
+<p>Whether we have drop frame rate</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-VIDEO-TIME-CODE-FLAGS-INTERLACED:CAPS"></a>GST_VIDEO_TIME_CODE_FLAGS_INTERLACED</p></td>
+<td class="enum_member_description">
+<p>Whether we have interlaced video</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
 </div>
 </div>
 <div class="footer">
diff --git a/docs/libs/html/gst-plugins-base-libs-gstvideodirection.html b/docs/libs/html/gst-plugins-base-libs-gstvideodirection.html
new file mode 100644
index 0000000..bcb2341
--- /dev/null
+++ b/docs/libs/html/gst-plugins-base-libs-gstvideodirection.html
@@ -0,0 +1,139 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>gstvideodirection: GStreamer Base Plugins 1.0 Library Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
+<link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Library Reference Manual">
+<link rel="up" href="gstreamer-video.html" title="Video Library">
+<link rel="prev" href="gst-plugins-base-libs-gstcolorbalancechannel.html" title="gstcolorbalancechannel">
+<link rel="next" href="gst-plugins-base-libs-gstvideoorientation.html" title="gstvideoorientation">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
+                  <a href="#gst-plugins-base-libs-gstvideodirection.description" class="shortcut">Description</a></span><span id="nav_hierarchy">  <span class="dim">|</span> 
+                  <a href="#gst-plugins-base-libs-gstvideodirection.object-hierarchy" class="shortcut">Object Hierarchy</a></span><span id="nav_properties">  <span class="dim">|</span> 
+                  <a href="#gst-plugins-base-libs-gstvideodirection.properties" class="shortcut">Properties</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="gstreamer-video.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="gst-plugins-base-libs-gstcolorbalancechannel.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="gst-plugins-base-libs-gstvideoorientation.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="gst-plugins-base-libs-gstvideodirection"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="gst-plugins-base-libs-gstvideodirection.top_of_page"></a>gstvideodirection</span></h2>
+<p>gstvideodirection — Interface for elements providing video
+rotation and flipping controls</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="gst-plugins-base-libs-gstvideodirection.properties"></a><h2>Properties</h2>
+<div class="informaltable"><table class="informaltable" border="0">
+<colgroup>
+<col width="150px" class="properties_type">
+<col width="300px" class="properties_name">
+<col width="200px" class="properties_flags">
+</colgroup>
+<tbody><tr>
+<td class="property_type"><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoOrientationMethod" title="enum GstVideoOrientationMethod"><span class="type">GstVideoOrientationMethod</span></a></td>
+<td class="property_name"><a class="link" href="gst-plugins-base-libs-gstvideodirection.html#GstVideoDirection--video-direction" title="The “video-direction” property">video-direction</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr></tbody>
+</table></div>
+</div>
+<a name="GstVideoDirection"></a><div class="refsect1">
+<a name="gst-plugins-base-libs-gstvideodirection.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword"> </td>
+<td class="function_name"><a class="link" href="gst-plugins-base-libs-gstvideodirection.html#GstVideoDirection-struct" title="GstVideoDirection">GstVideoDirection</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="gst-plugins-base-libs-gstvideodirection.html#GstVideoDirectionInterface" title="struct GstVideoDirectionInterface">GstVideoDirectionInterface</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="gst-plugins-base-libs-gstvideodirection.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen">    <a href="https://developer.gnome.org/gobject/unstable/GTypeModule.html">GInterface</a>
+    <span class="lineart">╰──</span> GstVideoDirection
+</pre>
+</div>
+<div class="refsect1">
+<a name="gst-plugins-base-libs-gstvideodirection.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include &lt;gst/video/videodirection.h&gt;
+</pre>
+</div>
+<div class="refsect1">
+<a name="gst-plugins-base-libs-gstvideodirection.description"></a><h2>Description</h2>
+<p>The interface allows unified access to control flipping and rotation
+operations of video-sources or operators.</p>
+</div>
+<div class="refsect1">
+<a name="gst-plugins-base-libs-gstvideodirection.functions_details"></a><h2>Functions</h2>
+<p></p>
+</div>
+<div class="refsect1">
+<a name="gst-plugins-base-libs-gstvideodirection.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="GstVideoDirection-struct"></a><h3>GstVideoDirection</h3>
+<pre class="programlisting">typedef struct _GstVideoDirection GstVideoDirection;</pre>
+<p>Opaque <a class="link" href="gst-plugins-base-libs-gstvideodirection.html#GstVideoDirection"><span class="type">GstVideoDirection</span></a> data structure.</p>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstVideoDirectionInterface"></a><h3>struct GstVideoDirectionInterface</h3>
+<pre class="programlisting">struct GstVideoDirectionInterface {
+  GTypeInterface iface;
+};
+</pre>
+<p><a class="link" href="gst-plugins-base-libs-gstvideodirection.html#GstVideoDirectionInterface" title="struct GstVideoDirectionInterface"><span class="type">GstVideoDirectionInterface</span></a> interface.</p>
+<div class="refsect3">
+<a name="GstVideoDirectionInterface.members"></a><h4>Members</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody><tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/gobjectgobject-Type-Information.html#GTypeInterface"><span class="type">GTypeInterface</span></a> <em class="structfield"><code><a name="GstVideoDirectionInterface.iface"></a>iface</code></em>;</p></td>
+<td class="struct_member_description"><p>parent interface type.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="gst-plugins-base-libs-gstvideodirection.property-details"></a><h2>Property Details</h2>
+<div class="refsect2">
+<a name="GstVideoDirection--video-direction"></a><h3>The <code class="literal">“video-direction”</code> property</h3>
+<pre class="programlisting">  “video-direction”          <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoOrientationMethod" title="enum GstVideoOrientationMethod"><span class="type">GstVideoOrientationMethod</span></a></pre>
+<p>Video direction: rotation and flipping.</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Default value: GST_VIDEO_ORIENTATION_IDENTITY</p>
+</div>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/libs/html/gst-plugins-base-libs-gstvideometa.html b/docs/libs/html/gst-plugins-base-libs-gstvideometa.html
index 9f4482d..6a7d901 100644
--- a/docs/libs/html/gst-plugins-base-libs-gstvideometa.html
+++ b/docs/libs/html/gst-plugins-base-libs-gstvideometa.html
@@ -166,6 +166,28 @@
 <a class="link" href="gst-plugins-base-libs-gstvideometa.html#gst-video-gl-texture-upload-meta-upload" title="gst_video_gl_texture_upload_meta_upload ()">gst_video_gl_texture_upload_meta_upload</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
+<tr>
+<td class="function_type">
+<a class="link" href="gst-plugins-base-libs-gstvideometa.html#GstVideoTimeCodeMeta" title="GstVideoTimeCodeMeta"><span class="returnvalue">GstVideoTimeCodeMeta</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideometa.html#gst-buffer-add-video-time-code-meta" title="gst_buffer_add_video_time_code_meta ()">gst_buffer_add_video_time_code_meta</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a class="link" href="gst-plugins-base-libs-gstvideometa.html#GstVideoTimeCodeMeta" title="GstVideoTimeCodeMeta"><span class="returnvalue">GstVideoTimeCodeMeta</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideometa.html#gst-buffer-add-video-time-code-meta-full" title="gst_buffer_add_video_time_code_meta_full ()">gst_buffer_add_video_time_code_meta_full</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-base-libs-gstvideometa.html#gst-buffer-get-video-time-code-meta" title="gst_buffer_get_video_time_code_meta()">gst_buffer_get_video_time_code_meta</a><span class="c_punctuation">()</span>
+</td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -201,6 +223,10 @@
 <td class="datatype_keyword">struct</td>
 <td class="function_name"><a class="link" href="gst-plugins-base-libs-gstvideometa.html#GstVideoGLTextureUploadMeta" title="struct GstVideoGLTextureUploadMeta">GstVideoGLTextureUploadMeta</a></td>
 </tr>
+<tr>
+<td class="datatype_keyword"> </td>
+<td class="function_name"><a class="link" href="gst-plugins-base-libs-gstvideometa.html#GstVideoTimeCodeMeta" title="GstVideoTimeCodeMeta">GstVideoTimeCodeMeta</a></td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -844,6 +870,138 @@
 <p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if uploading succeeded, <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a> otherwise.</p>
 </div>
 </div>
+<hr>
+<div class="refsect2">
+<a name="gst-buffer-add-video-time-code-meta"></a><h3>gst_buffer_add_video_time_code_meta ()</h3>
+<pre class="programlisting"><a class="link" href="gst-plugins-base-libs-gstvideometa.html#GstVideoTimeCodeMeta" title="GstVideoTimeCodeMeta"><span class="returnvalue">GstVideoTimeCodeMeta</span></a> *
+gst_buffer_add_video_time_code_meta (<em class="parameter"><code><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstBuffer.html#GstBuffer-struct"><span class="type">GstBuffer</span></a> *buffer</code></em>,
+                                     <em class="parameter"><code><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> *tc</code></em>);</pre>
+<p>Attaches <a class="link" href="gst-plugins-base-libs-gstvideometa.html#GstVideoTimeCodeMeta" title="GstVideoTimeCodeMeta"><span class="type">GstVideoTimeCodeMeta</span></a> metadata to <em class="parameter"><code>buffer</code></em>
+ with the given
+parameters.</p>
+<div class="refsect3">
+<a name="gst-buffer-add-video-time-code-meta.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>buffer</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstBuffer.html#GstBuffer-struct"><span class="type">GstBuffer</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>tc</p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-buffer-add-video-time-code-meta.returns"></a><h4>Returns</h4>
+<p> the <a class="link" href="gst-plugins-base-libs-gstvideometa.html#GstVideoTimeCodeMeta" title="GstVideoTimeCodeMeta"><span class="type">GstVideoTimeCodeMeta</span></a> on <em class="parameter"><code>buffer</code></em>
+. </p>
+<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-buffer-add-video-time-code-meta-full"></a><h3>gst_buffer_add_video_time_code_meta_full ()</h3>
+<pre class="programlisting"><a class="link" href="gst-plugins-base-libs-gstvideometa.html#GstVideoTimeCodeMeta" title="GstVideoTimeCodeMeta"><span class="returnvalue">GstVideoTimeCodeMeta</span></a> *
+gst_buffer_add_video_time_code_meta_full
+                               (<em class="parameter"><code><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstBuffer.html#GstBuffer-struct"><span class="type">GstBuffer</span></a> *buffer</code></em>,
+                                <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> fps_n</code></em>,
+                                <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> fps_d</code></em>,
+                                <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-GDateTime.html#GDateTime"><span class="type">GDateTime</span></a> *latest_daily_jam</code></em>,
+                                <em class="parameter"><code><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeFlags" title="enum GstVideoTimeCodeFlags"><span class="type">GstVideoTimeCodeFlags</span></a> flags</code></em>,
+                                <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> hours</code></em>,
+                                <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> minutes</code></em>,
+                                <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> seconds</code></em>,
+                                <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> frames</code></em>,
+                                <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> field_count</code></em>);</pre>
+<p>Attaches <a class="link" href="gst-plugins-base-libs-gstvideometa.html#GstVideoTimeCodeMeta" title="GstVideoTimeCodeMeta"><span class="type">GstVideoTimeCodeMeta</span></a> metadata to <em class="parameter"><code>buffer</code></em>
+ with the given
+parameters.</p>
+<div class="refsect3">
+<a name="gst-buffer-add-video-time-code-meta-full.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>buffer</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstBuffer.html#GstBuffer-struct"><span class="type">GstBuffer</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>fps_n</p></td>
+<td class="parameter_description"><p>framerate numerator</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>fps_d</p></td>
+<td class="parameter_description"><p>framerate denominator</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>latest_daily_jam</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/glibglib-GDateTime.html#GDateTime"><span class="type">GDateTime</span></a> for the latest daily jam</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>flags</p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCodeFlags" title="enum GstVideoTimeCodeFlags"><span class="type">GstVideoTimeCodeFlags</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>hours</p></td>
+<td class="parameter_description"><p>hours since the daily jam</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>minutes</p></td>
+<td class="parameter_description"><p>minutes since the daily jam</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>seconds</p></td>
+<td class="parameter_description"><p>seconds since the daily jam</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>frames</p></td>
+<td class="parameter_description"><p>frames since the daily jam</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>field_count</p></td>
+<td class="parameter_description"><p>fields since the daily jam</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="gst-buffer-add-video-time-code-meta-full.returns"></a><h4>Returns</h4>
+<p> the <a class="link" href="gst-plugins-base-libs-gstvideometa.html#GstVideoTimeCodeMeta" title="GstVideoTimeCodeMeta"><span class="type">GstVideoTimeCodeMeta</span></a> on <em class="parameter"><code>buffer</code></em>
+. </p>
+<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gst-buffer-get-video-time-code-meta"></a><h3>gst_buffer_get_video_time_code_meta()</h3>
+<pre class="programlisting">#define             gst_buffer_get_video_time_code_meta(b)</pre>
+</div>
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-libs-gstvideometa.other_details"></a><h2>Types and Values</h2>
@@ -1161,6 +1319,42 @@
 </table></div>
 </div>
 </div>
+<hr>
+<div class="refsect2">
+<a name="GstVideoTimeCodeMeta"></a><h3>GstVideoTimeCodeMeta</h3>
+<pre class="programlisting">typedef struct {
+  GstMeta meta;
+
+  GstVideoTimeCode tc;
+} GstVideoTimeCodeMeta;
+</pre>
+<p>Extra buffer metadata describing the GstVideoTimeCode of the frame.</p>
+<p>Each frame is assumed to have its own timecode, i.e. they are not
+automatically incremented/interpolated.</p>
+<div class="refsect3">
+<a name="GstVideoTimeCodeMeta.members"></a><h4>Members</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/gstreamer-1.0gstreamer-GstMeta.html#GstMeta"><span class="type">GstMeta</span></a> <em class="structfield"><code><a name="GstVideoTimeCodeMeta.meta"></a>meta</code></em>;</p></td>
+<td class="struct_member_description"><p>parent <a href="/usr/share/gtk-doc/html/gstreamer-1.0gstreamer-GstMeta.html#GstMeta"><span class="type">GstMeta</span></a></p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoTimeCode" title="struct GstVideoTimeCode"><span class="type">GstVideoTimeCode</span></a> <em class="structfield"><code><a name="GstVideoTimeCodeMeta.tc"></a>tc</code></em>;</p></td>
+<td class="struct_member_description"><p>the GstVideoTimeCode to attach</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 1.10</p>
+</div>
 </div>
 </div>
 <div class="footer">
diff --git a/docs/libs/html/gst-plugins-base-libs-gstvideoorientation.html b/docs/libs/html/gst-plugins-base-libs-gstvideoorientation.html
index d0216f6..124ce38 100644
--- a/docs/libs/html/gst-plugins-base-libs-gstvideoorientation.html
+++ b/docs/libs/html/gst-plugins-base-libs-gstvideoorientation.html
@@ -6,7 +6,7 @@
 <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
 <link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Library Reference Manual">
 <link rel="up" href="gstreamer-video.html" title="Video Library">
-<link rel="prev" href="gst-plugins-base-libs-gstcolorbalancechannel.html" title="gstcolorbalancechannel">
+<link rel="prev" href="gst-plugins-base-libs-gstvideodirection.html" title="gstvideodirection">
 <link rel="next" href="gst-plugins-base-libs-gstvideooverlay.html" title="gstvideooverlay">
 <meta name="generator" content="GTK-Doc V1.25 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
@@ -20,7 +20,7 @@
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="gstreamer-video.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="gst-plugins-base-libs-gstcolorbalancechannel.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="p" href="gst-plugins-base-libs-gstvideodirection.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="gst-plugins-base-libs-gstvideooverlay.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
diff --git a/docs/libs/html/gst-plugins-base-libs-gstvideooverlay.html b/docs/libs/html/gst-plugins-base-libs-gstvideooverlay.html
index 1aa62bc..608ba7e 100644
--- a/docs/libs/html/gst-plugins-base-libs-gstvideooverlay.html
+++ b/docs/libs/html/gst-plugins-base-libs-gstvideooverlay.html
@@ -134,7 +134,7 @@
 <div class="refsect1">
 <a name="gst-plugins-base-libs-gstvideooverlay.description"></a><h2>Description</h2>
 <div class="refsect2">
-<a name="id-1.2.15.16.8.2"></a><p>
+<a name="id-1.2.15.17.8.2"></a><p>
 The <a class="link" href="gst-plugins-base-libs-gstvideooverlay.html#GstVideoOverlay"><span class="type">GstVideoOverlay</span></a> interface is used for 2 main purposes :
 </p>
 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
@@ -246,7 +246,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.15.16.8.3"></a><h3>Two basic usage scenarios</h3>
+<a name="id-1.2.15.17.8.3"></a><h3>Two basic usage scenarios</h3>
 <p>
 There are two basic usage scenarios: in the simplest case, the application
 uses <span class="type">playbin</span> or <span class="type">plasink</span> or knows exactly what particular element is used
@@ -293,7 +293,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.15.16.8.4"></a><h3>GstVideoOverlay and Gtk+</h3>
+<a name="id-1.2.15.17.8.4"></a><h3>GstVideoOverlay and Gtk+</h3>
 <p>
 </p>
 <div class="informalexample">
@@ -502,7 +502,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.15.16.8.5"></a><h3>GstVideoOverlay and Qt</h3>
+<a name="id-1.2.15.17.8.5"></a><h3>GstVideoOverlay and Qt</h3>
 <p>
 </p>
 <div class="informalexample">
diff --git a/docs/libs/html/gst-plugins-base-libs-gstvideooverlaycomposition.html b/docs/libs/html/gst-plugins-base-libs-gstvideooverlaycomposition.html
index b7d0e8f..be3fd72 100644
--- a/docs/libs/html/gst-plugins-base-libs-gstvideooverlaycomposition.html
+++ b/docs/libs/html/gst-plugins-base-libs-gstvideooverlaycomposition.html
@@ -651,6 +651,9 @@
 . The data in <em class="parameter"><code>video_buf</code></em>
  must be writable and
 mapped appropriately.</p>
+<p>Since <em class="parameter"><code>video_buf</code></em>
+ data is read and will be modified, it ought be
+mapped with flag GST_MAP_READWRITE.</p>
 <div class="refsect3">
 <a name="gst-video-overlay-composition-blend.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -667,7 +670,8 @@
 </tr>
 <tr>
 <td class="parameter_name"><p>video_buf</p></td>
-<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoFrame" title="struct GstVideoFrame"><span class="type">GstVideoFrame</span></a> containing raw video data in a supported format</p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-libs-gstvideo.html#GstVideoFrame" title="struct GstVideoFrame"><span class="type">GstVideoFrame</span></a> containing raw video data in a
+supported format. It should be mapped using GST_MAP_READWRITE</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
diff --git a/docs/libs/html/gst-plugins-base-libs-gstvideoutils.html b/docs/libs/html/gst-plugins-base-libs-gstvideoutils.html
index 61b122e..8f15855 100644
--- a/docs/libs/html/gst-plugins-base-libs-gstvideoutils.html
+++ b/docs/libs/html/gst-plugins-base-libs-gstvideoutils.html
@@ -815,6 +815,8 @@
   GstCaps *caps;
 
   GstBuffer *codec_data;
+
+  GstCaps *allocation_caps;
 };
 </pre>
 <p>Structure representing the state of an incoming or outgoing video
@@ -843,7 +845,7 @@
 </tr>
 <tr>
 <td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstCaps.html#GstCaps-struct"><span class="type">GstCaps</span></a> *<em class="structfield"><code><a name="GstVideoCodecState.caps"></a>caps</code></em>;</p></td>
-<td class="struct_member_description"><p>The <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstCaps.html#GstCaps-struct"><span class="type">GstCaps</span></a></p></td>
+<td class="struct_member_description"><p>The <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstCaps.html#GstCaps-struct"><span class="type">GstCaps</span></a> used in the caps negotiation of the pad.</p></td>
 <td class="struct_member_annotations"> </td>
 </tr>
 <tr>
@@ -852,6 +854,12 @@
 'codec_data' field of a stream, or NULL.</p></td>
 <td class="struct_member_annotations"> </td>
 </tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstCaps.html#GstCaps-struct"><span class="type">GstCaps</span></a> *<em class="structfield"><code><a name="GstVideoCodecState.allocation-caps"></a>allocation_caps</code></em>;</p></td>
+<td class="struct_member_description"><p>The <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstCaps.html#GstCaps-struct"><span class="type">GstCaps</span></a> for allocation query and pool
+negotiation. Since: 1.10</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
 </tbody>
 </table></div>
 </div>
diff --git a/docs/libs/html/gstreamer-libs-hierarchy.html b/docs/libs/html/gstreamer-libs-hierarchy.html
index 602c912..55e306c 100644
--- a/docs/libs/html/gstreamer-libs-hierarchy.html
+++ b/docs/libs/html/gstreamer-libs-hierarchy.html
@@ -60,6 +60,7 @@
     <span class="lineart">├──</span> <a class="link" href="gst-plugins-base-libs-gstnavigation.html#GstNavigation">GstNavigation</a>
     <span class="lineart">├──</span> <a class="link" href="gst-plugins-base-libs-gststreamvolume.html#GstStreamVolume">GstStreamVolume</a>
     <span class="lineart">├──</span> <a class="link" href="gst-plugins-base-libs-gstcolorbalance.html#GstColorBalance">GstColorBalance</a>
+    <span class="lineart">├──</span> <a class="link" href="gst-plugins-base-libs-gstvideodirection.html#GstVideoDirection">GstVideoDirection</a>
     <span class="lineart">├──</span> <a class="link" href="gst-plugins-base-libs-gstvideoorientation.html#GstVideoOrientation">GstVideoOrientation</a>
     <span class="lineart">╰──</span> <a class="link" href="gst-plugins-base-libs-gstvideooverlay.html#GstVideoOverlay">GstVideoOverlay</a>
 </pre>
diff --git a/docs/libs/html/gstreamer-plugins-base.html b/docs/libs/html/gstreamer-plugins-base.html
index fcf5bf1..b494f60 100644
--- a/docs/libs/html/gstreamer-plugins-base.html
+++ b/docs/libs/html/gstreamer-plugins-base.html
@@ -289,6 +289,10 @@
         interface.</span>
 </dt>
 <dt>
+<span class="refentrytitle"><a href="gst-plugins-base-libs-gstvideodirection.html">gstvideodirection</a></span><span class="refpurpose"> — Interface for elements providing video
+rotation and flipping controls</span>
+</dt>
+<dt>
 <span class="refentrytitle"><a href="gst-plugins-base-libs-gstvideoorientation.html">gstvideoorientation</a></span><span class="refpurpose"> — Interface for elements providing video orientation
 controls</span>
 </dt>
diff --git a/docs/libs/html/gstreamer-video.html b/docs/libs/html/gstreamer-video.html
index 3dc6ce9..35281a8 100644
--- a/docs/libs/html/gstreamer-video.html
+++ b/docs/libs/html/gstreamer-video.html
@@ -61,6 +61,10 @@
         interface.</span>
 </dt>
 <dt>
+<span class="refentrytitle"><a href="gst-plugins-base-libs-gstvideodirection.html">gstvideodirection</a></span><span class="refpurpose"> — Interface for elements providing video
+rotation and flipping controls</span>
+</dt>
+<dt>
 <span class="refentrytitle"><a href="gst-plugins-base-libs-gstvideoorientation.html">gstvideoorientation</a></span><span class="refpurpose"> — Interface for elements providing video orientation
 controls</span>
 </dt>
diff --git a/docs/libs/html/index.html b/docs/libs/html/index.html
index b8fdc8c..188af43 100644
--- a/docs/libs/html/index.html
+++ b/docs/libs/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 Base Plugins 1.0 Library Reference Manual</p></th></tr></table></div>
 <div><p class="releaseinfo">
-      for GStreamer Base Library 1.0 (1.8.3)
+      for GStreamer Base Library 1.0 (1.9.90)
       <a class="ulink" href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/" target="_top">http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/</a>.
     </p></div>
 </div>
@@ -288,6 +288,10 @@
         interface.</span>
 </dt>
 <dt>
+<span class="refentrytitle"><a href="gst-plugins-base-libs-gstvideodirection.html">gstvideodirection</a></span><span class="refpurpose"> — Interface for elements providing video
+rotation and flipping controls</span>
+</dt>
+<dt>
 <span class="refentrytitle"><a href="gst-plugins-base-libs-gstvideoorientation.html">gstvideoorientation</a></span><span class="refpurpose"> — Interface for elements providing video orientation
 controls</span>
 </dt>
diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am
index 5e72a67..4722155 100644
--- a/docs/plugins/Makefile.am
+++ b/docs/plugins/Makefile.am
@@ -55,6 +55,8 @@
 	$(top_srcdir)/ext/cdparanoia/gstcdparanoiasrc.h \
 	$(top_srcdir)/ext/ogg/gstoggdemux.h \
 	$(top_srcdir)/ext/ogg/gstoggmux.h \
+	$(top_srcdir)/ext/opus/gstopusdec.h \
+	$(top_srcdir)/ext/opus/gstopusenc.h \
 	$(top_srcdir)/ext/pango/gstclockoverlay.h \
 	$(top_srcdir)/ext/pango/gsttextoverlay.h \
 	$(top_srcdir)/ext/pango/gsttextrender.h \
@@ -68,6 +70,8 @@
 	$(top_srcdir)/ext/vorbis/gstvorbistag.h \
 	$(top_srcdir)/gst/adder/gstadder.h \
 	$(top_srcdir)/gst/audioconvert/gstaudioconvert.h \
+	$(top_srcdir)/gst/audiorate/gstaudiorate.h \
+	$(top_srcdir)/gst/audioresample/gstaudioresample.h \
 	$(top_srcdir)/gst/audiotestsrc/gstaudiotestsrc.h \
 	$(top_srcdir)/gst/encoding/gstencodebin.h \
 	$(top_srcdir)/gst/gio/gstgiosink.h \
@@ -75,16 +79,23 @@
 	$(top_srcdir)/gst/gio/gstgiostreamsink.h \
 	$(top_srcdir)/gst/gio/gstgiostreamsrc.h \
 	$(top_srcdir)/gst/playback/gstplay-enum.h \
+	$(top_srcdir)/gst/playback/gstplaysink.h \
+	$(top_srcdir)/gst/playback/gststreamsynchronizer.h \
 	$(top_srcdir)/gst/playback/gstsubtitleoverlay.h \
 	$(top_srcdir)/gst/audiorate/gstaudiorate.h \
 	$(top_srcdir)/gst/audioresample/gstaudioresample.h \
+	$(top_srcdir)/gst/subparse/gstssaparse.h \
+	$(top_srcdir)/gst/subparse/gstsubparse.h \
+	$(top_srcdir)/gst/tcp/gstmultifdsink.h \
+	$(top_srcdir)/gst/tcp/gstmultihandlesink.h \
 	$(top_srcdir)/gst/tcp/gstmultisocketsink.h \
 	$(top_srcdir)/gst/tcp/gstsocketsrc.h \
-	$(top_srcdir)/gst/tcp/gsttcpclientsrc.h \
 	$(top_srcdir)/gst/tcp/gsttcpclientsink.h \
-	$(top_srcdir)/gst/tcp/gsttcpserversrc.h \
-	$(top_srcdir)/gst/tcp/gsttcpserversink.h \
+	$(top_srcdir)/gst/tcp/gsttcpclientsrc.h \
 	$(top_srcdir)/gst/tcp/gsttcp.h \
+	$(top_srcdir)/gst/tcp/gsttcpserversink.h \
+	$(top_srcdir)/gst/tcp/gsttcpserversrc.h \
+	$(top_srcdir)/gst/videoconvert/gstvideoconvert.h \
 	$(top_srcdir)/gst/videorate/gstvideorate.h \
 	$(top_srcdir)/gst/videoscale/gstvideoscale.h \
 	$(top_srcdir)/gst/videotestsrc/gstvideotestsrc.h \
diff --git a/docs/plugins/Makefile.in b/docs/plugins/Makefile.in
index 7d623bd..50768e9 100644
--- a/docs/plugins/Makefile.in
+++ b/docs/plugins/Makefile.in
@@ -113,6 +113,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -364,6 +365,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -377,6 +381,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -414,6 +421,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -522,6 +530,8 @@
 	$(top_srcdir)/ext/cdparanoia/gstcdparanoiasrc.h \
 	$(top_srcdir)/ext/ogg/gstoggdemux.h \
 	$(top_srcdir)/ext/ogg/gstoggmux.h \
+	$(top_srcdir)/ext/opus/gstopusdec.h \
+	$(top_srcdir)/ext/opus/gstopusenc.h \
 	$(top_srcdir)/ext/pango/gstclockoverlay.h \
 	$(top_srcdir)/ext/pango/gsttextoverlay.h \
 	$(top_srcdir)/ext/pango/gsttextrender.h \
@@ -535,6 +545,8 @@
 	$(top_srcdir)/ext/vorbis/gstvorbistag.h \
 	$(top_srcdir)/gst/adder/gstadder.h \
 	$(top_srcdir)/gst/audioconvert/gstaudioconvert.h \
+	$(top_srcdir)/gst/audiorate/gstaudiorate.h \
+	$(top_srcdir)/gst/audioresample/gstaudioresample.h \
 	$(top_srcdir)/gst/audiotestsrc/gstaudiotestsrc.h \
 	$(top_srcdir)/gst/encoding/gstencodebin.h \
 	$(top_srcdir)/gst/gio/gstgiosink.h \
@@ -542,16 +554,23 @@
 	$(top_srcdir)/gst/gio/gstgiostreamsink.h \
 	$(top_srcdir)/gst/gio/gstgiostreamsrc.h \
 	$(top_srcdir)/gst/playback/gstplay-enum.h \
+	$(top_srcdir)/gst/playback/gstplaysink.h \
+	$(top_srcdir)/gst/playback/gststreamsynchronizer.h \
 	$(top_srcdir)/gst/playback/gstsubtitleoverlay.h \
 	$(top_srcdir)/gst/audiorate/gstaudiorate.h \
 	$(top_srcdir)/gst/audioresample/gstaudioresample.h \
+	$(top_srcdir)/gst/subparse/gstssaparse.h \
+	$(top_srcdir)/gst/subparse/gstsubparse.h \
+	$(top_srcdir)/gst/tcp/gstmultifdsink.h \
+	$(top_srcdir)/gst/tcp/gstmultihandlesink.h \
 	$(top_srcdir)/gst/tcp/gstmultisocketsink.h \
 	$(top_srcdir)/gst/tcp/gstsocketsrc.h \
-	$(top_srcdir)/gst/tcp/gsttcpclientsrc.h \
 	$(top_srcdir)/gst/tcp/gsttcpclientsink.h \
-	$(top_srcdir)/gst/tcp/gsttcpserversrc.h \
-	$(top_srcdir)/gst/tcp/gsttcpserversink.h \
+	$(top_srcdir)/gst/tcp/gsttcpclientsrc.h \
 	$(top_srcdir)/gst/tcp/gsttcp.h \
+	$(top_srcdir)/gst/tcp/gsttcpserversink.h \
+	$(top_srcdir)/gst/tcp/gsttcpserversrc.h \
+	$(top_srcdir)/gst/videoconvert/gstvideoconvert.h \
 	$(top_srcdir)/gst/videorate/gstvideorate.h \
 	$(top_srcdir)/gst/videoscale/gstvideoscale.h \
 	$(top_srcdir)/gst/videotestsrc/gstvideotestsrc.h \
@@ -1001,9 +1020,13 @@
 @ENABLE_GTK_DOC_TRUE@		$(top_srcdir)/common/plugins.xsl $$a > xml/`basename $$a`; done
 @ENABLE_GTK_DOC_TRUE@	@for f in $(EXAMPLE_CFILES); do \
 @ENABLE_GTK_DOC_TRUE@		$(PYTHON) $(top_srcdir)/common/c-to-xml.py $$f > xml/element-`basename $$f .c`.xml; done
-@ENABLE_GTK_DOC_TRUE@	@gtkdoc-mkdb \
+@ENABLE_GTK_DOC_TRUE@	@_source_dir='' ;						\
+@ENABLE_GTK_DOC_TRUE@	for i in $(DOC_SOURCE_DIR) ; do					\
+@ENABLE_GTK_DOC_TRUE@	    _source_dir="$${_source_dir} --source-dir=$$i" ;	        \
+@ENABLE_GTK_DOC_TRUE@	done ;								\
+@ENABLE_GTK_DOC_TRUE@	gtkdoc-mkdb \
 @ENABLE_GTK_DOC_TRUE@		--module=$(DOC_MODULE) \
-@ENABLE_GTK_DOC_TRUE@		--source-dir=$(DOC_SOURCE_DIR) \
+@ENABLE_GTK_DOC_TRUE@		$${_source_dir} \
 @ENABLE_GTK_DOC_TRUE@		 --expand-content-files="$(expand_content_files)" \
 @ENABLE_GTK_DOC_TRUE@		--main-sgml-file=$(srcdir)/$(DOC_MAIN_SGML_FILE) \
 @ENABLE_GTK_DOC_TRUE@		--output-format=xml \
diff --git a/docs/plugins/gst-plugins-base-plugins-docs.sgml b/docs/plugins/gst-plugins-base-plugins-docs.sgml
index 9cb48d8..e822702 100644
--- a/docs/plugins/gst-plugins-base-plugins-docs.sgml
+++ b/docs/plugins/gst-plugins-base-plugins-docs.sgml
@@ -20,8 +20,8 @@
     <xi:include href="xml/element-adder.xml" />
     <xi:include href="xml/element-alsamidisrc.xml" />
     <xi:include href="xml/element-alsasink.xml" />
-    <xi:include href="xml/element-alsasrc.xml" />
     <xi:include href="xml/element-appsink.xml" />
+    <xi:include href="xml/element-alsasrc.xml" />
     <xi:include href="xml/element-appsrc.xml" />
     <xi:include href="xml/element-audioconvert.xml" />
     <xi:include href="xml/element-audiorate.xml" />
@@ -30,6 +30,7 @@
     <xi:include href="xml/element-cdparanoiasrc.xml" />
     <xi:include href="xml/element-clockoverlay.xml" />
     <xi:include href="xml/element-decodebin.xml" />
+    <xi:include href="xml/element-decodebin3.xml" />
     <xi:include href="xml/element-encodebin.xml" />
     <xi:include href="xml/element-giosink.xml" />
     <xi:include href="xml/element-giosrc.xml" />
@@ -46,7 +47,9 @@
     <xi:include href="xml/element-ogmvideoparse.xml" />
     <xi:include href="xml/element-opusdec.xml" />
     <xi:include href="xml/element-opusenc.xml" />
+    <xi:include href="xml/element-parsebin.xml" />
     <xi:include href="xml/element-playbin.xml" />
+    <xi:include href="xml/element-playbin3.xml" />
     <xi:include href="xml/element-playsink.xml" />
     <xi:include href="xml/element-socketsrc.xml" />
     <xi:include href="xml/element-ssaparse.xml" />
@@ -64,6 +67,7 @@
     <xi:include href="xml/element-theoraparse.xml" />
     <xi:include href="xml/element-timeoverlay.xml" />
     <xi:include href="xml/element-uridecodebin.xml" />
+    <xi:include href="xml/element-urisourcebin.xml" />
     <xi:include href="xml/element-videoconvert.xml" />
     <xi:include href="xml/element-videorate.xml" />
     <xi:include href="xml/element-videoscale.xml" />
diff --git a/docs/plugins/gst-plugins-base-plugins-sections.txt b/docs/plugins/gst-plugins-base-plugins-sections.txt
index 2cd8ce8..0d4d63c 100644
--- a/docs/plugins/gst-plugins-base-plugins-sections.txt
+++ b/docs/plugins/gst-plugins-base-plugins-sections.txt
@@ -5,16 +5,13 @@
 <SUBSECTION Standard>
 GstAdderClass
 GST_ADDER
+GST_ADDER_CAST
 GST_IS_ADDER
 GST_ADDER_CLASS
 GST_IS_ADDER_CLASS
 GST_TYPE_ADDER
 <SUBSECTION Private>
 gst_adder_get_type
-GstAdderClass
-GstAdderFormat
-GstAdderFunction
-GstAdderInputChannel
 </SECTION>
 
 <SECTION>
@@ -24,11 +21,12 @@
 <SUBSECTION Standard>
 GstAlsaMidiSrcClass
 GST_ALSA_MIDI_SRC
-GST_ALSA_MIDI_SRC_CLASS
+GST_ALSA_MIDI_SRC_CAST
 GST_IS_ALSA_MIDI_SRC
+GST_ALSA_MIDI_SRC_CLASS
 GST_IS_ALSA_MIDI_SRC_CLASS
 GST_TYPE_ALSA_MIDI_SRC
-SUBSECTION Private>
+<SUBSECTION Private>
 gst_alsa_midi_src_get_type
 </SECTION>
 
@@ -44,9 +42,6 @@
 GST_ALSA_SINK_CLASS
 GST_IS_ALSA_SINK_CLASS
 GST_TYPE_ALSA_SINK
-GST_ALSA_SINK_GET_LOCK
-GST_ALSA_SINK_LOCK
-GST_ALSA_SINK_UNLOCK
 <SUBSECTION Private>
 gst_alsa_sink_get_type
 </SECTION>
@@ -63,9 +58,6 @@
 GST_ALSA_SRC_CLASS
 GST_IS_ALSA_SRC_CLASS
 GST_TYPE_ALSA_SRC
-GST_ALSA_SRC_GET_LOCK
-GST_ALSA_SRC_LOCK
-GST_ALSA_SRC_UNLOCK
 <SUBSECTION Private>
 gst_alsa_src_get_type
 </SECTION>
@@ -75,22 +67,9 @@
 <TITLE>appsink</TITLE>
 GstAppSink
 <SUBSECTION Standard>
-gst_app_sink_set_caps
-gst_app_sink_get_caps
-gst_app_sink_is_eos
-gst_app_sink_set_emit_signals
-gst_app_sink_get_emit_signals
-gst_app_sink_set_max_buffers
-gst_app_sink_get_max_buffers
-gst_app_sink_set_drop
-gst_app_sink_get_drop
-gst_app_sink_pull_preroll
-gst_app_sink_pull_buffer
-gst_app_sink_set_callbacks
 GstAppSinkClass
-GstAppSinkPrivate
-GstAppSinkCallbacks
 GST_APP_SINK
+GST_APP_SINK_CAST
 GST_IS_APP_SINK
 GST_APP_SINK_CLASS
 GST_IS_APP_SINK_CLASS
@@ -104,26 +83,9 @@
 <TITLE>appsrc</TITLE>
 GstAppSrc
 <SUBSECTION Standard>
-gst_app_src_set_caps
-gst_app_src_get_caps
-gst_app_src_set_size
-gst_app_src_get_size
-gst_app_src_set_stream_type
-gst_app_src_get_stream_type
-gst_app_src_set_max_bytes
-gst_app_src_get_max_bytes
-gst_app_src_set_latency
-gst_app_src_get_latency
-gst_app_src_set_emit_signals
-gst_app_src_get_emit_signals
-gst_app_src_push_buffer
-gst_app_src_end_of_stream
-GstAppSrcCallbacks
-gst_app_src_set_callbacks
 GstAppSrcClass
-GstAppSrcPrivate
-GstAppStreamType
 GST_APP_SRC
+GST_APP_SRC_CAST
 GST_IS_APP_SRC
 GST_APP_SRC_CLASS
 GST_IS_APP_SRC_CLASS
@@ -136,26 +98,14 @@
 <FILE>element-audioconvert</FILE>
 <TITLE>audioconvert</TITLE>
 GstAudioConvert
-GstAudioConvertDithering
-GstAudioConvertNoiseShaping
 <SUBSECTION Standard>
 GstAudioConvertClass
 GST_AUDIO_CONVERT
+GST_AUDIO_CONVERT_CAST
 GST_IS_AUDIO_CONVERT
 GST_AUDIO_CONVERT_CLASS
 GST_IS_AUDIO_CONVERT_CLASS
 GST_TYPE_AUDIO_CONVERT
-AudioConvertCtx
-AudioConvertFmt
-AudioConvertMix
-AudioConvertPack
-AudioConvertQuantize
-AudioConvertUnpack
-audio_convert_clean_context
-audio_convert_clean_fmt
-audio_convert_convert
-audio_convert_get_sizes
-audio_convert_prepare_context
 <SUBSECTION Private>
 gst_audio_convert_get_type
 </SECTION>
@@ -167,6 +117,7 @@
 <SUBSECTION Standard>
 GstAudioRateClass
 GST_AUDIO_RATE
+GST_AUDIO_RATE_CAST
 GST_IS_AUDIO_RATE
 GST_AUDIO_RATE_CLASS
 GST_IS_AUDIO_RATE_CLASS
@@ -179,9 +130,13 @@
 <FILE>element-audioresample</FILE>
 <TITLE>audioresample</TITLE>
 GstAudioResample
+GstAudioResamplerMethod
+GstAudioResamplerFilterInterpolation
+GstAudioResamplerFilterMode
 <SUBSECTION Standard>
 GstAudioResampleClass
 GST_AUDIO_RESAMPLE
+GST_AUDIO_RESAMPLE_CAST
 GST_IS_AUDIO_RESAMPLE
 GST_AUDIO_RESAMPLE_CLASS
 GST_IS_AUDIO_RESAMPLE_CLASS
@@ -198,6 +153,7 @@
 <SUBSECTION Standard>
 GstAudioTestSrcClass
 GST_AUDIO_TEST_SRC
+GST_AUDIO_TEST_SRC_CAST
 GST_IS_AUDIO_TEST_SRC
 GST_AUDIO_TEST_SRC_CLASS
 GST_IS_AUDIO_TEST_SRC_CLASS
@@ -213,6 +169,7 @@
 <SUBSECTION Standard>
 GstCdParanoiaSrcClass
 GST_CD_PARANOIA_SRC
+GST_CD_PARANOIA_SRC_CAST
 GST_IS_CD_PARANOIA_SRC
 GST_CD_PARANOIA_SRC_CLASS
 GST_IS_CD_PARANOIA_SRC_CLASS
@@ -228,6 +185,7 @@
 <SUBSECTION Standard>
 GstClockOverlayClass
 GST_CLOCK_OVERLAY
+GST_CLOCK_OVERLAY_CAST
 GST_IS_CLOCK_OVERLAY
 GST_CLOCK_OVERLAY_CLASS
 GST_IS_CLOCK_OVERLAY_CLASS
@@ -253,6 +211,22 @@
 </SECTION>
 
 <SECTION>
+<FILE>element-decodebin3</FILE>
+<TITLE>decodebin3</TITLE>
+GstDecodebin3
+<SUBSECTION Standard>
+GstDecodebin3Class
+GST_DECODEBIN3
+GST_DECODEBIN3_CAST
+GST_IS_DECODEBIN3
+GST_DECODEBIN3_CLASS
+GST_IS_DECODEBIN3_CLASS
+GST_TYPE_DECODEBIN3
+<SUBSECTION Private>
+gst_decodebin3_get_type
+</SECTION>
+
+<SECTION>
 <FILE>element-encodebin</FILE>
 <TITLE>encodebin</TITLE>
 GstEncodeBin
@@ -260,6 +234,7 @@
 <SUBSECTION Standard>
 GstEncodeBinClass
 GST_ENCODE_BIN
+GST_ENCODE_BIN_CAST
 GST_IS_ENCODE_BIN
 GST_ENCODE_BIN_CLASS
 GST_IS_ENCODE_BIN_CLASS
@@ -275,6 +250,7 @@
 <SUBSECTION Standard>
 GstGioSinkClass
 GST_GIO_SINK
+GST_GIO_SINK_CAST
 GST_IS_GIO_SINK
 GST_GIO_SINK_CLASS
 GST_IS_GIO_SINK_CLASS
@@ -290,6 +266,7 @@
 <SUBSECTION Standard>
 GstGioSrcClass
 GST_GIO_SRC
+GST_GIO_SRC_CAST
 GST_IS_GIO_SRC
 GST_GIO_SRC_CLASS
 GST_IS_GIO_SRC_CLASS
@@ -305,6 +282,7 @@
 <SUBSECTION Standard>
 GstGioStreamSinkClass
 GST_GIO_STREAM_SINK
+GST_GIO_STREAM_SINK_CAST
 GST_IS_GIO_STREAM_SINK
 GST_GIO_STREAM_SINK_CLASS
 GST_IS_GIO_STREAM_SINK_CLASS
@@ -320,6 +298,7 @@
 <SUBSECTION Standard>
 GstGioStreamSrcClass
 GST_GIO_STREAM_SRC
+GST_GIO_STREAM_SRC_CAST
 GST_IS_GIO_STREAM_SRC
 GST_GIO_STREAM_SRC_CLASS
 GST_IS_GIO_STREAM_SRC_CLASS
@@ -332,19 +311,14 @@
 <FILE>element-multifdsink</FILE>
 <TITLE>multifdsink</TITLE>
 GstMultiFdSink
-GstRecoverPolicy
-GstSyncMethod
-GstClientStatus
-GstTCPProtocol
-GstTCPUnitType
 <SUBSECTION Standard>
 GstMultiFdSinkClass
 GST_MULTI_FD_SINK
+GST_MULTI_FD_SINK_CAST
 GST_IS_MULTI_FD_SINK
 GST_MULTI_FD_SINK_CLASS
 GST_IS_MULTI_FD_SINK_CLASS
 GST_TYPE_MULTI_FD_SINK
-GstTCPClient
 <SUBSECTION Private>
 gst_multi_fd_sink_get_type
 </SECTION>
@@ -353,19 +327,14 @@
 <FILE>element-multisocketsink</FILE>
 <TITLE>multisocketsink</TITLE>
 GstMultiSocketSink
-GstRecoverPolicy
-GstSyncMethod
-GstClientStatus
-GstTCPProtocol
-GstTCPUnitType
 <SUBSECTION Standard>
 GstMultiSocketSinkClass
 GST_MULTI_SOCKET_SINK
+GST_MULTI_SOCKET_SINK_CAST
 GST_IS_MULTI_SOCKET_SINK
 GST_MULTI_SOCKET_SINK_CLASS
 GST_IS_MULTI_SOCKET_SINK_CLASS
 GST_TYPE_MULTI_SOCKET_SINK
-GstTCPClient
 <SUBSECTION Private>
 gst_multi_socket_sink_get_type
 </SECTION>
@@ -393,20 +362,11 @@
 <SUBSECTION Standard>
 GstOggDemuxClass
 GST_OGG_DEMUX
+GST_OGG_DEMUX_CAST
 GST_IS_OGG_DEMUX
 GST_OGG_DEMUX_CLASS
 GST_IS_OGG_DEMUX_CLASS
 GST_TYPE_OGG_DEMUX
-GST_IS_OGG_PAD
-GST_IS_OGG_PAD_CLASS
-GST_OGG_PAD
-GST_OGG_PAD_CLASS
-GST_TYPE_OGG_PAD
-GstOggChain
-GstOggPad
-GstOggPadClass
-GstOggPadMode
-GstOggPadState
 <SUBSECTION Private>
 gst_ogg_demux_get_type
 </SECTION>
@@ -418,6 +378,7 @@
 <SUBSECTION Standard>
 GstOggMuxClass
 GST_OGG_MUX
+GST_OGG_MUX_CAST
 GST_IS_OGG_MUX
 GST_OGG_MUX_CLASS
 GST_IS_OGG_MUX_CLASS
@@ -490,37 +451,62 @@
 gst_ogm_video_parse_get_type
 </SECTION>
 
+<SECTION>
 <FILE>element-opusdec</FILE>
 <TITLE>opusdec</TITLE>
 GstOpusDec
 <SUBSECTION Standard>
 GstOpusDecClass
-gst_opus_dec_get_type
-GST_TYPE_OPUS_DEC
 GST_OPUS_DEC
-GST_OPUS_DEC_CLASS
+GST_OPUS_DEC_CAST
 GST_IS_OPUS_DEC
+GST_OPUS_DEC_CLASS
 GST_IS_OPUS_DEC_CLASS
+GST_TYPE_OPUS_DEC
+<SUBSECTION Private>
+gst_opus_dec_get_type
 </SECTION>
 
+<SECTION>
 <FILE>element-opusenc</FILE>
 <TITLE>opusenc</TITLE>
 GstOpusEnc
+GstOpusEncAudioType
+GstOpusEncBandwidth
+GstOpusEncBitrateType
+GstOpusEncFrameSize
 <SUBSECTION Standard>
 GstOpusEncClass
-gst_opus_enc_get_type
-GST_TYPE_OPUS_ENC
 GST_OPUS_ENC
-GST_OPUS_ENC_CLASS
+GST_OPUS_ENC_CAST
 GST_IS_OPUS_ENC
+GST_OPUS_ENC_CLASS
 GST_IS_OPUS_ENC_CLASS
+GST_TYPE_OPUS_ENC
+<SUBSECTION Private>
+gst_opus_enc_get_type
+</SECTION>
+
+<SECTION>
+<FILE>element-parsebin</FILE>
+<TITLE>parsebin</TITLE>
+GstParseBin
+<SUBSECTION Standard>
+GstParseBinClass
+GST_PARSE_BIN
+GST_PARSE_BIN_CAST
+GST_IS_PARSE_BIN
+GST_PARSE_BIN_CLASS
+GST_IS_PARSE_BIN_CLASS
+GST_TYPE_PARSE_BIN
+<SUBSECTION Private>
+gst_parse_bin_get_type
 </SECTION>
 
 <SECTION>
 <FILE>element-playbin</FILE>
 <TITLE>playbin</TITLE>
 GstPlayBin
-GstPlayFlags
 <SUBSECTION Standard>
 GstPlayBinClass
 GST_PLAY_BIN
@@ -529,13 +515,27 @@
 GST_PLAY_BIN_CLASS
 GST_IS_PLAY_BIN_CLASS
 GST_TYPE_PLAY_BIN
-gst_play_flags_get_type
-GST_TYPE_PLAY_FLAGS
 <SUBSECTION Private>
 gst_play_bin_get_type
 </SECTION>
 
 <SECTION>
+<FILE>element-playbin3</FILE>
+<TITLE>playbin3</TITLE>
+GstPlayBin3
+<SUBSECTION Standard>
+GstPlayBin3Class
+GST_PLAY_BIN3
+GST_PLAY_BIN3_CAST
+GST_IS_PLAY_BIN3
+GST_PLAY_BIN3_CLASS
+GST_IS_PLAY_BIN3_CLASS
+GST_TYPE_PLAY_BIN3
+<SUBSECTION Private>
+gst_play_bin3_get_type
+</SECTION>
+
+<SECTION>
 <FILE>element-playsink</FILE>
 <TITLE>playsink</TITLE>
 GstPlaySink
@@ -543,35 +543,10 @@
 <SUBSECTION Standard>
 GstPlaySinkClass
 GST_PLAY_SINK
+GST_PLAY_SINK_CAST
 GST_IS_PLAY_SINK
 GST_PLAY_SINK_CLASS
 GST_IS_PLAY_SINK_CLASS
-GstPlaySinkType
-gst_play_sink_request_pad
-gst_play_sink_release_pad
-gst_play_sink_refresh_pad
-gst_play_sink_set_filter
-gst_play_sink_get_filter
-gst_play_sink_set_sink
-gst_play_sink_get_sink
-gst_play_sink_set_vis_plugin
-gst_play_sink_get_vis_plugin
-gst_play_sink_set_volume
-gst_play_sink_get_volume
-gst_play_sink_set_mute
-gst_play_sink_get_mute
-gst_play_sink_set_flags
-gst_play_sink_get_flags
-gst_play_sink_set_font_desc
-gst_play_sink_get_font_desc
-gst_play_sink_set_subtitle_encoding
-gst_play_sink_get_subtitle_encoding
-gst_play_sink_set_av_offset
-gst_play_sink_get_av_offset
-gst_play_sink_get_last_sample
-gst_play_sink_convert_sample
-gst_play_sink_reconfigure
-gst_play_sink_plugin_init
 GST_TYPE_PLAY_SINK
 <SUBSECTION Private>
 gst_play_sink_get_type
@@ -584,6 +559,7 @@
 <SUBSECTION Standard>
 GstSocketSrcClass
 GST_SOCKET_SRC
+GST_SOCKET_SRC_CAST
 GST_IS_SOCKET_SRC
 GST_SOCKET_SRC_CLASS
 GST_IS_SOCKET_SRC_CLASS
@@ -615,6 +591,7 @@
 <SUBSECTION Standard>
 GstStreamSynchronizerClass
 GST_STREAM_SYNCHRONIZER
+GST_STREAM_SYNCHRONIZER_CAST
 GST_IS_STREAM_SYNCHRONIZER
 GST_STREAM_SYNCHRONIZER_CLASS
 GST_IS_STREAM_SYNCHRONIZER_CLASS
@@ -650,11 +627,8 @@
 GST_IS_SUBTITLE_OVERLAY
 GST_SUBTITLE_OVERLAY_CLASS
 GST_IS_SUBTITLE_OVERLAY_CLASS
-GST_SUBTITLE_OVERLAY_LOCK
-GST_SUBTITLE_OVERLAY_UNLOCK
 GST_TYPE_SUBTITLE_OVERLAY
 <SUBSECTION Private>
-gst_subtitle_overlay_plugin_init
 gst_subtitle_overlay_get_type
 </SECTION>
 
@@ -664,8 +638,8 @@
 GstTCPClientSink
 <SUBSECTION Standard>
 GstTCPClientSinkClass
-GstTCPClientSinkFlags
 GST_TCP_CLIENT_SINK
+GST_TCP_CLIENT_SINK_CAST
 GST_IS_TCP_CLIENT_SINK
 GST_TCP_CLIENT_SINK_CLASS
 GST_IS_TCP_CLIENT_SINK_CLASS
@@ -680,12 +654,13 @@
 GstTCPClientSrc
 <SUBSECTION Standard>
 GstTCPClientSrcClass
-GstTCPClientSrcFlags
 GST_TCP_CLIENT_SRC
+GST_TCP_CLIENT_SRC_CAST
 GST_IS_TCP_CLIENT_SRC
 GST_TCP_CLIENT_SRC_CLASS
 GST_IS_TCP_CLIENT_SRC_CLASS
 GST_TYPE_TCP_CLIENT_SRC
+<SUBSECTION Private>
 gst_tcp_client_src_get_type
 </SECTION>
 
@@ -695,8 +670,8 @@
 GstTCPServerSink
 <SUBSECTION Standard>
 GstTCPServerSinkClass
-GstTCPServerSinkFlags
 GST_TCP_SERVER_SINK
+GST_TCP_SERVER_SINK_CAST
 GST_IS_TCP_SERVER_SINK
 GST_TCP_SERVER_SINK_CLASS
 GST_IS_TCP_SERVER_SINK_CLASS
@@ -711,8 +686,8 @@
 GstTCPServerSrc
 <SUBSECTION Standard>
 GstTCPServerSrcClass
-GstTCPServerSrcFlags
 GST_TCP_SERVER_SRC
+GST_TCP_SERVER_SRC_CAST
 GST_IS_TCP_SERVER_SRC
 GST_TCP_SERVER_SRC_CLASS
 GST_IS_TCP_SERVER_SRC_CLASS
@@ -725,17 +700,13 @@
 <FILE>element-textoverlay</FILE>
 <TITLE>textoverlay</TITLE>
 GstTextOverlay
-GstTextOverlayVAlign
-GstTextOverlayHAlign
-GstTextOverlayWrapMode
 <SUBSECTION Standard>
 GstTextOverlayClass
-GstTextOverlayLineAlign
 GST_TEXT_OVERLAY
+GST_TEXT_OVERLAY_CAST
 GST_IS_TEXT_OVERLAY
 GST_TEXT_OVERLAY_CLASS
 GST_IS_TEXT_OVERLAY_CLASS
-GST_TEXT_OVERLAY_GET_CLASS
 GST_TYPE_TEXT_OVERLAY
 <SUBSECTION Private>
 gst_text_overlay_get_type
@@ -745,13 +716,16 @@
 <FILE>element-textrender</FILE>
 <TITLE>textrender</TITLE>
 GstTextRender
+GstTextRenderHAlign
+GstTextRenderLineAlign
+GstTextRenderVAlign
 <SUBSECTION Standard>
 GstTextRenderClass
 GST_TEXT_RENDER
+GST_TEXT_RENDER_CAST
 GST_IS_TEXT_RENDER
 GST_TEXT_RENDER_CLASS
 GST_IS_TEXT_RENDER_CLASS
-GST_TEXT_RENDER_GET_CLASS
 GST_TYPE_TEXT_RENDER
 <SUBSECTION Private>
 gst_text_render_get_type
@@ -764,6 +738,7 @@
 <SUBSECTION Standard>
 GstTheoraDecClass
 GST_THEORA_DEC
+GST_THEORA_DEC_CAST
 GST_IS_THEORA_DEC
 GST_THEORA_DEC_CLASS
 GST_IS_THEORA_DEC_CLASS
@@ -780,6 +755,7 @@
 <SUBSECTION Standard>
 GstTheoraEncClass
 GST_THEORA_ENC
+GST_THEORA_ENC_CAST
 GST_IS_THEORA_ENC
 GST_THEORA_ENC_CLASS
 GST_IS_THEORA_ENC_CLASS
@@ -795,6 +771,7 @@
 <SUBSECTION Standard>
 GstTheoraParseClass
 GST_THEORA_PARSE
+GST_THEORA_PARSE_CAST
 GST_IS_THEORA_PARSE
 GST_THEORA_PARSE_CLASS
 GST_IS_THEORA_PARSE_CLASS
@@ -811,6 +788,7 @@
 <SUBSECTION Standard>
 GstTimeOverlayClass
 GST_TIME_OVERLAY
+GST_TIME_OVERLAY_CAST
 GST_IS_TIME_OVERLAY
 GST_TIME_OVERLAY_CLASS
 GST_IS_TIME_OVERLAY_CLASS
@@ -823,7 +801,6 @@
 <FILE>element-uridecodebin</FILE>
 <TITLE>uridecodebin</TITLE>
 GstURIDecodeBin
-GstAutoplugSelectResult
 <SUBSECTION Standard>
 GstURIDecodeBinClass
 GST_URI_DECODE_BIN
@@ -832,10 +809,24 @@
 GST_URI_DECODE_BIN_CLASS
 GST_IS_URI_DECODE_BIN_CLASS
 GST_TYPE_URI_DECODE_BIN
-GST_TYPE_AUTOPLUG_SELECT_RESULT
 <SUBSECTION Private>
 gst_uri_decode_bin_get_type
-gst_autoplug_select_result_get_type
+</SECTION>
+
+<SECTION>
+<FILE>element-urisourcebin</FILE>
+<TITLE>urisourcebin</TITLE>
+GstURISourceBin
+<SUBSECTION Standard>
+GstURISourceBinClass
+GST_URI_SOURCE_BIN
+GST_URI_SOURCE_BIN_CAST
+GST_IS_URI_SOURCE_BIN
+GST_URI_SOURCE_BIN_CLASS
+GST_IS_URI_SOURCE_BIN_CLASS
+GST_TYPE_URI_SOURCE_BIN
+<SUBSECTION Private>
+gst_uri_source_bin_get_type
 </SECTION>
 
 <SECTION>
@@ -845,6 +836,7 @@
 <SUBSECTION Standard>
 GstVideoConvertClass
 GST_VIDEO_CONVERT
+GST_VIDEO_CONVERT_CAST
 GST_IS_VIDEO_CONVERT
 GST_VIDEO_CONVERT_CLASS
 GST_IS_VIDEO_CONVERT_CLASS
@@ -860,6 +852,7 @@
 <SUBSECTION Standard>
 GstVideoRateClass
 GST_VIDEO_RATE
+GST_VIDEO_RATE_CAST
 GST_IS_VIDEO_RATE
 GST_VIDEO_RATE_CLASS
 GST_IS_VIDEO_RATE_CLASS
@@ -876,6 +869,7 @@
 <SUBSECTION Standard>
 GstVideoScaleClass
 GST_VIDEO_SCALE
+GST_VIDEO_SCALE_CAST
 GST_IS_VIDEO_SCALE
 GST_VIDEO_SCALE_CLASS
 GST_IS_VIDEO_SCALE_CLASS
@@ -889,10 +883,10 @@
 <TITLE>videotestsrc</TITLE>
 GstVideoTestSrc
 GstVideoTestSrcPattern
-GstVideoTestSrcColorSpec
 <SUBSECTION Standard>
 GstVideoTestSrcClass
 GST_VIDEO_TEST_SRC
+GST_VIDEO_TEST_SRC_CAST
 GST_IS_VIDEO_TEST_SRC
 GST_VIDEO_TEST_SRC_CLASS
 GST_IS_VIDEO_TEST_SRC_CLASS
@@ -902,12 +896,141 @@
 </SECTION>
 
 <SECTION>
+<FILE>element-libvisual_bumpscope</FILE>
+<TITLE>libvisual_bumpscope</TITLE>
+GstVisualbumpscope
+<SUBSECTION Standard>
+GstVisualbumpscopeClass
+GST_VISUALBUMPSCOPE
+GST_VISUALBUMPSCOPE_CAST
+GST_IS_VISUALBUMPSCOPE
+GST_VISUALBUMPSCOPE_CLASS
+GST_IS_VISUALBUMPSCOPE_CLASS
+GST_TYPE_VISUALBUMPSCOPE
+<SUBSECTION Private>
+gst_visualbumpscope_get_type
+</SECTION>
+
+<SECTION>
+<FILE>element-libvisual_corona</FILE>
+<TITLE>libvisual_corona</TITLE>
+GstVisualcorona
+<SUBSECTION Standard>
+GstVisualcoronaClass
+GST_VISUALCORONA
+GST_VISUALCORONA_CAST
+GST_IS_VISUALCORONA
+GST_VISUALCORONA_CLASS
+GST_IS_VISUALCORONA_CLASS
+GST_TYPE_VISUALCORONA
+<SUBSECTION Private>
+gst_visualcorona_get_type
+</SECTION>
+
+<SECTION>
+<FILE>element-libvisual_infinite</FILE>
+<TITLE>libvisual_infinite</TITLE>
+GstVisualinfinite
+<SUBSECTION Standard>
+GstVisualinfiniteClass
+GST_VISUALINFINITE
+GST_VISUALINFINITE_CAST
+GST_IS_VISUALINFINITE
+GST_VISUALINFINITE_CLASS
+GST_IS_VISUALINFINITE_CLASS
+GST_TYPE_VISUALINFINITE
+<SUBSECTION Private>
+gst_visualinfinite_get_type
+</SECTION>
+
+<SECTION>
+<FILE>element-libvisual_jakdaw</FILE>
+<TITLE>libvisual_jakdaw</TITLE>
+GstVisualjakdaw
+<SUBSECTION Standard>
+GstVisualjakdawClass
+GST_VISUALJAKDAW
+GST_VISUALJAKDAW_CAST
+GST_IS_VISUALJAKDAW
+GST_VISUALJAKDAW_CLASS
+GST_IS_VISUALJAKDAW_CLASS
+GST_TYPE_VISUALJAKDAW
+<SUBSECTION Private>
+gst_visualjakdaw_get_type
+</SECTION>
+
+<SECTION>
+<FILE>element-libvisual_jess</FILE>
+<TITLE>libvisual_jess</TITLE>
+GstVisualjess
+<SUBSECTION Standard>
+GstVisualjessClass
+GST_VISUALJESS
+GST_VISUALJESS_CAST
+GST_IS_VISUALJESS
+GST_VISUALJESS_CLASS
+GST_IS_VISUALJESS_CLASS
+GST_TYPE_VISUALJESS
+<SUBSECTION Private>
+gst_visualjess_get_type
+</SECTION>
+
+<SECTION>
+<FILE>element-libvisual_lv_analyzer</FILE>
+<TITLE>libvisual_lv_analyzer</TITLE>
+GstVisuallv_analyzer
+<SUBSECTION Standard>
+GstVisuallv_analyzerClass
+GST_VISUALLV_ANALYZER
+GST_VISUALLV_ANALYZER_CAST
+GST_IS_VISUALLV_ANALYZER
+GST_VISUALLV_ANALYZER_CLASS
+GST_IS_VISUALLV_ANALYZER_CLASS
+GST_TYPE_VISUALLV_ANALYZER
+<SUBSECTION Private>
+gst_visuallv_analyzer_get_type
+</SECTION>
+
+<SECTION>
+<FILE>element-libvisual_lv_scope</FILE>
+<TITLE>libvisual_lv_scope</TITLE>
+GstVisuallv_scope
+<SUBSECTION Standard>
+GstVisuallv_scopeClass
+GST_VISUALLV_SCOPE
+GST_VISUALLV_SCOPE_CAST
+GST_IS_VISUALLV_SCOPE
+GST_VISUALLV_SCOPE_CLASS
+GST_IS_VISUALLV_SCOPE_CLASS
+GST_TYPE_VISUALLV_SCOPE
+<SUBSECTION Private>
+gst_visuallv_scope_get_type
+</SECTION>
+
+<SECTION>
+<FILE>element-libvisual_oinksie</FILE>
+<TITLE>libvisual_oinksie</TITLE>
+GstVisualoinksie
+<SUBSECTION Standard>
+GstVisualoinksieClass
+GST_VISUALOINKSIE
+GST_VISUALOINKSIE_CAST
+GST_IS_VISUALOINKSIE
+GST_VISUALOINKSIE_CLASS
+GST_IS_VISUALOINKSIE_CLASS
+GST_TYPE_VISUALOINKSIE
+<SUBSECTION Private>
+gst_visualoinksie_get_type
+</SECTION>
+
+<SECTION>
 <FILE>element-volume</FILE>
 <TITLE>volume</TITLE>
 GstVolume
 <SUBSECTION Standard>
 GstVolumeClass
 GST_VOLUME
+GST_VOLUME_CAST
 GST_IS_VOLUME
 GST_VOLUME_CLASS
 GST_IS_VOLUME_CLASS
@@ -923,6 +1046,7 @@
 <SUBSECTION Standard>
 GstVorbisDecClass
 GST_VORBIS_DEC
+GST_VORBIS_DEC_CAST
 GST_IS_VORBIS_DEC
 GST_VORBIS_DEC_CLASS
 GST_IS_VORBIS_DEC_CLASS
@@ -938,6 +1062,7 @@
 <SUBSECTION Standard>
 GstVorbisEncClass
 GST_VORBIS_ENC
+GST_VORBIS_ENC_CAST
 GST_IS_VORBIS_ENC
 GST_VORBIS_ENC_CLASS
 GST_IS_VORBIS_ENC_CLASS
@@ -953,6 +1078,7 @@
 <SUBSECTION Standard>
 GstVorbisParseClass
 GST_VORBIS_PARSE
+GST_VORBIS_PARSE_CAST
 GST_IS_VORBIS_PARSE
 GST_VORBIS_PARSE_CLASS
 GST_IS_VORBIS_PARSE_CLASS
@@ -968,6 +1094,7 @@
 <SUBSECTION Standard>
 GstVorbisTagClass
 GST_VORBIS_TAG
+GST_VORBIS_TAG_CAST
 GST_IS_VORBIS_TAG
 GST_VORBIS_TAG_CLASS
 GST_IS_VORBIS_TAG_CLASS
@@ -983,14 +1110,11 @@
 <SUBSECTION Standard>
 GstXImageSinkClass
 GST_X_IMAGE_SINK
+GST_X_IMAGE_SINK_CAST
 GST_IS_X_IMAGE_SINK
 GST_X_IMAGE_SINK_CLASS
 GST_IS_X_IMAGE_SINK_CLASS
 GST_TYPE_X_IMAGE_SINK
-GstXImageBuffer
-GstXImageBufferClass
-GstXContext
-GstXWindow
 <SUBSECTION Private>
 gst_x_image_sink_get_type
 </SECTION>
@@ -1002,13 +1126,12 @@
 <SUBSECTION Standard>
 GstXvImageSinkClass
 GST_XV_IMAGE_SINK
+GST_XV_IMAGE_SINK_CAST
 GST_IS_XV_IMAGE_SINK
 GST_XV_IMAGE_SINK_CLASS
 GST_IS_XV_IMAGE_SINK_CLASS
 GST_TYPE_XV_IMAGE_SINK
-GstXvImageBuffer
-GstXvImageBufferClass
-GstXvImageFormat
 <SUBSECTION Private>
 gst_xv_image_sink_get_type
 </SECTION>
+
diff --git a/docs/plugins/gst-plugins-base-plugins.args b/docs/plugins/gst-plugins-base-plugins.args
index 5c9330d..dc26fa3 100644
--- a/docs/plugins/gst-plugins-base-plugins.args
+++ b/docs/plugins/gst-plugins-base-plugins.args
@@ -870,12 +870,32 @@
 
 <ARG>
 <NAME>GstAudioResample::sinc-filter-mode</NAME>
-<TYPE>SpeexResamplerSincFilterMode</TYPE>
+<TYPE>GstAudioResamplerFilterMode</TYPE>
 <RANGE></RANGE>
 <FLAGS>rw</FLAGS>
 <NICK>Sinc filter table mode</NICK>
 <BLURB>What sinc filter table mode to use.</BLURB>
-<DEFAULT>Use full table if table size below threshold</DEFAULT>
+<DEFAULT>GST_AUDIO_RESAMPLER_FILTER_MODE_AUTO</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstAudioResample::resample-method</NAME>
+<TYPE>GstAudioResamplerMethod</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Resample method to use</NICK>
+<BLURB>What resample method to use.</BLURB>
+<DEFAULT>GST_AUDIO_RESAMPLER_METHOD_KAISER</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstAudioResample::sinc-filter-interpolation</NAME>
+<TYPE>GstAudioResamplerFilterInterpolation</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Sinc filter interpolation</NICK>
+<BLURB>How to interpolate the sinc filter table.</BLURB>
+<DEFAULT>GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_CUBIC</DEFAULT>
 </ARG>
 
 <ARG>
@@ -1299,6 +1319,16 @@
 </ARG>
 
 <ARG>
+<NAME>GstAppSrc::duration</NAME>
+<TYPE>guint64</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Duration</NICK>
+<BLURB>The duration of the data stream in nanoseconds (GST_CLOCK_TIME_NONE if unknown).</BLURB>
+<DEFAULT>18446744073709551615</DEFAULT>
+</ARG>
+
+<ARG>
 <NAME>GstAppSink::caps</NAME>
 <TYPE>GstCaps*</TYPE>
 <RANGE></RANGE>
@@ -2749,6 +2779,486 @@
 </ARG>
 
 <ARG>
+<NAME>GstURISourceBin::buffer-duration</NAME>
+<TYPE>gint64</TYPE>
+<RANGE>>= G_MAXULONG</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Buffer duration (ns)</NICK>
+<BLURB>Buffer duration when buffering streams (-1 default value).</BLURB>
+<DEFAULT>-1</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstURISourceBin::buffer-size</NAME>
+<TYPE>gint</TYPE>
+<RANGE>>= G_MAXULONG</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Buffer size (bytes)</NICK>
+<BLURB>Buffer size when buffering streams (-1 default value).</BLURB>
+<DEFAULT>-1</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstURISourceBin::connection-speed</NAME>
+<TYPE>guint64</TYPE>
+<RANGE><= 18446744073709551</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Connection Speed</NICK>
+<BLURB>Network connection speed in kbps (0 = unknown).</BLURB>
+<DEFAULT>0</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstURISourceBin::download</NAME>
+<TYPE>gboolean</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Download</NICK>
+<BLURB>Attempt download buffering when buffering network streams.</BLURB>
+<DEFAULT>FALSE</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstURISourceBin::ring-buffer-max-size</NAME>
+<TYPE>guint64</TYPE>
+<RANGE><= G_MAXUINT</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Max. ring buffer size (bytes)</NICK>
+<BLURB>Max. amount of data in the ring buffer (bytes, 0 = ring buffer disabled).</BLURB>
+<DEFAULT>0</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstURISourceBin::source</NAME>
+<TYPE>GstElement*</TYPE>
+<RANGE></RANGE>
+<FLAGS>r</FLAGS>
+<NICK>Source</NICK>
+<BLURB>Source object used.</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstURISourceBin::uri</NAME>
+<TYPE>gchar*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>URI</NICK>
+<BLURB>URI to decode.</BLURB>
+<DEFAULT>NULL</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstURISourceBin::use-buffering</NAME>
+<TYPE>gboolean</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Use Buffering</NICK>
+<BLURB>Perform buffering on demuxed/parsed media.</BLURB>
+<DEFAULT>FALSE</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::audio-filter</NAME>
+<TYPE>GstElement*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Audio filter</NICK>
+<BLURB>the audio filter(s) to apply, if possible.</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::audio-sink</NAME>
+<TYPE>GstElement*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Audio Sink</NICK>
+<BLURB>the audio output element to use (NULL = default sink).</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::audio-stream-combiner</NAME>
+<TYPE>GstElement*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Audio stream combiner</NICK>
+<BLURB>Current audio stream combiner (NULL = input-selector).</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::auto-select-streams</NAME>
+<TYPE>gboolean</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Automatic Select-Streams</NICK>
+<BLURB>Whether playbin should respond to stream-collection messags with select-streams events.</BLURB>
+<DEFAULT>TRUE</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::av-offset</NAME>
+<TYPE>gint64</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>AV Offset</NICK>
+<BLURB>The synchronisation offset between audio and video in nanoseconds.</BLURB>
+<DEFAULT>0</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::buffer-duration</NAME>
+<TYPE>gint64</TYPE>
+<RANGE>>= G_MAXULONG</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Buffer duration (ns)</NICK>
+<BLURB>Buffer duration when buffering network streams.</BLURB>
+<DEFAULT>-1</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::buffer-size</NAME>
+<TYPE>gint</TYPE>
+<RANGE>>= G_MAXULONG</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Buffer size (bytes)</NICK>
+<BLURB>Buffer size when buffering network streams.</BLURB>
+<DEFAULT>-1</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::connection-speed</NAME>
+<TYPE>guint64</TYPE>
+<RANGE><= 18446744073709551</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Connection Speed</NICK>
+<BLURB>Network connection speed in kbps (0 = unknown).</BLURB>
+<DEFAULT>0</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::current-audio</NAME>
+<TYPE>gint</TYPE>
+<RANGE>>= G_MAXULONG</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Current audio</NICK>
+<BLURB>Currently playing audio stream (-1 = auto).</BLURB>
+<DEFAULT>-1</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::current-suburi</NAME>
+<TYPE>gchar*</TYPE>
+<RANGE></RANGE>
+<FLAGS>r</FLAGS>
+<NICK>Current .sub-URI</NICK>
+<BLURB>The currently playing URI of a subtitle.</BLURB>
+<DEFAULT>NULL</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::current-text</NAME>
+<TYPE>gint</TYPE>
+<RANGE>>= G_MAXULONG</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Current Text</NICK>
+<BLURB>Currently playing text stream (-1 = auto).</BLURB>
+<DEFAULT>-1</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::current-uri</NAME>
+<TYPE>gchar*</TYPE>
+<RANGE></RANGE>
+<FLAGS>r</FLAGS>
+<NICK>Current URI</NICK>
+<BLURB>The currently playing URI.</BLURB>
+<DEFAULT>NULL</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::current-video</NAME>
+<TYPE>gint</TYPE>
+<RANGE>>= G_MAXULONG</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Current Video</NICK>
+<BLURB>Currently playing video stream (-1 = auto).</BLURB>
+<DEFAULT>-1</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::flags</NAME>
+<TYPE>GstPlayFlags</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Flags</NICK>
+<BLURB>Flags to control behaviour.</BLURB>
+<DEFAULT>Render the video stream|Render the audio stream|Render subtitles|Use software volume|Deinterlace video if necessary|Use software color balance</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::force-aspect-ratio</NAME>
+<TYPE>gboolean</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Force Aspect Ratio</NICK>
+<BLURB>When enabled, scaling will respect original aspect ratio.</BLURB>
+<DEFAULT>TRUE</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::mute</NAME>
+<TYPE>gboolean</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Mute</NICK>
+<BLURB>Mute the audio channel without changing the volume.</BLURB>
+<DEFAULT>FALSE</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::n-audio</NAME>
+<TYPE>gint</TYPE>
+<RANGE>>= 0</RANGE>
+<FLAGS>r</FLAGS>
+<NICK>Number Audio</NICK>
+<BLURB>Total number of audio streams.</BLURB>
+<DEFAULT>0</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::n-text</NAME>
+<TYPE>gint</TYPE>
+<RANGE>>= 0</RANGE>
+<FLAGS>r</FLAGS>
+<NICK>Number Text</NICK>
+<BLURB>Total number of text streams.</BLURB>
+<DEFAULT>0</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::n-video</NAME>
+<TYPE>gint</TYPE>
+<RANGE>>= 0</RANGE>
+<FLAGS>r</FLAGS>
+<NICK>Number Video</NICK>
+<BLURB>Total number of video streams.</BLURB>
+<DEFAULT>0</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::ring-buffer-max-size</NAME>
+<TYPE>guint64</TYPE>
+<RANGE><= G_MAXUINT</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Max. ring buffer size (bytes)</NICK>
+<BLURB>Max. amount of data in the ring buffer (bytes, 0 = ring buffer disabled).</BLURB>
+<DEFAULT>0</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::sample</NAME>
+<TYPE>GstSample*</TYPE>
+<RANGE></RANGE>
+<FLAGS>r</FLAGS>
+<NICK>Sample</NICK>
+<BLURB>The last sample (NULL = no video available).</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::source</NAME>
+<TYPE>GstElement*</TYPE>
+<RANGE></RANGE>
+<FLAGS>r</FLAGS>
+<NICK>Source</NICK>
+<BLURB>Source element.</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::subtitle-encoding</NAME>
+<TYPE>gchar*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>subtitle encoding</NICK>
+<BLURB>Encoding to assume if input subtitles are not in UTF-8 encoding. If not set, the GST_SUBTITLE_ENCODING environment variable will be checked for an encoding to use. If that is not set either, ISO-8859-15 will be assumed.</BLURB>
+<DEFAULT>NULL</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::subtitle-font-desc</NAME>
+<TYPE>gchar*</TYPE>
+<RANGE></RANGE>
+<FLAGS>w</FLAGS>
+<NICK>Subtitle font description</NICK>
+<BLURB>Pango font description of font to be used for subtitle rendering.</BLURB>
+<DEFAULT>NULL</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::suburi</NAME>
+<TYPE>gchar*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>.sub-URI</NICK>
+<BLURB>Optional URI of a subtitle.</BLURB>
+<DEFAULT>NULL</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::text-sink</NAME>
+<TYPE>GstElement*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Text plugin</NICK>
+<BLURB>the text output element to use (NULL = default subtitleoverlay).</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::text-stream-combiner</NAME>
+<TYPE>GstElement*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Text stream combiner</NICK>
+<BLURB>Current text stream combiner (NULL = input-selector).</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::uri</NAME>
+<TYPE>gchar*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>URI</NICK>
+<BLURB>URI of the media to play.</BLURB>
+<DEFAULT>NULL</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::video-filter</NAME>
+<TYPE>GstElement*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Video filter</NICK>
+<BLURB>the video filter(s) to apply, if possible.</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::video-multiview-flags</NAME>
+<TYPE>GstVideoMultiviewFlags</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Multiview Flags Override</NICK>
+<BLURB>Override details of the multiview frame layout.</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::video-multiview-mode</NAME>
+<TYPE>GstVideoMultiviewFramePacking</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Multiview Mode Override</NICK>
+<BLURB>Re-interpret a video stream as one of several frame-packed stereoscopic modes.</BLURB>
+<DEFAULT>GST_VIDEO_MULTIVIEW_FRAME_PACKING_NONE</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::video-sink</NAME>
+<TYPE>GstElement*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Video Sink</NICK>
+<BLURB>the video output element to use (NULL = default sink).</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::video-stream-combiner</NAME>
+<TYPE>GstElement*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Video stream combiner</NICK>
+<BLURB>Current video stream combiner (NULL = input-selector).</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::vis-plugin</NAME>
+<TYPE>GstElement*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Vis plugin</NICK>
+<BLURB>the visualization element to use (NULL = default).</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstPlayBin3::volume</NAME>
+<TYPE>gdouble</TYPE>
+<RANGE>[0,10]</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Volume</NICK>
+<BLURB>The audio volume, 1.0=100%.</BLURB>
+<DEFAULT>1</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstParseBin::connection-speed</NAME>
+<TYPE>guint64</TYPE>
+<RANGE><= 18446744073709551</RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Connection Speed</NICK>
+<BLURB>Network connection speed in kbps (0 = unknown).</BLURB>
+<DEFAULT>0</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstParseBin::expose-all-streams</NAME>
+<TYPE>gboolean</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Expose All Streams</NICK>
+<BLURB>Expose all streams, including those of unknown type or that don't match the 'caps' property.</BLURB>
+<DEFAULT>TRUE</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstParseBin::sink-caps</NAME>
+<TYPE>GstCaps*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Sink Caps</NICK>
+<BLURB>The caps of the input data. (NULL = use typefind element).</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstParseBin::subtitle-encoding</NAME>
+<TYPE>gchar*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>subtitle encoding</NICK>
+<BLURB>Encoding to assume if input subtitles are not in UTF-8 encoding. If not set, the GST_SUBTITLE_ENCODING environment variable will be checked for an encoding to use. If that is not set either, ISO-8859-15 will be assumed.</BLURB>
+<DEFAULT>NULL</DEFAULT>
+</ARG>
+
+<ARG>
+<NAME>GstDecodebin3::caps</NAME>
+<TYPE>GstCaps*</TYPE>
+<RANGE></RANGE>
+<FLAGS>rw</FLAGS>
+<NICK>Caps</NICK>
+<BLURB>The caps on which to stop decoding. (NULL = default).</BLURB>
+<DEFAULT></DEFAULT>
+</ARG>
+
+<ARG>
 <NAME>GstTheoraDec::visualize-bit-usage</NAME>
 <TYPE>gint</TYPE>
 <RANGE>[0,255]</RANGE>
diff --git a/docs/plugins/gst-plugins-base-plugins.hierarchy b/docs/plugins/gst-plugins-base-plugins.hierarchy
index c2d607b..75f4ff1 100644
--- a/docs/plugins/gst-plugins-base-plugins.hierarchy
+++ b/docs/plugins/gst-plugins-base-plugins.hierarchy
@@ -79,12 +79,16 @@
           GstVideoRate
         GstBin
           GstDecodeBin
+          GstDecodebin3
           GstEncodeBin
+          GstParseBin
           GstPipeline
             GstPlayBin
+            GstPlayBin3
           GstPlaySink
           GstSubtitleOverlay
           GstURIDecodeBin
+          GstURISourceBin
         GstOggAviParse
         GstOggDemux
         GstOggMux
@@ -108,6 +112,7 @@
         GstProxyPad
           GstGhostPad
             GstDecodePad
+            GstParsePad
       GstPadTemplate
       GstPlugin
       GstPluginFeature
@@ -116,6 +121,8 @@
         GstTracerFactory
         GstTypeFindFactory
       GstRegistry
+      GstStream
+      GstStreamCollection
       GstTask
       GstTaskPool
   GInputStream
diff --git a/docs/plugins/gst-plugins-base-plugins.interfaces b/docs/plugins/gst-plugins-base-plugins.interfaces
index 651688d..8ed5c52 100644
--- a/docs/plugins/gst-plugins-base-plugins.interfaces
+++ b/docs/plugins/gst-plugins-base-plugins.interfaces
@@ -9,17 +9,21 @@
 GstBin GstChildProxy
 GstCdParanoiaSrc GstURIHandler
 GstDecodeBin GstChildProxy
+GstDecodebin3 GstChildProxy
 GstEncodeBin GstChildProxy
 GstGioSink GstURIHandler
 GstGioSrc GstURIHandler
 GstOggMux GstPreset
 GstOpusEnc GstPreset GstTagSetter
+GstParseBin GstChildProxy
 GstPipeline GstChildProxy
 GstPlayBin GstChildProxy GstStreamVolume GstVideoOverlay GstNavigation GstColorBalance
+GstPlayBin3 GstChildProxy GstStreamVolume GstVideoOverlay GstNavigation GstColorBalance
 GstPlaySink GstChildProxy GstStreamVolume GstVideoOverlay GstNavigation GstColorBalance
 GstSubtitleOverlay GstChildProxy
 GstTheoraEnc GstPreset
 GstURIDecodeBin GstChildProxy
+GstURISourceBin GstChildProxy
 GstVideoEncoder GstPreset
 GstVolume GstStreamVolume
 GstVorbisEnc GstPreset GstTagSetter
diff --git a/docs/plugins/gst-plugins-base-plugins.signals b/docs/plugins/gst-plugins-base-plugins.signals
index 8be77d0..6dee30a 100644
--- a/docs/plugins/gst-plugins-base-plugins.signals
+++ b/docs/plugins/gst-plugins-base-plugins.signals
@@ -202,6 +202,14 @@
 </SIGNAL>
 
 <SIGNAL>
+<NAME>GstPlayBin::element-setup</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstPlayBin *gstplaybin
+GstElement *arg1
+</SIGNAL>
+
+<SIGNAL>
 <NAME>GstDecodeBin::autoplug-continue</NAME>
 <RETURNS>gboolean</RETURNS>
 <FLAGS>l</FLAGS>
@@ -363,6 +371,22 @@
 </SIGNAL>
 
 <SIGNAL>
+<NAME>GstAppSink::try-pull-preroll</NAME>
+<RETURNS>GstSample*</RETURNS>
+<FLAGS>la</FLAGS>
+GstAppSink *gstappsink
+guint64  arg1
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstAppSink::try-pull-sample</NAME>
+<RETURNS>GstSample*</RETURNS>
+<FLAGS>la</FLAGS>
+GstAppSink *gstappsink
+guint64  arg1
+</SIGNAL>
+
+<SIGNAL>
 <NAME>GstMultiSocketSink::add</NAME>
 <RETURNS>void</RETURNS>
 <FLAGS>la</FLAGS>
@@ -525,3 +549,272 @@
 GstSocketSrc *gstsocketsrc
 </SIGNAL>
 
+<SIGNAL>
+<NAME>GstURISourceBin::autoplug-continue</NAME>
+<RETURNS>gboolean</RETURNS>
+<FLAGS>l</FLAGS>
+GstURISourceBin *gsturisourcebin
+GstPad *arg1
+GstCaps *arg2
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstURISourceBin::autoplug-factories</NAME>
+<RETURNS>GValueArray*</RETURNS>
+<FLAGS>l</FLAGS>
+GstURISourceBin *gsturisourcebin
+GstPad *arg1
+GstCaps *arg2
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstURISourceBin::autoplug-query</NAME>
+<RETURNS>gboolean</RETURNS>
+<FLAGS>l</FLAGS>
+GstURISourceBin *gsturisourcebin
+GstPad *arg1
+GstElement *arg2
+GstQuery *arg3
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstURISourceBin::autoplug-select</NAME>
+<RETURNS>GstAutoplugSelectResult</RETURNS>
+<FLAGS>l</FLAGS>
+GstURISourceBin *gsturisourcebin
+GstPad *arg1
+GstCaps *arg2
+GstElementFactory *arg3
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstURISourceBin::autoplug-sort</NAME>
+<RETURNS>GValueArray*</RETURNS>
+<FLAGS>l</FLAGS>
+GstURISourceBin *gsturisourcebin
+GstPad *arg1
+GstCaps *arg2
+GValueArray *arg3
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstURISourceBin::drained</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstURISourceBin *gsturisourcebin
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstURISourceBin::source-setup</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstURISourceBin *gsturisourcebin
+GstElement *arg1
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstURISourceBin::unknown-type</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstURISourceBin *gsturisourcebin
+GstPad *arg1
+GstCaps *arg2
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstPlayBin3::about-to-finish</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstPlayBin3 *gstplaybin3
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstPlayBin3::audio-changed</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstPlayBin3 *gstplaybin3
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstPlayBin3::audio-tags-changed</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstPlayBin3 *gstplaybin3
+gint  arg1
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstPlayBin3::convert-sample</NAME>
+<RETURNS>GstSample*</RETURNS>
+<FLAGS>la</FLAGS>
+GstPlayBin3 *gstplaybin3
+GstCaps *arg1
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstPlayBin3::get-audio-pad</NAME>
+<RETURNS>GstPad*</RETURNS>
+<FLAGS>la</FLAGS>
+GstPlayBin3 *gstplaybin3
+gint  arg1
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstPlayBin3::get-audio-tags</NAME>
+<RETURNS>GstTagList*</RETURNS>
+<FLAGS>la</FLAGS>
+GstPlayBin3 *gstplaybin3
+gint  arg1
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstPlayBin3::get-text-pad</NAME>
+<RETURNS>GstPad*</RETURNS>
+<FLAGS>la</FLAGS>
+GstPlayBin3 *gstplaybin3
+gint  arg1
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstPlayBin3::get-text-tags</NAME>
+<RETURNS>GstTagList*</RETURNS>
+<FLAGS>la</FLAGS>
+GstPlayBin3 *gstplaybin3
+gint  arg1
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstPlayBin3::get-video-pad</NAME>
+<RETURNS>GstPad*</RETURNS>
+<FLAGS>la</FLAGS>
+GstPlayBin3 *gstplaybin3
+gint  arg1
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstPlayBin3::get-video-tags</NAME>
+<RETURNS>GstTagList*</RETURNS>
+<FLAGS>la</FLAGS>
+GstPlayBin3 *gstplaybin3
+gint  arg1
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstPlayBin3::source-setup</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstPlayBin3 *gstplaybin3
+GstElement *arg1
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstPlayBin3::text-changed</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstPlayBin3 *gstplaybin3
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstPlayBin3::text-tags-changed</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstPlayBin3 *gstplaybin3
+gint  arg1
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstPlayBin3::video-changed</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstPlayBin3 *gstplaybin3
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstPlayBin3::video-tags-changed</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstPlayBin3 *gstplaybin3
+gint  arg1
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstPlayBin3::element-setup</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstPlayBin3 *gstplaybin3
+GstElement *arg1
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstParseBin::autoplug-continue</NAME>
+<RETURNS>gboolean</RETURNS>
+<FLAGS>l</FLAGS>
+GstParseBin *gstparsebin
+GstPad *arg1
+GstCaps *arg2
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstParseBin::autoplug-factories</NAME>
+<RETURNS>GValueArray*</RETURNS>
+<FLAGS>l</FLAGS>
+GstParseBin *gstparsebin
+GstPad *arg1
+GstCaps *arg2
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstParseBin::autoplug-query</NAME>
+<RETURNS>gboolean</RETURNS>
+<FLAGS>l</FLAGS>
+GstParseBin *gstparsebin
+GstPad *arg1
+GstElement *arg2
+GstQuery *arg3
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstParseBin::autoplug-select</NAME>
+<RETURNS>GstAutoplugSelectResult</RETURNS>
+<FLAGS>l</FLAGS>
+GstParseBin *gstparsebin
+GstPad *arg1
+GstCaps *arg2
+GstElementFactory *arg3
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstParseBin::autoplug-sort</NAME>
+<RETURNS>GValueArray*</RETURNS>
+<FLAGS>l</FLAGS>
+GstParseBin *gstparsebin
+GstPad *arg1
+GstCaps *arg2
+GValueArray *arg3
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstParseBin::drained</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstParseBin *gstparsebin
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstParseBin::unknown-type</NAME>
+<RETURNS>void</RETURNS>
+<FLAGS>l</FLAGS>
+GstParseBin *gstparsebin
+GstPad *arg1
+GstCaps *arg2
+</SIGNAL>
+
+<SIGNAL>
+<NAME>GstDecodebin3::select-stream</NAME>
+<RETURNS>gint</RETURNS>
+<FLAGS>l</FLAGS>
+GstDecodebin3 *gstdecodebin3
+GstStreamCollection *arg1
+GstStream *arg2
+</SIGNAL>
+
diff --git a/docs/plugins/html/ch01.html b/docs/plugins/html/ch01.html
index 6b074fe..92df760 100644
--- a/docs/plugins/html/ch01.html
+++ b/docs/plugins/html/ch01.html
@@ -33,10 +33,10 @@
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-alsasink.html">alsasink</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
-<span class="refentrytitle"><a href="gst-plugins-base-plugins-alsasrc.html">alsasrc</a></span><span class="refpurpose"></span>
+<span class="refentrytitle"><a href="gst-plugins-base-plugins-appsink.html">appsink</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
-<span class="refentrytitle"><a href="gst-plugins-base-plugins-appsink.html">appsink</a></span><span class="refpurpose"></span>
+<span class="refentrytitle"><a href="gst-plugins-base-plugins-alsasrc.html">alsasrc</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-appsrc.html">appsrc</a></span><span class="refpurpose"></span>
@@ -63,6 +63,9 @@
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-decodebin.html">decodebin</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
+<span class="refentrytitle"><a href="gst-plugins-base-plugins-decodebin3.html">decodebin3</a></span><span class="refpurpose"></span>
+</dt>
+<dt>
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-encodebin.html">encodebin</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
@@ -111,9 +114,15 @@
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-opusenc.html">opusenc</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
+<span class="refentrytitle"><a href="gst-plugins-base-plugins-parsebin.html">parsebin</a></span><span class="refpurpose"></span>
+</dt>
+<dt>
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-playbin.html">playbin</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
+<span class="refentrytitle"><a href="gst-plugins-base-plugins-playbin3.html">playbin3</a></span><span class="refpurpose"></span>
+</dt>
+<dt>
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-playsink.html">playsink</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
@@ -165,6 +174,9 @@
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-uridecodebin.html">uridecodebin</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
+<span class="refentrytitle"><a href="gst-plugins-base-plugins-urisourcebin.html">urisourcebin</a></span><span class="refpurpose"></span>
+</dt>
+<dt>
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-videoconvert.html">videoconvert</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-1.0.devhelp2 b/docs/plugins/html/gst-plugins-base-plugins-1.0.devhelp2
index 921bcbf..478ba61 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-1.0.devhelp2
+++ b/docs/plugins/html/gst-plugins-base-plugins-1.0.devhelp2
@@ -5,8 +5,8 @@
       <sub name="adder" link="gst-plugins-base-plugins-adder.html"/>
       <sub name="alsamidisrc" link="gst-plugins-base-plugins-alsamidisrc.html"/>
       <sub name="alsasink" link="gst-plugins-base-plugins-alsasink.html"/>
-      <sub name="alsasrc" link="gst-plugins-base-plugins-alsasrc.html"/>
       <sub name="appsink" link="gst-plugins-base-plugins-appsink.html"/>
+      <sub name="alsasrc" link="gst-plugins-base-plugins-alsasrc.html"/>
       <sub name="appsrc" link="gst-plugins-base-plugins-appsrc.html"/>
       <sub name="audioconvert" link="gst-plugins-base-plugins-audioconvert.html"/>
       <sub name="audiorate" link="gst-plugins-base-plugins-audiorate.html"/>
@@ -15,6 +15,7 @@
       <sub name="cdparanoiasrc" link="gst-plugins-base-plugins-cdparanoiasrc.html"/>
       <sub name="clockoverlay" link="gst-plugins-base-plugins-clockoverlay.html"/>
       <sub name="decodebin" link="gst-plugins-base-plugins-decodebin.html"/>
+      <sub name="decodebin3" link="gst-plugins-base-plugins-decodebin3.html"/>
       <sub name="encodebin" link="gst-plugins-base-plugins-encodebin.html"/>
       <sub name="giosink" link="gst-plugins-base-plugins-giosink.html"/>
       <sub name="giosrc" link="gst-plugins-base-plugins-giosrc.html"/>
@@ -31,7 +32,9 @@
       <sub name="ogmvideoparse" link="gst-plugins-base-plugins-ogmvideoparse.html"/>
       <sub name="opusdec" link="gst-plugins-base-plugins-opusdec.html"/>
       <sub name="opusenc" link="gst-plugins-base-plugins-opusenc.html"/>
+      <sub name="parsebin" link="gst-plugins-base-plugins-parsebin.html"/>
       <sub name="playbin" link="gst-plugins-base-plugins-playbin.html"/>
+      <sub name="playbin3" link="gst-plugins-base-plugins-playbin3.html"/>
       <sub name="playsink" link="gst-plugins-base-plugins-playsink.html"/>
       <sub name="socketsrc" link="gst-plugins-base-plugins-socketsrc.html"/>
       <sub name="ssaparse" link="gst-plugins-base-plugins-ssaparse.html"/>
@@ -49,6 +52,7 @@
       <sub name="theoraparse" link="gst-plugins-base-plugins-theoraparse.html"/>
       <sub name="timeoverlay" link="gst-plugins-base-plugins-timeoverlay.html"/>
       <sub name="uridecodebin" link="gst-plugins-base-plugins-uridecodebin.html"/>
+      <sub name="urisourcebin" link="gst-plugins-base-plugins-urisourcebin.html"/>
       <sub name="videoconvert" link="gst-plugins-base-plugins-videoconvert.html"/>
       <sub name="videorate" link="gst-plugins-base-plugins-videorate.html"/>
       <sub name="videoscale" link="gst-plugins-base-plugins-videoscale.html"/>
@@ -101,10 +105,6 @@
     <keyword type="property" name="The “card-name” property" link="gst-plugins-base-plugins-alsasink.html#GstAlsaSink--card-name"/>
     <keyword type="property" name="The “device” property" link="gst-plugins-base-plugins-alsasink.html#GstAlsaSink--device"/>
     <keyword type="property" name="The “device-name” property" link="gst-plugins-base-plugins-alsasink.html#GstAlsaSink--device-name"/>
-    <keyword type="struct" name="struct GstAlsaSrc" link="gst-plugins-base-plugins-alsasrc.html#GstAlsaSrc-struct"/>
-    <keyword type="property" name="The “card-name” property" link="gst-plugins-base-plugins-alsasrc.html#GstAlsaSrc--card-name"/>
-    <keyword type="property" name="The “device” property" link="gst-plugins-base-plugins-alsasrc.html#GstAlsaSrc--device"/>
-    <keyword type="property" name="The “device-name” property" link="gst-plugins-base-plugins-alsasrc.html#GstAlsaSrc--device-name"/>
     <keyword type="struct" name="struct GstAppSink" link="gst-plugins-base-plugins-appsink.html#GstAppSink-struct"/>
     <keyword type="property" name="The “caps” property" link="gst-plugins-base-plugins-appsink.html#GstAppSink--caps"/>
     <keyword type="property" name="The “drop” property" link="gst-plugins-base-plugins-appsink.html#GstAppSink--drop"/>
@@ -117,6 +117,12 @@
     <keyword type="signal" name="The “new-sample” signal" link="gst-plugins-base-plugins-appsink.html#GstAppSink-new-sample"/>
     <keyword type="signal" name="The “pull-preroll” signal" link="gst-plugins-base-plugins-appsink.html#GstAppSink-pull-preroll"/>
     <keyword type="signal" name="The “pull-sample” signal" link="gst-plugins-base-plugins-appsink.html#GstAppSink-pull-sample"/>
+    <keyword type="signal" name="The “try-pull-preroll” signal" link="gst-plugins-base-plugins-appsink.html#GstAppSink-try-pull-preroll"/>
+    <keyword type="signal" name="The “try-pull-sample” signal" link="gst-plugins-base-plugins-appsink.html#GstAppSink-try-pull-sample"/>
+    <keyword type="struct" name="struct GstAlsaSrc" link="gst-plugins-base-plugins-alsasrc.html#GstAlsaSrc-struct"/>
+    <keyword type="property" name="The “card-name” property" link="gst-plugins-base-plugins-alsasrc.html#GstAlsaSrc--card-name"/>
+    <keyword type="property" name="The “device” property" link="gst-plugins-base-plugins-alsasrc.html#GstAlsaSrc--device"/>
+    <keyword type="property" name="The “device-name” property" link="gst-plugins-base-plugins-alsasrc.html#GstAlsaSrc--device-name"/>
     <keyword type="struct" name="struct GstAppSrc" link="gst-plugins-base-plugins-appsrc.html#GstAppSrc-struct"/>
     <keyword type="property" name="The “block” property" link="gst-plugins-base-plugins-appsrc.html#GstAppSrc--block"/>
     <keyword type="property" name="The “caps” property" link="gst-plugins-base-plugins-appsrc.html#GstAppSrc--caps"/>
@@ -130,6 +136,7 @@
     <keyword type="property" name="The “min-percent” property" link="gst-plugins-base-plugins-appsrc.html#GstAppSrc--min-percent"/>
     <keyword type="property" name="The “size” property" link="gst-plugins-base-plugins-appsrc.html#GstAppSrc--size"/>
     <keyword type="property" name="The “stream-type” property" link="gst-plugins-base-plugins-appsrc.html#GstAppSrc--stream-type"/>
+    <keyword type="property" name="The “duration” property" link="gst-plugins-base-plugins-appsrc.html#GstAppSrc--duration"/>
     <keyword type="signal" name="The “end-of-stream” signal" link="gst-plugins-base-plugins-appsrc.html#GstAppSrc-end-of-stream"/>
     <keyword type="signal" name="The “enough-data” signal" link="gst-plugins-base-plugins-appsrc.html#GstAppSrc-enough-data"/>
     <keyword type="signal" name="The “need-data” signal" link="gst-plugins-base-plugins-appsrc.html#GstAppSrc-need-data"/>
@@ -151,6 +158,8 @@
     <keyword type="property" name="The “quality” property" link="gst-plugins-base-plugins-audioresample.html#GstAudioResample--quality"/>
     <keyword type="property" name="The “sinc-filter-auto-threshold” property" link="gst-plugins-base-plugins-audioresample.html#GstAudioResample--sinc-filter-auto-threshold"/>
     <keyword type="property" name="The “sinc-filter-mode” property" link="gst-plugins-base-plugins-audioresample.html#GstAudioResample--sinc-filter-mode"/>
+    <keyword type="property" name="The “resample-method” property" link="gst-plugins-base-plugins-audioresample.html#GstAudioResample--resample-method"/>
+    <keyword type="property" name="The “sinc-filter-interpolation” property" link="gst-plugins-base-plugins-audioresample.html#GstAudioResample--sinc-filter-interpolation"/>
     <keyword type="struct" name="struct GstAudioTestSrc" link="gst-plugins-base-plugins-audiotestsrc.html#GstAudioTestSrc-struct"/>
     <keyword type="enum" name="enum GstAudioTestSrcWave" link="gst-plugins-base-plugins-audiotestsrc.html#GstAudioTestSrcWave"/>
     <keyword type="property" name="The “can-activate-pull” property" link="gst-plugins-base-plugins-audiotestsrc.html#GstAudioTestSrc--can-activate-pull"/>
@@ -212,9 +221,6 @@
     <keyword type="struct" name="struct GstGioStreamSrc" link="gst-plugins-base-plugins-giostreamsrc.html#GstGioStreamSrc-struct"/>
     <keyword type="property" name="The “stream” property" link="gst-plugins-base-plugins-giostreamsrc.html#GstGioStreamSrc--stream"/>
     <keyword type="struct" name="struct GstMultiFdSink" link="gst-plugins-base-plugins-multifdsink.html#GstMultiFdSink-struct"/>
-    <keyword type="enum" name="enum GstRecoverPolicy" link="gst-plugins-base-plugins-multifdsink.html#GstRecoverPolicy"/>
-    <keyword type="enum" name="enum GstSyncMethod" link="gst-plugins-base-plugins-multifdsink.html#GstSyncMethod"/>
-    <keyword type="enum" name="enum GstClientStatus" link="gst-plugins-base-plugins-multifdsink.html#GstClientStatus"/>
     <keyword type="property" name="The “handle-read” property" link="gst-plugins-base-plugins-multifdsink.html#GstMultiFdSink--handle-read"/>
     <keyword type="signal" name="The “add” signal" link="gst-plugins-base-plugins-multifdsink.html#GstMultiFdSink-add"/>
     <keyword type="signal" name="The “add-full” signal" link="gst-plugins-base-plugins-multifdsink.html#GstMultiFdSink-add-full"/>
@@ -225,9 +231,6 @@
     <keyword type="signal" name="The “remove” signal" link="gst-plugins-base-plugins-multifdsink.html#GstMultiFdSink-remove"/>
     <keyword type="signal" name="The “remove-flush” signal" link="gst-plugins-base-plugins-multifdsink.html#GstMultiFdSink-remove-flush"/>
     <keyword type="struct" name="struct GstMultiSocketSink" link="gst-plugins-base-plugins-multisocketsink.html#GstMultiSocketSink-struct"/>
-    <keyword type="enum" name="enum GstRecoverPolicy" link="gst-plugins-base-plugins-multisocketsink.html#GstRecoverPolicy"/>
-    <keyword type="enum" name="enum GstSyncMethod" link="gst-plugins-base-plugins-multisocketsink.html#GstSyncMethod"/>
-    <keyword type="enum" name="enum GstClientStatus" link="gst-plugins-base-plugins-multisocketsink.html#GstClientStatus"/>
     <keyword type="property" name="The “send-dispatched” property" link="gst-plugins-base-plugins-multisocketsink.html#GstMultiSocketSink--send-dispatched"/>
     <keyword type="property" name="The “send-messages” property" link="gst-plugins-base-plugins-multisocketsink.html#GstMultiSocketSink--send-messages"/>
     <keyword type="signal" name="The “add” signal" link="gst-plugins-base-plugins-multisocketsink.html#GstMultiSocketSink-add"/>
@@ -248,6 +251,7 @@
     <keyword type="property" name="The “apply-gain” property" link="gst-plugins-base-plugins-opusdec.html#GstOpusDec--apply-gain"/>
     <keyword type="property" name="The “use-inband-fec” property" link="gst-plugins-base-plugins-opusdec.html#GstOpusDec--use-inband-fec"/>
     <keyword type="struct" name="struct GstOpusEnc" link="gst-plugins-base-plugins-opusenc.html#GstOpusEnc-struct"/>
+    <keyword type="enum" name="enum GstOpusEncBitrateType" link="gst-plugins-base-plugins-opusenc.html#GstOpusEncBitrateType"/>
     <keyword type="property" name="The “audio” property" link="gst-plugins-base-plugins-opusenc.html#GstOpusEnc--audio"/>
     <keyword type="property" name="The “audio-type” property" link="gst-plugins-base-plugins-opusenc.html#GstOpusEnc--audio-type"/>
     <keyword type="property" name="The “bandwidth” property" link="gst-plugins-base-plugins-opusenc.html#GstOpusEnc--bandwidth"/>
@@ -262,7 +266,6 @@
     <keyword type="property" name="The “max-payload-size” property" link="gst-plugins-base-plugins-opusenc.html#GstOpusEnc--max-payload-size"/>
     <keyword type="property" name="The “packet-loss-percentage” property" link="gst-plugins-base-plugins-opusenc.html#GstOpusEnc--packet-loss-percentage"/>
     <keyword type="struct" name="struct GstPlayBin" link="gst-plugins-base-plugins-playbin.html#GstPlayBin-struct"/>
-    <keyword type="enum" name="enum GstPlayFlags" link="gst-plugins-base-plugins-playbin.html#GstPlayFlags"/>
     <keyword type="property" name="The “audio-sink” property" link="gst-plugins-base-plugins-playbin.html#GstPlayBin--audio-sink"/>
     <keyword type="property" name="The “audio-stream-combiner” property" link="gst-plugins-base-plugins-playbin.html#GstPlayBin--audio-stream-combiner"/>
     <keyword type="property" name="The “av-offset” property" link="gst-plugins-base-plugins-playbin.html#GstPlayBin--av-offset"/>
@@ -312,6 +315,7 @@
     <keyword type="signal" name="The “text-tags-changed” signal" link="gst-plugins-base-plugins-playbin.html#GstPlayBin-text-tags-changed"/>
     <keyword type="signal" name="The “video-changed” signal" link="gst-plugins-base-plugins-playbin.html#GstPlayBin-video-changed"/>
     <keyword type="signal" name="The “video-tags-changed” signal" link="gst-plugins-base-plugins-playbin.html#GstPlayBin-video-tags-changed"/>
+    <keyword type="signal" name="The “element-setup” signal" link="gst-plugins-base-plugins-playbin.html#GstPlayBin-element-setup"/>
     <keyword type="struct" name="GstPlaySink" link="gst-plugins-base-plugins-playsink.html#GstPlaySink-struct"/>
     <keyword type="property" name="The “audio-sink” property" link="gst-plugins-base-plugins-playsink.html#GstPlaySink--audio-sink"/>
     <keyword type="property" name="The “av-offset” property" link="gst-plugins-base-plugins-playsink.html#GstPlaySink--av-offset"/>
@@ -360,6 +364,9 @@
     <keyword type="property" name="The “port” property" link="gst-plugins-base-plugins-tcpserversrc.html#GstTCPServerSrc--port"/>
     <keyword type="struct" name="struct GstTextOverlay" link="gst-plugins-base-plugins-textoverlay.html#GstTextOverlay-struct"/>
     <keyword type="struct" name="struct GstTextRender" link="gst-plugins-base-plugins-textrender.html#GstTextRender-struct"/>
+    <keyword type="enum" name="enum GstTextRenderHAlign" link="gst-plugins-base-plugins-textrender.html#GstTextRenderHAlign"/>
+    <keyword type="enum" name="enum GstTextRenderLineAlign" link="gst-plugins-base-plugins-textrender.html#GstTextRenderLineAlign"/>
+    <keyword type="enum" name="enum GstTextRenderVAlign" link="gst-plugins-base-plugins-textrender.html#GstTextRenderVAlign"/>
     <keyword type="property" name="The “font-desc” property" link="gst-plugins-base-plugins-textrender.html#GstTextRender--font-desc"/>
     <keyword type="property" name="The “halignment” property" link="gst-plugins-base-plugins-textrender.html#GstTextRender--halignment"/>
     <keyword type="property" name="The “line-alignment” property" link="gst-plugins-base-plugins-textrender.html#GstTextRender--line-alignment"/>
@@ -391,7 +398,6 @@
     <keyword type="enum" name="enum GstTimeOverlayTimeLine" link="gst-plugins-base-plugins-timeoverlay.html#GstTimeOverlayTimeLine"/>
     <keyword type="property" name="The “time-mode” property" link="gst-plugins-base-plugins-timeoverlay.html#GstTimeOverlay--time-mode"/>
     <keyword type="struct" name="struct GstURIDecodeBin" link="gst-plugins-base-plugins-uridecodebin.html#GstURIDecodeBin-struct"/>
-    <keyword type="enum" name="enum GstAutoplugSelectResult" link="gst-plugins-base-plugins-uridecodebin.html#GstAutoplugSelectResult"/>
     <keyword type="property" name="The “buffer-duration” property" link="gst-plugins-base-plugins-uridecodebin.html#GstURIDecodeBin--buffer-duration"/>
     <keyword type="property" name="The “buffer-size” property" link="gst-plugins-base-plugins-uridecodebin.html#GstURIDecodeBin--buffer-size"/>
     <keyword type="property" name="The “caps” property" link="gst-plugins-base-plugins-uridecodebin.html#GstURIDecodeBin--caps"/>
@@ -515,61 +521,25 @@
     <keyword type="constant" name="GST_AUDIO_TEST_SRC_WAVE_RED_NOISE" link="gst-plugins-base-plugins-audiotestsrc.html#GST-AUDIO-TEST-SRC-WAVE-RED-NOISE:CAPS"/>
     <keyword type="constant" name="GST_AUDIO_TEST_SRC_WAVE_BLUE_NOISE" link="gst-plugins-base-plugins-audiotestsrc.html#GST-AUDIO-TEST-SRC-WAVE-BLUE-NOISE:CAPS"/>
     <keyword type="constant" name="GST_AUDIO_TEST_SRC_WAVE_VIOLET_NOISE" link="gst-plugins-base-plugins-audiotestsrc.html#GST-AUDIO-TEST-SRC-WAVE-VIOLET-NOISE:CAPS"/>
-    <keyword type="constant" name="GST_RECOVER_POLICY_NONE" link="gst-plugins-base-plugins-multifdsink.html#GST-RECOVER-POLICY-NONE:CAPS"/>
-    <keyword type="constant" name="GST_RECOVER_POLICY_RESYNC_LATEST" link="gst-plugins-base-plugins-multifdsink.html#GST-RECOVER-POLICY-RESYNC-LATEST:CAPS"/>
-    <keyword type="constant" name="GST_RECOVER_POLICY_RESYNC_SOFT_LIMIT" link="gst-plugins-base-plugins-multifdsink.html#GST-RECOVER-POLICY-RESYNC-SOFT-LIMIT:CAPS"/>
-    <keyword type="constant" name="GST_RECOVER_POLICY_RESYNC_KEYFRAME" link="gst-plugins-base-plugins-multifdsink.html#GST-RECOVER-POLICY-RESYNC-KEYFRAME:CAPS"/>
-    <keyword type="constant" name="GST_SYNC_METHOD_LATEST" link="gst-plugins-base-plugins-multifdsink.html#GST-SYNC-METHOD-LATEST:CAPS"/>
-    <keyword type="constant" name="GST_SYNC_METHOD_NEXT_KEYFRAME" link="gst-plugins-base-plugins-multifdsink.html#GST-SYNC-METHOD-NEXT-KEYFRAME:CAPS"/>
-    <keyword type="constant" name="GST_SYNC_METHOD_LATEST_KEYFRAME" link="gst-plugins-base-plugins-multifdsink.html#GST-SYNC-METHOD-LATEST-KEYFRAME:CAPS"/>
-    <keyword type="constant" name="GST_SYNC_METHOD_BURST" link="gst-plugins-base-plugins-multifdsink.html#GST-SYNC-METHOD-BURST:CAPS"/>
-    <keyword type="constant" name="GST_SYNC_METHOD_BURST_KEYFRAME" link="gst-plugins-base-plugins-multifdsink.html#GST-SYNC-METHOD-BURST-KEYFRAME:CAPS"/>
-    <keyword type="constant" name="GST_SYNC_METHOD_BURST_WITH_KEYFRAME" link="gst-plugins-base-plugins-multifdsink.html#GST-SYNC-METHOD-BURST-WITH-KEYFRAME:CAPS"/>
-    <keyword type="constant" name="GST_CLIENT_STATUS_OK" link="gst-plugins-base-plugins-multifdsink.html#GST-CLIENT-STATUS-OK:CAPS"/>
-    <keyword type="constant" name="GST_CLIENT_STATUS_CLOSED" link="gst-plugins-base-plugins-multifdsink.html#GST-CLIENT-STATUS-CLOSED:CAPS"/>
-    <keyword type="constant" name="GST_CLIENT_STATUS_REMOVED" link="gst-plugins-base-plugins-multifdsink.html#GST-CLIENT-STATUS-REMOVED:CAPS"/>
-    <keyword type="constant" name="GST_CLIENT_STATUS_SLOW" link="gst-plugins-base-plugins-multifdsink.html#GST-CLIENT-STATUS-SLOW:CAPS"/>
-    <keyword type="constant" name="GST_CLIENT_STATUS_ERROR" link="gst-plugins-base-plugins-multifdsink.html#GST-CLIENT-STATUS-ERROR:CAPS"/>
-    <keyword type="constant" name="GST_CLIENT_STATUS_DUPLICATE" link="gst-plugins-base-plugins-multifdsink.html#GST-CLIENT-STATUS-DUPLICATE:CAPS"/>
-    <keyword type="constant" name="GST_CLIENT_STATUS_FLUSHING" link="gst-plugins-base-plugins-multifdsink.html#GST-CLIENT-STATUS-FLUSHING:CAPS"/>
-    <keyword type="constant" name="GST_RECOVER_POLICY_NONE" link="gst-plugins-base-plugins-multisocketsink.html#GST-RECOVER-POLICY-NONE:CAPS"/>
-    <keyword type="constant" name="GST_RECOVER_POLICY_RESYNC_LATEST" link="gst-plugins-base-plugins-multisocketsink.html#GST-RECOVER-POLICY-RESYNC-LATEST:CAPS"/>
-    <keyword type="constant" name="GST_RECOVER_POLICY_RESYNC_SOFT_LIMIT" link="gst-plugins-base-plugins-multisocketsink.html#GST-RECOVER-POLICY-RESYNC-SOFT-LIMIT:CAPS"/>
-    <keyword type="constant" name="GST_RECOVER_POLICY_RESYNC_KEYFRAME" link="gst-plugins-base-plugins-multisocketsink.html#GST-RECOVER-POLICY-RESYNC-KEYFRAME:CAPS"/>
-    <keyword type="constant" name="GST_SYNC_METHOD_LATEST" link="gst-plugins-base-plugins-multisocketsink.html#GST-SYNC-METHOD-LATEST:CAPS"/>
-    <keyword type="constant" name="GST_SYNC_METHOD_NEXT_KEYFRAME" link="gst-plugins-base-plugins-multisocketsink.html#GST-SYNC-METHOD-NEXT-KEYFRAME:CAPS"/>
-    <keyword type="constant" name="GST_SYNC_METHOD_LATEST_KEYFRAME" link="gst-plugins-base-plugins-multisocketsink.html#GST-SYNC-METHOD-LATEST-KEYFRAME:CAPS"/>
-    <keyword type="constant" name="GST_SYNC_METHOD_BURST" link="gst-plugins-base-plugins-multisocketsink.html#GST-SYNC-METHOD-BURST:CAPS"/>
-    <keyword type="constant" name="GST_SYNC_METHOD_BURST_KEYFRAME" link="gst-plugins-base-plugins-multisocketsink.html#GST-SYNC-METHOD-BURST-KEYFRAME:CAPS"/>
-    <keyword type="constant" name="GST_SYNC_METHOD_BURST_WITH_KEYFRAME" link="gst-plugins-base-plugins-multisocketsink.html#GST-SYNC-METHOD-BURST-WITH-KEYFRAME:CAPS"/>
-    <keyword type="constant" name="GST_CLIENT_STATUS_OK" link="gst-plugins-base-plugins-multisocketsink.html#GST-CLIENT-STATUS-OK:CAPS"/>
-    <keyword type="constant" name="GST_CLIENT_STATUS_CLOSED" link="gst-plugins-base-plugins-multisocketsink.html#GST-CLIENT-STATUS-CLOSED:CAPS"/>
-    <keyword type="constant" name="GST_CLIENT_STATUS_REMOVED" link="gst-plugins-base-plugins-multisocketsink.html#GST-CLIENT-STATUS-REMOVED:CAPS"/>
-    <keyword type="constant" name="GST_CLIENT_STATUS_SLOW" link="gst-plugins-base-plugins-multisocketsink.html#GST-CLIENT-STATUS-SLOW:CAPS"/>
-    <keyword type="constant" name="GST_CLIENT_STATUS_ERROR" link="gst-plugins-base-plugins-multisocketsink.html#GST-CLIENT-STATUS-ERROR:CAPS"/>
-    <keyword type="constant" name="GST_CLIENT_STATUS_DUPLICATE" link="gst-plugins-base-plugins-multisocketsink.html#GST-CLIENT-STATUS-DUPLICATE:CAPS"/>
-    <keyword type="constant" name="GST_CLIENT_STATUS_FLUSHING" link="gst-plugins-base-plugins-multisocketsink.html#GST-CLIENT-STATUS-FLUSHING:CAPS"/>
-    <keyword type="constant" name="GST_PLAY_FLAG_VIDEO" link="gst-plugins-base-plugins-playbin.html#GST-PLAY-FLAG-VIDEO:CAPS"/>
-    <keyword type="constant" name="GST_PLAY_FLAG_AUDIO" link="gst-plugins-base-plugins-playbin.html#GST-PLAY-FLAG-AUDIO:CAPS"/>
-    <keyword type="constant" name="GST_PLAY_FLAG_TEXT" link="gst-plugins-base-plugins-playbin.html#GST-PLAY-FLAG-TEXT:CAPS"/>
-    <keyword type="constant" name="GST_PLAY_FLAG_VIS" link="gst-plugins-base-plugins-playbin.html#GST-PLAY-FLAG-VIS:CAPS"/>
-    <keyword type="constant" name="GST_PLAY_FLAG_SOFT_VOLUME" link="gst-plugins-base-plugins-playbin.html#GST-PLAY-FLAG-SOFT-VOLUME:CAPS"/>
-    <keyword type="constant" name="GST_PLAY_FLAG_NATIVE_AUDIO" link="gst-plugins-base-plugins-playbin.html#GST-PLAY-FLAG-NATIVE-AUDIO:CAPS"/>
-    <keyword type="constant" name="GST_PLAY_FLAG_NATIVE_VIDEO" link="gst-plugins-base-plugins-playbin.html#GST-PLAY-FLAG-NATIVE-VIDEO:CAPS"/>
-    <keyword type="constant" name="GST_PLAY_FLAG_DOWNLOAD" link="gst-plugins-base-plugins-playbin.html#GST-PLAY-FLAG-DOWNLOAD:CAPS"/>
-    <keyword type="constant" name="GST_PLAY_FLAG_BUFFERING" link="gst-plugins-base-plugins-playbin.html#GST-PLAY-FLAG-BUFFERING:CAPS"/>
-    <keyword type="constant" name="GST_PLAY_FLAG_DEINTERLACE" link="gst-plugins-base-plugins-playbin.html#GST-PLAY-FLAG-DEINTERLACE:CAPS"/>
-    <keyword type="constant" name="GST_PLAY_FLAG_SOFT_COLORBALANCE" link="gst-plugins-base-plugins-playbin.html#GST-PLAY-FLAG-SOFT-COLORBALANCE:CAPS"/>
-    <keyword type="constant" name="GST_PLAY_FLAG_FORCE_FILTERS" link="gst-plugins-base-plugins-playbin.html#GST-PLAY-FLAG-FORCE-FILTERS:CAPS"/>
+    <keyword type="constant" name="BITRATE_TYPE_CBR" link="gst-plugins-base-plugins-opusenc.html#BITRATE-TYPE-CBR:CAPS"/>
+    <keyword type="constant" name="BITRATE_TYPE_VBR" link="gst-plugins-base-plugins-opusenc.html#BITRATE-TYPE-VBR:CAPS"/>
+    <keyword type="constant" name="BITRATE_TYPE_CONSTRAINED_VBR" link="gst-plugins-base-plugins-opusenc.html#BITRATE-TYPE-CONSTRAINED-VBR:CAPS"/>
+    <keyword type="constant" name="GST_TEXT_RENDER_HALIGN_LEFT" link="gst-plugins-base-plugins-textrender.html#GST-TEXT-RENDER-HALIGN-LEFT:CAPS"/>
+    <keyword type="constant" name="GST_TEXT_RENDER_HALIGN_CENTER" link="gst-plugins-base-plugins-textrender.html#GST-TEXT-RENDER-HALIGN-CENTER:CAPS"/>
+    <keyword type="constant" name="GST_TEXT_RENDER_HALIGN_RIGHT" link="gst-plugins-base-plugins-textrender.html#GST-TEXT-RENDER-HALIGN-RIGHT:CAPS"/>
+    <keyword type="constant" name="GST_TEXT_RENDER_LINE_ALIGN_LEFT" link="gst-plugins-base-plugins-textrender.html#GST-TEXT-RENDER-LINE-ALIGN-LEFT:CAPS"/>
+    <keyword type="constant" name="GST_TEXT_RENDER_LINE_ALIGN_CENTER" link="gst-plugins-base-plugins-textrender.html#GST-TEXT-RENDER-LINE-ALIGN-CENTER:CAPS"/>
+    <keyword type="constant" name="GST_TEXT_RENDER_LINE_ALIGN_RIGHT" link="gst-plugins-base-plugins-textrender.html#GST-TEXT-RENDER-LINE-ALIGN-RIGHT:CAPS"/>
+    <keyword type="constant" name="GST_TEXT_RENDER_VALIGN_BASELINE" link="gst-plugins-base-plugins-textrender.html#GST-TEXT-RENDER-VALIGN-BASELINE:CAPS"/>
+    <keyword type="constant" name="GST_TEXT_RENDER_VALIGN_BOTTOM" link="gst-plugins-base-plugins-textrender.html#GST-TEXT-RENDER-VALIGN-BOTTOM:CAPS"/>
+    <keyword type="constant" name="GST_TEXT_RENDER_VALIGN_TOP" link="gst-plugins-base-plugins-textrender.html#GST-TEXT-RENDER-VALIGN-TOP:CAPS"/>
     <keyword type="constant" name="MULTIPASS_MODE_SINGLE_PASS" link="gst-plugins-base-plugins-theoraenc.html#MULTIPASS-MODE-SINGLE-PASS:CAPS"/>
     <keyword type="constant" name="MULTIPASS_MODE_FIRST_PASS" link="gst-plugins-base-plugins-theoraenc.html#MULTIPASS-MODE-FIRST-PASS:CAPS"/>
     <keyword type="constant" name="MULTIPASS_MODE_SECOND_PASS" link="gst-plugins-base-plugins-theoraenc.html#MULTIPASS-MODE-SECOND-PASS:CAPS"/>
     <keyword type="constant" name="GST_TIME_OVERLAY_TIME_LINE_BUFFER_TIME" link="gst-plugins-base-plugins-timeoverlay.html#GST-TIME-OVERLAY-TIME-LINE-BUFFER-TIME:CAPS"/>
     <keyword type="constant" name="GST_TIME_OVERLAY_TIME_LINE_STREAM_TIME" link="gst-plugins-base-plugins-timeoverlay.html#GST-TIME-OVERLAY-TIME-LINE-STREAM-TIME:CAPS"/>
     <keyword type="constant" name="GST_TIME_OVERLAY_TIME_LINE_RUNNING_TIME" link="gst-plugins-base-plugins-timeoverlay.html#GST-TIME-OVERLAY-TIME-LINE-RUNNING-TIME:CAPS"/>
-    <keyword type="constant" name="GST_AUTOPLUG_SELECT_TRY" link="gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-TRY:CAPS"/>
-    <keyword type="constant" name="GST_AUTOPLUG_SELECT_EXPOSE" link="gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-EXPOSE:CAPS"/>
-    <keyword type="constant" name="GST_AUTOPLUG_SELECT_SKIP" link="gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-SKIP:CAPS"/>
+    <keyword type="constant" name="GST_TIME_OVERLAY_TIME_LINE_TIME_CODE" link="gst-plugins-base-plugins-timeoverlay.html#GST-TIME-OVERLAY-TIME-LINE-TIME-CODE:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_SCALE_NEAREST" link="gst-plugins-base-plugins-videoscale.html#GST-VIDEO-SCALE-NEAREST:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_SCALE_BILINEAR" link="gst-plugins-base-plugins-videoscale.html#GST-VIDEO-SCALE-BILINEAR:CAPS"/>
     <keyword type="constant" name="GST_VIDEO_SCALE_4TAP" link="gst-plugins-base-plugins-videoscale.html#GST-VIDEO-SCALE-4TAP:CAPS"/>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-alsamidisrc.html b/docs/plugins/html/gst-plugins-base-plugins-alsamidisrc.html
index 6eccbc8..cc67f87 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-alsamidisrc.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-alsamidisrc.html
@@ -75,10 +75,29 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-alsamidisrc.description"></a><h2>Description</h2>
+<p>The alsamidisrc element is an element that fetches ALSA MIDI sequencer
+events and makes them available to elements understanding
+audio/x-midi-events in their sink pads.</p>
+<p>It can be used to generate notes from a MIDI input device.</p>
+<div class="refsect2">
+<a name="id-1.2.3.7.4"></a><h3>Example launch line</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</pre></td>
+        <td class="listing_code"><pre class="programlisting">gst<span class="gtkdoc opt">-</span>launch <span class="gtkdoc opt">-</span>v alsamidisrc ports<span class="gtkdoc opt">=</span><span class="number">129</span><span class="gtkdoc opt">:</span><span class="number">0</span> <span class="gtkdoc opt">!</span> fluiddec <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> autoaudiosink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ This pipeline will listen for events from the sequencer device at port 129:0,
+and generate notes using the fluiddec element.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.3.7.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.3.7.5.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -104,7 +123,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.3.7.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.3.7.5.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -141,6 +160,7 @@
 <div class="refsect2">
 <a name="GstAlsaMidiSrc-struct"></a><h3>struct GstAlsaMidiSrc</h3>
 <pre class="programlisting">struct GstAlsaMidiSrc;</pre>
+<p>Opaque <a class="link" href="gst-plugins-base-plugins-alsamidisrc.html#GstAlsaMidiSrc"><span class="type">GstAlsaMidiSrc</span></a> data structure.</p>
 </div>
 </div>
 <div class="refsect1">
@@ -153,6 +173,10 @@
 <p>Default value: NULL</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-alsamidisrc.see-also"></a><h2>See Also</h2>
+<p><a href="/usr/share/gtk-doc/html/gstreamer-libs-1.0GstPushSrc.html#GstPushSrc-struct"><span class="type">GstPushSrc</span></a></p>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-alsasink.html b/docs/plugins/html/gst-plugins-base-plugins-alsasink.html
index 77d354c..8ac5951 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-alsasink.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-alsasink.html
@@ -7,7 +7,7 @@
 <link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Plugins Reference Manual">
 <link rel="up" href="ch01.html" title="gst-plugins-base Elements">
 <link rel="prev" href="gst-plugins-base-plugins-alsamidisrc.html" title="alsamidisrc">
-<link rel="next" href="gst-plugins-base-plugins-alsasrc.html" title="alsasrc">
+<link rel="next" href="gst-plugins-base-plugins-appsink.html" title="appsink">
 <meta name="generator" content="GTK-Doc V1.25 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
@@ -22,7 +22,7 @@
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="ch01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="gst-plugins-base-plugins-alsamidisrc.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="gst-plugins-base-plugins-alsasrc.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="n" href="gst-plugins-base-plugins-appsink.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
 <a name="gst-plugins-base-plugins-alsasink"></a><div class="titlepage"></div>
@@ -90,10 +90,25 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-alsasink.description"></a><h2>Description</h2>
+<p>This element renders audio samples using the ALSA audio API.</p>
+<div class="refsect2">
+<a name="id-1.2.4.7.3"></a><h3>Example pipelines</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v uridecodebin uri<span class="gtkdoc opt">=</span>file<span class="gtkdoc opt">:</span><span class="gtkdoc slc">///path/to/audio.ogg ! audioconvert ! audioresample ! autoaudiosink</span></pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Play an Ogg/Vorbis file and output audio via ALSA.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.4.7.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.4.7.4.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -119,7 +134,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.4.7.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.4.7.4.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -172,6 +187,7 @@
 <div class="refsect2">
 <a name="GstAlsaSink-struct"></a><h3>struct GstAlsaSink</h3>
 <pre class="programlisting">struct GstAlsaSink;</pre>
+<p>Opaque data structure</p>
 </div>
 </div>
 <div class="refsect1">
@@ -200,6 +216,10 @@
 <p>Default value: ""</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-alsasink.see-also"></a><h2>See Also</h2>
+<p>alsasrc</p>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-alsasrc.html b/docs/plugins/html/gst-plugins-base-plugins-alsasrc.html
index 1ce9fb2..54ea73f 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-alsasrc.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-alsasrc.html
@@ -6,8 +6,8 @@
 <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
 <link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Plugins Reference Manual">
 <link rel="up" href="ch01.html" title="gst-plugins-base Elements">
-<link rel="prev" href="gst-plugins-base-plugins-alsasink.html" title="alsasink">
-<link rel="next" href="gst-plugins-base-plugins-appsink.html" title="appsink">
+<link rel="prev" href="gst-plugins-base-plugins-appsink.html" title="appsink">
+<link rel="next" href="gst-plugins-base-plugins-appsrc.html" title="appsrc">
 <meta name="generator" content="GTK-Doc V1.25 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
@@ -21,8 +21,8 @@
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="ch01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="gst-plugins-base-plugins-alsasink.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="gst-plugins-base-plugins-appsink.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="p" href="gst-plugins-base-plugins-appsink.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="gst-plugins-base-plugins-appsrc.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
 <a name="gst-plugins-base-plugins-alsasrc"></a><div class="titlepage"></div>
@@ -91,10 +91,25 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-alsasrc.description"></a><h2>Description</h2>
+<p>This element reads data from an audio card using the ALSA API.</p>
+<div class="refsect2">
+<a name="id-1.2.6.7.3"></a><h3>Example pipelines</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v alsasrc <span class="gtkdoc opt">!</span> queue <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> vorbisenc <span class="gtkdoc opt">!</span> oggmux <span class="gtkdoc opt">!</span> filesink location<span class="gtkdoc opt">=</span>alsasrc<span class="gtkdoc opt">.</span>ogg</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Record from a sound card using ALSA and encode to Ogg/Vorbis.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.5.7.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.6.7.4.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -120,7 +135,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.5.7.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.6.7.4.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -157,6 +172,7 @@
 <div class="refsect2">
 <a name="GstAlsaSrc-struct"></a><h3>struct GstAlsaSrc</h3>
 <pre class="programlisting">struct GstAlsaSrc;</pre>
+<p>Opaque data structure</p>
 </div>
 </div>
 <div class="refsect1">
@@ -185,6 +201,10 @@
 <p>Default value: ""</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-alsasrc.see-also"></a><h2>See Also</h2>
+<p>alsasink</p>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-appsink.html b/docs/plugins/html/gst-plugins-base-plugins-appsink.html
index 5169cdf..53a960f 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-appsink.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-appsink.html
@@ -6,8 +6,8 @@
 <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
 <link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Plugins Reference Manual">
 <link rel="up" href="ch01.html" title="gst-plugins-base Elements">
-<link rel="prev" href="gst-plugins-base-plugins-alsasrc.html" title="alsasrc">
-<link rel="next" href="gst-plugins-base-plugins-appsrc.html" title="appsrc">
+<link rel="prev" href="gst-plugins-base-plugins-alsasink.html" title="alsasink">
+<link rel="next" href="gst-plugins-base-plugins-alsasrc.html" title="alsasrc">
 <meta name="generator" content="GTK-Doc V1.25 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
@@ -23,8 +23,8 @@
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="ch01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="gst-plugins-base-plugins-alsasrc.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="gst-plugins-base-plugins-appsrc.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="p" href="gst-plugins-base-plugins-alsasink.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="gst-plugins-base-plugins-alsasrc.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
 <a name="gst-plugins-base-plugins-appsink"></a><div class="titlepage"></div>
@@ -114,6 +114,18 @@
 <td class="signal_name"><a class="link" href="gst-plugins-base-plugins-appsink.html#GstAppSink-pull-sample" title="The “pull-sample” signal">pull-sample</a></td>
 <td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-ACTION:CAPS">Action</a></td>
 </tr>
+<tr>
+<td class="signal_type">
+<a href="/usr/share/gtk-doc/html/gstreamer-1.0GstSample.html#GstSample-struct"><span class="returnvalue">GstSample</span></a>*</td>
+<td class="signal_name"><a class="link" href="gst-plugins-base-plugins-appsink.html#GstAppSink-try-pull-preroll" title="The “try-pull-preroll” signal">try-pull-preroll</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-ACTION:CAPS">Action</a></td>
+</tr>
+<tr>
+<td class="signal_type">
+<a href="/usr/share/gtk-doc/html/gstreamer-1.0GstSample.html#GstSample-struct"><span class="returnvalue">GstSample</span></a>*</td>
+<td class="signal_name"><a class="link" href="gst-plugins-base-plugins-appsink.html#GstAppSink-try-pull-sample" title="The “try-pull-sample” signal">try-pull-sample</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-ACTION:CAPS">Action</a></td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -157,7 +169,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.6.9.6.1"></a><h3>Element Information</h3>
+<a name="id-1.2.5.9.6.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -183,7 +195,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.6.9.6.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.5.9.6.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -312,6 +324,24 @@
                <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a>    user_data)</pre>
 <p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-ACTION:CAPS">Action</a></p>
 </div>
+<hr>
+<div class="refsect2">
+<a name="GstAppSink-try-pull-preroll"></a><h3>The <code class="literal">“try-pull-preroll”</code> signal</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstSample.html#GstSample-struct"><span class="returnvalue">GstSample</span></a>*
+user_function (<a class="link" href="gst-plugins-base-plugins-appsink.html#GstAppSink"><span class="type">GstAppSink</span></a> *gstappsink,
+               <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="type">guint64</span></a>     arg1,
+               <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a>    user_data)</pre>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-ACTION:CAPS">Action</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstAppSink-try-pull-sample"></a><h3>The <code class="literal">“try-pull-sample”</code> signal</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstSample.html#GstSample-struct"><span class="returnvalue">GstSample</span></a>*
+user_function (<a class="link" href="gst-plugins-base-plugins-appsink.html#GstAppSink"><span class="type">GstAppSink</span></a> *gstappsink,
+               <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="type">guint64</span></a>     arg1,
+               <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a>    user_data)</pre>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-ACTION:CAPS">Action</a></p>
+</div>
 </div>
 </div>
 <div class="footer">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-appsrc.html b/docs/plugins/html/gst-plugins-base-plugins-appsrc.html
index 5877cde..aef1122 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-appsrc.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-appsrc.html
@@ -6,7 +6,7 @@
 <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
 <link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Plugins Reference Manual">
 <link rel="up" href="ch01.html" title="gst-plugins-base Elements">
-<link rel="prev" href="gst-plugins-base-plugins-appsink.html" title="appsink">
+<link rel="prev" href="gst-plugins-base-plugins-alsasrc.html" title="alsasrc">
 <link rel="next" href="gst-plugins-base-plugins-audioconvert.html" title="audioconvert">
 <meta name="generator" content="GTK-Doc V1.25 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
@@ -23,7 +23,7 @@
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="ch01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="gst-plugins-base-plugins-appsink.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="p" href="gst-plugins-base-plugins-alsasrc.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="gst-plugins-base-plugins-audioconvert.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
@@ -105,6 +105,11 @@
 <td class="property_name"><a class="link" href="gst-plugins-base-plugins-appsrc.html#GstAppSrc--stream-type" title="The “stream-type” property">stream-type</a></td>
 <td class="property_flags">Read / Write</td>
 </tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="type">guint64</span></a></td>
+<td class="property_name"><a class="link" href="gst-plugins-base-plugins-appsrc.html#GstAppSrc--duration" title="The “duration” property">duration</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -355,6 +360,14 @@
 <p>Flags: Read / Write</p>
 <p>Default value: GST_APP_STREAM_TYPE_STREAM</p>
 </div>
+<hr>
+<div class="refsect2">
+<a name="GstAppSrc--duration"></a><h3>The <code class="literal">“duration”</code> property</h3>
+<pre class="programlisting">  “duration”                 <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="type">guint64</span></a></pre>
+<p>The duration of the data stream in nanoseconds (GST_CLOCK_TIME_NONE if unknown).</p>
+<p>Flags: Read / Write</p>
+<p>Default value: 18446744073709551615</p>
+</div>
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-appsrc.signal-details"></a><h2>Signal Details</h2>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-audioresample.html b/docs/plugins/html/gst-plugins-base-plugins-audioresample.html
index feab78d..9106cfa 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-audioresample.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-audioresample.html
@@ -53,10 +53,20 @@
 <td class="property_flags">Read / Write</td>
 </tr>
 <tr>
-<td class="property_type"><span class="type">SpeexResamplerSincFilterMode</span></td>
+<td class="property_type"><span class="type">GstAudioResamplerFilterMode</span></td>
 <td class="property_name"><a class="link" href="gst-plugins-base-plugins-audioresample.html#GstAudioResample--sinc-filter-mode" title="The “sinc-filter-mode” property">sinc-filter-mode</a></td>
 <td class="property_flags">Read / Write</td>
 </tr>
+<tr>
+<td class="property_type"><span class="type">GstAudioResamplerMethod</span></td>
+<td class="property_name"><a class="link" href="gst-plugins-base-plugins-audioresample.html#GstAudioResample--resample-method" title="The “resample-method” property">resample-method</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><span class="type">GstAudioResamplerFilterInterpolation</span></td>
+<td class="property_name"><a class="link" href="gst-plugins-base-plugins-audioresample.html#GstAudioResample--sinc-filter-interpolation" title="The “sinc-filter-interpolation” property">sinc-filter-interpolation</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -160,7 +170,7 @@
 </tr>
 <tr>
 <td><p><span class="term">details</span></p></td>
-<td>audio/x-raw, format=(string){ F32LE, F64LE, S32LE, S24LE, S16LE, S8 }, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], layout=(string){ interleaved, non-interleaved }</td>
+<td>audio/x-raw, format=(string){ S8, U8, S16LE, S16BE, U16LE, U16BE, S24_32LE, S24_32BE, U24_32LE, U24_32BE, S32LE, S32BE, U32LE, U32BE, S24LE, S24BE, U24LE, U24BE, S20LE, S20BE, U20LE, U20BE, S18LE, S18BE, U18LE, U18BE, F32LE, F32BE, F64LE, F64BE }, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], layout=(string){ interleaved, non-interleaved }</td>
 </tr>
 </tbody>
 </table></div>
@@ -184,7 +194,7 @@
 </tr>
 <tr>
 <td><p><span class="term">details</span></p></td>
-<td>audio/x-raw, format=(string){ F32LE, F64LE, S32LE, S24LE, S16LE, S8 }, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], layout=(string){ interleaved, non-interleaved }</td>
+<td>audio/x-raw, format=(string){ S8, U8, S16LE, S16BE, U16LE, U16BE, S24_32LE, S24_32BE, U24_32LE, U24_32BE, S32LE, S32BE, U32LE, U32BE, S24LE, S24BE, U24LE, U24BE, S20LE, S20BE, U20LE, U20BE, S18LE, S18BE, U18LE, U18BE, F32LE, F32BE, F64LE, F64BE }, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], layout=(string){ interleaved, non-interleaved }</td>
 </tr>
 </tbody>
 </table></div>
@@ -224,10 +234,26 @@
 <hr>
 <div class="refsect2">
 <a name="GstAudioResample--sinc-filter-mode"></a><h3>The <code class="literal">“sinc-filter-mode”</code> property</h3>
-<pre class="programlisting">  “sinc-filter-mode”         <span class="type">SpeexResamplerSincFilterMode</span></pre>
+<pre class="programlisting">  “sinc-filter-mode”         <span class="type">GstAudioResamplerFilterMode</span></pre>
 <p>What sinc filter table mode to use.</p>
 <p>Flags: Read / Write</p>
-<p>Default value: Use full table if table size below threshold</p>
+<p>Default value: GST_AUDIO_RESAMPLER_FILTER_MODE_AUTO</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstAudioResample--resample-method"></a><h3>The <code class="literal">“resample-method”</code> property</h3>
+<pre class="programlisting">  “resample-method”          <span class="type">GstAudioResamplerMethod</span></pre>
+<p>What resample method to use.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: GST_AUDIO_RESAMPLER_METHOD_KAISER</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstAudioResample--sinc-filter-interpolation"></a><h3>The <code class="literal">“sinc-filter-interpolation”</code> property</h3>
+<pre class="programlisting">  “sinc-filter-interpolation” <span class="type">GstAudioResamplerFilterInterpolation</span></pre>
+<p>How to interpolate the sinc filter table.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_CUBIC</p>
 </div>
 </div>
 </div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-cdparanoiasrc.html b/docs/plugins/html/gst-plugins-base-plugins-cdparanoiasrc.html
index d1abe49..e057f5b 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-cdparanoiasrc.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-cdparanoiasrc.html
@@ -194,6 +194,7 @@
 <div class="refsect2">
 <a name="GstCdParanoiaSrc-struct"></a><h3>struct GstCdParanoiaSrc</h3>
 <pre class="programlisting">struct GstCdParanoiaSrc;</pre>
+<p>The cdparanoia object structure.</p>
 </div>
 </div>
 <div class="refsect1">
@@ -201,7 +202,7 @@
 <div class="refsect2">
 <a name="GstCdParanoiaSrc--cache-size"></a><h3>The <code class="literal">“cache-size”</code> property</h3>
 <pre class="programlisting">  “cache-size”               <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></pre>
-<p>Set CD cache size to n sectors (-1 = auto).</p>
+<p>Set CD cache size to n sectors (-1 = auto)</p>
 <p>Flags: Read / Write</p>
 <p>Allowed values: &gt;= G_MAXULONG</p>
 <p>Default value: -1</p>
@@ -246,18 +247,76 @@
 <div class="refsect2">
 <a name="GstCdParanoiaSrc-transport-error"></a><h3>The <code class="literal">“transport-error”</code> signal</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-user_function (<a class="link" href="gst-plugins-base-plugins-cdparanoiasrc.html#GstCdParanoiaSrc"><span class="type">GstCdParanoiaSrc</span></a> *gstcdparanoiasrc,
-               <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a>              arg1,
+user_function (<a class="link" href="gst-plugins-base-plugins-cdparanoiasrc.html#GstCdParanoiaSrc"><span class="type">GstCdParanoiaSrc</span></a> *cdparanoia,
+               <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a>              sector,
                <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a>          user_data)</pre>
+<p>This signal is emitted whenever an error occurs while reading.
+CdParanoia will attempt to recover the data.</p>
+<div class="refsect3">
+<a name="GstCdParanoiaSrc-transport-error.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>cdparanoia</p></td>
+<td class="parameter_description"><p>The CdParanoia instance</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>sector</p></td>
+<td class="parameter_description"><p>The sector number at which the error was encountered.</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="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="GstCdParanoiaSrc-uncorrected-error"></a><h3>The <code class="literal">“uncorrected-error”</code> signal</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-user_function (<a class="link" href="gst-plugins-base-plugins-cdparanoiasrc.html#GstCdParanoiaSrc"><span class="type">GstCdParanoiaSrc</span></a> *gstcdparanoiasrc,
-               <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a>              arg1,
+user_function (<a class="link" href="gst-plugins-base-plugins-cdparanoiasrc.html#GstCdParanoiaSrc"><span class="type">GstCdParanoiaSrc</span></a> *cdparanoia,
+               <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a>              sector,
                <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a>          user_data)</pre>
+<p>This signal is emitted whenever an uncorrectable error occurs while
+reading. The data could not be read.</p>
+<div class="refsect3">
+<a name="GstCdParanoiaSrc-uncorrected-error.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>cdparanoia</p></td>
+<td class="parameter_description"><p>The CdParanoia instance</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>sector</p></td>
+<td class="parameter_description"><p>The sector number at which the error was encountered.</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="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
 </div>
 </div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-clockoverlay.html b/docs/plugins/html/gst-plugins-base-plugins-clockoverlay.html
index 7a7d8dd..d7c0dbc 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-clockoverlay.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-clockoverlay.html
@@ -74,10 +74,43 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-clockoverlay.description"></a><h2>Description</h2>
+<p>This element overlays the current clock time on top of a video
+stream. You can position the text and configure the font details
+using the properties of the <span class="type">GstBaseTextOverlay</span> class. By default, the
+time is displayed in the top left corner of the picture, with some
+padding to the left and to the top.</p>
+<div class="refsect2">
+<a name="id-1.2.13.7.3"></a><h3>Example launch lines</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v videotestsrc <span class="gtkdoc opt">!</span> clockoverlay <span class="gtkdoc opt">!</span> autovideosink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Display the current wall clock time in the top left corner of the video picture
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v videotestsrc <span class="gtkdoc opt">!</span> clockoverlay halignment<span class="gtkdoc opt">=</span>right valignment<span class="gtkdoc opt">=</span>bottom text<span class="gtkdoc opt">=</span><span class="string">&quot;Edge City&quot;</span> shaded<span class="gtkdoc opt">-</span>background<span class="gtkdoc opt">=</span><span class="keyword">true</span> font<span class="gtkdoc opt">-</span>desc<span class="gtkdoc opt">=</span><span class="string">&quot;Sans, 36&quot;</span> <span class="gtkdoc opt">!</span> videoconvert <span class="gtkdoc opt">!</span> autovideosink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Another pipeline that displays the current time with some leading
+text in the bottom right corner of the video picture, with the background
+of the text being shaded in order to make it more legible on top of a
+bright video background.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.13.7.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.13.7.4.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -103,7 +136,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.13.7.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.13.7.4.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -128,7 +161,7 @@
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 </tbody>
 </table></div>
@@ -156,7 +189,7 @@
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 </tbody>
 </table></div>
@@ -172,6 +205,7 @@
 <div class="refsect2">
 <a name="GstClockOverlay-struct"></a><h3>struct GstClockOverlay</h3>
 <pre class="programlisting">struct GstClockOverlay;</pre>
+<p>Opaque clockoverlay data structure.</p>
 </div>
 </div>
 <div class="refsect1">
@@ -184,6 +218,10 @@
 <p>Default value: "%H:%M:%S"</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-clockoverlay.see-also"></a><h2>See Also</h2>
+<p><span class="type">GstBaseTextOverlay</span>, <a class="link" href="gst-plugins-base-plugins-timeoverlay.html#GstTimeOverlay"><span class="type">GstTimeOverlay</span></a></p>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-decodebin.html b/docs/plugins/html/gst-plugins-base-plugins-decodebin.html
index c8a154c..c96f586 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-decodebin.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-decodebin.html
@@ -7,7 +7,7 @@
 <link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Plugins Reference Manual">
 <link rel="up" href="ch01.html" title="gst-plugins-base Elements">
 <link rel="prev" href="gst-plugins-base-plugins-clockoverlay.html" title="clockoverlay">
-<link rel="next" href="gst-plugins-base-plugins-encodebin.html" title="encodebin">
+<link rel="next" href="gst-plugins-base-plugins-decodebin3.html" title="decodebin3">
 <meta name="generator" content="GTK-Doc V1.25 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
@@ -24,7 +24,7 @@
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="ch01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="gst-plugins-base-plugins-clockoverlay.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="gst-plugins-base-plugins-encodebin.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="n" href="gst-plugins-base-plugins-decodebin3.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
 <a name="gst-plugins-base-plugins-decodebin"></a><div class="titlepage"></div>
@@ -136,7 +136,7 @@
 <td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
 </tr>
 <tr>
-<td class="signal_type"><a class="link" href="gst-plugins-base-plugins-uridecodebin.html#GstAutoplugSelectResult" title="enum GstAutoplugSelectResult"><span class="returnvalue">GstAutoplugSelectResult</span></a></td>
+<td class="signal_type"><a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-uridecodebin.html#GstAutoplugSelectResult"><span class="returnvalue">GstAutoplugSelectResult</span></a></td>
 <td class="signal_name"><a class="link" href="gst-plugins-base-plugins-decodebin.html#GstDecodeBin-autoplug-select" title="The “autoplug-select” signal">autoplug-select</a></td>
 <td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
 </tr>
@@ -566,7 +566,7 @@
 <hr>
 <div class="refsect2">
 <a name="GstDecodeBin-autoplug-select"></a><h3>The <code class="literal">“autoplug-select”</code> signal</h3>
-<pre class="programlisting"><a class="link" href="gst-plugins-base-plugins-uridecodebin.html#GstAutoplugSelectResult" title="enum GstAutoplugSelectResult"><span class="returnvalue">GstAutoplugSelectResult</span></a>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-uridecodebin.html#GstAutoplugSelectResult"><span class="returnvalue">GstAutoplugSelectResult</span></a>
 user_function (<a class="link" href="gst-plugins-base-plugins-decodebin.html#GstDecodeBin"><span class="type">GstDecodeBin</span></a>      *bin,
                <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstPad.html#GstPad-struct"><span class="type">GstPad</span></a>            *pad,
                <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstCaps.html#GstCaps-struct"><span class="type">GstCaps</span></a>           *caps,
@@ -578,13 +578,13 @@
 those factories, this signal is emitted.</p>
 <p>The signal handler should return a <span class="type">GST_TYPE_AUTOPLUG_SELECT_RESULT</span> enum
 value indicating what decodebin should do next.</p>
-<p>A value of <a class="link" href="gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-TRY:CAPS"><span class="type">GST_AUTOPLUG_SELECT_TRY</span></a> will try to autoplug an element from
+<p>A value of <a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-TRY:CAPS"><span class="type">GST_AUTOPLUG_SELECT_TRY</span></a> will try to autoplug an element from
 <em class="parameter"><code>factory</code></em>
 .</p>
-<p>A value of <a class="link" href="gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-EXPOSE:CAPS"><span class="type">GST_AUTOPLUG_SELECT_EXPOSE</span></a> will expose <em class="parameter"><code>pad</code></em>
+<p>A value of <a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-EXPOSE:CAPS"><span class="type">GST_AUTOPLUG_SELECT_EXPOSE</span></a> will expose <em class="parameter"><code>pad</code></em>
  without plugging
 any element to it.</p>
-<p>A value of <a class="link" href="gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-SKIP:CAPS"><span class="type">GST_AUTOPLUG_SELECT_SKIP</span></a> will skip <em class="parameter"><code>factory</code></em>
+<p>A value of <a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-SKIP:CAPS"><span class="type">GST_AUTOPLUG_SELECT_SKIP</span></a> will skip <em class="parameter"><code>factory</code></em>
  and move to the
 next factory.</p>
 <div class="note">
@@ -635,7 +635,7 @@
 <a name="GstDecodeBin-autoplug-select.returns"></a><h4>Returns</h4>
 <p> a <span class="type">GST_TYPE_AUTOPLUG_SELECT_RESULT</span> that indicates the required
 operation. the default handler will always return
-<a class="link" href="gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-TRY:CAPS"><span class="type">GST_AUTOPLUG_SELECT_TRY</span></a>.</p>
+<a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-TRY:CAPS"><span class="type">GST_AUTOPLUG_SELECT_TRY</span></a>.</p>
 </div>
 <p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
 </div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-decodebin3.html b/docs/plugins/html/gst-plugins-base-plugins-decodebin3.html
new file mode 100644
index 0000000..5016347
--- /dev/null
+++ b/docs/plugins/html/gst-plugins-base-plugins-decodebin3.html
@@ -0,0 +1,251 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>decodebin3: GStreamer Base Plugins 1.0 Plugins Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
+<link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Plugins Reference Manual">
+<link rel="up" href="ch01.html" title="gst-plugins-base Elements">
+<link rel="prev" href="gst-plugins-base-plugins-decodebin.html" title="decodebin">
+<link rel="next" href="gst-plugins-base-plugins-encodebin.html" title="encodebin">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
+                  <a href="#gst-plugins-base-plugins-decodebin3.description" class="shortcut">Description</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="gst-plugins-base-plugins-decodebin.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="gst-plugins-base-plugins-encodebin.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="gst-plugins-base-plugins-decodebin3"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="gst-plugins-base-plugins-decodebin3.top_of_page"></a>decodebin3</span></h2>
+<p>decodebin3</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-decodebin3.description"></a><h2>Description</h2>
+<p><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstBin.html#GstBin-struct"><span class="type">GstBin</span></a> that auto-magically constructs a decoding pipeline using available
+decoders and demuxers via auto-plugging. The output is raw audio, video
+or subtitle streams.</p>
+<p>decodebin3 differs from the previous decodebin (decodebin2) in important ways:</p>
+<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
+<li class="listitem">
+supports publication and selection of stream information via
+GstStreamCollection messages and <span class="type">GST_EVENT_SELECT_STREAM</span> events.
+</li>
+<li class="listitem">
+dynamically switches stream connections internally, and
+reuses decoder elements when stream selections change, so that in
+the normal case it maintains 1 decoder of each type (video/audio/subtitle)
+and only creates new elements when streams change and an existing decoder
+is not capable of handling the new format.
+</li>
+<li class="listitem">
+supports multiple input pads for the parallel decoding of auxilliary streams
+not muxed with the primary stream.
+</li>
+<li class="listitem">
+does not handle network stream buffering. decodebin3 expects that network stream
+buffering is handled upstream, before data is passed to it.
+</li>
+</ul></div>
+<p><span class="emphasis"><em>decodebin3 is still experimental API and a technology preview.
+Its behaviour and exposed API is subject to change.</em></span></p>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="refsect2">
+<a name="id-1.2.15.3.6.1"></a><h3>Element Information</h3>
+<div class="variablelist"><table border="0" class="variablelist">
+<colgroup>
+<col align="left" valign="top">
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td><p><span class="term">plugin</span></p></td>
+<td>
+            <a class="link" href="gst-plugins-base-plugins-plugin-playback.html#plugin-playback">playback</a>
+          </td>
+</tr>
+<tr>
+<td><p><span class="term">author</span></p></td>
+<td>Edward Hervey &lt;edward@centricular.com&gt;</td>
+</tr>
+<tr>
+<td><p><span class="term">class</span></p></td>
+<td>Generic/Bin/Decoder</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.15.3.6.2"></a><h3>Element Pads</h3>
+<div class="variablelist"><table border="0" class="variablelist">
+<colgroup>
+<col align="left" valign="top">
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td><p><span class="term">name</span></p></td>
+<td>sink</td>
+</tr>
+<tr>
+<td><p><span class="term">direction</span></p></td>
+<td>sink</td>
+</tr>
+<tr>
+<td><p><span class="term">presence</span></p></td>
+<td>always</td>
+</tr>
+<tr>
+<td><p><span class="term">details</span></p></td>
+<td>ANY</td>
+</tr>
+</tbody>
+</table></div>
+<div class="variablelist"><table border="0" class="variablelist">
+<colgroup>
+<col align="left" valign="top">
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td><p><span class="term">name</span></p></td>
+<td>sink_%u</td>
+</tr>
+<tr>
+<td><p><span class="term">direction</span></p></td>
+<td>sink</td>
+</tr>
+<tr>
+<td><p><span class="term">presence</span></p></td>
+<td>request</td>
+</tr>
+<tr>
+<td><p><span class="term">details</span></p></td>
+<td>ANY</td>
+</tr>
+</tbody>
+</table></div>
+<div class="variablelist"><table border="0" class="variablelist">
+<colgroup>
+<col align="left" valign="top">
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td><p><span class="term">name</span></p></td>
+<td>audio_%u</td>
+</tr>
+<tr>
+<td><p><span class="term">direction</span></p></td>
+<td>source</td>
+</tr>
+<tr>
+<td><p><span class="term">presence</span></p></td>
+<td>sometimes</td>
+</tr>
+<tr>
+<td><p><span class="term">details</span></p></td>
+<td>ANY</td>
+</tr>
+</tbody>
+</table></div>
+<div class="variablelist"><table border="0" class="variablelist">
+<colgroup>
+<col align="left" valign="top">
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td><p><span class="term">name</span></p></td>
+<td>src_%u</td>
+</tr>
+<tr>
+<td><p><span class="term">direction</span></p></td>
+<td>source</td>
+</tr>
+<tr>
+<td><p><span class="term">presence</span></p></td>
+<td>sometimes</td>
+</tr>
+<tr>
+<td><p><span class="term">details</span></p></td>
+<td>ANY</td>
+</tr>
+</tbody>
+</table></div>
+<div class="variablelist"><table border="0" class="variablelist">
+<colgroup>
+<col align="left" valign="top">
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td><p><span class="term">name</span></p></td>
+<td>text_%u</td>
+</tr>
+<tr>
+<td><p><span class="term">direction</span></p></td>
+<td>source</td>
+</tr>
+<tr>
+<td><p><span class="term">presence</span></p></td>
+<td>sometimes</td>
+</tr>
+<tr>
+<td><p><span class="term">details</span></p></td>
+<td>ANY</td>
+</tr>
+</tbody>
+</table></div>
+<div class="variablelist"><table border="0" class="variablelist">
+<colgroup>
+<col align="left" valign="top">
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td><p><span class="term">name</span></p></td>
+<td>video_%u</td>
+</tr>
+<tr>
+<td><p><span class="term">direction</span></p></td>
+<td>source</td>
+</tr>
+<tr>
+<td><p><span class="term">presence</span></p></td>
+<td>sometimes</td>
+</tr>
+<tr>
+<td><p><span class="term">details</span></p></td>
+<td>ANY</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-decodebin3.functions_details"></a><h2>Functions</h2>
+<p></p>
+</div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-decodebin3.other_details"></a><h2>Types and Values</h2>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/plugins/html/gst-plugins-base-plugins-encodebin.html b/docs/plugins/html/gst-plugins-base-plugins-encodebin.html
index c966010..607f735 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-encodebin.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-encodebin.html
@@ -6,7 +6,7 @@
 <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
 <link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Plugins Reference Manual">
 <link rel="up" href="ch01.html" title="gst-plugins-base Elements">
-<link rel="prev" href="gst-plugins-base-plugins-decodebin.html" title="decodebin">
+<link rel="prev" href="gst-plugins-base-plugins-decodebin3.html" title="decodebin3">
 <link rel="next" href="gst-plugins-base-plugins-giosink.html" title="giosink">
 <meta name="generator" content="GTK-Doc V1.25 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
@@ -23,7 +23,7 @@
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="ch01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="gst-plugins-base-plugins-decodebin.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="p" href="gst-plugins-base-plugins-decodebin3.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="gst-plugins-base-plugins-giosink.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
@@ -146,7 +146,7 @@
 provide it raw or pre-encoded streams of data in input and have your
 encoded/muxed/converted stream in output.</p>
 <div class="refsect2">
-<a name="id-1.2.15.9.4"></a><h3>Features</h3>
+<a name="id-1.2.16.9.4"></a><h3>Features</h3>
 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
 <li class="listitem">
 Automatic encoder and muxer selection based on elements available on the
@@ -209,7 +209,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.15.9.5.1"></a><h3>Element Information</h3>
+<a name="id-1.2.16.9.5.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -235,7 +235,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.15.9.5.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.16.9.5.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-giosink.html b/docs/plugins/html/gst-plugins-base-plugins-giosink.html
index 9f05ba1..6086b14 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-giosink.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-giosink.html
@@ -110,7 +110,7 @@
 mounted. This message can be used by application to mount the location
 and retry after the location was mounted successfully.</p>
 <div class="refsect2">
-<a name="id-1.2.16.8.5"></a><h3>Example pipelines</h3>
+<a name="id-1.2.17.8.5"></a><h3>Example pipelines</h3>
 <div class="informalexample">
   <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
     <tbody>
@@ -151,7 +151,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.16.8.6.1"></a><h3>Element Information</h3>
+<a name="id-1.2.17.8.6.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -177,7 +177,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.16.8.6.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.17.8.6.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-giosrc.html b/docs/plugins/html/gst-plugins-base-plugins-giosrc.html
index 18c7e1a..cc9e9b9 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-giosrc.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-giosrc.html
@@ -106,7 +106,7 @@
 message was received and gst_bus_set_flushing(bus, FALSE) after the
 mounting was successful.</p>
 <div class="refsect2">
-<a name="id-1.2.17.8.4"></a><h3>Example launch lines</h3>
+<a name="id-1.2.18.8.4"></a><h3>Example launch lines</h3>
 <div class="informalexample">
   <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
     <tbody>
@@ -148,7 +148,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.17.8.5.1"></a><h3>Element Information</h3>
+<a name="id-1.2.18.8.5.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -174,7 +174,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.17.8.5.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.18.8.5.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-giostreamsink.html b/docs/plugins/html/gst-plugins-base-plugins-giostreamsink.html
index 9ab9b10..e0d0057 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-giostreamsink.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-giostreamsink.html
@@ -79,7 +79,7 @@
 <p>It can, for example, be used to write a stream to memory with a
 <span class="type">GMemoryOuputStream</span> or to write to a file with a <span class="type">GFileOuputStream</span>.</p>
 <div class="refsect2">
-<a name="id-1.2.18.7.4"></a><h3>Example code</h3>
+<a name="id-1.2.19.7.4"></a><h3>Example code</h3>
 <p>
 The following example writes the received data to a <a href="/usr/share/gtk-doc/html/gioGMemoryOutputStream.html#GMemoryOutputStream-struct"><span class="type">GMemoryOutputStream</span></a>.
 </p>
@@ -144,7 +144,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.18.7.5.1"></a><h3>Element Information</h3>
+<a name="id-1.2.19.7.5.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -170,7 +170,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.18.7.5.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.19.7.5.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-giostreamsrc.html b/docs/plugins/html/gst-plugins-base-plugins-giostreamsrc.html
index 6dfcb36..a4c9e14 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-giostreamsrc.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-giostreamsrc.html
@@ -80,7 +80,7 @@
 <a href="/usr/share/gtk-doc/html/gioGMemoryInputStream.html#GMemoryInputStream-struct"><span class="type">GMemoryInputStream</span></a> or to read from a file with a
 <a href="/usr/share/gtk-doc/html/gioGFileInputStream.html#GFileInputStream-struct"><span class="type">GFileInputStream</span></a>.</p>
 <div class="refsect2">
-<a name="id-1.2.19.7.4"></a><h3>Example code</h3>
+<a name="id-1.2.20.7.4"></a><h3>Example code</h3>
 <p>
 The following example reads data from a <a href="/usr/share/gtk-doc/html/gioGMemoryInputStream.html#GMemoryInputStream-struct"><span class="type">GMemoryInputStream</span></a>.
 </p>
@@ -143,7 +143,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.19.7.5.1"></a><h3>Element Information</h3>
+<a name="id-1.2.20.7.5.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -169,7 +169,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.19.7.5.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.20.7.5.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-multifdsink.html b/docs/plugins/html/gst-plugins-base-plugins-multifdsink.html
index 417635d..ad2fe82 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-multifdsink.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-multifdsink.html
@@ -109,24 +109,10 @@
 <col width="150px" class="name">
 <col class="description">
 </colgroup>
-<tbody>
-<tr>
+<tbody><tr>
 <td class="datatype_keyword">struct</td>
 <td class="function_name"><a class="link" href="gst-plugins-base-plugins-multifdsink.html#GstMultiFdSink-struct" title="struct GstMultiFdSink">GstMultiFdSink</a></td>
-</tr>
-<tr>
-<td class="datatype_keyword">enum</td>
-<td class="function_name"><a class="link" href="gst-plugins-base-plugins-multifdsink.html#GstRecoverPolicy" title="enum GstRecoverPolicy">GstRecoverPolicy</a></td>
-</tr>
-<tr>
-<td class="datatype_keyword">enum</td>
-<td class="function_name"><a class="link" href="gst-plugins-base-plugins-multifdsink.html#GstSyncMethod" title="enum GstSyncMethod">GstSyncMethod</a></td>
-</tr>
-<tr>
-<td class="datatype_keyword">enum</td>
-<td class="function_name"><a class="link" href="gst-plugins-base-plugins-multifdsink.html#GstClientStatus" title="enum GstClientStatus">GstClientStatus</a></td>
-</tr>
-</tbody>
+</tr></tbody>
 </table></div>
 </div>
 <div class="refsect1">
@@ -209,7 +195,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.20.8.13.1"></a><h3>Element Information</h3>
+<a name="id-1.2.21.8.13.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -235,7 +221,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.20.8.13.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.21.8.13.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -274,182 +260,6 @@
 <pre class="programlisting">struct GstMultiFdSink;</pre>
 <p>The multifdsink object structure.</p>
 </div>
-<hr>
-<div class="refsect2">
-<a name="GstRecoverPolicy"></a><h3>enum GstRecoverPolicy</h3>
-<p>Possible values for the recovery procedure to use when a client consumes
-data too slow and has a backlag of more that soft-limit buffers.</p>
-<div class="refsect3">
-<a name="GstRecoverPolicy.members"></a><h4>Members</h4>
-<div class="informaltable"><table class="informaltable" width="100%" border="0">
-<colgroup>
-<col width="300px" class="enum_members_name">
-<col class="enum_members_description">
-<col width="200px" class="enum_members_annotations">
-</colgroup>
-<tbody>
-<tr>
-<td class="enum_member_name"><p><a name="GST-RECOVER-POLICY-NONE:CAPS"></a>GST_RECOVER_POLICY_NONE</p></td>
-<td class="enum_member_description">
-<p>no recovering is done</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-RECOVER-POLICY-RESYNC-LATEST:CAPS"></a>GST_RECOVER_POLICY_RESYNC_LATEST</p></td>
-<td class="enum_member_description">
-<p>client is moved to last buffer</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-RECOVER-POLICY-RESYNC-SOFT-LIMIT:CAPS"></a>GST_RECOVER_POLICY_RESYNC_SOFT_LIMIT</p></td>
-<td class="enum_member_description">
-<p>client is moved to the soft limit</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-RECOVER-POLICY-RESYNC-KEYFRAME:CAPS"></a>GST_RECOVER_POLICY_RESYNC_KEYFRAME</p></td>
-<td class="enum_member_description">
-<p>client is moved to latest keyframe</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-</tbody>
-</table></div>
-</div>
-</div>
-<hr>
-<div class="refsect2">
-<a name="GstSyncMethod"></a><h3>enum GstSyncMethod</h3>
-<p>This enum defines the selection of the first buffer that is sent
-to a new client.</p>
-<div class="refsect3">
-<a name="GstSyncMethod.members"></a><h4>Members</h4>
-<div class="informaltable"><table class="informaltable" width="100%" border="0">
-<colgroup>
-<col width="300px" class="enum_members_name">
-<col class="enum_members_description">
-<col width="200px" class="enum_members_annotations">
-</colgroup>
-<tbody>
-<tr>
-<td class="enum_member_name"><p><a name="GST-SYNC-METHOD-LATEST:CAPS"></a>GST_SYNC_METHOD_LATEST</p></td>
-<td class="enum_member_description">
-<p>client receives most recent buffer</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-SYNC-METHOD-NEXT-KEYFRAME:CAPS"></a>GST_SYNC_METHOD_NEXT_KEYFRAME</p></td>
-<td class="enum_member_description">
-<p>client receives next keyframe</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-SYNC-METHOD-LATEST-KEYFRAME:CAPS"></a>GST_SYNC_METHOD_LATEST_KEYFRAME</p></td>
-<td class="enum_member_description">
-<p>client receives latest keyframe (burst)</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-SYNC-METHOD-BURST:CAPS"></a>GST_SYNC_METHOD_BURST</p></td>
-<td class="enum_member_description">
-<p>client receives specific amount of data</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-SYNC-METHOD-BURST-KEYFRAME:CAPS"></a>GST_SYNC_METHOD_BURST_KEYFRAME</p></td>
-<td class="enum_member_description">
-<p>client receives specific amount of data 
-                                       starting from latest keyframe</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-SYNC-METHOD-BURST-WITH-KEYFRAME:CAPS"></a>GST_SYNC_METHOD_BURST_WITH_KEYFRAME</p></td>
-<td class="enum_member_description">
-<p>client receives specific amount of data from
-                                       a keyframe, or if there is not enough data after
-                                       the keyframe, starting before the keyframe</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-</tbody>
-</table></div>
-</div>
-</div>
-<hr>
-<div class="refsect2">
-<a name="GstClientStatus"></a><h3>enum GstClientStatus</h3>
-<p>This specifies the reason why a client was removed from
-multisocketsink and is received in the "client-removed" signal.</p>
-<div class="refsect3">
-<a name="GstClientStatus.members"></a><h4>Members</h4>
-<div class="informaltable"><table class="informaltable" width="100%" border="0">
-<colgroup>
-<col width="300px" class="enum_members_name">
-<col class="enum_members_description">
-<col width="200px" class="enum_members_annotations">
-</colgroup>
-<tbody>
-<tr>
-<td class="enum_member_name"><p><a name="GST-CLIENT-STATUS-OK:CAPS"></a>GST_CLIENT_STATUS_OK</p></td>
-<td class="enum_member_description">
-<p>client is ok</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-CLIENT-STATUS-CLOSED:CAPS"></a>GST_CLIENT_STATUS_CLOSED</p></td>
-<td class="enum_member_description">
-<p>client closed the socket</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-CLIENT-STATUS-REMOVED:CAPS"></a>GST_CLIENT_STATUS_REMOVED</p></td>
-<td class="enum_member_description">
-<p>client is removed</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-CLIENT-STATUS-SLOW:CAPS"></a>GST_CLIENT_STATUS_SLOW</p></td>
-<td class="enum_member_description">
-<p>client is too slow</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-CLIENT-STATUS-ERROR:CAPS"></a>GST_CLIENT_STATUS_ERROR</p></td>
-<td class="enum_member_description">
-<p>client is in error</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-CLIENT-STATUS-DUPLICATE:CAPS"></a>GST_CLIENT_STATUS_DUPLICATE</p></td>
-<td class="enum_member_description">
-<p>same client added twice</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-CLIENT-STATUS-FLUSHING:CAPS"></a>GST_CLIENT_STATUS_FLUSHING</p></td>
-<td class="enum_member_description">
-<p>client is flushing out the remaining buffers.</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-</tbody>
-</table></div>
-</div>
-</div>
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-multifdsink.property-details"></a><h2>Property Details</h2>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-multisocketsink.html b/docs/plugins/html/gst-plugins-base-plugins-multisocketsink.html
index a531d65..84b8206 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-multisocketsink.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-multisocketsink.html
@@ -116,24 +116,10 @@
 <col width="150px" class="name">
 <col class="description">
 </colgroup>
-<tbody>
-<tr>
+<tbody><tr>
 <td class="datatype_keyword">struct</td>
 <td class="function_name"><a class="link" href="gst-plugins-base-plugins-multisocketsink.html#GstMultiSocketSink-struct" title="struct GstMultiSocketSink">GstMultiSocketSink</a></td>
-</tr>
-<tr>
-<td class="datatype_keyword">enum</td>
-<td class="function_name"><a class="link" href="gst-plugins-base-plugins-multifdsink.html#GstRecoverPolicy" title="enum GstRecoverPolicy">GstRecoverPolicy</a></td>
-</tr>
-<tr>
-<td class="datatype_keyword">enum</td>
-<td class="function_name"><a class="link" href="gst-plugins-base-plugins-multifdsink.html#GstSyncMethod" title="enum GstSyncMethod">GstSyncMethod</a></td>
-</tr>
-<tr>
-<td class="datatype_keyword">enum</td>
-<td class="function_name"><a class="link" href="gst-plugins-base-plugins-multifdsink.html#GstClientStatus" title="enum GstClientStatus">GstClientStatus</a></td>
-</tr>
-</tbody>
+</tr></tbody>
 </table></div>
 </div>
 <div class="refsect1">
@@ -215,7 +201,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.21.8.12.1"></a><h3>Element Information</h3>
+<a name="id-1.2.22.8.12.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -241,7 +227,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.21.8.12.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.22.8.12.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -280,182 +266,6 @@
 <pre class="programlisting">struct GstMultiSocketSink;</pre>
 <p>The multisocketsink object structure.</p>
 </div>
-<hr>
-<div class="refsect2">
-<a name="GstRecoverPolicy"></a><h3>enum GstRecoverPolicy</h3>
-<p>Possible values for the recovery procedure to use when a client consumes
-data too slow and has a backlag of more that soft-limit buffers.</p>
-<div class="refsect3">
-<a name="GstRecoverPolicy.members"></a><h4>Members</h4>
-<div class="informaltable"><table class="informaltable" width="100%" border="0">
-<colgroup>
-<col width="300px" class="enum_members_name">
-<col class="enum_members_description">
-<col width="200px" class="enum_members_annotations">
-</colgroup>
-<tbody>
-<tr>
-<td class="enum_member_name"><p><a name="GST-RECOVER-POLICY-NONE:CAPS"></a>GST_RECOVER_POLICY_NONE</p></td>
-<td class="enum_member_description">
-<p>no recovering is done</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-RECOVER-POLICY-RESYNC-LATEST:CAPS"></a>GST_RECOVER_POLICY_RESYNC_LATEST</p></td>
-<td class="enum_member_description">
-<p>client is moved to last buffer</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-RECOVER-POLICY-RESYNC-SOFT-LIMIT:CAPS"></a>GST_RECOVER_POLICY_RESYNC_SOFT_LIMIT</p></td>
-<td class="enum_member_description">
-<p>client is moved to the soft limit</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-RECOVER-POLICY-RESYNC-KEYFRAME:CAPS"></a>GST_RECOVER_POLICY_RESYNC_KEYFRAME</p></td>
-<td class="enum_member_description">
-<p>client is moved to latest keyframe</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-</tbody>
-</table></div>
-</div>
-</div>
-<hr>
-<div class="refsect2">
-<a name="GstSyncMethod"></a><h3>enum GstSyncMethod</h3>
-<p>This enum defines the selection of the first buffer that is sent
-to a new client.</p>
-<div class="refsect3">
-<a name="GstSyncMethod.members"></a><h4>Members</h4>
-<div class="informaltable"><table class="informaltable" width="100%" border="0">
-<colgroup>
-<col width="300px" class="enum_members_name">
-<col class="enum_members_description">
-<col width="200px" class="enum_members_annotations">
-</colgroup>
-<tbody>
-<tr>
-<td class="enum_member_name"><p><a name="GST-SYNC-METHOD-LATEST:CAPS"></a>GST_SYNC_METHOD_LATEST</p></td>
-<td class="enum_member_description">
-<p>client receives most recent buffer</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-SYNC-METHOD-NEXT-KEYFRAME:CAPS"></a>GST_SYNC_METHOD_NEXT_KEYFRAME</p></td>
-<td class="enum_member_description">
-<p>client receives next keyframe</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-SYNC-METHOD-LATEST-KEYFRAME:CAPS"></a>GST_SYNC_METHOD_LATEST_KEYFRAME</p></td>
-<td class="enum_member_description">
-<p>client receives latest keyframe (burst)</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-SYNC-METHOD-BURST:CAPS"></a>GST_SYNC_METHOD_BURST</p></td>
-<td class="enum_member_description">
-<p>client receives specific amount of data</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-SYNC-METHOD-BURST-KEYFRAME:CAPS"></a>GST_SYNC_METHOD_BURST_KEYFRAME</p></td>
-<td class="enum_member_description">
-<p>client receives specific amount of data 
-                                       starting from latest keyframe</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-SYNC-METHOD-BURST-WITH-KEYFRAME:CAPS"></a>GST_SYNC_METHOD_BURST_WITH_KEYFRAME</p></td>
-<td class="enum_member_description">
-<p>client receives specific amount of data from
-                                       a keyframe, or if there is not enough data after
-                                       the keyframe, starting before the keyframe</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-</tbody>
-</table></div>
-</div>
-</div>
-<hr>
-<div class="refsect2">
-<a name="GstClientStatus"></a><h3>enum GstClientStatus</h3>
-<p>This specifies the reason why a client was removed from
-multisocketsink and is received in the "client-removed" signal.</p>
-<div class="refsect3">
-<a name="GstClientStatus.members"></a><h4>Members</h4>
-<div class="informaltable"><table class="informaltable" width="100%" border="0">
-<colgroup>
-<col width="300px" class="enum_members_name">
-<col class="enum_members_description">
-<col width="200px" class="enum_members_annotations">
-</colgroup>
-<tbody>
-<tr>
-<td class="enum_member_name"><p><a name="GST-CLIENT-STATUS-OK:CAPS"></a>GST_CLIENT_STATUS_OK</p></td>
-<td class="enum_member_description">
-<p>client is ok</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-CLIENT-STATUS-CLOSED:CAPS"></a>GST_CLIENT_STATUS_CLOSED</p></td>
-<td class="enum_member_description">
-<p>client closed the socket</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-CLIENT-STATUS-REMOVED:CAPS"></a>GST_CLIENT_STATUS_REMOVED</p></td>
-<td class="enum_member_description">
-<p>client is removed</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-CLIENT-STATUS-SLOW:CAPS"></a>GST_CLIENT_STATUS_SLOW</p></td>
-<td class="enum_member_description">
-<p>client is too slow</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-CLIENT-STATUS-ERROR:CAPS"></a>GST_CLIENT_STATUS_ERROR</p></td>
-<td class="enum_member_description">
-<p>client is in error</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-CLIENT-STATUS-DUPLICATE:CAPS"></a>GST_CLIENT_STATUS_DUPLICATE</p></td>
-<td class="enum_member_description">
-<p>same client added twice</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-CLIENT-STATUS-FLUSHING:CAPS"></a>GST_CLIENT_STATUS_FLUSHING</p></td>
-<td class="enum_member_description">
-<p>client is flushing out the remaining buffers.</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-</tbody>
-</table></div>
-</div>
-</div>
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-multisocketsink.property-details"></a><h2>Property Details</h2>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-oggaviparse.html b/docs/plugins/html/gst-plugins-base-plugins-oggaviparse.html
index 36e78a5..68b0ae7 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-oggaviparse.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-oggaviparse.html
@@ -36,7 +36,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.22.3.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.23.3.2.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -62,7 +62,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.22.3.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.23.3.2.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-oggdemux.html b/docs/plugins/html/gst-plugins-base-plugins-oggdemux.html
index 8fa9023..2f5f585 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-oggdemux.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-oggdemux.html
@@ -56,10 +56,25 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-oggdemux.description"></a><h2>Description</h2>
+<p>This element demuxes ogg files into their encoded audio and video components.</p>
+<div class="refsect2">
+<a name="id-1.2.24.6.3"></a><h3>Example pipelines</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v filesrc location<span class="gtkdoc opt">=</span>test<span class="gtkdoc opt">.</span>ogg <span class="gtkdoc opt">!</span> oggdemux <span class="gtkdoc opt">!</span> vorbisdec <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> audioresample <span class="gtkdoc opt">!</span> autoaudiosink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Decodes a vorbis audio stream stored inside an ogg container and plays it.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.23.6.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.24.6.4.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -85,7 +100,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.23.6.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.24.6.4.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -158,8 +173,13 @@
 <div class="refsect2">
 <a name="GstOggDemux-struct"></a><h3>struct GstOggDemux</h3>
 <pre class="programlisting">struct GstOggDemux;</pre>
+<p>The ogg demuxer object structure.</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-oggdemux.see-also"></a><h2>See Also</h2>
+<a class="link" href="gst-plugins-base-plugins-oggmux.html" title="oggmux">oggmux</a>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-oggmux.html b/docs/plugins/html/gst-plugins-base-plugins-oggmux.html
index c8d2b57..b3c231d 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-oggmux.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-oggmux.html
@@ -96,10 +96,26 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-oggmux.description"></a><h2>Description</h2>
+<p>This element merges streams (audio and video) into ogg files.</p>
+<div class="refsect2">
+<a name="id-1.2.25.8.3"></a><h3>Example pipelines</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> v4l2src num<span class="gtkdoc opt">-</span>buffers<span class="gtkdoc opt">=</span><span class="number">500</span> <span class="gtkdoc opt">!</span> video<span class="gtkdoc opt">/</span>x<span class="gtkdoc opt">-</span>raw<span class="gtkdoc opt">,</span>width<span class="gtkdoc opt">=</span><span class="number">320</span><span class="gtkdoc opt">,</span>height<span class="gtkdoc opt">=</span><span class="number">240</span> <span class="gtkdoc opt">!</span> videoconvert <span class="gtkdoc opt">!</span> videorate <span class="gtkdoc opt">!</span> theoraenc <span class="gtkdoc opt">!</span> oggmux <span class="gtkdoc opt">!</span> filesink location<span class="gtkdoc opt">=</span>video<span class="gtkdoc opt">.</span>ogg</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Encodes a video stream captured from a v4l2-compatible camera to Ogg/Theora
+(the encoding will stop automatically after 500 frames)
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.24.8.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.25.8.4.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -125,7 +141,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.24.8.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.25.8.4.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -290,6 +306,7 @@
 <div class="refsect2">
 <a name="GstOggMux-struct"></a><h3>struct GstOggMux</h3>
 <pre class="programlisting">struct GstOggMux;</pre>
+<p>The ogg muxer object structure.</p>
 </div>
 </div>
 <div class="refsect1">
@@ -326,6 +343,10 @@
 <p>Default value: FALSE</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-oggmux.see-also"></a><h2>See Also</h2>
+<a class="link" href="gst-plugins-base-plugins-oggdemux.html" title="oggdemux">oggdemux</a>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-oggparse.html b/docs/plugins/html/gst-plugins-base-plugins-oggparse.html
index 33b1d44..d4addca 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-oggparse.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-oggparse.html
@@ -36,7 +36,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.25.3.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.26.3.2.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -62,7 +62,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.25.3.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.26.3.2.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-ogmaudioparse.html b/docs/plugins/html/gst-plugins-base-plugins-ogmaudioparse.html
index cfb2807..1c44b82 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-ogmaudioparse.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-ogmaudioparse.html
@@ -36,7 +36,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.26.3.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.27.3.2.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -62,7 +62,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.26.3.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.27.3.2.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -107,27 +107,27 @@
 </tr>
 <tr>
 <td><p><span class="term">details</span></p></td>
-<td>audio/ms-gsm, rate=(int)[ 1, 96000 ], channels=(int)[ 1, 2 ]</td>
+<td>audio/ms-gsm</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/mpeg, mpegversion=(int)1, layer=(int)3, rate=(int)[ 8000, 48000 ], channels=(int)[ 1, 2 ]</td>
+<td> audio/mpeg, mpegversion=(int)1, layer=(int)3</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/mpeg, mpegversion=(int)1, layer=(int)2, rate=(int)[ 16000, 48000 ], channels=(int)[ 1, 2 ]</td>
+<td> audio/mpeg, mpegversion=(int)1, layer=(int)2</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-raw, format=(string){ S8, U8, S16LE, U16LE, S24LE, U24LE, S32LE, U32LE }, layout=(string)interleaved, rate=(int)[ 1000, 192000 ], channels=(int)[ 1, 8 ]</td>
+<td> audio/x-raw, format=(string){ S8, U8, S16LE, U16LE, S24LE, U24LE, S32LE, U32LE }, layout=(string)interleaved</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-vorbis, rate=(int)[ 1000, 192000 ], channels=(int)[ 1, 2 ]</td>
+<td> audio/x-vorbis</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-ac3, rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 6 ]</td>
+<td> audio/x-ac3</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
@@ -135,75 +135,75 @@
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/mpeg, mpegversion=(int)4, rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 8 ]</td>
+<td> audio/mpeg, mpegversion=(int)4</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-alaw, rate=(int)[ 1000, 48000 ], channels=(int)[ 1, 2 ]</td>
+<td> audio/x-alaw</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-mulaw, rate=(int)[ 1000, 48000 ], channels=(int)[ 1, 2 ]</td>
+<td> audio/x-mulaw</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-wms, bitrate=(int)[ 0, 2147483647 ], rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 2 ], block_align=(int)[ 1, 2147483647 ]</td>
+<td> audio/x-wms, bitrate=(int)[ 0, 2147483647 ], block_align=(int)[ 1, 2147483647 ]</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-adpcm, layout=(string)microsoft, rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 2 ], block_align=(int)[ 1, 2147483647 ]</td>
+<td> audio/x-adpcm, layout=(string)microsoft, block_align=(int)[ 1, 2147483647 ]</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-adpcm, layout=(string)dvi, rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 2 ], block_align=(int)[ 1, 2147483647 ]</td>
+<td> audio/x-adpcm, layout=(string)dvi, block_align=(int)[ 1, 2147483647 ]</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-truespeech, rate=(int)8000, channels=(int)[ 1, 2 ]</td>
+<td> audio/x-truespeech</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-wma, wmaversion=(int)1, bitrate=(int)[ 0, 2147483647 ], rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 8 ], block_align=(int)[ 1, 2147483647 ]</td>
+<td> audio/x-wma, wmaversion=(int)1, bitrate=(int)[ 0, 2147483647 ], block_align=(int)[ 1, 2147483647 ]</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-wma, wmaversion=(int)2, bitrate=(int)[ 0, 2147483647 ], rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 8 ], block_align=(int)[ 1, 2147483647 ]</td>
+<td> audio/x-wma, wmaversion=(int)2, bitrate=(int)[ 0, 2147483647 ], block_align=(int)[ 1, 2147483647 ]</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-wma, wmaversion=(int)3, bitrate=(int)[ 0, 2147483647 ], rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 8 ], block_align=(int)[ 1, 2147483647 ]</td>
+<td> audio/x-wma, wmaversion=(int)3, bitrate=(int)[ 0, 2147483647 ], block_align=(int)[ 1, 2147483647 ]</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-vnd.sony.atrac3, rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 2 ]</td>
+<td> audio/x-vnd.sony.atrac3</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-raw, format=(string){ F32LE, F64LE }, layout=(string)interleaved, rate=(int)[ 1000, 192000 ], channels=(int)[ 1, 8 ]</td>
+<td> audio/x-raw, format=(string){ F32LE, F64LE }, layout=(string)interleaved</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-voxware, voxwaretype=(int)117, rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 2 ]</td>
+<td> audio/x-voxware, voxwaretype=(int)117</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-adpcm, layout=(string)dk4, rate=(int)[ 8000, 96000 ], channels=(int)[ 1, 2 ]</td>
+<td> audio/x-adpcm, layout=(string)dk4</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-adpcm, layout=(string)dk3, rate=(int)[ 8000, 96000 ], channels=(int)[ 1, 2 ]</td>
+<td> audio/x-adpcm, layout=(string)dk3</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/x-adpcm, layout=(string)dvi, rate=(int)[ 8000, 96000 ], channels=(int)[ 1, 2 ]</td>
+<td> audio/x-adpcm, layout=(string)dvi</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/AMR, rate=(int)8000, channels=(int)1</td>
+<td> audio/AMR</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> audio/AMR-WB, rate=(int)16000, channels=(int)1</td>
+<td> audio/AMR-WB</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-ogmtextparse.html b/docs/plugins/html/gst-plugins-base-plugins-ogmtextparse.html
index dcae3ce..79b35eb 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-ogmtextparse.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-ogmtextparse.html
@@ -36,7 +36,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.27.3.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.28.3.2.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -62,7 +62,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.27.3.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.28.3.2.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-ogmvideoparse.html b/docs/plugins/html/gst-plugins-base-plugins-ogmvideoparse.html
index 7595030..834bff0 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-ogmvideoparse.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-ogmvideoparse.html
@@ -36,7 +36,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.28.3.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.29.3.2.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -62,7 +62,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.28.3.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.29.3.2.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-opusdec.html b/docs/plugins/html/gst-plugins-base-plugins-opusdec.html
index eebfa19..8ca5684 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-opusdec.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-opusdec.html
@@ -80,10 +80,25 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-opusdec.description"></a><h2>Description</h2>
+<p>This element decodes a OPUS stream to raw integer audio.</p>
+<div class="refsect2">
+<a name="id-1.2.30.7.3"></a><h3>Example pipelines</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v filesrc location<span class="gtkdoc opt">=</span>opus<span class="gtkdoc opt">.</span>ogg <span class="gtkdoc opt">!</span> oggdemux <span class="gtkdoc opt">!</span> opusdec <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> audioresample <span class="gtkdoc opt">!</span> alsasink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Decode an Ogg/Opus file. To create an Ogg/Opus file refer to the documentation of opusenc.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.29.7.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.30.7.4.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -109,7 +124,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.29.7.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.30.7.4.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -194,6 +209,10 @@
 <p>Default value: FALSE</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-opusdec.see-also"></a><h2>See Also</h2>
+<p>opusenc, oggdemux</p>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-opusenc.html b/docs/plugins/html/gst-plugins-base-plugins-opusenc.html
index 877f44d..857a9e3 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-opusenc.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-opusenc.html
@@ -7,7 +7,7 @@
 <link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Plugins Reference Manual">
 <link rel="up" href="ch01.html" title="gst-plugins-base Elements">
 <link rel="prev" href="gst-plugins-base-plugins-opusdec.html" title="opusdec">
-<link rel="next" href="gst-plugins-base-plugins-playbin.html" title="playbin">
+<link rel="next" href="gst-plugins-base-plugins-parsebin.html" title="parsebin">
 <meta name="generator" content="GTK-Doc V1.25 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
@@ -16,13 +16,14 @@
 <td width="100%" align="left" class="shortcuts">
 <a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
                   <a href="#gst-plugins-base-plugins-opusenc.description" class="shortcut">Description</a></span><span id="nav_hierarchy">  <span class="dim">|</span> 
-                  <a href="#gst-plugins-base-plugins-opusenc.object-hierarchy" class="shortcut">Object Hierarchy</a></span><span id="nav_properties">  <span class="dim">|</span> 
+                  <a href="#gst-plugins-base-plugins-opusenc.object-hierarchy" class="shortcut">Object Hierarchy</a></span><span id="nav_interfaces">  <span class="dim">|</span> 
+                  <a href="#gst-plugins-base-plugins-opusenc.implemented-interfaces" class="shortcut">Implemented Interfaces</a></span><span id="nav_properties">  <span class="dim">|</span> 
                   <a href="#gst-plugins-base-plugins-opusenc.properties" class="shortcut">Properties</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="ch01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="gst-plugins-base-plugins-opusdec.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="gst-plugins-base-plugins-playbin.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="n" href="gst-plugins-base-plugins-parsebin.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
 <a name="gst-plugins-base-plugins-opusenc"></a><div class="titlepage"></div>
@@ -63,7 +64,7 @@
 <td class="property_flags">Read / Write</td>
 </tr>
 <tr>
-<td class="property_type"><span class="type">GstOpusEncBitrateType</span></td>
+<td class="property_type"><a class="link" href="gst-plugins-base-plugins-opusenc.html#GstOpusEncBitrateType" title="enum GstOpusEncBitrateType"><span class="type">GstOpusEncBitrateType</span></a></td>
 <td class="property_name"><a class="link" href="gst-plugins-base-plugins-opusenc.html#GstOpusEnc--bitrate-type" title="The “bitrate-type” property">bitrate-type</a></td>
 <td class="property_flags">Read / Write</td>
 </tr>
@@ -110,17 +111,23 @@
 </tbody>
 </table></div>
 </div>
-<a name="GstOpusDec"></a><a name="GstOpusEnc"></a><div class="refsect1">
+<a name="GstOpusEnc"></a><div class="refsect1">
 <a name="gst-plugins-base-plugins-opusenc.other"></a><h2>Types and Values</h2>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
 <colgroup>
 <col width="150px" class="name">
 <col class="description">
 </colgroup>
-<tbody><tr>
+<tbody>
+<tr>
 <td class="datatype_keyword">struct</td>
 <td class="function_name"><a class="link" href="gst-plugins-base-plugins-opusenc.html#GstOpusEnc-struct" title="struct GstOpusEnc">GstOpusEnc</a></td>
-</tr></tbody>
+</tr>
+<tr>
+<td class="datatype_keyword">enum</td>
+<td class="function_name"><a class="link" href="gst-plugins-base-plugins-opusenc.html#GstOpusEncBitrateType" title="enum GstOpusEncBitrateType">GstOpusEncBitrateType</a></td>
+</tr>
+</tbody>
 </table></div>
 </div>
 <div class="refsect1">
@@ -134,11 +141,32 @@
 </pre>
 </div>
 <div class="refsect1">
+<a name="gst-plugins-base-plugins-opusenc.implemented-interfaces"></a><h2>Implemented Interfaces</h2>
+<p>
+GstOpusEnc implements
+ <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstPreset.html#GstPreset-struct">GstPreset</a> and  <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstTagSetter.html#GstTagSetter-struct">GstTagSetter</a>.</p>
+</div>
+<div class="refsect1">
 <a name="gst-plugins-base-plugins-opusenc.description"></a><h2>Description</h2>
+<p>This element encodes raw audio to OPUS.</p>
+<div class="refsect2">
+<a name="id-1.2.31.8.3"></a><h3>Example pipelines</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v audiotestsrc wave<span class="gtkdoc opt">=</span>sine num<span class="gtkdoc opt">-</span>buffers<span class="gtkdoc opt">=</span><span class="number">100</span> <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> opusenc <span class="gtkdoc opt">!</span> oggmux <span class="gtkdoc opt">!</span> filesink location<span class="gtkdoc opt">=</span>sine<span class="gtkdoc opt">.</span>ogg</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Encode a test sine signal to Ogg/OPUS.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.30.8.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.31.8.4.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -164,7 +192,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.30.8.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.31.8.4.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -230,6 +258,37 @@
 <a name="GstOpusEnc-struct"></a><h3>struct GstOpusEnc</h3>
 <pre class="programlisting">struct GstOpusEnc;</pre>
 </div>
+<hr>
+<div class="refsect2">
+<a name="GstOpusEncBitrateType"></a><h3>enum GstOpusEncBitrateType</h3>
+<div class="refsect3">
+<a name="GstOpusEncBitrateType.members"></a><h4>Members</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="300px" class="enum_members_name">
+<col class="enum_members_description">
+<col width="200px" class="enum_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="enum_member_name"><p><a name="BITRATE-TYPE-CBR:CAPS"></a>BITRATE_TYPE_CBR</p></td>
+<td> </td>
+<td> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="BITRATE-TYPE-VBR:CAPS"></a>BITRATE_TYPE_VBR</p></td>
+<td> </td>
+<td> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="BITRATE-TYPE-CONSTRAINED-VBR:CAPS"></a>BITRATE_TYPE_CONSTRAINED_VBR</p></td>
+<td> </td>
+<td> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-opusenc.property-details"></a><h2>Property Details</h2>
@@ -268,7 +327,7 @@
 <hr>
 <div class="refsect2">
 <a name="GstOpusEnc--bitrate-type"></a><h3>The <code class="literal">“bitrate-type”</code> property</h3>
-<pre class="programlisting">  “bitrate-type”             <span class="type">GstOpusEncBitrateType</span></pre>
+<pre class="programlisting">  “bitrate-type”             <a class="link" href="gst-plugins-base-plugins-opusenc.html#GstOpusEncBitrateType" title="enum GstOpusEncBitrateType"><span class="type">GstOpusEncBitrateType</span></a></pre>
 <p>Bitrate type.</p>
 <p>Flags: Read / Write</p>
 <p>Default value: CBR</p>
@@ -341,6 +400,10 @@
 <p>Default value: 0</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-opusenc.see-also"></a><h2>See Also</h2>
+<p>opusdec, oggmux</p>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-parsebin.html b/docs/plugins/html/gst-plugins-base-plugins-parsebin.html
new file mode 100644
index 0000000..b36cea6
--- /dev/null
+++ b/docs/plugins/html/gst-plugins-base-plugins-parsebin.html
@@ -0,0 +1,137 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>parsebin: GStreamer Base Plugins 1.0 Plugins Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
+<link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Plugins Reference Manual">
+<link rel="up" href="ch01.html" title="gst-plugins-base Elements">
+<link rel="prev" href="gst-plugins-base-plugins-opusenc.html" title="opusenc">
+<link rel="next" href="gst-plugins-base-plugins-playbin.html" title="playbin">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
+                  <a href="#gst-plugins-base-plugins-parsebin.description" class="shortcut">Description</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="gst-plugins-base-plugins-opusenc.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="gst-plugins-base-plugins-playbin.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="gst-plugins-base-plugins-parsebin"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="gst-plugins-base-plugins-parsebin.top_of_page"></a>parsebin</span></h2>
+<p>parsebin</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-parsebin.description"></a><h2>Description</h2>
+<p><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstBin.html#GstBin-struct"><span class="type">GstBin</span></a> that auto-magically constructs a parsing pipeline
+using available parsers and demuxers via auto-plugging.</p>
+<p>parsebin unpacks the contents of the input stream to the
+level of parsed elementary streams, but unlike decodebin
+it doesn't connect decoder elements. The output pads
+produce packetised encoded data with timestamps where possible,
+or send missing-element messages where not.</p>
+<p><span class="emphasis"><em>parsebin is still experimental API and a technology preview.
+Its behaviour and exposed API is subject to change.</em></span></p>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="refsect2">
+<a name="id-1.2.32.3.5.1"></a><h3>Element Information</h3>
+<div class="variablelist"><table border="0" class="variablelist">
+<colgroup>
+<col align="left" valign="top">
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td><p><span class="term">plugin</span></p></td>
+<td>
+            <a class="link" href="gst-plugins-base-plugins-plugin-playback.html#plugin-playback">playback</a>
+          </td>
+</tr>
+<tr>
+<td><p><span class="term">author</span></p></td>
+<td>Jan Schmidt &lt;jan@centricular.com&gt;, Edward Hervey &lt;edward@centricular.com&gt;</td>
+</tr>
+<tr>
+<td><p><span class="term">class</span></p></td>
+<td>Generic/Bin/Parser</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.32.3.5.2"></a><h3>Element Pads</h3>
+<div class="variablelist"><table border="0" class="variablelist">
+<colgroup>
+<col align="left" valign="top">
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td><p><span class="term">name</span></p></td>
+<td>sink</td>
+</tr>
+<tr>
+<td><p><span class="term">direction</span></p></td>
+<td>sink</td>
+</tr>
+<tr>
+<td><p><span class="term">presence</span></p></td>
+<td>always</td>
+</tr>
+<tr>
+<td><p><span class="term">details</span></p></td>
+<td>ANY</td>
+</tr>
+</tbody>
+</table></div>
+<div class="variablelist"><table border="0" class="variablelist">
+<colgroup>
+<col align="left" valign="top">
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td><p><span class="term">name</span></p></td>
+<td>src_%u</td>
+</tr>
+<tr>
+<td><p><span class="term">direction</span></p></td>
+<td>source</td>
+</tr>
+<tr>
+<td><p><span class="term">presence</span></p></td>
+<td>sometimes</td>
+</tr>
+<tr>
+<td><p><span class="term">details</span></p></td>
+<td>ANY</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-parsebin.functions_details"></a><h2>Functions</h2>
+<p></p>
+</div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-parsebin.other_details"></a><h2>Types and Values</h2>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/plugins/html/gst-plugins-base-plugins-playbin.html b/docs/plugins/html/gst-plugins-base-plugins-playbin.html
index 2406333..e91875f 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-playbin.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-playbin.html
@@ -6,8 +6,8 @@
 <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
 <link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Plugins Reference Manual">
 <link rel="up" href="ch01.html" title="gst-plugins-base Elements">
-<link rel="prev" href="gst-plugins-base-plugins-opusenc.html" title="opusenc">
-<link rel="next" href="gst-plugins-base-plugins-playsink.html" title="playsink">
+<link rel="prev" href="gst-plugins-base-plugins-parsebin.html" title="parsebin">
+<link rel="next" href="gst-plugins-base-plugins-playbin3.html" title="playbin3">
 <meta name="generator" content="GTK-Doc V1.25 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
@@ -23,8 +23,8 @@
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="ch01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="gst-plugins-base-plugins-opusenc.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="gst-plugins-base-plugins-playsink.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="p" href="gst-plugins-base-plugins-parsebin.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="gst-plugins-base-plugins-playbin3.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
 <a name="gst-plugins-base-plugins-playbin"></a><div class="titlepage"></div>
@@ -104,7 +104,7 @@
 <td class="property_flags">Read / Write</td>
 </tr>
 <tr>
-<td class="property_type"><a class="link" href="gst-plugins-base-plugins-playbin.html#GstPlayFlags" title="enum GstPlayFlags"><span class="type">GstPlayFlags</span></a></td>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-playbin.html#GstPlayFlags"><span class="type">GstPlayFlags</span></a></td>
 <td class="property_name"><a class="link" href="gst-plugins-base-plugins-playbin.html#GstPlayBin--flags" title="The “flags” property">flags</a></td>
 <td class="property_flags">Read / Write</td>
 </tr>
@@ -325,6 +325,11 @@
 <td class="signal_name"><a class="link" href="gst-plugins-base-plugins-playbin.html#GstPlayBin-video-tags-changed" title="The “video-tags-changed” signal">video-tags-changed</a></td>
 <td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-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-base-plugins-playbin.html#GstPlayBin-element-setup" title="The “element-setup” signal">element-setup</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -335,16 +340,10 @@
 <col width="150px" class="name">
 <col class="description">
 </colgroup>
-<tbody>
-<tr>
+<tbody><tr>
 <td class="datatype_keyword">struct</td>
 <td class="function_name"><a class="link" href="gst-plugins-base-plugins-playbin.html#GstPlayBin-struct" title="struct GstPlayBin">GstPlayBin</a></td>
-</tr>
-<tr>
-<td class="datatype_keyword">enum</td>
-<td class="function_name"><a class="link" href="gst-plugins-base-plugins-playbin.html#GstPlayFlags" title="enum GstPlayFlags">GstPlayFlags</a></td>
-</tr>
-</tbody>
+</tr></tbody>
 </table></div>
 </div>
 <div class="refsect1">
@@ -398,7 +397,7 @@
 </li>
 </ul></div>
 <div class="refsect2">
-<a name="id-1.2.31.9.5"></a><h3>Usage</h3>
+<a name="id-1.2.33.9.5"></a><h3>Usage</h3>
 <p>
 A playbin element can be created just like any other element using
 <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstElementFactory.html#gst-element-factory-make"><code class="function">gst_element_factory_make()</code></a>. The file/URI to play should be set via the <a class="link" href="gst-plugins-base-plugins-playbin.html#GstPlayBin--uri" title="The “uri” property"><span class="type">“uri”</span></a>
@@ -439,7 +438,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.31.9.6"></a><h3>Advanced Usage: specifying the audio and video sink</h3>
+<a name="id-1.2.33.9.6"></a><h3>Advanced Usage: specifying the audio and video sink</h3>
 <p>
 By default, if no audio sink or video sink has been specified via the
 <a class="link" href="gst-plugins-base-plugins-playbin.html#GstPlayBin--audio-sink" title="The “audio-sink” property"><span class="type">“audio-sink”</span></a> or <a class="link" href="gst-plugins-base-plugins-playbin.html#GstPlayBin--video-sink" title="The “video-sink” property"><span class="type">“video-sink”</span></a> property, playbin will use the autoaudiosink
@@ -474,7 +473,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.31.9.7"></a><h3>Retrieving Tags and Other Meta Data</h3>
+<a name="id-1.2.33.9.7"></a><h3>Retrieving Tags and Other Meta Data</h3>
 <p>
 Most of the common meta data (artist, title, etc.) can be retrieved by
 watching for TAG messages on the pipeline's bus (see above).
@@ -486,7 +485,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.31.9.8"></a><h3>Buffering</h3>
+<a name="id-1.2.33.9.8"></a><h3>Buffering</h3>
 Playbin handles buffering automatically for the most part, but applications
 need to handle parts of the buffering process as well. Whenever playbin is
 buffering, it will post BUFFERING messages on the bus with a percentage
@@ -528,7 +527,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.31.9.9"></a><h3>Embedding the video window in your application</h3>
+<a name="id-1.2.33.9.9"></a><h3>Embedding the video window in your application</h3>
 By default, playbin (or rather the video sinks used) will create their own
 window. Applications will usually want to force output to a window of their
 own, however. This can be done using the <a href="../html/gst-plugins-base-libs-gstvideooverlay.html#GstVideoOverlay-struct"><span class="type">GstVideoOverlay</span></a> interface, which most
@@ -536,7 +535,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.31.9.10"></a><h3>Specifying which CD/DVD device to use</h3>
+<a name="id-1.2.33.9.10"></a><h3>Specifying which CD/DVD device to use</h3>
 The device to use for CDs/DVDs needs to be set on the source element
 playbin creates before it is opened. The most generic way of doing this
 is to connect to playbin's "source-setup" (or "notify::source") signal,
@@ -550,7 +549,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.31.9.11"></a><h3>Handling redirects</h3>
+<a name="id-1.2.33.9.11"></a><h3>Handling redirects</h3>
 <p>
 Some elements may post 'redirect' messages on the bus to tell the
 application to open another location. These are element messages containing
@@ -561,7 +560,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.31.9.12"></a><h3>Examples</h3>
+<a name="id-1.2.33.9.12"></a><h3>Examples</h3>
 <div class="informalexample">
   <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
     <tbody>
@@ -605,7 +604,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.31.9.13.1"></a><h3>Element Information</h3>
+<a name="id-1.2.33.9.13.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -631,7 +630,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.31.9.13.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.33.9.13.2"></a><h3>Element Pads</h3>
 </div>
 </div>
 </div>
@@ -646,112 +645,6 @@
 <pre class="programlisting">struct GstPlayBin;</pre>
 <p>playbin element structure</p>
 </div>
-<hr>
-<div class="refsect2">
-<a name="GstPlayFlags"></a><h3>enum GstPlayFlags</h3>
-<p>Extra flags to configure the behaviour of the sinks.</p>
-<div class="refsect3">
-<a name="GstPlayFlags.members"></a><h4>Members</h4>
-<div class="informaltable"><table class="informaltable" width="100%" border="0">
-<colgroup>
-<col width="300px" class="enum_members_name">
-<col class="enum_members_description">
-<col width="200px" class="enum_members_annotations">
-</colgroup>
-<tbody>
-<tr>
-<td class="enum_member_name"><p><a name="GST-PLAY-FLAG-VIDEO:CAPS"></a>GST_PLAY_FLAG_VIDEO</p></td>
-<td class="enum_member_description">
-<p>Enable rendering of the video stream</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-PLAY-FLAG-AUDIO:CAPS"></a>GST_PLAY_FLAG_AUDIO</p></td>
-<td class="enum_member_description">
-<p>Enable rendering of the audio stream</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-PLAY-FLAG-TEXT:CAPS"></a>GST_PLAY_FLAG_TEXT</p></td>
-<td class="enum_member_description">
-<p>Enable rendering of subtitles</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-PLAY-FLAG-VIS:CAPS"></a>GST_PLAY_FLAG_VIS</p></td>
-<td class="enum_member_description">
-<p>Enable rendering of visualisations when there is
-      no video stream.</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-PLAY-FLAG-SOFT-VOLUME:CAPS"></a>GST_PLAY_FLAG_SOFT_VOLUME</p></td>
-<td class="enum_member_description">
-<p>Use software volume</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-PLAY-FLAG-NATIVE-AUDIO:CAPS"></a>GST_PLAY_FLAG_NATIVE_AUDIO</p></td>
-<td class="enum_member_description">
-<p>only allow native audio formats, this omits
-  configuration of audioconvert and audioresample.</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-PLAY-FLAG-NATIVE-VIDEO:CAPS"></a>GST_PLAY_FLAG_NATIVE_VIDEO</p></td>
-<td class="enum_member_description">
-<p>only allow native video formats, this omits
-  configuration of videoconvert and videoscale.</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-PLAY-FLAG-DOWNLOAD:CAPS"></a>GST_PLAY_FLAG_DOWNLOAD</p></td>
-<td class="enum_member_description">
-<p>enable progressice download buffering for selected
-  formats.</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-PLAY-FLAG-BUFFERING:CAPS"></a>GST_PLAY_FLAG_BUFFERING</p></td>
-<td class="enum_member_description">
-<p>enable buffering of the demuxed or parsed data.</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-PLAY-FLAG-DEINTERLACE:CAPS"></a>GST_PLAY_FLAG_DEINTERLACE</p></td>
-<td class="enum_member_description">
-<p>deinterlace raw video (if native not forced).</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-PLAY-FLAG-SOFT-COLORBALANCE:CAPS"></a>GST_PLAY_FLAG_SOFT_COLORBALANCE</p></td>
-<td class="enum_member_description">
-<p>Use a software filter for colour balance</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-PLAY-FLAG-FORCE-FILTERS:CAPS"></a>GST_PLAY_FLAG_FORCE_FILTERS</p></td>
-<td class="enum_member_description">
-<p>force audio/video filters to be applied if
-  set.</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-</tbody>
-</table></div>
-</div>
-</div>
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-playbin.property-details"></a><h2>Property Details</h2>
@@ -855,7 +748,7 @@
 <hr>
 <div class="refsect2">
 <a name="GstPlayBin--flags"></a><h3>The <code class="literal">“flags”</code> property</h3>
-<pre class="programlisting">  “flags”                    <a class="link" href="gst-plugins-base-plugins-playbin.html#GstPlayFlags" title="enum GstPlayFlags"><span class="type">GstPlayFlags</span></a></pre>
+<pre class="programlisting">  “flags”                    <a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-playbin.html#GstPlayFlags"><span class="type">GstPlayFlags</span></a></pre>
 <p>Control the behaviour of playbin.</p>
 <p>Flags: Read / Write</p>
 <p>Default value: Render the video stream|Render the audio stream|Render subtitles|Use software volume|Deinterlace video if necessary|Use software color balance</p>
@@ -1657,6 +1550,50 @@
 </div>
 <p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
 </div>
+<hr>
+<div class="refsect2">
+<a name="GstPlayBin-element-setup"></a><h3>The <code class="literal">“element-setup”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="gst-plugins-base-plugins-playbin.html#GstPlayBin"><span class="type">GstPlayBin</span></a> *playbin,
+               <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstElement.html#GstElement-struct"><span class="type">GstElement</span></a> *element,
+               <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a>    user_data)</pre>
+<p>This signal is emitted when a new element is added to playbin or any of
+its sub-bins. This signal can be used to configure elements, e.g. to set
+properties on decoders. This is functionally equivalent to connecting to
+the deep-element-added signal, but more convenient.</p>
+<p>This signal is usually emitted from the context of a GStreamer streaming
+thread, so might be called at the same time as code running in the main
+application thread.</p>
+<div class="refsect3">
+<a name="GstPlayBin-element-setup.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" 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>playbin</p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-base-plugins-playbin.html#GstPlayBin"><span class="type">GstPlayBin</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>element</p></td>
+<td class="parameter_description"><p>an element that was added to the playbin hierarchy</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="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+<p class="since">Since: 1.10</p>
+</div>
 </div>
 </div>
 <div class="footer">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-playbin3.html b/docs/plugins/html/gst-plugins-base-plugins-playbin3.html
new file mode 100644
index 0000000..7c2244e
--- /dev/null
+++ b/docs/plugins/html/gst-plugins-base-plugins-playbin3.html
@@ -0,0 +1,323 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>playbin3: GStreamer Base Plugins 1.0 Plugins Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
+<link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Plugins Reference Manual">
+<link rel="up" href="ch01.html" title="gst-plugins-base Elements">
+<link rel="prev" href="gst-plugins-base-plugins-playbin.html" title="playbin">
+<link rel="next" href="gst-plugins-base-plugins-playsink.html" title="playsink">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
+                  <a href="#gst-plugins-base-plugins-playbin3.description" class="shortcut">Description</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="gst-plugins-base-plugins-playbin.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="gst-plugins-base-plugins-playsink.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="gst-plugins-base-plugins-playbin3"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="gst-plugins-base-plugins-playbin3.top_of_page"></a>playbin3</span></h2>
+<p>playbin3</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-playbin3.description"></a><h2>Description</h2>
+<p>playbin3 provides a stand-alone everything-in-one abstraction for an
+audio and/or video player. It differs from the previous playbin (playbin2)
+by supporting publication and selection of available streams via the
+<span class="type">GstStreamCollection</span> message and <span class="type">GST_EVENT_SELECT_STREAMS</span> event API.</p>
+<p><span class="emphasis"><em>playbin3 is still experimental API and a technology preview.
+Its behaviour and exposed API is subject to change.</em></span></p>
+<p>playbin3 can handle both audio and video files and features</p>
+<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
+<li class="listitem">
+automatic file type recognition and based on that automatic
+selection and usage of the right audio/video/subtitle demuxers/decoders
+</li>
+<li class="listitem">
+auxilliary files - such as external subtitles and audio tracks
+</li>
+<li class="listitem">
+visualisations for audio files
+</li>
+<li class="listitem">
+subtitle support for video files. Subtitles can be store in external
+files.
+</li>
+<li class="listitem">
+stream selection between different video/audio/subtitles streams
+</li>
+<li class="listitem">
+meta info (tag) extraction
+</li>
+<li class="listitem">
+easy access to the last video sample
+</li>
+<li class="listitem">
+buffering when playing streams over a network
+</li>
+<li class="listitem">
+volume control with mute option
+</li>
+</ul></div>
+<div class="refsect2">
+<a name="id-1.2.34.3.6"></a><h3>Usage</h3>
+<p>
+A playbin element can be created just like any other element using
+<a href="/usr/share/gtk-doc/html/gstreamer-1.0GstElementFactory.html#gst-element-factory-make"><code class="function">gst_element_factory_make()</code></a>. The file/URI to play should be set via the <span class="type">“uri”</span>
+property. This must be an absolute URI, relative file paths are not allowed.
+Example URIs are file:///home/joe/movie.avi or http://www.joedoe.com/foo.ogg
+
+Playbin3 is a <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstPipeline.html#GstPipeline-struct"><span class="type">GstPipeline</span></a>. It will notify the application of everything
+that's happening (errors, end of stream, tags found, state changes, etc.)
+by posting messages on its <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstBus.html#GstBus-struct"><span class="type">GstBus</span></a>. The application needs to watch the
+bus.
+
+Playback can be initiated by setting the element to PLAYING state using
+<a href="/usr/share/gtk-doc/html/gstreamer-1.0GstElement.html#gst-element-set-state"><code class="function">gst_element_set_state()</code></a>. Note that the state change will take place in
+the background in a separate thread, when the function returns playback
+is probably not happening yet and any errors might not have occured yet.
+Applications using playbin3 should ideally be written to deal with things
+completely asynchroneous.
+
+When playback has finished (an EOS message has been received on the bus)
+or an error has occured (an ERROR message has been received on the bus) or
+the user wants to play a different track, playbin3 should be set back to
+READY or NULL state, then the <span class="type">“uri”</span> property should be set to the
+new location and then playbin3 be set to PLAYING state again.
+
+Seeking can be done using <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstElement.html#gst-element-seek-simple"><code class="function">gst_element_seek_simple()</code></a> or <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstElement.html#gst-element-seek"><code class="function">gst_element_seek()</code></a>
+on the playbin3 element. Again, the seek will not be executed
+instantaneously, but will be done in a background thread. When the seek
+call returns the seek will most likely still be in process. An application
+may wait for the seek to finish (or fail) using <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstElement.html#gst-element-get-state"><code class="function">gst_element_get_state()</code></a> with
+-1 as the timeout, but this will block the user interface and is not
+recommended at all.
+
+Applications may query the current position and duration of the stream
+via <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstElement.html#gst-element-query-position"><code class="function">gst_element_query_position()</code></a> and <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstElement.html#gst-element-query-duration"><code class="function">gst_element_query_duration()</code></a> and
+setting the format passed to GST_FORMAT_TIME. If the query was successful,
+the duration or position will have been returned in units of nanoseconds.
+</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.34.3.7"></a><h3>Advanced Usage: specifying the audio and video sink</h3>
+<p>
+By default, if no audio sink or video sink has been specified via the
+<span class="type">“audio-sink”</span> or <span class="type">“video-sink”</span> property, playbin3 will use the autoaudiosink
+and autovideosink elements to find the first-best available output method.
+This should work in most cases, but is not always desirable. Often either
+the user or application might want to specify more explicitly what to use
+for audio and video output.
+
+If the application wants more control over how audio or video should be
+output, it may create the audio/video sink elements itself (for example
+using <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstElementFactory.html#gst-element-factory-make"><code class="function">gst_element_factory_make()</code></a>) and provide them to playbin3 using the
+<span class="type">“audio-sink”</span> or <span class="type">“video-sink”</span> property.
+
+GNOME-based applications, for example, will usually want to create
+gconfaudiosink and gconfvideosink elements and make playbin3 use those,
+so that output happens to whatever the user has configured in the GNOME
+Multimedia System Selector configuration dialog.
+
+The sink elements do not necessarily need to be ready-made sinks. It is
+possible to create container elements that look like a sink to playbin3,
+but in reality contain a number of custom elements linked together. This
+can be achieved by creating a <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstBin.html#GstBin-struct"><span class="type">GstBin</span></a> and putting elements in there and
+linking them, and then creating a sink <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstGhostPad.html#GstGhostPad-struct"><span class="type">GstGhostPad</span></a> for the bin and pointing
+it to the sink pad of the first element within the bin. This can be used
+for a number of purposes, for example to force output to a particular
+format or to modify or observe the data before it is output.
+
+It is also possible to 'suppress' audio and/or video output by using
+'fakesink' elements (or capture it from there using the fakesink element's
+"handoff" signal, which, nota bene, is fired from the streaming thread!).
+</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.34.3.8"></a><h3>Retrieving Tags and Other Meta Data</h3>
+<p>
+Most of the common meta data (artist, title, etc.) can be retrieved by
+watching for TAG messages on the pipeline's bus (see above).
+
+Other more specific meta information like width/height/framerate of video
+streams or samplerate/number of channels of audio streams can be obtained
+from the negotiated caps on the sink pads of the sinks.
+</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.34.3.9"></a><h3>Buffering</h3>
+Playbin3 handles buffering automatically for the most part, but applications
+need to handle parts of the buffering process as well. Whenever playbin3 is
+buffering, it will post BUFFERING messages on the bus with a percentage
+value that shows the progress of the buffering process. Applications need
+to set playbin3 to PLAYING or PAUSED state in response to these messages.
+They may also want to convey the buffering progress to the user in some
+way. Here is how to extract the percentage information from the message:
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1
+2
+3
+4
+5
+6
+7
+8
+9</pre></td>
+        <td class="listing_code"><pre class="programlisting"><span class="keyword">switch</span> <span class="gtkdoc opt">(</span><span class="function"><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstMessage.html#GST-MESSAGE-TYPE:CAPS">GST_MESSAGE_TYPE</a></span> <span class="gtkdoc opt">(</span>msg<span class="gtkdoc opt">)) {</span>
+  <span class="keyword">case</span> GST_MESSAGE_BUFFERING<span class="gtkdoc opt">: {</span>
+    gint percent <span class="gtkdoc opt">=</span> <span class="number">0</span><span class="gtkdoc opt">;</span>
+    <span class="function"><a href="/usr/share/gtk-doc/html/gstreamer-1.0GstMessage.html#gst-message-parse-buffering">gst_message_parse_buffering</a></span> <span class="gtkdoc opt">(</span>msg<span class="gtkdoc opt">, &amp;</span>percent<span class="gtkdoc opt">);</span>
+    <span class="function"><a href="/usr/share/gtk-doc/html/glibglib-Warnings-and-Assertions.html#g-print">g_print</a></span> <span class="gtkdoc opt">(</span><span class="string">&quot;Buffering (%u percent done)&quot;</span><span class="gtkdoc opt">,</span> percent<span class="gtkdoc opt">);</span>
+    <span class="keyword">break</span><span class="gtkdoc opt">;</span>
+  <span class="gtkdoc opt">}</span>
+  <span class="gtkdoc opt">...</span>
+<span class="gtkdoc opt">}</span></pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+
+Note that applications should keep/set the pipeline in the PAUSED state when
+a BUFFERING message is received with a buffer percent value &lt; 100 and set
+the pipeline back to PLAYING state when a BUFFERING message with a value
+of 100 percent is received (if PLAYING is the desired state, that is).
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.34.3.10"></a><h3>Embedding the video window in your application</h3>
+By default, playbin3 (or rather the video sinks used) will create their own
+window. Applications will usually want to force output to a window of their
+own, however. This can be done using the <a href="../html/gst-plugins-base-libs-gstvideooverlay.html#GstVideoOverlay-struct"><span class="type">GstVideoOverlay</span></a> interface, which most
+video sinks implement. See the documentation there for more details.
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.34.3.11"></a><h3>Specifying which CD/DVD device to use</h3>
+The device to use for CDs/DVDs needs to be set on the source element
+playbin3 creates before it is opened. The most generic way of doing this
+is to connect to playbin3's "source-setup" (or "notify::source") signal,
+which will be emitted by playbin3 when it has created the source element
+for a particular URI. In the signal callback you can check if the source
+element has a "device" property and set it appropriately. In some cases
+the device can also be set as part of the URI, but it depends on the
+elements involved if this will work or not. For example, for DVD menu
+playback, the following syntax might work (if the resindvd plugin is used):
+dvd://[/path/to/device]
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.34.3.12"></a><h3>Handling redirects</h3>
+<p>
+Some elements may post 'redirect' messages on the bus to tell the
+application to open another location. These are element messages containing
+a structure named 'redirect' along with a 'new-location' field of string
+type. The new location may be a relative or an absolute URI. Examples
+for such redirects can be found in many quicktime movie trailers.
+</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.34.3.13"></a><h3>Examples</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v playbin3 uri<span class="gtkdoc opt">=</span>file<span class="gtkdoc opt">:</span><span class="gtkdoc slc">///path/to/somefile.mp4</span></pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ This will play back the given AVI video file, given that the video and
+audio decoders required to decode the content are installed. Since no
+special audio sink or video sink is supplied (via playbin3's audio-sink or
+video-sink properties) playbin3 will try to find a suitable audio and
+video sink automatically using the autoaudiosink and autovideosink elements.
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v playbin3 uri<span class="gtkdoc opt">=</span>cdda<span class="gtkdoc opt">:</span><span class="gtkdoc slc">//4</span></pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ This will play back track 4 on an audio CD in your disc drive (assuming
+the drive is detected automatically by the plugin).
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v playbin3 uri<span class="gtkdoc opt">=</span>dvd<span class="gtkdoc opt">:</span><span class="gtkdoc slc">//</span></pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ This will play back the DVD in your disc drive (assuming
+the drive is detected automatically by the plugin).
+</div>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="refsect2">
+<a name="id-1.2.34.3.14.1"></a><h3>Element Information</h3>
+<div class="variablelist"><table border="0" class="variablelist">
+<colgroup>
+<col align="left" valign="top">
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td><p><span class="term">plugin</span></p></td>
+<td>
+            <a class="link" href="gst-plugins-base-plugins-plugin-playback.html#plugin-playback">playback</a>
+          </td>
+</tr>
+<tr>
+<td><p><span class="term">author</span></p></td>
+<td>Wim Taymans &lt;wim.taymans@gmail.com&gt;</td>
+</tr>
+<tr>
+<td><p><span class="term">class</span></p></td>
+<td>Generic/Bin/Player</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.34.3.14.2"></a><h3>Element Pads</h3>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-playbin3.functions_details"></a><h2>Functions</h2>
+<p></p>
+</div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-playbin3.other_details"></a><h2>Types and Values</h2>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/plugins/html/gst-plugins-base-plugins-playsink.html b/docs/plugins/html/gst-plugins-base-plugins-playsink.html
index b3fc5ae..009c858 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-playsink.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-playsink.html
@@ -6,7 +6,7 @@
 <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
 <link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Plugins Reference Manual">
 <link rel="up" href="ch01.html" title="gst-plugins-base Elements">
-<link rel="prev" href="gst-plugins-base-plugins-playbin.html" title="playbin">
+<link rel="prev" href="gst-plugins-base-plugins-playbin3.html" title="playbin3">
 <link rel="next" href="gst-plugins-base-plugins-socketsrc.html" title="socketsrc">
 <meta name="generator" content="GTK-Doc V1.25 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
@@ -23,7 +23,7 @@
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="ch01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="gst-plugins-base-plugins-playbin.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="p" href="gst-plugins-base-plugins-playbin3.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="gst-plugins-base-plugins-socketsrc.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
@@ -56,7 +56,7 @@
 <td class="property_flags">Read / Write</td>
 </tr>
 <tr>
-<td class="property_type"><a class="link" href="gst-plugins-base-plugins-playbin.html#GstPlayFlags" title="enum GstPlayFlags"><span class="type">GstPlayFlags</span></a></td>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-playbin.html#GstPlayFlags"><span class="type">GstPlayFlags</span></a></td>
 <td class="property_name"><a class="link" href="gst-plugins-base-plugins-playsink.html#GstPlaySink--flags" title="The “flags” property">flags</a></td>
 <td class="property_flags">Read / Write</td>
 </tr>
@@ -188,7 +188,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.32.9.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.35.9.2.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -214,7 +214,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.32.9.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.35.9.2.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -371,7 +371,7 @@
 <hr>
 <div class="refsect2">
 <a name="GstPlaySink--flags"></a><h3>The <code class="literal">“flags”</code> property</h3>
-<pre class="programlisting">  “flags”                    <a class="link" href="gst-plugins-base-plugins-playbin.html#GstPlayFlags" title="enum GstPlayFlags"><span class="type">GstPlayFlags</span></a></pre>
+<pre class="programlisting">  “flags”                    <a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-playbin.html#GstPlayFlags"><span class="type">GstPlayFlags</span></a></pre>
 <p>Control the behaviour of playsink.</p>
 <p>Flags: Read / Write</p>
 <p>Default value: Render the video stream|Render the audio stream|Render subtitles|Use software volume|Use software color balance</p>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-adder.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-adder.html
index 187b6f6..926fbbc 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-adder.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-adder.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-alsa.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-alsa.html
index 2478b70..9e50cc1 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-alsa.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-alsa.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-app.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-app.html
index 82b68e6..7642de6 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-app.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-app.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-audioconvert.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-audioconvert.html
index 2ac2be0..3a13941 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-audioconvert.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-audioconvert.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-audiorate.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-audiorate.html
index bc4e988..406086d 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-audiorate.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-audiorate.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-audioresample.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-audioresample.html
index 04ccead..af25b2f 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-audioresample.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-audioresample.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-audiotestsrc.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-audiotestsrc.html
index 891fcfb..96a7825 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-audiotestsrc.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-audiotestsrc.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-cdparanoia.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-cdparanoia.html
index 77c3d63..c908992 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-cdparanoia.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-cdparanoia.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-encoding.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-encoding.html
index 90617dd..1039767 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-encoding.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-encoding.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-gio.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-gio.html
index c755a5c..1ccbc6c 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-gio.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-gio.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-libvisual.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-libvisual.html
index 469b818..59a142b 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-libvisual.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-libvisual.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-ogg.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-ogg.html
index 99bd8e6..b3960b0 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-ogg.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-ogg.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-opus.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-opus.html
index ea890ce..ae6272e 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-opus.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-opus.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-pango.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-pango.html
index c68bf27..da3e404 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-pango.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-pango.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-playback.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-playback.html
index c6414d7..34619ed 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-playback.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-playback.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
@@ -72,10 +72,22 @@
 <td>Autoplug and decode to raw media</td>
 </tr>
 <tr>
+<td><p><span class="term"><a class="link" href="gst-plugins-base-plugins-decodebin3.html" title="decodebin3">decodebin3</a></span></p></td>
+<td>Autoplug and decode to raw media</td>
+</tr>
+<tr>
+<td><p><span class="term"><a class="link" href="gst-plugins-base-plugins-parsebin.html" title="parsebin">parsebin</a></span></p></td>
+<td>Parse and de-multiplex to elementary stream</td>
+</tr>
+<tr>
 <td><p><span class="term"><a class="link" href="gst-plugins-base-plugins-playbin.html" title="playbin">playbin</a></span></p></td>
 <td>Autoplug and play media from an uri</td>
 </tr>
 <tr>
+<td><p><span class="term"><a class="link" href="gst-plugins-base-plugins-playbin3.html" title="playbin3">playbin3</a></span></p></td>
+<td>Autoplug and play media from an uri</td>
+</tr>
+<tr>
 <td><p><span class="term"><a class="link" href="gst-plugins-base-plugins-playsink.html" title="playsink">playsink</a></span></p></td>
 <td>Convenience sink for multiple streams</td>
 </tr>
@@ -91,6 +103,10 @@
 <td><p><span class="term"><a class="link" href="gst-plugins-base-plugins-uridecodebin.html" title="uridecodebin">uridecodebin</a></span></p></td>
 <td>Autoplug and decode an URI to raw media</td>
 </tr>
+<tr>
+<td><p><span class="term"><a class="link" href="gst-plugins-base-plugins-urisourcebin.html" title="urisourcebin">urisourcebin</a></span></p></td>
+<td>Download and buffer a URI as needed</td>
+</tr>
 </tbody>
 </table></div>
 </div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-subparse.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-subparse.html
index b02d455..455b3ff 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-subparse.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-subparse.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-tcp.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-tcp.html
index e3969a3..6d90926 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-tcp.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-tcp.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-theora.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-theora.html
index 80108b4..bbc44de 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-theora.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-theora.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-typefindfunctions.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-typefindfunctions.html
index 3ec6788..719115f 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-typefindfunctions.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-typefindfunctions.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-videoconvert.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-videoconvert.html
index 5a577ca..0270be7 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-videoconvert.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-videoconvert.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-videorate.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-videorate.html
index 345f2d5..5630349 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-videorate.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-videorate.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-videoscale.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-videoscale.html
index 2ad232f..6f28975 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-videoscale.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-videoscale.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-videotestsrc.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-videotestsrc.html
index f695557..5dd8861 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-videotestsrc.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-videotestsrc.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-volume.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-volume.html
index 98a3897..fd75d4f 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-volume.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-volume.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-vorbis.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-vorbis.html
index 27e8bfa..036bb85 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-vorbis.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-vorbis.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-ximagesink.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-ximagesink.html
index f0e6fc3..0a00988 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-ximagesink.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-ximagesink.html
@@ -42,7 +42,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-plugin-xvimagesink.html b/docs/plugins/html/gst-plugins-base-plugins-plugin-xvimagesink.html
index 45dce9d..dd786fa 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-plugin-xvimagesink.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-plugin-xvimagesink.html
@@ -41,7 +41,7 @@
 </tr>
 <tr>
 <td><p><span class="term">version</span></p></td>
-<td>1.8.3</td>
+<td>1.9.90</td>
 </tr>
 <tr>
 <td><p><span class="term">run-time license</span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-socketsrc.html b/docs/plugins/html/gst-plugins-base-plugins-socketsrc.html
index a864db9..b61a302 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-socketsrc.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-socketsrc.html
@@ -121,7 +121,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.33.8.8.1"></a><h3>Element Information</h3>
+<a name="id-1.2.36.8.8.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -147,7 +147,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.33.8.8.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.36.8.8.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-ssaparse.html b/docs/plugins/html/gst-plugins-base-plugins-ssaparse.html
index 04da6fa..ece2a40 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-ssaparse.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-ssaparse.html
@@ -59,7 +59,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.34.6.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.37.6.2.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -85,7 +85,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.34.6.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.37.6.2.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-streamsynchronizer.html b/docs/plugins/html/gst-plugins-base-plugins-streamsynchronizer.html
index 28504d4..3b58532 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-streamsynchronizer.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-streamsynchronizer.html
@@ -59,7 +59,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.35.6.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.38.6.2.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -85,7 +85,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.35.6.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.38.6.2.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-subparse.html b/docs/plugins/html/gst-plugins-base-plugins-subparse.html
index e897d85..8043458 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-subparse.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-subparse.html
@@ -83,7 +83,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.36.7.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.39.7.2.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -109,7 +109,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.36.7.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.39.7.2.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -156,6 +156,10 @@
 <td><p><span class="term"></span></p></td>
 <td> application/x-subtitle-lrc</td>
 </tr>
+<tr>
+<td><p><span class="term"></span></p></td>
+<td> application/x-subtitle-vtt</td>
+</tr>
 </tbody>
 </table></div>
 <div class="variablelist"><table border="0" class="variablelist">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-subtitleoverlay.html b/docs/plugins/html/gst-plugins-base-plugins-subtitleoverlay.html
index 0da51f2..b771890 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-subtitleoverlay.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-subtitleoverlay.html
@@ -99,7 +99,7 @@
 <p>It supports raw, timestamped text, different textual subtitle formats and
 DVD subpicture subtitles.</p>
 <div class="refsect2">
-<a name="id-1.2.37.8.4"></a><h3>Examples</h3>
+<a name="id-1.2.40.8.4"></a><h3>Examples</h3>
 <div class="informalexample">
   <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
     <tbody>
@@ -115,7 +115,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.37.8.5.1"></a><h3>Element Information</h3>
+<a name="id-1.2.40.8.5.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -141,7 +141,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.37.8.5.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.40.8.5.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-tcpclientsink.html b/docs/plugins/html/gst-plugins-base-plugins-tcpclientsink.html
index 179f10b..f412269 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-tcpclientsink.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-tcpclientsink.html
@@ -82,7 +82,7 @@
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-tcpclientsink.description"></a><h2>Description</h2>
 <div class="refsect2">
-<a name="id-1.2.38.7.2"></a><h3>Example launch line</h3>
+<a name="id-1.2.41.7.2"></a><h3>Example launch line</h3>
 <div class="informalexample">
   <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
     <tbody>
@@ -105,7 +105,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.38.7.3.1"></a><h3>Element Information</h3>
+<a name="id-1.2.41.7.3.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -131,7 +131,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.38.7.3.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.41.7.3.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-tcpclientsrc.html b/docs/plugins/html/gst-plugins-base-plugins-tcpclientsrc.html
index 4ec4db7..9ca4d57 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-tcpclientsrc.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-tcpclientsrc.html
@@ -83,7 +83,7 @@
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-tcpclientsrc.description"></a><h2>Description</h2>
 <div class="refsect2">
-<a name="id-1.2.39.7.2"></a><h3>Example launch line</h3>
+<a name="id-1.2.42.7.2"></a><h3>Example launch line</h3>
 <div class="informalexample">
   <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
     <tbody>
@@ -105,7 +105,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.39.7.3.1"></a><h3>Element Information</h3>
+<a name="id-1.2.42.7.3.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -131,7 +131,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.39.7.3.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.42.7.3.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-tcpserversink.html b/docs/plugins/html/gst-plugins-base-plugins-tcpserversink.html
index 477acf1..78c9e5c 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-tcpserversink.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-tcpserversink.html
@@ -89,7 +89,7 @@
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-tcpserversink.description"></a><h2>Description</h2>
 <div class="refsect2">
-<a name="id-1.2.40.7.2"></a><h3>Example launch line</h3>
+<a name="id-1.2.43.7.2"></a><h3>Example launch line</h3>
 <div class="informalexample">
   <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
     <tbody>
@@ -111,7 +111,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.40.7.3.1"></a><h3>Element Information</h3>
+<a name="id-1.2.43.7.3.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -137,7 +137,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.40.7.3.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.43.7.3.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-tcpserversrc.html b/docs/plugins/html/gst-plugins-base-plugins-tcpserversrc.html
index 6a0e75d..ea4814b 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-tcpserversrc.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-tcpserversrc.html
@@ -88,7 +88,7 @@
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-tcpserversrc.description"></a><h2>Description</h2>
 <div class="refsect2">
-<a name="id-1.2.41.7.2"></a><h3>Example launch line</h3>
+<a name="id-1.2.44.7.2"></a><h3>Example launch line</h3>
 <div class="informalexample">
   <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
     <tbody>
@@ -110,7 +110,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.41.7.3.1"></a><h3>Element Information</h3>
+<a name="id-1.2.44.7.3.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -136,7 +136,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.41.7.3.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.44.7.3.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-textoverlay.html b/docs/plugins/html/gst-plugins-base-plugins-textoverlay.html
index 04e0475..8e6fe39 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-textoverlay.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-textoverlay.html
@@ -57,10 +57,87 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-textoverlay.description"></a><h2>Description</h2>
+<p>This plugin renders text on top of a video stream. This can be either
+static text or text from buffers received on the text sink pad, e.g.
+as produced by the subparse element. If the text sink pad is not linked,
+the text set via the "text" property will be rendered. If the text sink
+pad is linked, text will be rendered as it is received on that pad,
+honouring and matching the buffer timestamps of both input streams.</p>
+<p>The text can contain newline characters and text wrapping is enabled by
+default.</p>
+<div class="refsect2">
+<a name="id-1.2.45.6.4"></a><h3>Example launch lines</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v gst<span class="gtkdoc opt">-</span>launch<span class="gtkdoc opt">-</span><span class="number">1.0</span> videotestsrc <span class="gtkdoc opt">!</span> textoverlay text<span class="gtkdoc opt">=</span><span class="string">&quot;Room A&quot;</span> valignment<span class="gtkdoc opt">=</span>top halignment<span class="gtkdoc opt">=</span>left font<span class="gtkdoc opt">-</span>desc<span class="gtkdoc opt">=</span><span class="string">&quot;Sans, 72&quot;</span> <span class="gtkdoc opt">!</span> autovideosink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Here is a simple pipeline that displays a static text in the top left
+corner of the video picture
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v filesrc location<span class="gtkdoc opt">=</span>subtitles<span class="gtkdoc opt">.</span>srt <span class="gtkdoc opt">!</span> subparse <span class="gtkdoc opt">!</span> txt<span class="gtkdoc opt">.</span>   videotestsrc <span class="gtkdoc opt">!</span> timeoverlay <span class="gtkdoc opt">!</span> textoverlay name<span class="gtkdoc opt">=</span>txt shaded<span class="gtkdoc opt">-</span>background<span class="gtkdoc opt">=</span>yes <span class="gtkdoc opt">!</span> autovideosink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Here is another pipeline that displays subtitles from an .srt subtitle
+file, centered at the bottom of the picture and with a rectangular shading
+around the text in the background:
+<p>
+If you do not have such a subtitle file, create one looking like this
+in a text editor:
+</p>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13</pre></td>
+        <td class="listing_code"><pre class="programlisting"><span class="number">1</span>
+<span class="number">00</span><span class="gtkdoc opt">:</span><span class="number">00</span><span class="gtkdoc opt">:</span><span class="number">03</span><span class="gtkdoc opt">,</span><span class="number">000</span> <span class="gtkdoc opt">--&gt;</span> <span class="number">00</span><span class="gtkdoc opt">:</span><span class="number">00</span><span class="gtkdoc opt">:</span><span class="number">05</span><span class="gtkdoc opt">,</span><span class="number">000</span>
+Hello? <span class="gtkdoc opt">(</span><span class="number">3</span><span class="gtkdoc opt">-</span><span class="number">5</span>s<span class="gtkdoc opt">)</span>
+
+<span class="number">2</span>
+<span class="number">00</span><span class="gtkdoc opt">:</span><span class="number">00</span><span class="gtkdoc opt">:</span><span class="number">08</span><span class="gtkdoc opt">,</span><span class="number">000</span> <span class="gtkdoc opt">--&gt;</span> <span class="number">00</span><span class="gtkdoc opt">:</span><span class="number">00</span><span class="gtkdoc opt">:</span><span class="number">13</span><span class="gtkdoc opt">,</span><span class="number">000</span>
+Yes<span class="gtkdoc opt">,</span> <span class="keyword">this</span> is a subtitle<span class="gtkdoc opt">.</span> Don<span class="string">'t</span>
+<span class="string">you like it? (8-13s)</span>
+<span class="string"></span>
+<span class="string">3</span>
+<span class="string">00:00:18,826 --&gt; 00:01:02,886</span>
+<span class="string">Uh? What are you talking about?</span>
+<span class="string">I don'</span>t <span class="function">understand</span>  <span class="gtkdoc opt">(</span><span class="number">18</span><span class="gtkdoc opt">-</span><span class="number">62</span>s<span class="gtkdoc opt">)</span></pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+
+<p>
+</p>
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.42.6.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.45.6.5.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -86,7 +163,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.42.6.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.45.6.5.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -135,7 +212,7 @@
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 </tbody>
 </table></div>
@@ -163,7 +240,7 @@
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 </tbody>
 </table></div>
@@ -179,8 +256,13 @@
 <div class="refsect2">
 <a name="GstTextOverlay-struct"></a><h3>struct GstTextOverlay</h3>
 <pre class="programlisting">struct GstTextOverlay;</pre>
+<p>Opaque textoverlay data structure.</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-textoverlay.see-also"></a><h2>See Also</h2>
+<p><a class="link" href="gst-plugins-base-plugins-textrender.html#GstTextRender"><span class="type">GstTextRender</span></a>, <a class="link" href="gst-plugins-base-plugins-textoverlay.html#GstTextOverlay"><span class="type">GstTextOverlay</span></a>, <a class="link" href="gst-plugins-base-plugins-timeoverlay.html#GstTimeOverlay"><span class="type">GstTimeOverlay</span></a>, <a class="link" href="gst-plugins-base-plugins-subparse.html#GstSubParse"><span class="type">GstSubParse</span></a></p>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-textrender.html b/docs/plugins/html/gst-plugins-base-plugins-textrender.html
index 376ad46..710a002 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-textrender.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-textrender.html
@@ -49,17 +49,17 @@
 <td class="property_flags">Write</td>
 </tr>
 <tr>
-<td class="property_type"><span class="type">GstTextRenderHAlign</span></td>
+<td class="property_type"><a class="link" href="gst-plugins-base-plugins-textrender.html#GstTextRenderHAlign" title="enum GstTextRenderHAlign"><span class="type">GstTextRenderHAlign</span></a></td>
 <td class="property_name"><a class="link" href="gst-plugins-base-plugins-textrender.html#GstTextRender--halignment" title="The “halignment” property">halignment</a></td>
 <td class="property_flags">Read / Write</td>
 </tr>
 <tr>
-<td class="property_type"><span class="type">GstTextRenderLineAlign</span></td>
+<td class="property_type"><a class="link" href="gst-plugins-base-plugins-textrender.html#GstTextRenderLineAlign" title="enum GstTextRenderLineAlign"><span class="type">GstTextRenderLineAlign</span></a></td>
 <td class="property_name"><a class="link" href="gst-plugins-base-plugins-textrender.html#GstTextRender--line-alignment" title="The “line-alignment” property">line-alignment</a></td>
 <td class="property_flags">Read / Write</td>
 </tr>
 <tr>
-<td class="property_type"><span class="type">GstTextRenderVAlign</span></td>
+<td class="property_type"><a class="link" href="gst-plugins-base-plugins-textrender.html#GstTextRenderVAlign" title="enum GstTextRenderVAlign"><span class="type">GstTextRenderVAlign</span></a></td>
 <td class="property_name"><a class="link" href="gst-plugins-base-plugins-textrender.html#GstTextRender--valignment" title="The “valignment” property">valignment</a></td>
 <td class="property_flags">Read / Write</td>
 </tr>
@@ -83,10 +83,24 @@
 <col width="150px" class="name">
 <col class="description">
 </colgroup>
-<tbody><tr>
+<tbody>
+<tr>
 <td class="datatype_keyword">struct</td>
 <td class="function_name"><a class="link" href="gst-plugins-base-plugins-textrender.html#GstTextRender-struct" title="struct GstTextRender">GstTextRender</a></td>
-</tr></tbody>
+</tr>
+<tr>
+<td class="datatype_keyword">enum</td>
+<td class="function_name"><a class="link" href="gst-plugins-base-plugins-textrender.html#GstTextRenderHAlign" title="enum GstTextRenderHAlign">GstTextRenderHAlign</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">enum</td>
+<td class="function_name"><a class="link" href="gst-plugins-base-plugins-textrender.html#GstTextRenderLineAlign" title="enum GstTextRenderLineAlign">GstTextRenderLineAlign</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">enum</td>
+<td class="function_name"><a class="link" href="gst-plugins-base-plugins-textrender.html#GstTextRenderVAlign" title="enum GstTextRenderVAlign">GstTextRenderVAlign</a></td>
+</tr>
+</tbody>
 </table></div>
 </div>
 <div class="refsect1">
@@ -100,10 +114,29 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-textrender.description"></a><h2>Description</h2>
+<p>This plugin renders text received on the text sink pad to a video
+buffer (retaining the alpha channel), so it can later be overlayed
+on top of video streams using other elements.</p>
+<p>The text can contain newline characters. (FIXME: What about text 
+wrapping? It does not make sense in this context)</p>
+<div class="refsect2">
+<a name="id-1.2.46.7.4"></a><h3>Example launch lines</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v filesrc location<span class="gtkdoc opt">=</span>subtitles<span class="gtkdoc opt">.</span>srt <span class="gtkdoc opt">!</span> subparse <span class="gtkdoc opt">!</span> textrender <span class="gtkdoc opt">!</span> videoconvert <span class="gtkdoc opt">!</span> autovideosink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.43.7.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.46.7.5.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -129,7 +162,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.43.7.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.46.7.5.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -190,6 +223,121 @@
 <div class="refsect2">
 <a name="GstTextRender-struct"></a><h3>struct GstTextRender</h3>
 <pre class="programlisting">struct GstTextRender;</pre>
+<p>Opaque textrender data structure.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstTextRenderHAlign"></a><h3>enum GstTextRenderHAlign</h3>
+<p>Horizontal alignment of the text.</p>
+<div class="refsect3">
+<a name="GstTextRenderHAlign.members"></a><h4>Members</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="300px" class="enum_members_name">
+<col class="enum_members_description">
+<col width="200px" class="enum_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="enum_member_name"><p><a name="GST-TEXT-RENDER-HALIGN-LEFT:CAPS"></a>GST_TEXT_RENDER_HALIGN_LEFT</p></td>
+<td class="enum_member_description">
+<p>align text left</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-TEXT-RENDER-HALIGN-CENTER:CAPS"></a>GST_TEXT_RENDER_HALIGN_CENTER</p></td>
+<td class="enum_member_description">
+<p>align text center</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-TEXT-RENDER-HALIGN-RIGHT:CAPS"></a>GST_TEXT_RENDER_HALIGN_RIGHT</p></td>
+<td class="enum_member_description">
+<p>align text right</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstTextRenderLineAlign"></a><h3>enum GstTextRenderLineAlign</h3>
+<p>Alignment of text lines relative to each other</p>
+<div class="refsect3">
+<a name="GstTextRenderLineAlign.members"></a><h4>Members</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="300px" class="enum_members_name">
+<col class="enum_members_description">
+<col width="200px" class="enum_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="enum_member_name"><p><a name="GST-TEXT-RENDER-LINE-ALIGN-LEFT:CAPS"></a>GST_TEXT_RENDER_LINE_ALIGN_LEFT</p></td>
+<td class="enum_member_description">
+<p>lines are left-aligned</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-TEXT-RENDER-LINE-ALIGN-CENTER:CAPS"></a>GST_TEXT_RENDER_LINE_ALIGN_CENTER</p></td>
+<td class="enum_member_description">
+<p>lines are center-aligned</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-TEXT-RENDER-LINE-ALIGN-RIGHT:CAPS"></a>GST_TEXT_RENDER_LINE_ALIGN_RIGHT</p></td>
+<td class="enum_member_description">
+<p>lines are right-aligned</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GstTextRenderVAlign"></a><h3>enum GstTextRenderVAlign</h3>
+<p>Vertical alignment of the text.</p>
+<div class="refsect3">
+<a name="GstTextRenderVAlign.members"></a><h4>Members</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="300px" class="enum_members_name">
+<col class="enum_members_description">
+<col width="200px" class="enum_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="enum_member_name"><p><a name="GST-TEXT-RENDER-VALIGN-BASELINE:CAPS"></a>GST_TEXT_RENDER_VALIGN_BASELINE</p></td>
+<td class="enum_member_description">
+<p>draw text on the baseline</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-TEXT-RENDER-VALIGN-BOTTOM:CAPS"></a>GST_TEXT_RENDER_VALIGN_BOTTOM</p></td>
+<td class="enum_member_description">
+<p>draw text on the bottom</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-TEXT-RENDER-VALIGN-TOP:CAPS"></a>GST_TEXT_RENDER_VALIGN_TOP</p></td>
+<td class="enum_member_description">
+<p>draw test on top</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
 </div>
 </div>
 <div class="refsect1">
@@ -204,7 +352,7 @@
 <hr>
 <div class="refsect2">
 <a name="GstTextRender--halignment"></a><h3>The <code class="literal">“halignment”</code> property</h3>
-<pre class="programlisting">  “halignment”               <span class="type">GstTextRenderHAlign</span></pre>
+<pre class="programlisting">  “halignment”               <a class="link" href="gst-plugins-base-plugins-textrender.html#GstTextRenderHAlign" title="enum GstTextRenderHAlign"><span class="type">GstTextRenderHAlign</span></a></pre>
 <p>Horizontal alignment of the text.</p>
 <p>Flags: Read / Write</p>
 <p>Default value: center</p>
@@ -212,7 +360,7 @@
 <hr>
 <div class="refsect2">
 <a name="GstTextRender--line-alignment"></a><h3>The <code class="literal">“line-alignment”</code> property</h3>
-<pre class="programlisting">  “line-alignment”           <span class="type">GstTextRenderLineAlign</span></pre>
+<pre class="programlisting">  “line-alignment”           <a class="link" href="gst-plugins-base-plugins-textrender.html#GstTextRenderLineAlign" title="enum GstTextRenderLineAlign"><span class="type">GstTextRenderLineAlign</span></a></pre>
 <p>Alignment of text lines relative to each other.</p>
 <p>Flags: Read / Write</p>
 <p>Default value: center</p>
@@ -220,7 +368,7 @@
 <hr>
 <div class="refsect2">
 <a name="GstTextRender--valignment"></a><h3>The <code class="literal">“valignment”</code> property</h3>
-<pre class="programlisting">  “valignment”               <span class="type">GstTextRenderVAlign</span></pre>
+<pre class="programlisting">  “valignment”               <a class="link" href="gst-plugins-base-plugins-textrender.html#GstTextRenderVAlign" title="enum GstTextRenderVAlign"><span class="type">GstTextRenderVAlign</span></a></pre>
 <p>Vertical alignment of the text.</p>
 <p>Flags: Read / Write</p>
 <p>Default value: baseline</p>
@@ -244,6 +392,10 @@
 <p>Default value: 25</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-textrender.see-also"></a><h2>See Also</h2>
+<p><a class="link" href="gst-plugins-base-plugins-textoverlay.html#GstTextOverlay"><span class="type">GstTextOverlay</span></a></p>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-theoradec.html b/docs/plugins/html/gst-plugins-base-plugins-theoradec.html
index db4df33..cce830c 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-theoradec.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-theoradec.html
@@ -90,10 +90,29 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-theoradec.description"></a><h2>Description</h2>
+<p>This element decodes theora streams into raw video</p>
+<a class="ulink" href="http://www.theora.org/" target="_top">Theora</a> is a royalty-free
+<p>video codec maintained by the <a class="ulink" href="http://www.xiph.org/" target="_top">Xiph.org
+Foundation</a>, based on the VP3 codec.</p>
+<div class="refsect2">
+<a name="id-1.2.47.7.5"></a><h3>Example pipeline</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v filesrc location<span class="gtkdoc opt">=</span>videotestsrc<span class="gtkdoc opt">.</span>ogg <span class="gtkdoc opt">!</span> oggdemux <span class="gtkdoc opt">!</span> theoradec <span class="gtkdoc opt">!</span> videoconvert <span class="gtkdoc opt">!</span> videoscale <span class="gtkdoc opt">!</span> autovideosink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ This example pipeline will decode an ogg stream and decodes the theora video in it.
+Refer to the theoraenc example to create the ogg file.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.44.7.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.47.7.6.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -119,7 +138,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.44.7.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.47.7.6.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -180,6 +199,7 @@
 <div class="refsect2">
 <a name="GstTheoraDec-struct"></a><h3>struct GstTheoraDec</h3>
 <pre class="programlisting">struct GstTheoraDec;</pre>
+<p>Opaque object data structure.</p>
 </div>
 </div>
 <div class="refsect1">
@@ -220,6 +240,10 @@
 <p>Default value: 0</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-theoradec.see-also"></a><h2>See Also</h2>
+<p>theoraenc, oggdemux</p>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-theoraenc.html b/docs/plugins/html/gst-plugins-base-plugins-theoraenc.html
index 2efd264..74ba100 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-theoraenc.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-theoraenc.html
@@ -149,10 +149,43 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-theoraenc.description"></a><h2>Description</h2>
+<p>This element encodes raw video into a Theora stream.</p>
+<a class="ulink" href="http://www.theora.org/" target="_top">Theora</a> is a royalty-free
+<p>video codec maintained by the <a class="ulink" href="http://www.xiph.org/" target="_top">Xiph.org
+Foundation</a>, based on the VP3 codec.</p>
+<p>The theora codec internally only supports encoding of images that are a
+multiple of 16 pixels in both X and Y direction. It is however perfectly
+possible to encode images with other dimensions because an arbitrary
+rectangular cropping region can be set up. This element will automatically
+set up a correct cropping region if the dimensions are not multiples of 16
+pixels.</p>
+<p>To control the quality of the encoding, the <span class="type">“bitrate”</span> and
+<span class="type">“quality”</span> properties can be used. These two properties are
+mutualy exclusive. Setting the bitrate property will produce a constant
+bitrate (CBR) stream while setting the quality property will produce a
+variable bitrate (VBR) stream.</p>
+<p>A videorate element is often required in front of theoraenc, especially
+when transcoding and when putting Theora into the Ogg container.</p>
+<div class="refsect2">
+<a name="id-1.2.48.8.8"></a><h3>Example pipeline</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v videotestsrc num<span class="gtkdoc opt">-</span>buffers<span class="gtkdoc opt">=</span><span class="number">500</span> <span class="gtkdoc opt">!</span> video<span class="gtkdoc opt">/</span>x<span class="gtkdoc opt">-</span>raw<span class="gtkdoc opt">,</span>width<span class="gtkdoc opt">=</span><span class="number">1280</span><span class="gtkdoc opt">,</span>height<span class="gtkdoc opt">=</span><span class="number">720</span> <span class="gtkdoc opt">!</span> queue <span class="gtkdoc opt">!</span> progressreport <span class="gtkdoc opt">!</span> theoraenc <span class="gtkdoc opt">!</span> oggmux <span class="gtkdoc opt">!</span> filesink location<span class="gtkdoc opt">=</span>videotestsrc<span class="gtkdoc opt">.</span>ogg</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ This example pipeline will encode a test video source to theora muxed in an
+ogg container. Refer to the theoradec documentation to decode the create
+stream.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.45.8.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.48.8.9.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -178,7 +211,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.45.8.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.48.8.9.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -239,6 +272,7 @@
 <div class="refsect2">
 <a name="GstTheoraEnc-struct"></a><h3>struct GstTheoraEnc</h3>
 <pre class="programlisting">struct GstTheoraEnc;</pre>
+<p>Opaque data structure.</p>
 </div>
 <hr>
 <div class="refsect2">
@@ -254,18 +288,24 @@
 <tbody>
 <tr>
 <td class="enum_member_name"><p><a name="MULTIPASS-MODE-SINGLE-PASS:CAPS"></a>MULTIPASS_MODE_SINGLE_PASS</p></td>
-<td> </td>
-<td> </td>
+<td class="enum_member_description">
+<p>Single pass encoding</p>
+</td>
+<td class="enum_member_annotations"> </td>
 </tr>
 <tr>
 <td class="enum_member_name"><p><a name="MULTIPASS-MODE-FIRST-PASS:CAPS"></a>MULTIPASS_MODE_FIRST_PASS</p></td>
-<td> </td>
-<td> </td>
+<td class="enum_member_description">
+<p>First pass of two pass encoding</p>
+</td>
+<td class="enum_member_annotations"> </td>
 </tr>
 <tr>
 <td class="enum_member_name"><p><a name="MULTIPASS-MODE-SECOND-PASS:CAPS"></a>MULTIPASS_MODE_SECOND_PASS</p></td>
-<td> </td>
-<td> </td>
+<td class="enum_member_description">
+<p>Second pass of two pass encoding</p>
+</td>
+<td class="enum_member_annotations"> </td>
 </tr>
 </tbody>
 </table></div>
@@ -384,6 +424,10 @@
 <p>Default value: FALSE</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-theoraenc.see-also"></a><h2>See Also</h2>
+<p>theoradec, oggmux</p>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-theoraparse.html b/docs/plugins/html/gst-plugins-base-plugins-theoraparse.html
index fe6fb30..a60fa11 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-theoraparse.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-theoraparse.html
@@ -56,10 +56,54 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-theoraparse.description"></a><h2>Description</h2>
+<p>The theoraparse element will parse the header packets of the Theora
+stream and put them as the streamheader in the caps. This is used in the
+multifdsink case where you want to stream live theora streams to multiple
+clients, each client has to receive the streamheaders first before they can
+consume the theora packets.</p>
+<p>This element also makes sure that the buffers that it pushes out are properly
+timestamped and that their offset and offset_end are set. The buffers that
+theoraparse outputs have all of the metadata that oggmux expects to receive,
+which allows you to (for example) remux an ogg/theora file.</p>
+<p>In addition, this element allows you to fix badly synchronized streams. You
+pass in an array of (granule time, buffer time) synchronization points via
+the synchronization-points GValueArray property, and this element will adjust
+the granulepos values that it outputs. The adjustment will be made by
+offsetting all buffers that it outputs by a specified amount, and updating
+that offset from the value array whenever a keyframe is processed.</p>
+<div class="refsect2">
+<a name="id-1.2.49.6.5"></a><h3>Example pipelines</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v filesrc location<span class="gtkdoc opt">=</span>video<span class="gtkdoc opt">.</span>ogg <span class="gtkdoc opt">!</span> oggdemux <span class="gtkdoc opt">!</span> theoraparse <span class="gtkdoc opt">!</span> fakesink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ This pipeline shows that the streamheader is set in the caps, and that each
+buffer has the timestamp, duration, offset, and offset_end set.
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1
+2</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> filesrc location<span class="gtkdoc opt">=</span>video<span class="gtkdoc opt">.</span>ogg <span class="gtkdoc opt">!</span> oggdemux <span class="gtkdoc opt">!</span> theoraparse \
+           <span class="gtkdoc opt">!</span> oggmux <span class="gtkdoc opt">!</span> filesink location<span class="gtkdoc opt">=</span>video<span class="gtkdoc opt">-</span>remuxed<span class="gtkdoc opt">.</span>ogg</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ This pipeline shows remuxing. video-remuxed.ogg might not be exactly the same
+as video.ogg, but they should produce exactly the same decoded data.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.46.6.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.49.6.6.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -85,7 +129,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.46.6.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.49.6.6.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -146,8 +190,13 @@
 <div class="refsect2">
 <a name="GstTheoraParse-struct"></a><h3>struct GstTheoraParse</h3>
 <pre class="programlisting">struct GstTheoraParse;</pre>
+<p>Opaque data structure.</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-theoraparse.see-also"></a><h2>See Also</h2>
+<p>theoradec, oggdemux, vorbisparse</p>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-timeoverlay.html b/docs/plugins/html/gst-plugins-base-plugins-timeoverlay.html
index b3b7148..08e4a39 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-timeoverlay.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-timeoverlay.html
@@ -79,10 +79,42 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-timeoverlay.description"></a><h2>Description</h2>
+<p>This element overlays the buffer time stamps of a video stream on
+top of itself. You can position the text and configure the font details
+using the properties of the <span class="type">GstBaseTextOverlay</span> class. By default, the
+time stamp is displayed in the top left corner of the picture, with some
+padding to the left and to the top.</p>
+<div class="refsect2">
+<a name="id-1.2.50.7.3"></a><div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v videotestsrc <span class="gtkdoc opt">!</span> timeoverlay <span class="gtkdoc opt">!</span> autovideosink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Display the time stamps in the top left corner of the video picture.
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v videotestsrc <span class="gtkdoc opt">!</span> timeoverlay halignment<span class="gtkdoc opt">=</span>right valignment<span class="gtkdoc opt">=</span>bottom text<span class="gtkdoc opt">=</span><span class="string">&quot;Stream time:&quot;</span> shaded<span class="gtkdoc opt">-</span>background<span class="gtkdoc opt">=</span><span class="keyword">true</span> font<span class="gtkdoc opt">-</span>desc<span class="gtkdoc opt">=</span><span class="string">&quot;Sans, 24&quot;</span> <span class="gtkdoc opt">!</span> autovideosink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Another pipeline that displays the time stamps with some leading
+text in the bottom right corner of the video picture, with the background
+of the text being shaded in order to make it more legible on top of a
+bright video background.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.47.7.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.50.7.4.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -108,7 +140,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.47.7.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.50.7.4.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -133,7 +165,7 @@
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 </tbody>
 </table></div>
@@ -161,7 +193,7 @@
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 </tbody>
 </table></div>
@@ -177,6 +209,7 @@
 <div class="refsect2">
 <a name="GstTimeOverlay-struct"></a><h3>struct GstTimeOverlay</h3>
 <pre class="programlisting">struct GstTimeOverlay;</pre>
+<p>Opaque timeoverlay data structure.</p>
 </div>
 <hr>
 <div class="refsect2">
@@ -205,6 +238,11 @@
 <td> </td>
 <td> </td>
 </tr>
+<tr>
+<td class="enum_member_name"><p><a name="GST-TIME-OVERLAY-TIME-LINE-TIME-CODE:CAPS"></a>GST_TIME_OVERLAY_TIME_LINE_TIME_CODE</p></td>
+<td> </td>
+<td> </td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -220,6 +258,10 @@
 <p>Default value: buffer-time</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-timeoverlay.see-also"></a><h2>See Also</h2>
+<p><span class="type">GstBaseTextOverlay</span>, <a class="link" href="gst-plugins-base-plugins-clockoverlay.html#GstClockOverlay"><span class="type">GstClockOverlay</span></a></p>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-uridecodebin.html b/docs/plugins/html/gst-plugins-base-plugins-uridecodebin.html
index 734e6f3..61b5271 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-uridecodebin.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-uridecodebin.html
@@ -7,7 +7,7 @@
 <link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Plugins Reference Manual">
 <link rel="up" href="ch01.html" title="gst-plugins-base Elements">
 <link rel="prev" href="gst-plugins-base-plugins-timeoverlay.html" title="timeoverlay">
-<link rel="next" href="gst-plugins-base-plugins-videoconvert.html" title="videoconvert">
+<link rel="next" href="gst-plugins-base-plugins-urisourcebin.html" title="urisourcebin">
 <meta name="generator" content="GTK-Doc V1.25 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
@@ -24,7 +24,7 @@
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="ch01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="gst-plugins-base-plugins-timeoverlay.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="gst-plugins-base-plugins-videoconvert.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="n" href="gst-plugins-base-plugins-urisourcebin.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
 <a name="gst-plugins-base-plugins-uridecodebin"></a><div class="titlepage"></div>
@@ -132,7 +132,7 @@
 <td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
 </tr>
 <tr>
-<td class="signal_type"><a class="link" href="gst-plugins-base-plugins-uridecodebin.html#GstAutoplugSelectResult" title="enum GstAutoplugSelectResult"><span class="returnvalue">GstAutoplugSelectResult</span></a></td>
+<td class="signal_type"><a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-uridecodebin.html#GstAutoplugSelectResult"><span class="returnvalue">GstAutoplugSelectResult</span></a></td>
 <td class="signal_name"><a class="link" href="gst-plugins-base-plugins-uridecodebin.html#GstURIDecodeBin-autoplug-select" title="The “autoplug-select” signal">autoplug-select</a></td>
 <td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
 </tr>
@@ -167,16 +167,10 @@
 <col width="150px" class="name">
 <col class="description">
 </colgroup>
-<tbody>
-<tr>
+<tbody><tr>
 <td class="datatype_keyword">struct</td>
 <td class="function_name"><a class="link" href="gst-plugins-base-plugins-uridecodebin.html#GstURIDecodeBin-struct" title="struct GstURIDecodeBin">GstURIDecodeBin</a></td>
-</tr>
-<tr>
-<td class="datatype_keyword">enum</td>
-<td class="function_name"><a class="link" href="gst-plugins-base-plugins-uridecodebin.html#GstAutoplugSelectResult" title="enum GstAutoplugSelectResult">GstAutoplugSelectResult</a></td>
-</tr>
-</tbody>
+</tr></tbody>
 </table></div>
 </div>
 <div class="refsect1">
@@ -202,7 +196,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.48.9.3.1"></a><h3>Element Information</h3>
+<a name="id-1.2.51.9.3.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -228,7 +222,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.48.9.3.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.51.9.3.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -267,44 +261,6 @@
 <pre class="programlisting">struct GstURIDecodeBin;</pre>
 <p>uridecodebin element struct</p>
 </div>
-<hr>
-<div class="refsect2">
-<a name="GstAutoplugSelectResult"></a><h3>enum GstAutoplugSelectResult</h3>
-<p>return values for the autoplug-select signal.</p>
-<div class="refsect3">
-<a name="GstAutoplugSelectResult.members"></a><h4>Members</h4>
-<div class="informaltable"><table class="informaltable" width="100%" border="0">
-<colgroup>
-<col width="300px" class="enum_members_name">
-<col class="enum_members_description">
-<col width="200px" class="enum_members_annotations">
-</colgroup>
-<tbody>
-<tr>
-<td class="enum_member_name"><p><a name="GST-AUTOPLUG-SELECT-TRY:CAPS"></a>GST_AUTOPLUG_SELECT_TRY</p></td>
-<td class="enum_member_description">
-<p>try to autoplug the current factory</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-AUTOPLUG-SELECT-EXPOSE:CAPS"></a>GST_AUTOPLUG_SELECT_EXPOSE</p></td>
-<td class="enum_member_description">
-<p>expose the pad as a raw stream</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GST-AUTOPLUG-SELECT-SKIP:CAPS"></a>GST_AUTOPLUG_SELECT_SKIP</p></td>
-<td class="enum_member_description">
-<p>skip the current factory</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-</tbody>
-</table></div>
-</div>
-</div>
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-uridecodebin.property-details"></a><h2>Property Details</h2>
@@ -532,7 +488,7 @@
 <hr>
 <div class="refsect2">
 <a name="GstURIDecodeBin-autoplug-select"></a><h3>The <code class="literal">“autoplug-select”</code> signal</h3>
-<pre class="programlisting"><a class="link" href="gst-plugins-base-plugins-uridecodebin.html#GstAutoplugSelectResult" title="enum GstAutoplugSelectResult"><span class="returnvalue">GstAutoplugSelectResult</span></a>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-uridecodebin.html#GstAutoplugSelectResult"><span class="returnvalue">GstAutoplugSelectResult</span></a>
 user_function (<a class="link" href="gst-plugins-base-plugins-uridecodebin.html#GstURIDecodeBin"><span class="type">GstURIDecodeBin</span></a>   *bin,
                <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstPad.html#GstPad-struct"><span class="type">GstPad</span></a>            *pad,
                <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstCaps.html#GstCaps-struct"><span class="type">GstCaps</span></a>           *caps,
@@ -544,13 +500,13 @@
 those factories, this signal is emitted.</p>
 <p>The signal handler should return a <span class="type">GST_TYPE_AUTOPLUG_SELECT_RESULT</span> enum
 value indicating what decodebin should do next.</p>
-<p>A value of <a class="link" href="gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-TRY:CAPS"><span class="type">GST_AUTOPLUG_SELECT_TRY</span></a> will try to autoplug an element from
+<p>A value of <a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-TRY:CAPS"><span class="type">GST_AUTOPLUG_SELECT_TRY</span></a> will try to autoplug an element from
 <em class="parameter"><code>factory</code></em>
 .</p>
-<p>A value of <a class="link" href="gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-EXPOSE:CAPS"><span class="type">GST_AUTOPLUG_SELECT_EXPOSE</span></a> will expose <em class="parameter"><code>pad</code></em>
+<p>A value of <a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-EXPOSE:CAPS"><span class="type">GST_AUTOPLUG_SELECT_EXPOSE</span></a> will expose <em class="parameter"><code>pad</code></em>
  without plugging
 any element to it.</p>
-<p>A value of <a class="link" href="gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-SKIP:CAPS"><span class="type">GST_AUTOPLUG_SELECT_SKIP</span></a> will skip <em class="parameter"><code>factory</code></em>
+<p>A value of <a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-SKIP:CAPS"><span class="type">GST_AUTOPLUG_SELECT_SKIP</span></a> will skip <em class="parameter"><code>factory</code></em>
  and move to the
 next factory.</p>
 <div class="note">
@@ -601,7 +557,7 @@
 <a name="GstURIDecodeBin-autoplug-select.returns"></a><h4>Returns</h4>
 <p> a <span class="type">GST_TYPE_AUTOPLUG_SELECT_RESULT</span> that indicates the required
 operation. The default handler will always return
-<a class="link" href="gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-TRY:CAPS"><span class="type">GST_AUTOPLUG_SELECT_TRY</span></a>.</p>
+<a href="/usr/share/gtk-doc/html/gst-plugins-base-plugins-1.0gst-plugins-base-plugins-uridecodebin.html#GST-AUTOPLUG-SELECT-TRY:CAPS"><span class="type">GST_AUTOPLUG_SELECT_TRY</span></a>.</p>
 </div>
 <p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
 </div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-urisourcebin.html b/docs/plugins/html/gst-plugins-base-plugins-urisourcebin.html
new file mode 100644
index 0000000..f8c7691
--- /dev/null
+++ b/docs/plugins/html/gst-plugins-base-plugins-urisourcebin.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>urisourcebin: GStreamer Base Plugins 1.0 Plugins Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
+<link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Plugins Reference Manual">
+<link rel="up" href="ch01.html" title="gst-plugins-base Elements">
+<link rel="prev" href="gst-plugins-base-plugins-uridecodebin.html" title="uridecodebin">
+<link rel="next" href="gst-plugins-base-plugins-videoconvert.html" title="videoconvert">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
+                  <a href="#gst-plugins-base-plugins-urisourcebin.description" class="shortcut">Description</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="gst-plugins-base-plugins-uridecodebin.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="gst-plugins-base-plugins-videoconvert.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="gst-plugins-base-plugins-urisourcebin"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="gst-plugins-base-plugins-urisourcebin.top_of_page"></a>urisourcebin</span></h2>
+<p>urisourcebin</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-urisourcebin.description"></a><h2>Description</h2>
+<p>urisourcebin is an element for accessing URIs in a uniform manner.</p>
+<p>It handles selecting a URI source element and potentially download
+buffering for network sources. It produces one or more source pads,
+depending on the input source, for feeding to decoding chains or decodebin.</p>
+<p>The main configuration is via the <span class="type">“uri”</span> property.</p>
+<p><span class="emphasis"><em>urisourcebin is still experimental API and a technology preview.
+Its behaviour and exposed API is subject to change.</em></span></p>
+<div class="refsynopsisdiv">
+<h2>Synopsis</h2>
+<div class="refsect2">
+<a name="id-1.2.52.3.6.1"></a><h3>Element Information</h3>
+<div class="variablelist"><table border="0" class="variablelist">
+<colgroup>
+<col align="left" valign="top">
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td><p><span class="term">plugin</span></p></td>
+<td>
+            <a class="link" href="gst-plugins-base-plugins-plugin-playback.html#plugin-playback">playback</a>
+          </td>
+</tr>
+<tr>
+<td><p><span class="term">author</span></p></td>
+<td>Jan Schmidt &lt;jan@centricular.com&gt;</td>
+</tr>
+<tr>
+<td><p><span class="term">class</span></p></td>
+<td>Generic/Bin/Source</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.52.3.6.2"></a><h3>Element Pads</h3>
+<div class="variablelist"><table border="0" class="variablelist">
+<colgroup>
+<col align="left" valign="top">
+<col>
+</colgroup>
+<tbody>
+<tr>
+<td><p><span class="term">name</span></p></td>
+<td>src_%u</td>
+</tr>
+<tr>
+<td><p><span class="term">direction</span></p></td>
+<td>source</td>
+</tr>
+<tr>
+<td><p><span class="term">presence</span></p></td>
+<td>sometimes</td>
+</tr>
+<tr>
+<td><p><span class="term">details</span></p></td>
+<td>ANY</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-urisourcebin.functions_details"></a><h2>Functions</h2>
+<p></p>
+</div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-urisourcebin.other_details"></a><h2>Types and Values</h2>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/plugins/html/gst-plugins-base-plugins-videoconvert.html b/docs/plugins/html/gst-plugins-base-plugins-videoconvert.html
index 5071237..f3f1056 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-videoconvert.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-videoconvert.html
@@ -6,7 +6,7 @@
 <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
 <link rel="home" href="index.html" title="GStreamer Base Plugins 1.0 Plugins Reference Manual">
 <link rel="up" href="ch01.html" title="gst-plugins-base Elements">
-<link rel="prev" href="gst-plugins-base-plugins-uridecodebin.html" title="uridecodebin">
+<link rel="prev" href="gst-plugins-base-plugins-urisourcebin.html" title="urisourcebin">
 <link rel="next" href="gst-plugins-base-plugins-videorate.html" title="videorate">
 <meta name="generator" content="GTK-Doc V1.25 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
@@ -21,7 +21,7 @@
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="ch01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="gst-plugins-base-plugins-uridecodebin.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="p" href="gst-plugins-base-plugins-urisourcebin.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="gst-plugins-base-plugins-videorate.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
@@ -118,7 +118,7 @@
 <a name="gst-plugins-base-plugins-videoconvert.description"></a><h2>Description</h2>
 <p>Convert video frames between a great variety of video formats.</p>
 <div class="refsect2">
-<a name="id-1.2.49.7.3"></a><h3>Example launch line</h3>
+<a name="id-1.2.53.7.3"></a><h3>Example launch line</h3>
 <div class="informalexample">
   <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
     <tbody>
@@ -136,7 +136,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.49.7.4.1"></a><h3>Element Information</h3>
+<a name="id-1.2.53.7.4.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -162,7 +162,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.49.7.4.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.53.7.4.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -183,11 +183,11 @@
 </tr>
 <tr>
 <td><p><span class="term">details</span></p></td>
-<td>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 </tbody>
 </table></div>
@@ -211,11 +211,11 @@
 </tr>
 <tr>
 <td><p><span class="term">details</span></p></td>
-<td>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 </tbody>
 </table></div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-videorate.html b/docs/plugins/html/gst-plugins-base-plugins-videorate.html
index 68d07b0..deededb 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-videorate.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-videorate.html
@@ -145,7 +145,7 @@
 Note that property notification will happen from the streaming thread, so
 applications should be prepared for this.</p>
 <div class="refsect2">
-<a name="id-1.2.50.7.10"></a><h3>Example pipelines</h3>
+<a name="id-1.2.54.7.10"></a><h3>Example pipelines</h3>
 <div class="informalexample">
   <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
     <tbody>
@@ -185,7 +185,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.50.7.11.1"></a><h3>Element Information</h3>
+<a name="id-1.2.54.7.11.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -211,7 +211,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.50.7.11.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.54.7.11.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-videoscale.html b/docs/plugins/html/gst-plugins-base-plugins-videoscale.html
index 66bbea3..1bd5ea9 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-videoscale.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-videoscale.html
@@ -120,7 +120,7 @@
 RGB formats and is therefore generally able to operate anywhere in a
 pipeline.</p>
 <div class="refsect2">
-<a name="id-1.2.51.7.4"></a><h3>Example pipelines</h3>
+<a name="id-1.2.55.7.4"></a><h3>Example pipelines</h3>
 <div class="informalexample">
   <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
     <tbody>
@@ -150,7 +150,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.51.7.5.1"></a><h3>Element Information</h3>
+<a name="id-1.2.55.7.5.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -176,7 +176,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.51.7.5.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.55.7.5.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -197,11 +197,11 @@
 </tr>
 <tr>
 <td><p><span class="term">details</span></p></td>
-<td>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 </tbody>
 </table></div>
@@ -225,11 +225,11 @@
 </tr>
 <tr>
 <td><p><span class="term">details</span></p></td>
-<td>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
-<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td> video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 </tbody>
 </table></div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-videotestsrc.html b/docs/plugins/html/gst-plugins-base-plugins-videotestsrc.html
index b546a7d..2bfda15 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-videotestsrc.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-videotestsrc.html
@@ -171,7 +171,7 @@
 of formats. The video test data produced can be controlled with the "pattern"
 property.</p>
 <div class="refsect2">
-<a name="id-1.2.52.7.3"></a><h3>Example launch line</h3>
+<a name="id-1.2.56.7.3"></a><h3>Example launch line</h3>
 <div class="informalexample">
   <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
     <tbody>
@@ -187,7 +187,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.52.7.4.1"></a><h3>Element Information</h3>
+<a name="id-1.2.56.7.4.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -213,7 +213,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.52.7.4.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.56.7.4.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -234,7 +234,7 @@
 </tr>
 <tr>
 <td><p><span class="term">details</span></p></td>
-<td>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
+<td>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</td>
 </tr>
 <tr>
 <td><p><span class="term"></span></p></td>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-volume.html b/docs/plugins/html/gst-plugins-base-plugins-volume.html
index 2ae48c7..6e78875 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-volume.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-volume.html
@@ -90,7 +90,7 @@
 <a name="gst-plugins-base-plugins-volume.description"></a><h2>Description</h2>
 <p>The volume element changes the volume of the audio data.</p>
 <div class="refsect2">
-<a name="id-1.2.53.8.3"></a><h3>Example launch line</h3>
+<a name="id-1.2.57.8.3"></a><h3>Example launch line</h3>
 <div class="informalexample">
   <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
     <tbody>
@@ -108,7 +108,7 @@
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.53.8.4.1"></a><h3>Element Information</h3>
+<a name="id-1.2.57.8.4.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -134,7 +134,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.53.8.4.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.57.8.4.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
diff --git a/docs/plugins/html/gst-plugins-base-plugins-vorbisdec.html b/docs/plugins/html/gst-plugins-base-plugins-vorbisdec.html
index 9ed03f1..e80d705 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-vorbisdec.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-vorbisdec.html
@@ -57,10 +57,29 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-vorbisdec.description"></a><h2>Description</h2>
+<p>This element decodes a Vorbis stream to raw float audio.</p>
+<a class="ulink" href="http://www.vorbis.com/" target="_top">Vorbis</a> is a royalty-free
+<p>audio codec maintained by the <a class="ulink" href="http://www.xiph.org/" target="_top">Xiph.org
+Foundation</a>. As it outputs raw float audio you will often need to
+put an audioconvert element after it.</p>
+<div class="refsect2">
+<a name="id-1.2.58.6.5"></a><h3>Example pipelines</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v filesrc location<span class="gtkdoc opt">=</span>sine<span class="gtkdoc opt">.</span>ogg <span class="gtkdoc opt">!</span> oggdemux <span class="gtkdoc opt">!</span> vorbisdec <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> audioresample <span class="gtkdoc opt">!</span> autoaudiosink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Decode an Ogg/Vorbis. To create an Ogg/Vorbis file refer to the documentation of vorbisenc.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.54.6.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.58.6.6.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -86,7 +105,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.54.6.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.58.6.6.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -147,8 +166,13 @@
 <div class="refsect2">
 <a name="GstVorbisDec-struct"></a><h3>struct GstVorbisDec</h3>
 <pre class="programlisting">struct GstVorbisDec;</pre>
+<p>Opaque data structure.</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-vorbisdec.see-also"></a><h2>See Also</h2>
+<p>vorbisenc, oggdemux</p>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-vorbisenc.html b/docs/plugins/html/gst-plugins-base-plugins-vorbisenc.html
index c8ad1e6..c713f32 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-vorbisenc.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-vorbisenc.html
@@ -108,10 +108,40 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-vorbisenc.description"></a><h2>Description</h2>
+<p>This element encodes raw float audio into a Vorbis stream.</p>
+<a class="ulink" href="http://www.vorbis.com/" target="_top">Vorbis</a> is a royalty-free
+<p>audio codec maintained by the <a class="ulink" href="http://www.xiph.org/" target="_top">Xiph.org
+Foundation</a>.</p>
+<div class="refsect2">
+<a name="id-1.2.59.8.5"></a><h3>Example pipelines</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v audiotestsrc wave<span class="gtkdoc opt">=</span>sine num<span class="gtkdoc opt">-</span>buffers<span class="gtkdoc opt">=</span><span class="number">100</span> <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> vorbisenc <span class="gtkdoc opt">!</span> oggmux <span class="gtkdoc opt">!</span> filesink location<span class="gtkdoc opt">=</span>sine<span class="gtkdoc opt">.</span>ogg</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Encode a test sine signal to Ogg/Vorbis.  Note that the resulting file
+will be really small because a sine signal compresses very well.
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v autoaudiosrc <span class="gtkdoc opt">!</span> audioconvert <span class="gtkdoc opt">!</span> vorbisenc <span class="gtkdoc opt">!</span> oggmux <span class="gtkdoc opt">!</span> filesink location<span class="gtkdoc opt">=</span>alsasrc<span class="gtkdoc opt">.</span>ogg</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Record from a sound card and encode to Ogg/Vorbis.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.55.8.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.59.8.6.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -137,7 +167,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.55.8.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.59.8.6.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -230,6 +260,7 @@
 <div class="refsect2">
 <a name="GstVorbisEnc-struct"></a><h3>struct GstVorbisEnc</h3>
 <pre class="programlisting">struct GstVorbisEnc;</pre>
+<p>Opaque data structure.</p>
 </div>
 </div>
 <div class="refsect1">
@@ -286,6 +317,10 @@
 <p>Default value: 0.3</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-vorbisenc.see-also"></a><h2>See Also</h2>
+<p>vorbisdec, oggmux</p>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-vorbisparse.html b/docs/plugins/html/gst-plugins-base-plugins-vorbisparse.html
index d6257b8..e783d9c 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-vorbisparse.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-vorbisparse.html
@@ -57,10 +57,48 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-vorbisparse.description"></a><h2>Description</h2>
+<p>The vorbisparse element will parse the header packets of the Vorbis
+stream and put them as the streamheader in the caps. This is used in the
+multifdsink case where you want to stream live vorbis streams to multiple
+clients, each client has to receive the streamheaders first before they can
+consume the vorbis packets.</p>
+<p>This element also makes sure that the buffers that it pushes out are properly
+timestamped and that their offset and offset_end are set. The buffers that
+vorbisparse outputs have all of the metadata that oggmux expects to receive,
+which allows you to (for example) remux an ogg/vorbis file.</p>
+<div class="refsect2">
+<a name="id-1.2.60.6.4"></a><h3>Example pipelines</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v filesrc location<span class="gtkdoc opt">=</span>sine<span class="gtkdoc opt">.</span>ogg <span class="gtkdoc opt">!</span> oggdemux <span class="gtkdoc opt">!</span> vorbisparse <span class="gtkdoc opt">!</span> fakesink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ This pipeline shows that the streamheader is set in the caps, and that each
+buffer has the timestamp, duration, offset, and offset_end set.
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1
+2</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> filesrc location<span class="gtkdoc opt">=</span>sine<span class="gtkdoc opt">.</span>ogg <span class="gtkdoc opt">!</span> oggdemux <span class="gtkdoc opt">!</span> vorbisparse \
+           <span class="gtkdoc opt">!</span> oggmux <span class="gtkdoc opt">!</span> filesink location<span class="gtkdoc opt">=</span>sine<span class="gtkdoc opt">-</span>remuxed<span class="gtkdoc opt">.</span>ogg</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ This pipeline shows remuxing. sine-remuxed.ogg might not be exactly the same
+as sine.ogg, but they should produce exactly the same decoded data.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.56.6.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.60.6.5.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -86,7 +124,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.56.6.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.60.6.5.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -147,8 +185,13 @@
 <div class="refsect2">
 <a name="GstVorbisParse-struct"></a><h3>struct GstVorbisParse</h3>
 <pre class="programlisting">struct GstVorbisParse;</pre>
+<p>Opaque data structure.</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-vorbisparse.see-also"></a><h2>See Also</h2>
+<p>vorbisdec, oggdemux, theoraparse</p>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-vorbistag.html b/docs/plugins/html/gst-plugins-base-plugins-vorbistag.html
index 91854ce..e5172fe 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-vorbistag.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-vorbistag.html
@@ -64,10 +64,36 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-vorbistag.description"></a><h2>Description</h2>
+<p>The vorbistags element can change the tag contained within a raw
+vorbis stream. Specifically, it modifies the comments header packet
+of the vorbis stream.</p>
+<p>The element will also process the stream as the <span class="type">vorbisparse</span> element does
+so it can be used when remuxing an Ogg Vorbis stream, without additional
+elements.</p>
+<p>Applications can set the tags to write using the <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstTagSetter.html#GstTagSetter-struct"><span class="type">GstTagSetter</span></a> interface.
+Tags contained withing the vorbis bitstream will be picked up
+automatically (and merged according to the merge mode set via the tag
+setter interface).</p>
+<div class="refsect2">
+<a name="id-1.2.61.7.5"></a><h3>Example pipelines</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v filesrc location<span class="gtkdoc opt">=</span>foo<span class="gtkdoc opt">.</span>ogg <span class="gtkdoc opt">!</span> oggdemux <span class="gtkdoc opt">!</span> vorbistag <span class="gtkdoc opt">!</span> oggmux <span class="gtkdoc opt">!</span> filesink location<span class="gtkdoc opt">=</span>bar<span class="gtkdoc opt">.</span>ogg</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ This element is not useful with gst-launch-1.0, because it does not support
+setting the tags on a <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstTagSetter.html#GstTagSetter-struct"><span class="type">GstTagSetter</span></a> interface. Conceptually, the element
+will usually be used in this order though.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.57.7.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.61.7.6.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -93,7 +119,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.57.7.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.61.7.6.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -154,8 +180,13 @@
 <div class="refsect2">
 <a name="GstVorbisTag-struct"></a><h3>struct GstVorbisTag</h3>
 <pre class="programlisting">struct GstVorbisTag;</pre>
+<p>Opaque data structure.</p>
 </div>
 </div>
+<div class="refsect1">
+<a name="gst-plugins-base-plugins-vorbistag.see-also"></a><h2>See Also</h2>
+<p><span class="type">oggdemux</span>, <span class="type">oggmux</span>, <span class="type">vorbisparse</span>, <a href="/usr/share/gtk-doc/html/gstreamer-1.0GstTagSetter.html#GstTagSetter-struct"><span class="type">GstTagSetter</span></a></p>
+</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.25</div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-ximagesink.html b/docs/plugins/html/gst-plugins-base-plugins-ximagesink.html
index 1651579..a8990b1 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-ximagesink.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-ximagesink.html
@@ -120,10 +120,113 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-ximagesink.description"></a><h2>Description</h2>
+<p>XImageSink renders video frames to a drawable (XWindow) on a local or remote
+display. This element can receive a Window ID from the application through
+the <a href="../html/gst-plugins-base-libs-gstvideooverlay.html#GstVideoOverlay-struct"><span class="type">GstVideoOverlay</span></a> interface and will then render video frames in this
+drawable. If no Window ID was provided by the application, the element will
+create its own internal window and render into it.</p>
+<div class="refsect2">
+<a name="id-1.2.62.8.3"></a><h3>Scaling</h3>
+<p>
+As standard XImage rendering to a drawable is not scaled, XImageSink will use
+reverse caps negotiation to try to get scaled video frames for the drawable.
+This is accomplished by asking the peer pad if it accepts some different caps
+which in most cases implies that there is a scaling element in the pipeline,
+or that an element generating the video frames can generate them with a 
+different geometry. This mechanism is handled during buffer allocations, for
+each allocation request the video sink will check the drawable geometry, look
+at the <a class="link" href="gst-plugins-base-plugins-ximagesink.html#GstXImageSink--force-aspect-ratio" title="The “force-aspect-ratio” property"><span class="type">“force-aspect-ratio”</span></a> property, calculate the geometry of
+desired video frames and then check that the peer pad accept those new caps.
+If it does it will then allocate a buffer in video memory with this new
+geometry and return it with the new caps.
+</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.62.8.4"></a><h3>Events</h3>
+<p>
+XImageSink creates a thread to handle events coming from the drawable. There
+are several kind of events that can be grouped in 2 big categories: input 
+events and window state related events. Input events will be translated to
+navigation events and pushed upstream for other elements to react on them.
+This includes events such as pointer moves, key press/release, clicks etc...
+Other events are used to handle the drawable appearance even when the data
+is not flowing (GST_STATE_PAUSED). That means that even when the element is
+paused, it will receive expose events from the drawable and draw the latest
+frame with correct borders/aspect-ratio.
+</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.62.8.5"></a><h3>Pixel aspect ratio</h3>
+<p>
+When changing state to GST_STATE_READY, XImageSink will open a connection to
+the display specified in the <a class="link" href="gst-plugins-base-plugins-ximagesink.html#GstXImageSink--display" title="The “display” property"><span class="type">“display”</span></a> property or the default
+display if nothing specified. Once this connection is open it will inspect 
+the display configuration including the physical display geometry and 
+then calculate the pixel aspect ratio. When caps negotiation will occur, the
+video sink will set the calculated pixel aspect ratio on the caps to make 
+sure that incoming video frames will have the correct pixel aspect ratio for
+this display. Sometimes the calculated pixel aspect ratio can be wrong, it is
+then possible to enforce a specific pixel aspect ratio using the
+<a class="link" href="gst-plugins-base-plugins-ximagesink.html#GstXImageSink--pixel-aspect-ratio" title="The “pixel-aspect-ratio” property"><span class="type">“pixel-aspect-ratio”</span></a> property.
+</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.62.8.6"></a><h3>Examples</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v videotestsrc <span class="gtkdoc opt">!</span> queue <span class="gtkdoc opt">!</span> ximagesink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ A pipeline to test reverse negotiation. When the test video signal appears
+you can resize the window and see that scaled buffers of the desired size are
+going to arrive with a short delay. This illustrates how buffers of desired
+size are allocated along the way. If you take away the queue, scaling will
+happen almost immediately.
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v videotestsrc <span class="gtkdoc opt">!</span> navigationtest <span class="gtkdoc opt">!</span> videoconvert <span class="gtkdoc opt">!</span> ximagesink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ A pipeline to test navigation events.
+While moving the mouse pointer over the test signal you will see a black box
+following the mouse pointer. If you press the mouse button somewhere on the 
+video and release it somewhere else a green box will appear where you pressed
+the button and a red one where you released it. (The navigationtest element
+is part of gst-plugins-good.)
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v videotestsrc <span class="gtkdoc opt">!</span> video<span class="gtkdoc opt">/</span>x<span class="gtkdoc opt">-</span>raw<span class="gtkdoc opt">,</span> pixel<span class="gtkdoc opt">-</span>aspect<span class="gtkdoc opt">-</span>ratio<span class="gtkdoc opt">=(</span>fraction<span class="gtkdoc opt">)</span><span class="number">4</span><span class="gtkdoc opt">/</span><span class="number">3</span> <span class="gtkdoc opt">!</span> videoscale <span class="gtkdoc opt">!</span> ximagesink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ This is faking a 4/3 pixel aspect ratio caps on video frames produced by
+videotestsrc, in most cases the pixel aspect ratio of the display will be
+1/1. This means that videoscale will have to do the scaling to convert 
+incoming frames to a size that will match the display pixel aspect ratio
+(from 320x240 to 320x180 in this case). Note that you might have to escape 
+some characters for your shell like '\(fraction\)'.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.58.8.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.62.8.7.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -149,7 +252,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.58.8.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.62.8.7.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -186,6 +289,18 @@
 <div class="refsect2">
 <a name="GstXImageSink-struct"></a><h3>struct GstXImageSink</h3>
 <pre class="programlisting">struct GstXImageSink;</pre>
+<p>The <a class="link" href="gst-plugins-base-plugins-ximagesink.html#GstXImageSink"><span class="type">GstXImageSink</span></a> data structure.</p>
+<div class="refsect3">
+<a name="GstXImageSink.members"></a><h4>Members</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody></tbody>
+</table></div>
+</div>
 </div>
 </div>
 <div class="refsect1">
@@ -241,7 +356,7 @@
 <div class="refsect2">
 <a name="GstXImageSink--window-height"></a><h3>The <code class="literal">“window-height”</code> property</h3>
 <pre class="programlisting">  “window-height”            <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="type">guint64</span></a></pre>
-<p>Height of the window.</p>
+<p>Actual height of the video window.</p>
 <p>Flags: Read</p>
 <p>Default value: 0</p>
 </div>
@@ -249,7 +364,7 @@
 <div class="refsect2">
 <a name="GstXImageSink--window-width"></a><h3>The <code class="literal">“window-width”</code> property</h3>
 <pre class="programlisting">  “window-width”             <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="type">guint64</span></a></pre>
-<p>Width of the window.</p>
+<p>Actual width of the video window.</p>
 <p>Flags: Read</p>
 <p>Default value: 0</p>
 </div>
diff --git a/docs/plugins/html/gst-plugins-base-plugins-xvimagesink.html b/docs/plugins/html/gst-plugins-base-plugins-xvimagesink.html
index 4c1f986..1bf4bf9 100644
--- a/docs/plugins/html/gst-plugins-base-plugins-xvimagesink.html
+++ b/docs/plugins/html/gst-plugins-base-plugins-xvimagesink.html
@@ -172,10 +172,139 @@
 </div>
 <div class="refsect1">
 <a name="gst-plugins-base-plugins-xvimagesink.description"></a><h2>Description</h2>
+<p>XvImageSink renders video frames to a drawable (XWindow) on a local display
+using the XVideo extension. Rendering to a remote display is theoretically
+possible but i doubt that the XVideo extension is actually available when
+connecting to a remote display. This element can receive a Window ID from the
+application through the <a href="../html/gst-plugins-base-libs-gstvideooverlay.html#GstVideoOverlay-struct"><span class="type">GstVideoOverlay</span></a> interface and will then render
+video frames in this drawable. If no Window ID was provided by the
+application, the element will create its own internal window and render
+into it.</p>
+<div class="refsect2">
+<a name="id-1.2.63.8.3"></a><h3>Scaling</h3>
+<p>
+The XVideo extension, when it's available, handles hardware accelerated
+scaling of video frames. This means that the element will just accept
+incoming video frames no matter their geometry and will then put them to the
+drawable scaling them on the fly. Using the <a class="link" href="gst-plugins-base-plugins-xvimagesink.html#GstXvImageSink--force-aspect-ratio" title="The “force-aspect-ratio” property"><span class="type">“force-aspect-ratio”</span></a>
+property it is possible to enforce scaling with a constant aspect ratio,
+which means drawing black borders around the video frame.
+</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.63.8.4"></a><h3>Events</h3>
+<p>
+XvImageSink creates a thread to handle events coming from the drawable. There
+are several kind of events that can be grouped in 2 big categories: input
+events and window state related events. Input events will be translated to
+navigation events and pushed upstream for other elements to react on them.
+This includes events such as pointer moves, key press/release, clicks etc...
+Other events are used to handle the drawable appearance even when the data
+is not flowing (GST_STATE_PAUSED). That means that even when the element is
+paused, it will receive expose events from the drawable and draw the latest
+frame with correct borders/aspect-ratio.
+</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.63.8.5"></a><h3>Pixel aspect ratio</h3>
+<p>
+When changing state to GST_STATE_READY, XvImageSink will open a connection to
+the display specified in the <a class="link" href="gst-plugins-base-plugins-xvimagesink.html#GstXvImageSink--display" title="The “display” property"><span class="type">“display”</span></a> property or the
+default display if nothing specified. Once this connection is open it will
+inspect the display configuration including the physical display geometry and
+then calculate the pixel aspect ratio. When receiving video frames with a
+different pixel aspect ratio, XvImageSink will use hardware scaling to
+display the video frames correctly on display's pixel aspect ratio.
+Sometimes the calculated pixel aspect ratio can be wrong, it is
+then possible to enforce a specific pixel aspect ratio using the
+<a class="link" href="gst-plugins-base-plugins-xvimagesink.html#GstXvImageSink--pixel-aspect-ratio" title="The “pixel-aspect-ratio” property"><span class="type">“pixel-aspect-ratio”</span></a> property.
+</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="id-1.2.63.8.6"></a><h3>Examples</h3>
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v videotestsrc <span class="gtkdoc opt">!</span> xvimagesink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ A pipeline to test hardware scaling.
+When the test video signal appears you can resize the window and see that
+video frames are scaled through hardware (no extra CPU cost). By default
+the image will never be distorted when scaled, instead black borders will
+be added if needed.
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v videotestsrc <span class="gtkdoc opt">!</span> xvimagesink force<span class="gtkdoc opt">-</span>aspect<span class="gtkdoc opt">-</span>ratio<span class="gtkdoc opt">=</span><span class="keyword">false</span></pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Same pipeline with <a class="link" href="gst-plugins-base-plugins-xvimagesink.html#GstXvImageSink--force-aspect-ratio" title="The “force-aspect-ratio” property"><span class="type">“force-aspect-ratio”</span></a> property set to
+false. You can observe that no borders are drawn around the scaled image
+now and it will be distorted to fill the entire frame instead of respecting
+the aspect ratio.
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v videotestsrc <span class="gtkdoc opt">!</span> navigationtest <span class="gtkdoc opt">!</span> xvimagesink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ A pipeline to test navigation events.
+While moving the mouse pointer over the test signal you will see a black box
+following the mouse pointer. If you press the mouse button somewhere on the
+video and release it somewhere else a green box will appear where you pressed
+the button and a red one where you released it. (The navigationtest element
+is part of gst-plugins-good.) You can observe here that even if the images
+are scaled through hardware the pointer coordinates are converted back to the
+original video frame geometry so that the box can be drawn to the correct
+position. This also handles borders correctly, limiting coordinates to the
+image area
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v videotestsrc <span class="gtkdoc opt">!</span> video<span class="gtkdoc opt">/</span>x<span class="gtkdoc opt">-</span>raw<span class="gtkdoc opt">,</span> pixel<span class="gtkdoc opt">-</span>aspect<span class="gtkdoc opt">-</span>ratio<span class="gtkdoc opt">=</span><span class="number">4</span><span class="gtkdoc opt">/</span><span class="number">3</span> <span class="gtkdoc opt">!</span> xvimagesink</pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ This is faking a 4/3 pixel aspect ratio caps on video frames produced by
+videotestsrc, in most cases the pixel aspect ratio of the display will be
+1/1. This means that XvImageSink will have to do the scaling to convert
+incoming frames to a size that will match the display pixel aspect ratio
+(from 320x240 to 320x180 in this case).
+<div class="informalexample">
+  <table class="listing_frame" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td class="listing_lines" align="right"><pre>1</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> <span class="gtkdoc opt">-</span>v videotestsrc <span class="gtkdoc opt">!</span> xvimagesink hue<span class="gtkdoc opt">=</span><span class="number">100</span> saturation<span class="gtkdoc opt">=-</span><span class="number">100</span> brightness<span class="gtkdoc opt">=</span><span class="number">100</span></pre></td>
+      </tr>
+    </tbody>
+  </table>
+</div>
+ Demonstrates how to use the colorbalance interface.
+</div>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <div class="refsect2">
-<a name="id-1.2.59.8.2.1"></a><h3>Element Information</h3>
+<a name="id-1.2.63.8.7.1"></a><h3>Element Information</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -201,7 +330,7 @@
 </div>
 <hr>
 <div class="refsect2">
-<a name="id-1.2.59.8.2.2"></a><h3>Element Pads</h3>
+<a name="id-1.2.63.8.7.2"></a><h3>Element Pads</h3>
 <div class="variablelist"><table border="0" class="variablelist">
 <colgroup>
 <col align="left" valign="top">
@@ -238,6 +367,18 @@
 <div class="refsect2">
 <a name="GstXvImageSink-struct"></a><h3>struct GstXvImageSink</h3>
 <pre class="programlisting">struct GstXvImageSink;</pre>
+<p>The <a class="link" href="gst-plugins-base-plugins-xvimagesink.html#GstXvImageSink"><span class="type">GstXvImageSink</span></a> data structure.</p>
+<div class="refsect3">
+<a name="GstXvImageSink.members"></a><h4>Members</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody></tbody>
+</table></div>
+</div>
 </div>
 </div>
 <div class="refsect1">
@@ -245,7 +386,7 @@
 <div class="refsect2">
 <a name="GstXvImageSink--autopaint-colorkey"></a><h3>The <code class="literal">“autopaint-colorkey”</code> property</h3>
 <pre class="programlisting">  “autopaint-colorkey”       <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
-<p>Whether to autofill overlay with colorkey.</p>
+<p>Whether to autofill overlay with colorkey</p>
 <p>Flags: Read / Write</p>
 <p>Default value: TRUE</p>
 </div>
@@ -311,7 +452,8 @@
 <div class="refsect2">
 <a name="GstXvImageSink--draw-borders"></a><h3>The <code class="literal">“draw-borders”</code> property</h3>
 <pre class="programlisting">  “draw-borders”             <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
-<p>Draw black borders to fill unused area in force-aspect-ratio mode.</p>
+<p>Draw black borders when using GstXvImageSink:force-aspect-ratio to fill
+unused parts of the video area.</p>
 <p>Flags: Read / Write</p>
 <p>Default value: TRUE</p>
 </div>
@@ -335,7 +477,8 @@
 <div class="refsect2">
 <a name="GstXvImageSink--handle-expose"></a><h3>The <code class="literal">“handle-expose”</code> property</h3>
 <pre class="programlisting">  “handle-expose”            <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
-<p>When enabled, the current frame will always be drawn in response to X Expose events.</p>
+<p>When enabled, the current frame will always be drawn in response to X
+Expose.</p>
 <p>Flags: Read / Write</p>
 <p>Default value: TRUE</p>
 </div>
@@ -377,7 +520,7 @@
 <div class="refsect2">
 <a name="GstXvImageSink--window-height"></a><h3>The <code class="literal">“window-height”</code> property</h3>
 <pre class="programlisting">  “window-height”            <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="type">guint64</span></a></pre>
-<p>Height of the window.</p>
+<p>Actual height of the video window.</p>
 <p>Flags: Read</p>
 <p>Default value: 0</p>
 </div>
@@ -385,7 +528,7 @@
 <div class="refsect2">
 <a name="GstXvImageSink--window-width"></a><h3>The <code class="literal">“window-width”</code> property</h3>
 <pre class="programlisting">  “window-width”             <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="type">guint64</span></a></pre>
-<p>Width of the window.</p>
+<p>Actual width of the video window.</p>
 <p>Flags: Read</p>
 <p>Default value: 0</p>
 </div>
diff --git a/docs/plugins/html/index.html b/docs/plugins/html/index.html
index 764cba9..e794f07 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 Base Plugins 1.0 Plugins Reference Manual</p></th></tr></table></div>
 <div><p class="releaseinfo">
-      for GStreamer Base Plugins 1.0 (1.8.3)
+      for GStreamer Base Plugins 1.0 (1.9.90)
       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-base/html/" target="_top">http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base/html/</a>.
     </p></div>
@@ -35,10 +35,10 @@
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-alsasink.html">alsasink</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
-<span class="refentrytitle"><a href="gst-plugins-base-plugins-alsasrc.html">alsasrc</a></span><span class="refpurpose"></span>
+<span class="refentrytitle"><a href="gst-plugins-base-plugins-appsink.html">appsink</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
-<span class="refentrytitle"><a href="gst-plugins-base-plugins-appsink.html">appsink</a></span><span class="refpurpose"></span>
+<span class="refentrytitle"><a href="gst-plugins-base-plugins-alsasrc.html">alsasrc</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-appsrc.html">appsrc</a></span><span class="refpurpose"></span>
@@ -65,6 +65,9 @@
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-decodebin.html">decodebin</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
+<span class="refentrytitle"><a href="gst-plugins-base-plugins-decodebin3.html">decodebin3</a></span><span class="refpurpose"></span>
+</dt>
+<dt>
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-encodebin.html">encodebin</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
@@ -113,9 +116,15 @@
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-opusenc.html">opusenc</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
+<span class="refentrytitle"><a href="gst-plugins-base-plugins-parsebin.html">parsebin</a></span><span class="refpurpose"></span>
+</dt>
+<dt>
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-playbin.html">playbin</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
+<span class="refentrytitle"><a href="gst-plugins-base-plugins-playbin3.html">playbin3</a></span><span class="refpurpose"></span>
+</dt>
+<dt>
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-playsink.html">playsink</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
@@ -167,6 +176,9 @@
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-uridecodebin.html">uridecodebin</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
+<span class="refentrytitle"><a href="gst-plugins-base-plugins-urisourcebin.html">urisourcebin</a></span><span class="refpurpose"></span>
+</dt>
+<dt>
 <span class="refentrytitle"><a href="gst-plugins-base-plugins-videoconvert.html">videoconvert</a></span><span class="refpurpose"></span>
 </dt>
 <dt>
diff --git a/docs/plugins/inspect/plugin-adder.xml b/docs/plugins/inspect/plugin-adder.xml
index 55134ed..4b33951 100644
--- a/docs/plugins/inspect/plugin-adder.xml
+++ b/docs/plugins/inspect/plugin-adder.xml
@@ -3,7 +3,7 @@
   <description>Adds multiple streams</description>
   <filename>../../gst/adder/.libs/libgstadder.so</filename>
   <basename>libgstadder.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-alsa.xml b/docs/plugins/inspect/plugin-alsa.xml
index 0340182..93639ed 100644
--- a/docs/plugins/inspect/plugin-alsa.xml
+++ b/docs/plugins/inspect/plugin-alsa.xml
@@ -3,7 +3,7 @@
   <description>ALSA plugin library</description>
   <filename>../../ext/alsa/.libs/libgstalsa.so</filename>
   <basename>libgstalsa.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-app.xml b/docs/plugins/inspect/plugin-app.xml
index 108d58f..5f00d19 100644
--- a/docs/plugins/inspect/plugin-app.xml
+++ b/docs/plugins/inspect/plugin-app.xml
@@ -3,7 +3,7 @@
   <description>Elements used to communicate with applications</description>
   <filename>../../gst/app/.libs/libgstapp.so</filename>
   <basename>libgstapp.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-audioconvert.xml b/docs/plugins/inspect/plugin-audioconvert.xml
index 98b7e56..d4482f7 100644
--- a/docs/plugins/inspect/plugin-audioconvert.xml
+++ b/docs/plugins/inspect/plugin-audioconvert.xml
@@ -3,7 +3,7 @@
   <description>Convert audio to different formats</description>
   <filename>../../gst/audioconvert/.libs/libgstaudioconvert.so</filename>
   <basename>libgstaudioconvert.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-audiorate.xml b/docs/plugins/inspect/plugin-audiorate.xml
index 6ecdc8b..1ed6e56 100644
--- a/docs/plugins/inspect/plugin-audiorate.xml
+++ b/docs/plugins/inspect/plugin-audiorate.xml
@@ -3,7 +3,7 @@
   <description>Adjusts audio frames</description>
   <filename>../../gst/audiorate/.libs/libgstaudiorate.so</filename>
   <basename>libgstaudiorate.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-audioresample.xml b/docs/plugins/inspect/plugin-audioresample.xml
index 0204ae1..fe9634e 100644
--- a/docs/plugins/inspect/plugin-audioresample.xml
+++ b/docs/plugins/inspect/plugin-audioresample.xml
@@ -3,7 +3,7 @@
   <description>Resamples audio</description>
   <filename>../../gst/audioresample/.libs/libgstaudioresample.so</filename>
   <basename>libgstaudioresample.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
@@ -20,13 +20,13 @@
           <name>sink</name>
           <direction>sink</direction>
           <presence>always</presence>
-          <details>audio/x-raw, format=(string){ F32LE, F64LE, S32LE, S24LE, S16LE, S8 }, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], layout=(string){ interleaved, non-interleaved }</details>
+          <details>audio/x-raw, format=(string){ S8, U8, S16LE, S16BE, U16LE, U16BE, S24_32LE, S24_32BE, U24_32LE, U24_32BE, S32LE, S32BE, U32LE, U32BE, S24LE, S24BE, U24LE, U24BE, S20LE, S20BE, U20LE, U20BE, S18LE, S18BE, U18LE, U18BE, F32LE, F32BE, F64LE, F64BE }, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], layout=(string){ interleaved, non-interleaved }</details>
         </caps>
         <caps>
           <name>src</name>
           <direction>source</direction>
           <presence>always</presence>
-          <details>audio/x-raw, format=(string){ F32LE, F64LE, S32LE, S24LE, S16LE, S8 }, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], layout=(string){ interleaved, non-interleaved }</details>
+          <details>audio/x-raw, format=(string){ S8, U8, S16LE, S16BE, U16LE, U16BE, S24_32LE, S24_32BE, U24_32LE, U24_32BE, S32LE, S32BE, U32LE, U32BE, S24LE, S24BE, U24LE, U24BE, S20LE, S20BE, U20LE, U20BE, S18LE, S18BE, U18LE, U18BE, F32LE, F32BE, F64LE, F64BE }, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], layout=(string){ interleaved, non-interleaved }</details>
         </caps>
       </pads>
     </element>
diff --git a/docs/plugins/inspect/plugin-audiotestsrc.xml b/docs/plugins/inspect/plugin-audiotestsrc.xml
index 7db7722..ac1f95e 100644
--- a/docs/plugins/inspect/plugin-audiotestsrc.xml
+++ b/docs/plugins/inspect/plugin-audiotestsrc.xml
@@ -3,7 +3,7 @@
   <description>Creates audio test signals of given frequency and volume</description>
   <filename>../../gst/audiotestsrc/.libs/libgstaudiotestsrc.so</filename>
   <basename>libgstaudiotestsrc.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-cdparanoia.xml b/docs/plugins/inspect/plugin-cdparanoia.xml
index 266d390..874ebc8 100644
--- a/docs/plugins/inspect/plugin-cdparanoia.xml
+++ b/docs/plugins/inspect/plugin-cdparanoia.xml
@@ -3,7 +3,7 @@
   <description>Read audio from CD in paranoid mode</description>
   <filename>../../ext/cdparanoia/.libs/libgstcdparanoia.so</filename>
   <basename>libgstcdparanoia.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-encoding.xml b/docs/plugins/inspect/plugin-encoding.xml
index 7afc091..30a693e 100644
--- a/docs/plugins/inspect/plugin-encoding.xml
+++ b/docs/plugins/inspect/plugin-encoding.xml
@@ -3,7 +3,7 @@
   <description>various encoding-related elements</description>
   <filename>../../gst/encoding/.libs/libgstencodebin.so</filename>
   <basename>libgstencodebin.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-gio.xml b/docs/plugins/inspect/plugin-gio.xml
index cfdb024..bf7049b 100644
--- a/docs/plugins/inspect/plugin-gio.xml
+++ b/docs/plugins/inspect/plugin-gio.xml
@@ -3,7 +3,7 @@
   <description>GIO elements</description>
   <filename>../../gst/gio/.libs/libgstgio.so</filename>
   <basename>libgstgio.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-libvisual.xml b/docs/plugins/inspect/plugin-libvisual.xml
index ccd95ee..d16008a 100644
--- a/docs/plugins/inspect/plugin-libvisual.xml
+++ b/docs/plugins/inspect/plugin-libvisual.xml
@@ -3,7 +3,7 @@
   <description>libvisual visualization plugins</description>
   <filename>../../ext/libvisual/.libs/libgstlibvisual.so</filename>
   <basename>libgstlibvisual.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-ogg.xml b/docs/plugins/inspect/plugin-ogg.xml
index a040d6f..e7eb52b 100644
--- a/docs/plugins/inspect/plugin-ogg.xml
+++ b/docs/plugins/inspect/plugin-ogg.xml
@@ -3,7 +3,7 @@
   <description>ogg stream manipulation (info about ogg: http://xiph.org)</description>
   <filename>../../ext/ogg/.libs/libgstogg.so</filename>
   <basename>libgstogg.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
@@ -122,7 +122,7 @@
           <name>src</name>
           <direction>source</direction>
           <presence>sometimes</presence>
-          <details>audio/ms-gsm, rate=(int)[ 1, 96000 ], channels=(int)[ 1, 2 ]; audio/mpeg, mpegversion=(int)1, layer=(int)3, rate=(int)[ 8000, 48000 ], channels=(int)[ 1, 2 ]; audio/mpeg, mpegversion=(int)1, layer=(int)2, rate=(int)[ 16000, 48000 ], channels=(int)[ 1, 2 ]; audio/x-raw, format=(string){ S8, U8, S16LE, U16LE, S24LE, U24LE, S32LE, U32LE }, layout=(string)interleaved, rate=(int)[ 1000, 192000 ], channels=(int)[ 1, 8 ]; audio/x-vorbis, rate=(int)[ 1000, 192000 ], channels=(int)[ 1, 2 ]; audio/x-ac3, rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 6 ]; audio/x-dts; audio/mpeg, mpegversion=(int)4, rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 8 ]; audio/x-alaw, rate=(int)[ 1000, 48000 ], channels=(int)[ 1, 2 ]; audio/x-mulaw, rate=(int)[ 1000, 48000 ], channels=(int)[ 1, 2 ]; audio/x-wms, bitrate=(int)[ 0, 2147483647 ], rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 2 ], block_align=(int)[ 1, 2147483647 ]; audio/x-adpcm, layout=(string)microsoft, rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 2 ], block_align=(int)[ 1, 2147483647 ]; audio/x-adpcm, layout=(string)dvi, rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 2 ], block_align=(int)[ 1, 2147483647 ]; audio/x-truespeech, rate=(int)8000, channels=(int)[ 1, 2 ]; audio/x-wma, wmaversion=(int)1, bitrate=(int)[ 0, 2147483647 ], rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 8 ], block_align=(int)[ 1, 2147483647 ]; audio/x-wma, wmaversion=(int)2, bitrate=(int)[ 0, 2147483647 ], rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 8 ], block_align=(int)[ 1, 2147483647 ]; audio/x-wma, wmaversion=(int)3, bitrate=(int)[ 0, 2147483647 ], rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 8 ], block_align=(int)[ 1, 2147483647 ]; audio/x-vnd.sony.atrac3, rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 2 ]; audio/x-raw, format=(string){ F32LE, F64LE }, layout=(string)interleaved, rate=(int)[ 1000, 192000 ], channels=(int)[ 1, 8 ]; audio/x-voxware, voxwaretype=(int)117, rate=(int)[ 1000, 96000 ], channels=(int)[ 1, 2 ]; audio/x-adpcm, layout=(string)dk4, rate=(int)[ 8000, 96000 ], channels=(int)[ 1, 2 ]; audio/x-adpcm, layout=(string)dk3, rate=(int)[ 8000, 96000 ], channels=(int)[ 1, 2 ]; audio/x-adpcm, layout=(string)dvi, rate=(int)[ 8000, 96000 ], channels=(int)[ 1, 2 ]; audio/AMR, rate=(int)8000, channels=(int)1; audio/AMR-WB, rate=(int)16000, channels=(int)1; audio/x-siren; application/x-ogg-avi</details>
+          <details>audio/ms-gsm; audio/mpeg, mpegversion=(int)1, layer=(int)3; audio/mpeg, mpegversion=(int)1, layer=(int)2; audio/x-raw, format=(string){ S8, U8, S16LE, U16LE, S24LE, U24LE, S32LE, U32LE }, layout=(string)interleaved; audio/x-vorbis; audio/x-ac3; audio/x-dts; audio/mpeg, mpegversion=(int)4; audio/x-alaw; audio/x-mulaw; audio/x-wms, bitrate=(int)[ 0, 2147483647 ], block_align=(int)[ 1, 2147483647 ]; audio/x-adpcm, layout=(string)microsoft, block_align=(int)[ 1, 2147483647 ]; audio/x-adpcm, layout=(string)dvi, block_align=(int)[ 1, 2147483647 ]; audio/x-truespeech; audio/x-wma, wmaversion=(int)1, bitrate=(int)[ 0, 2147483647 ], block_align=(int)[ 1, 2147483647 ]; audio/x-wma, wmaversion=(int)2, bitrate=(int)[ 0, 2147483647 ], block_align=(int)[ 1, 2147483647 ]; audio/x-wma, wmaversion=(int)3, bitrate=(int)[ 0, 2147483647 ], block_align=(int)[ 1, 2147483647 ]; audio/x-vnd.sony.atrac3; audio/x-raw, format=(string){ F32LE, F64LE }, layout=(string)interleaved; audio/x-voxware, voxwaretype=(int)117; audio/x-adpcm, layout=(string)dk4; audio/x-adpcm, layout=(string)dk3; audio/x-adpcm, layout=(string)dvi; audio/AMR; audio/AMR-WB; audio/x-siren; application/x-ogg-avi</details>
         </caps>
       </pads>
     </element>
diff --git a/docs/plugins/inspect/plugin-opus.xml b/docs/plugins/inspect/plugin-opus.xml
index e2ac049..2ede8a1 100644
--- a/docs/plugins/inspect/plugin-opus.xml
+++ b/docs/plugins/inspect/plugin-opus.xml
@@ -3,7 +3,7 @@
   <description>OPUS plugin library</description>
   <filename>../../ext/opus/.libs/libgstopus.so</filename>
   <basename>libgstopus.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-pango.xml b/docs/plugins/inspect/plugin-pango.xml
index 4116aef..5179d85 100644
--- a/docs/plugins/inspect/plugin-pango.xml
+++ b/docs/plugins/inspect/plugin-pango.xml
@@ -3,7 +3,7 @@
   <description>Pango-based text rendering and overlay</description>
   <filename>../../ext/pango/.libs/libgstpango.so</filename>
   <basename>libgstpango.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
@@ -20,13 +20,13 @@
           <name>video_sink</name>
           <direction>sink</direction>
           <presence>always</presence>
-          <details>video/x-raw, format=(string){ BGRx, RGBx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, I420, YV12, AYUV, YUY2, UYVY, v308, Y41B, Y42B, Y444, NV12, NV21, A420, YUV9, YVU9, IYU1, GRAY8 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
+          <details>video/x-raw, format=(string){ BGRx, RGBx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, I420, YV12, AYUV, YUY2, UYVY, v308, Y41B, Y42B, Y444, NV12, NV21, A420, YUV9, YVU9, IYU1, GRAY8 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
         </caps>
         <caps>
           <name>src</name>
           <direction>source</direction>
           <presence>always</presence>
-          <details>video/x-raw, format=(string){ BGRx, RGBx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, I420, YV12, AYUV, YUY2, UYVY, v308, Y41B, Y42B, Y444, NV12, NV21, A420, YUV9, YVU9, IYU1, GRAY8 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
+          <details>video/x-raw, format=(string){ BGRx, RGBx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, I420, YV12, AYUV, YUY2, UYVY, v308, Y41B, Y42B, Y444, NV12, NV21, A420, YUV9, YVU9, IYU1, GRAY8 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
         </caps>
       </pads>
     </element>
@@ -47,13 +47,13 @@
           <name>video_sink</name>
           <direction>sink</direction>
           <presence>always</presence>
-          <details>video/x-raw, format=(string){ BGRx, RGBx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, I420, YV12, AYUV, YUY2, UYVY, v308, Y41B, Y42B, Y444, NV12, NV21, A420, YUV9, YVU9, IYU1, GRAY8 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
+          <details>video/x-raw, format=(string){ BGRx, RGBx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, I420, YV12, AYUV, YUY2, UYVY, v308, Y41B, Y42B, Y444, NV12, NV21, A420, YUV9, YVU9, IYU1, GRAY8 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
         </caps>
         <caps>
           <name>src</name>
           <direction>source</direction>
           <presence>always</presence>
-          <details>video/x-raw, format=(string){ BGRx, RGBx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, I420, YV12, AYUV, YUY2, UYVY, v308, Y41B, Y42B, Y444, NV12, NV21, A420, YUV9, YVU9, IYU1, GRAY8 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
+          <details>video/x-raw, format=(string){ BGRx, RGBx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, I420, YV12, AYUV, YUY2, UYVY, v308, Y41B, Y42B, Y444, NV12, NV21, A420, YUV9, YVU9, IYU1, GRAY8 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
         </caps>
       </pads>
     </element>
@@ -89,13 +89,13 @@
           <name>video_sink</name>
           <direction>sink</direction>
           <presence>always</presence>
-          <details>video/x-raw, format=(string){ BGRx, RGBx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, I420, YV12, AYUV, YUY2, UYVY, v308, Y41B, Y42B, Y444, NV12, NV21, A420, YUV9, YVU9, IYU1, GRAY8 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
+          <details>video/x-raw, format=(string){ BGRx, RGBx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, I420, YV12, AYUV, YUY2, UYVY, v308, Y41B, Y42B, Y444, NV12, NV21, A420, YUV9, YVU9, IYU1, GRAY8 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
         </caps>
         <caps>
           <name>src</name>
           <direction>source</direction>
           <presence>always</presence>
-          <details>video/x-raw, format=(string){ BGRx, RGBx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, I420, YV12, AYUV, YUY2, UYVY, v308, Y41B, Y42B, Y444, NV12, NV21, A420, YUV9, YVU9, IYU1, GRAY8 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
+          <details>video/x-raw, format=(string){ BGRx, RGBx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, I420, YV12, AYUV, YUY2, UYVY, v308, Y41B, Y42B, Y444, NV12, NV21, A420, YUV9, YVU9, IYU1, GRAY8 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
         </caps>
       </pads>
     </element>
diff --git a/docs/plugins/inspect/plugin-playback.xml b/docs/plugins/inspect/plugin-playback.xml
index fa5066b..65ad797 100644
--- a/docs/plugins/inspect/plugin-playback.xml
+++ b/docs/plugins/inspect/plugin-playback.xml
@@ -3,7 +3,7 @@
   <description>various playback elements</description>
   <filename>../../gst/playback/.libs/libgstplayback.so</filename>
   <basename>libgstplayback.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
@@ -31,6 +31,72 @@
       </pads>
     </element>
     <element>
+      <name>decodebin3</name>
+      <longname>Decoder Bin 3</longname>
+      <class>Generic/Bin/Decoder</class>
+      <description>Autoplug and decode to raw media</description>
+      <author>Edward Hervey &lt;edward@centricular.com&gt;</author>
+      <pads>
+        <caps>
+          <name>sink</name>
+          <direction>sink</direction>
+          <presence>always</presence>
+          <details>ANY</details>
+        </caps>
+        <caps>
+          <name>sink_%u</name>
+          <direction>sink</direction>
+          <presence>request</presence>
+          <details>ANY</details>
+        </caps>
+        <caps>
+          <name>audio_%u</name>
+          <direction>source</direction>
+          <presence>sometimes</presence>
+          <details>ANY</details>
+        </caps>
+        <caps>
+          <name>src_%u</name>
+          <direction>source</direction>
+          <presence>sometimes</presence>
+          <details>ANY</details>
+        </caps>
+        <caps>
+          <name>text_%u</name>
+          <direction>source</direction>
+          <presence>sometimes</presence>
+          <details>ANY</details>
+        </caps>
+        <caps>
+          <name>video_%u</name>
+          <direction>source</direction>
+          <presence>sometimes</presence>
+          <details>ANY</details>
+        </caps>
+      </pads>
+    </element>
+    <element>
+      <name>parsebin</name>
+      <longname>Parse Bin</longname>
+      <class>Generic/Bin/Parser</class>
+      <description>Parse and de-multiplex to elementary stream</description>
+      <author>Jan Schmidt &lt;jan@centricular.com&gt;, Edward Hervey &lt;edward@centricular.com&gt;</author>
+      <pads>
+        <caps>
+          <name>sink</name>
+          <direction>sink</direction>
+          <presence>always</presence>
+          <details>ANY</details>
+        </caps>
+        <caps>
+          <name>src_%u</name>
+          <direction>source</direction>
+          <presence>sometimes</presence>
+          <details>ANY</details>
+        </caps>
+      </pads>
+    </element>
+    <element>
       <name>playbin</name>
       <longname>Player Bin 2</longname>
       <class>Generic/Bin/Player</class>
@@ -40,6 +106,15 @@
       </pads>
     </element>
     <element>
+      <name>playbin3</name>
+      <longname>Player Bin 3</longname>
+      <class>Generic/Bin/Player</class>
+      <description>Autoplug and play media from an uri</description>
+      <author>Wim Taymans &lt;wim.taymans@gmail.com&gt;</author>
+      <pads>
+      </pads>
+    </element>
+    <element>
       <name>playsink</name>
       <longname>Player Sink</longname>
       <class>Generic/Bin/Sink</class>
@@ -141,5 +216,20 @@
         </caps>
       </pads>
     </element>
+    <element>
+      <name>urisourcebin</name>
+      <longname>URI reader</longname>
+      <class>Generic/Bin/Source</class>
+      <description>Download and buffer a URI as needed</description>
+      <author>Jan Schmidt &lt;jan@centricular.com&gt;</author>
+      <pads>
+        <caps>
+          <name>src_%u</name>
+          <direction>source</direction>
+          <presence>sometimes</presence>
+          <details>ANY</details>
+        </caps>
+      </pads>
+    </element>
   </elements>
 </plugin>
\ No newline at end of file
diff --git a/docs/plugins/inspect/plugin-subparse.xml b/docs/plugins/inspect/plugin-subparse.xml
index c2bd802..b237508 100644
--- a/docs/plugins/inspect/plugin-subparse.xml
+++ b/docs/plugins/inspect/plugin-subparse.xml
@@ -3,7 +3,7 @@
   <description>Subtitle parsing</description>
   <filename>../../gst/subparse/.libs/libgstsubparse.so</filename>
   <basename>libgstsubparse.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
@@ -41,7 +41,7 @@
           <name>sink</name>
           <direction>sink</direction>
           <presence>always</presence>
-          <details>application/x-subtitle; application/x-subtitle-sami; application/x-subtitle-tmplayer; application/x-subtitle-mpl2; application/x-subtitle-dks; application/x-subtitle-qttext; application/x-subtitle-lrc</details>
+          <details>application/x-subtitle; application/x-subtitle-sami; application/x-subtitle-tmplayer; application/x-subtitle-mpl2; application/x-subtitle-dks; application/x-subtitle-qttext; application/x-subtitle-lrc; application/x-subtitle-vtt</details>
         </caps>
         <caps>
           <name>src</name>
diff --git a/docs/plugins/inspect/plugin-tcp.xml b/docs/plugins/inspect/plugin-tcp.xml
index 2afc240..9ff7b1d 100644
--- a/docs/plugins/inspect/plugin-tcp.xml
+++ b/docs/plugins/inspect/plugin-tcp.xml
@@ -3,7 +3,7 @@
   <description>transfer data over the network via TCP</description>
   <filename>../../gst/tcp/.libs/libgsttcp.so</filename>
   <basename>libgsttcp.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-theora.xml b/docs/plugins/inspect/plugin-theora.xml
index c57d87b..135ec2e 100644
--- a/docs/plugins/inspect/plugin-theora.xml
+++ b/docs/plugins/inspect/plugin-theora.xml
@@ -3,7 +3,7 @@
   <description>Theora plugin library</description>
   <filename>../../ext/theora/.libs/libgsttheora.so</filename>
   <basename>libgsttheora.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-typefindfunctions.xml b/docs/plugins/inspect/plugin-typefindfunctions.xml
index 064d53f..5a8ee77 100644
--- a/docs/plugins/inspect/plugin-typefindfunctions.xml
+++ b/docs/plugins/inspect/plugin-typefindfunctions.xml
@@ -3,7 +3,7 @@
   <description>default typefind functions</description>
   <filename>../../gst/typefind/.libs/libgsttypefindfunctions.so</filename>
   <basename>libgsttypefindfunctions.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-videoconvert.xml b/docs/plugins/inspect/plugin-videoconvert.xml
index 7e8b81b..a90b084 100644
--- a/docs/plugins/inspect/plugin-videoconvert.xml
+++ b/docs/plugins/inspect/plugin-videoconvert.xml
@@ -3,7 +3,7 @@
   <description>Colorspace conversion</description>
   <filename>../../gst/videoconvert/.libs/libgstvideoconvert.so</filename>
   <basename>libgstvideoconvert.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
@@ -20,13 +20,13 @@
           <name>sink</name>
           <direction>sink</direction>
           <presence>always</presence>
-          <details>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
+          <details>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
         </caps>
         <caps>
           <name>src</name>
           <direction>source</direction>
           <presence>always</presence>
-          <details>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
+          <details>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
         </caps>
       </pads>
     </element>
diff --git a/docs/plugins/inspect/plugin-videorate.xml b/docs/plugins/inspect/plugin-videorate.xml
index 567878b..3ebf6f6 100644
--- a/docs/plugins/inspect/plugin-videorate.xml
+++ b/docs/plugins/inspect/plugin-videorate.xml
@@ -3,7 +3,7 @@
   <description>Adjusts video frames</description>
   <filename>../../gst/videorate/.libs/libgstvideorate.so</filename>
   <basename>libgstvideorate.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-videoscale.xml b/docs/plugins/inspect/plugin-videoscale.xml
index a438bdb..32de3e6 100644
--- a/docs/plugins/inspect/plugin-videoscale.xml
+++ b/docs/plugins/inspect/plugin-videoscale.xml
@@ -3,7 +3,7 @@
   <description>Resizes video</description>
   <filename>../../gst/videoscale/.libs/libgstvideoscale.so</filename>
   <basename>libgstvideoscale.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
@@ -20,13 +20,13 @@
           <name>sink</name>
           <direction>sink</direction>
           <presence>always</presence>
-          <details>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
+          <details>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
         </caps>
         <caps>
           <name>src</name>
           <direction>source</direction>
           <presence>always</presence>
-          <details>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
+          <details>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw(ANY), format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 32767 ], height=(int)[ 1, 32767 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
         </caps>
       </pads>
     </element>
diff --git a/docs/plugins/inspect/plugin-videotestsrc.xml b/docs/plugins/inspect/plugin-videotestsrc.xml
index f8bc389..4db9ddc 100644
--- a/docs/plugins/inspect/plugin-videotestsrc.xml
+++ b/docs/plugins/inspect/plugin-videotestsrc.xml
@@ -3,7 +3,7 @@
   <description>Creates a test video stream</description>
   <filename>../../gst/videotestsrc/.libs/libgstvideotestsrc.so</filename>
   <basename>libgstvideotestsrc.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
@@ -20,7 +20,7 @@
           <name>src</name>
           <direction>source</direction>
           <presence>always</presence>
-          <details>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-bayer, format=(string){ bggr, rggb, grbg, gbrg }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
+          <details>video/x-raw, format=(string){ I420, YV12, YUY2, UYVY, AYUV, RGBx, BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-bayer, format=(string){ bggr, rggb, grbg, gbrg }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
         </caps>
       </pads>
     </element>
diff --git a/docs/plugins/inspect/plugin-volume.xml b/docs/plugins/inspect/plugin-volume.xml
index 46c1b5e..31353a6 100644
--- a/docs/plugins/inspect/plugin-volume.xml
+++ b/docs/plugins/inspect/plugin-volume.xml
@@ -3,7 +3,7 @@
   <description>plugin for controlling audio volume</description>
   <filename>../../gst/volume/.libs/libgstvolume.so</filename>
   <basename>libgstvolume.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-vorbis.xml b/docs/plugins/inspect/plugin-vorbis.xml
index dbebc3f..3782b02 100644
--- a/docs/plugins/inspect/plugin-vorbis.xml
+++ b/docs/plugins/inspect/plugin-vorbis.xml
@@ -3,7 +3,7 @@
   <description>Vorbis plugin library</description>
   <filename>../../ext/vorbis/.libs/libgstvorbis.so</filename>
   <basename>libgstvorbis.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-ximagesink.xml b/docs/plugins/inspect/plugin-ximagesink.xml
index c58b449..88d8078 100644
--- a/docs/plugins/inspect/plugin-ximagesink.xml
+++ b/docs/plugins/inspect/plugin-ximagesink.xml
@@ -3,7 +3,7 @@
   <description>X11 video output element based on standard Xlib calls</description>
   <filename>../../sys/ximage/.libs/libgstximagesink.so</filename>
   <basename>libgstximagesink.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/docs/plugins/inspect/plugin-xvimagesink.xml b/docs/plugins/inspect/plugin-xvimagesink.xml
index 8ad371d..5e92856 100644
--- a/docs/plugins/inspect/plugin-xvimagesink.xml
+++ b/docs/plugins/inspect/plugin-xvimagesink.xml
@@ -3,7 +3,7 @@
   <description>XFree86 video output plugin using Xv extension</description>
   <filename>../../sys/xvimage/.libs/libgstxvimagesink.so</filename>
   <basename>libgstxvimagesink.so</basename>
-  <version>1.8.3</version>
+  <version>1.9.90</version>
   <license>LGPL</license>
   <source>gst-plugins-base</source>
   <package>GStreamer Base Plug-ins source release</package>
diff --git a/ext/Makefile.in b/ext/Makefile.in
index 5bd33b7..f83c95e 100644
--- a/ext/Makefile.in
+++ b/ext/Makefile.in
@@ -101,6 +101,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -410,6 +411,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -423,6 +427,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -460,6 +467,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/ext/alsa/Makefile.in b/ext/alsa/Makefile.in
index 456b1d8..4cd4ec2 100644
--- a/ext/alsa/Makefile.in
+++ b/ext/alsa/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -434,6 +435,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -447,6 +451,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -484,6 +491,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/ext/alsa/gstalsa.c b/ext/alsa/gstalsa.c
index 9d2a973..a44e6e1 100644
--- a/ext/alsa/gstalsa.c
+++ b/ext/alsa/gstalsa.c
@@ -750,6 +750,7 @@
     GstAudioChannelPosition * pos)
 {
   int c;
+  gboolean all_mono = TRUE;
 
   for (c = 0; c < chmap->channels; c++) {
     if (chmap->pos[c] > SND_CHMAP_LAST)
@@ -758,7 +759,64 @@
     if (!pos[c])
       return FALSE;
     pos[c]--;
+
+    if (pos[c] != GST_AUDIO_CHANNEL_POSITION_MONO)
+      all_mono = FALSE;
   }
+
+  if (all_mono && chmap->channels > 1) {
+    /* GST_AUDIO_CHANNEL_POSITION_MONO can only be used with 1 channel and
+     * GST_AUDIO_CHANNEL_POSITION_NONE is meant to be used for position-less
+     * multi channels.
+     * Converting as ALSA can only express such configuration by using an array
+     * full of SND_CHMAP_MONO.
+     */
+    for (c = 0; c < chmap->channels; c++)
+      pos[c] = GST_AUDIO_CHANNEL_POSITION_NONE;
+  }
+
   return TRUE;
 }
+
+void
+alsa_detect_channels_mapping (GstObject * obj, snd_pcm_t * handle,
+    GstAudioRingBufferSpec * spec, guint channels, GstAudioRingBuffer * buf)
+{
+  snd_pcm_chmap_t *chmap;
+  GstAudioChannelPosition pos[8];
+
+  if (spec->type != GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW || channels >= 9)
+    return;
+
+  chmap = snd_pcm_get_chmap (handle);
+  if (!chmap) {
+    GST_LOG_OBJECT (obj, "ALSA driver does not implement channels mapping API");
+    return;
+  }
+
+  if (chmap->channels != channels) {
+    GST_LOG_OBJECT (obj,
+        "got channels mapping for %u channels but stream has %u channels; ignoring",
+        chmap->channels, channels);
+    goto out;
+  }
+
+  if (alsa_chmap_to_channel_positions (chmap, pos)) {
+#ifndef GST_DISABLE_GST_DEBUG
+    {
+      gchar *tmp = gst_audio_channel_positions_to_string (pos, channels);
+
+      GST_LOG_OBJECT (obj, "got channels mapping %s", tmp);
+      g_free (tmp);
+    }
+#endif /* GST_DISABLE_GST_DEBUG */
+
+    gst_audio_ring_buffer_set_channel_positions (buf, pos);
+  } else {
+    GST_LOG_OBJECT (obj, "failed to convert ALSA channels mapping");
+  }
+
+out:
+  free (chmap);
+}
 #endif /* SND_CHMAP_API_VERSION */
diff --git a/ext/alsa/gstalsa.h b/ext/alsa/gstalsa.h
index 8026619..56fa075 100644
--- a/ext/alsa/gstalsa.h
+++ b/ext/alsa/gstalsa.h
@@ -73,7 +73,13 @@
 extern const GstAudioChannelPosition alsa_position[][8];
 #ifdef SND_CHMAP_API_VERSION
 gboolean alsa_chmap_to_channel_positions (const snd_pcm_chmap_t *chmap,
-					  GstAudioChannelPosition *pos);
+                                          GstAudioChannelPosition *pos);
+
+void alsa_detect_channels_mapping (GstObject * obj,
+                                   snd_pcm_t * handle,
+                                   GstAudioRingBufferSpec * spec,
+                                   guint channels,
+                                   GstAudioRingBuffer * buf);
 #endif
 
 #endif /* __GST_ALSA_H__ */
diff --git a/ext/alsa/gstalsamidisrc.c b/ext/alsa/gstalsamidisrc.c
index 645d0b0..edf7624 100644
--- a/ext/alsa/gstalsamidisrc.c
+++ b/ext/alsa/gstalsamidisrc.c
@@ -247,8 +247,7 @@
       "AlsaMidi Source",
       "Source",
       "Push ALSA MIDI sequencer events around", "Antonio Ospite <ao2@ao2.it>");
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
+  gst_element_class_add_static_pad_template (gstelement_class, &srctemplate);
 
   gstbase_src_class->start = GST_DEBUG_FUNCPTR (gst_alsa_midi_src_start);
   gstbase_src_class->stop = GST_DEBUG_FUNCPTR (gst_alsa_midi_src_stop);
diff --git a/ext/alsa/gstalsasink.c b/ext/alsa/gstalsasink.c
index 28f328e..86606f7 100644
--- a/ext/alsa/gstalsasink.c
+++ b/ext/alsa/gstalsasink.c
@@ -166,8 +166,8 @@
       "Audio sink (ALSA)", "Sink/Audio",
       "Output to a sound card via ALSA", "Wim Taymans <wim@fluendo.com>");
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&alsasink_sink_factory));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &alsasink_sink_factory);
 
   gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_alsasink_getcaps);
   gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_alsasink_query);
@@ -909,16 +909,8 @@
   }
 
 #ifdef SND_CHMAP_API_VERSION
-  if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW && alsa->channels < 9) {
-    snd_pcm_chmap_t *chmap = snd_pcm_get_chmap (alsa->handle);
-    if (chmap && chmap->channels == alsa->channels) {
-      GstAudioChannelPosition pos[8];
-      if (alsa_chmap_to_channel_positions (chmap, pos))
-        gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SINK
-            (alsa)->ringbuffer, pos);
-    }
-    free (chmap);
-  }
+  alsa_detect_channels_mapping (GST_OBJECT (alsa), alsa->handle, spec,
+      alsa->channels, GST_AUDIO_BASE_SINK (alsa)->ringbuffer);
 #endif /* SND_CHMAP_API_VERSION */
 
   return TRUE;
diff --git a/ext/alsa/gstalsasink.h b/ext/alsa/gstalsasink.h
index 8c4c1b0..b240fe4 100644
--- a/ext/alsa/gstalsasink.h
+++ b/ext/alsa/gstalsasink.h
@@ -58,8 +58,6 @@
   gchar                 *device;
 
   snd_pcm_t             *handle;
-  snd_pcm_hw_params_t   *hwparams;
-  snd_pcm_sw_params_t   *swparams;
 
   snd_pcm_access_t access;
   snd_pcm_format_t format;
diff --git a/ext/alsa/gstalsasrc.c b/ext/alsa/gstalsasrc.c
index a359cc3..74b8bf9 100644
--- a/ext/alsa/gstalsasrc.c
+++ b/ext/alsa/gstalsasrc.c
@@ -142,8 +142,8 @@
       "Audio source (ALSA)", "Source/Audio",
       "Read from a sound card via ALSA", "Wim Taymans <wim@fluendo.com>");
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&alsasrc_src_factory));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &alsasrc_src_factory);
 
   gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_alsasrc_getcaps);
 
@@ -785,16 +785,8 @@
   }
 
 #ifdef SND_CHMAP_API_VERSION
-  if (spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW && alsa->channels < 9) {
-    snd_pcm_chmap_t *chmap = snd_pcm_get_chmap (alsa->handle);
-    if (chmap && chmap->channels == alsa->channels) {
-      GstAudioChannelPosition pos[8];
-      if (alsa_chmap_to_channel_positions (chmap, pos))
-        gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SRC
-            (alsa)->ringbuffer, pos);
-    }
-    free (chmap);
-  }
+  alsa_detect_channels_mapping (GST_OBJECT (alsa), alsa->handle, spec,
+      alsa->channels, GST_AUDIO_BASE_SRC (alsa)->ringbuffer);
 #endif /* SND_CHMAP_API_VERSION */
 
   return TRUE;
diff --git a/ext/cdparanoia/Makefile.in b/ext/cdparanoia/Makefile.in
index 4e39ffd..f0d1f91 100644
--- a/ext/cdparanoia/Makefile.in
+++ b/ext/cdparanoia/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -433,6 +434,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -446,6 +450,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -483,6 +490,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/ext/libvisual/Makefile.in b/ext/libvisual/Makefile.in
index 8e7cbf1..a690c35 100644
--- a/ext/libvisual/Makefile.in
+++ b/ext/libvisual/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -435,6 +436,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -448,6 +452,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -485,6 +492,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/ext/libvisual/visual.c b/ext/libvisual/visual.c
index 460c106..2ed94f0 100644
--- a/ext/libvisual/visual.c
+++ b/ext/libvisual/visual.c
@@ -30,16 +30,16 @@
 /* amounf of samples before we can feed libvisual */
 #define VISUAL_SAMPLES  512
 
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+#define RGB_ORDER_CAPS "xRGB, RGB"
+#else
+#define RGB_ORDER_CAPS "BGRx, BGR"
+#endif
+
 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (" { "
-#if G_BYTE_ORDER == G_BIG_ENDIAN
-            "\"xRGB\", " "\"RGB\", "
-#else
-            "\"BGRx\", " "\"BGR\", "
-#endif
-            "\"RGB16\" } "))
+    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (" { " RGB_ORDER_CAPS ", RGB16 } "))
     );
 
 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
@@ -103,10 +103,8 @@
         klass->plugin->info->name, klass->plugin->info->version);
 
     /* FIXME: improve to only register what plugin supports? */
-    gst_element_class_add_pad_template (element_class,
-        gst_static_pad_template_get (&src_template));
-    gst_element_class_add_pad_template (element_class,
-        gst_static_pad_template_get (&sink_template));
+    gst_element_class_add_static_pad_template (element_class, &src_template);
+    gst_element_class_add_static_pad_template (element_class, &sink_template);
 
     gst_element_class_set_static_metadata (element_class,
         longname, "Visualization",
diff --git a/ext/ogg/Makefile.in b/ext/ogg/Makefile.in
index c4ded52..f54e0e0 100644
--- a/ext/ogg/Makefile.in
+++ b/ext/ogg/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -439,6 +440,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -452,6 +456,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -489,6 +496,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/ext/ogg/gstoggaviparse.c b/ext/ogg/gstoggaviparse.c
index c96a2df..7a12a32 100644
--- a/ext/ogg/gstoggaviparse.c
+++ b/ext/ogg/gstoggaviparse.c
@@ -140,10 +140,10 @@
       "parse an ogg avi stream into pages (info about ogg: http://xiph.org)",
       "Wim Taymans <wim@fluendo.com>");
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&ogg_avi_parse_sink_template_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&ogg_avi_parse_src_template_factory));
+  gst_element_class_add_static_pad_template (element_class,
+      &ogg_avi_parse_sink_template_factory);
+  gst_element_class_add_static_pad_template (element_class,
+      &ogg_avi_parse_src_template_factory);
 }
 
 static void
diff --git a/ext/ogg/gstoggdemux.c b/ext/ogg/gstoggdemux.c
index 10c34a8..517430e 100644
--- a/ext/ogg/gstoggdemux.c
+++ b/ext/ogg/gstoggdemux.c
@@ -48,7 +48,7 @@
 #define CHUNKSIZE (8500)        /* this is out of vorbisfile */
 
 /* we hope we get a granpos within this many bytes off the end */
-#define DURATION_CHUNK_OFFSET (64*1024)
+#define DURATION_CHUNK_OFFSET (128*1024)
 
 /* An Ogg page can not be larger than 255 segments of 255 bytes, plus
    26 bytes of header */
@@ -807,8 +807,6 @@
           pad->discont = FALSE;
   }
 
-  pad->position = ogg->segment.position;
-
   /* don't push the header packets when we are asked to skip them */
   if (!packet->b_o_s || push_headers) {
     if (pad->last_ret == GST_FLOW_OK) {
@@ -853,6 +851,8 @@
   GST_DEBUG_OBJECT (ogg, "ogg current time %" GST_TIME_FORMAT
       " (%" G_GINT64_FORMAT ")", GST_TIME_ARGS (current_time), current_time);
 
+  pad->position = ogg->segment.position;
+
   /* check stream eos */
   if (!pad->is_eos && !delta_unit &&
       ((ogg->segment.rate > 0.0 &&
@@ -1538,6 +1538,10 @@
   event = ogg->push_mode_seek_delayed_event;
   ogg->push_mode_seek_delayed_event = NULL;
 
+  /* if we haven't learnt about the total time yet, disable seeking */
+  if (ogg->total_time == -1)
+    ogg->push_disable_seeking = TRUE;
+
   ogg->push_state = PUSH_PLAYING;
 
   /* If there is one, perform it. Otherwise, seek back at start to start
@@ -2236,10 +2240,10 @@
       "demux ogg streams (info about ogg: http://xiph.org)",
       "Wim Taymans <wim@fluendo.com>");
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&ogg_demux_sink_template_factory));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&ogg_demux_src_template_factory));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &ogg_demux_sink_template_factory);
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &ogg_demux_src_template_factory);
 
   gstelement_class->change_state = gst_ogg_demux_change_state;
   gstelement_class->send_event = gst_ogg_demux_receive_event;
@@ -2317,6 +2321,7 @@
     stream->start_time = -1;
     stream->map.accumulated_granule = 0;
     stream->current_granule = -1;
+    stream->keyframe_granule = -1;
   }
   ogg->building_chain = chain;
   GST_DEBUG_OBJECT (ogg, "Resetting current chain");
@@ -4551,7 +4556,7 @@
   drop = (ogg->seek_event_drop_till > 0);
   GST_PUSH_UNLOCK (ogg);
   if (drop) {
-    GST_ERROR_OBJECT (ogg, "Dropping buffer because we have a pending seek");
+    GST_DEBUG_OBJECT (ogg, "Dropping buffer because we have a pending seek");
     gst_buffer_unref (buffer);
     return GST_FLOW_OK;
   }
@@ -4801,8 +4806,7 @@
     if (flushing) {
       ret = GST_FLOW_FLUSHING;
     } else {
-      GST_ELEMENT_ERROR (ogg, STREAM, DEMUX, (NULL),
-          ("failed to start demuxing ogg"));
+      GST_ELEMENT_FLOW_ERROR (ogg, ret);
       ret = GST_FLOW_ERROR;
     }
     goto pause;
@@ -4844,9 +4848,7 @@
         event = gst_event_new_eos ();
       }
     } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
-      GST_ELEMENT_ERROR (ogg, STREAM, FAILED,
-          (_("Internal data stream error.")),
-          ("stream stopped, reason %s", reason));
+      GST_ELEMENT_FLOW_ERROR (ogg, ret);
       event = gst_event_new_eos ();
     }
 
diff --git a/ext/ogg/gstoggmux.c b/ext/ogg/gstoggmux.c
index 4e1ce94..d2adb3b 100644
--- a/ext/ogg/gstoggmux.c
+++ b/ext/ogg/gstoggmux.c
@@ -150,14 +150,13 @@
   gobject_class->get_property = gst_ogg_mux_get_property;
   gobject_class->set_property = gst_ogg_mux_set_property;
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&src_factory));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&video_sink_factory));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&audio_sink_factory));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&subtitle_sink_factory));
+  gst_element_class_add_static_pad_template (gstelement_class, &src_factory);
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &video_sink_factory);
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &audio_sink_factory);
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &subtitle_sink_factory);
 
   gst_element_class_set_static_metadata (gstelement_class,
       "Ogg muxer", "Codec/Muxer",
diff --git a/ext/ogg/gstoggparse.c b/ext/ogg/gstoggparse.c
index 76f53ab..2045263 100644
--- a/ext/ogg/gstoggparse.c
+++ b/ext/ogg/gstoggparse.c
@@ -148,16 +148,19 @@
   if (ogg_stream_init (&stream->stream, serialno) != 0) {
     GST_ERROR ("Could not initialize ogg_stream struct for serial %08x.",
         serialno);
-    return NULL;
+    goto failure;
   }
 
-  /* FIXME check return */
-  ogg_stream_pagein (&stream->stream, page);
+  if (ogg_stream_pagein (&stream->stream, page) != 0)
+    goto failure;
 
-  /* FIXME check return */
   ret = ogg_stream_packetout (&stream->stream, &packet);
   if (ret == 1) {
-    gst_ogg_stream_setup_map (stream, &packet);
+    if (!gst_ogg_stream_setup_map (stream, &packet)) {
+      GST_ERROR ("Could not setup map for ogg packet.");
+      goto failure;
+    }
+
     if (stream->is_video) {
       parser->video_stream = stream;
     }
@@ -166,6 +169,10 @@
   parser->oggstreams = g_slist_append (parser->oggstreams, stream);
 
   return stream;
+
+failure:
+  free_stream (stream);
+  return NULL;
 }
 
 static GstOggStream *
@@ -225,10 +232,10 @@
       "parse ogg streams into pages (info about ogg: http://xiph.org)",
       "Michael Smith <msmith@fluendo.com>");
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&ogg_parse_sink_template_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&ogg_parse_src_template_factory));
+  gst_element_class_add_static_pad_template (element_class,
+      &ogg_parse_sink_template_factory);
+  gst_element_class_add_static_pad_template (element_class,
+      &ogg_parse_src_template_factory);
 }
 
 static void
@@ -477,6 +484,10 @@
         }
 
         stream = gst_ogg_parse_new_stream (ogg, &page);
+        if (!stream) {
+          GST_LOG_OBJECT (ogg, "Incorrect page");
+          goto failure;
+        }
 
         ogg->last_page_not_bos = FALSE;
 
diff --git a/ext/ogg/gstogmparse.c b/ext/ogg/gstogmparse.c
index c85c064..00632ea 100644
--- a/ext/ogg/gstogmparse.c
+++ b/ext/ogg/gstogmparse.c
@@ -281,10 +281,10 @@
       "parse an OGM audio header and stream",
       "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_factory_audio));
-  audio_src_templ = gst_pad_template_new ("src",
-      GST_PAD_SRC, GST_PAD_SOMETIMES, caps);
+  gst_element_class_add_static_pad_template (element_class,
+      &sink_factory_audio);
+  audio_src_templ =
+      gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_SOMETIMES, caps);
   gst_element_class_add_pad_template (element_class, audio_src_templ);
   gst_caps_unref (caps);
 }
@@ -300,10 +300,10 @@
       "parse an OGM video header and stream",
       "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_factory_video));
-  video_src_templ = gst_pad_template_new ("src",
-      GST_PAD_SRC, GST_PAD_SOMETIMES, caps);
+  gst_element_class_add_static_pad_template (element_class,
+      &sink_factory_video);
+  video_src_templ =
+      gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_SOMETIMES, caps);
   gst_element_class_add_pad_template (element_class, video_src_templ);
   gst_caps_unref (caps);
 }
@@ -320,8 +320,7 @@
       "parse an OGM text header and stream",
       "GStreamer maintainers <gstreamer-devel@lists.freedesktop.org>");
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_factory_text));
+  gst_element_class_add_static_pad_template (element_class, &sink_factory_text);
   text_src_templ = gst_pad_template_new ("src",
       GST_PAD_SRC, GST_PAD_SOMETIMES, caps);
   gst_element_class_add_pad_template (element_class, text_src_templ);
diff --git a/ext/opus/Makefile.in b/ext/opus/Makefile.in
index f11e74e..eda9240 100644
--- a/ext/opus/Makefile.in
+++ b/ext/opus/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -436,6 +437,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -449,6 +453,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -486,6 +493,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/ext/opus/gstopusdec.c b/ext/opus/gstopusdec.c
index 501a379..7e99478 100644
--- a/ext/opus/gstopusdec.c
+++ b/ext/opus/gstopusdec.c
@@ -126,13 +126,12 @@
   adclass->set_format = GST_DEBUG_FUNCPTR (gst_opus_dec_set_format);
   adclass->getcaps = GST_DEBUG_FUNCPTR (gst_opus_dec_getcaps);
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&opus_dec_src_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&opus_dec_sink_factory));
+  gst_element_class_add_static_pad_template (element_class,
+      &opus_dec_src_factory);
+  gst_element_class_add_static_pad_template (element_class,
+      &opus_dec_sink_factory);
   gst_element_class_set_static_metadata (element_class, "Opus audio decoder",
-      "Codec/Decoder/Audio",
-      "decode opus streams to audio",
+      "Codec/Decoder/Audio", "decode opus streams to audio",
       "Vincent Penquerc'h <vincent.penquerch@collabora.co.uk>");
   g_object_class_install_property (gobject_class, PROP_USE_INBAND_FEC,
       g_param_spec_boolean ("use-inband-fec", "Use in-band FEC",
@@ -167,6 +166,7 @@
   dec->sample_rate = 0;
   dec->n_channels = 0;
   dec->leftover_plc_duration = 0;
+  dec->last_known_buffer_duration = GST_CLOCK_TIME_NONE;
 }
 
 static void
@@ -317,7 +317,8 @@
   const GstAudioChannelPosition *posn = NULL;
 
   if (!gst_opus_header_is_id_header (buf)) {
-    GST_ERROR_OBJECT (dec, "Header is not an Opus ID header");
+    GST_ELEMENT_ERROR (dec, STREAM, FORMAT, (NULL),
+        ("Header is not an Opus ID header"));
     return GST_FLOW_ERROR;
   }
 
@@ -328,7 +329,8 @@
           &dec->n_streams,
           &dec->n_stereo_streams,
           dec->channel_mapping, &dec->pre_skip, &dec->r128_gain)) {
-    GST_ERROR_OBJECT (dec, "Failed to parse Opus ID header");
+    GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL),
+        ("Failed to parse Opus ID header"));
     return GST_FLOW_ERROR;
   }
   dec->r128_gain_volume = gst_opus_dec_get_r128_volume (dec->r128_gain);
@@ -382,6 +384,66 @@
   return GST_FLOW_OK;
 }
 
+/* adapted from ext/ogg/gstoggstream.c */
+static gint64
+packet_duration_opus (const unsigned char *data, size_t bytes)
+{
+  static const guint64 durations[32] = {
+    480, 960, 1920, 2880,       /* Silk NB */
+    480, 960, 1920, 2880,       /* Silk MB */
+    480, 960, 1920, 2880,       /* Silk WB */
+    480, 960,                   /* Hybrid SWB */
+    480, 960,                   /* Hybrid FB */
+    120, 240, 480, 960,         /* CELT NB */
+    120, 240, 480, 960,         /* CELT NB */
+    120, 240, 480, 960,         /* CELT NB */
+    120, 240, 480, 960,         /* CELT NB */
+  };
+
+  gint64 duration;
+  gint64 frame_duration;
+  gint nframes = 0;
+  guint8 toc;
+
+  if (bytes < 1)
+    return 0;
+
+  /* headers */
+  if (bytes >= 8 && !memcmp (data, "Opus", 4))
+    return 0;
+
+  toc = data[0];
+
+  frame_duration = durations[toc >> 3];
+  switch (toc & 3) {
+    case 0:
+      nframes = 1;
+      break;
+    case 1:
+      nframes = 2;
+      break;
+    case 2:
+      nframes = 2;
+      break;
+    case 3:
+      if (bytes < 2) {
+        GST_WARNING ("Code 3 Opus packet has less than 2 bytes");
+        return 0;
+      }
+      nframes = data[1] & 63;
+      break;
+  }
+
+  duration = nframes * frame_duration;
+  if (duration > 5760) {
+    GST_WARNING ("Opus packet duration > 120 ms, invalid");
+    return 0;
+  }
+  GST_LOG ("Opus packet: frame size %.1f ms, %d frames, duration %.1f ms",
+      frame_duration / 48.f, nframes, duration / 48.f);
+  return duration / 48.f * 1000000;
+}
+
 static GstFlowReturn
 opus_dec_chain_parse_data (GstOpusDec * dec, GstBuffer * buffer)
 {
@@ -478,6 +540,19 @@
     GstClockTime aligned_missing_duration;
     GstClockTime missing_duration = GST_BUFFER_DURATION (bufd);
 
+    if (!GST_CLOCK_TIME_IS_VALID (missing_duration)) {
+      if (GST_CLOCK_TIME_IS_VALID (dec->last_known_buffer_duration)) {
+        missing_duration = dec->last_known_buffer_duration;
+        GST_WARNING_OBJECT (dec,
+            "Missing duration, using last duration %" GST_TIME_FORMAT,
+            GST_TIME_ARGS (missing_duration));
+      } else {
+        GST_WARNING_OBJECT (dec,
+            "Missing buffer, but unknown duration, and no previously known duration, assuming 20 ms");
+        missing_duration = 20 * GST_MSECOND;
+      }
+    }
+
     GST_DEBUG_OBJECT (dec,
         "missing buffer, doing PLC duration %" GST_TIME_FORMAT
         " plus leftover %" GST_TIME_FORMAT, GST_TIME_ARGS (missing_duration),
@@ -530,6 +605,9 @@
     goto buffer_failed;
   }
 
+  if (size > 0)
+    dec->last_known_buffer_duration = packet_duration_opus (data, size);
+
   gst_buffer_map (outbuf, &omap, GST_MAP_WRITE);
   out_data = (gint16 *) omap.data;
 
@@ -558,7 +636,7 @@
     GstFlowReturn ret = GST_FLOW_ERROR;
 
     gst_buffer_unref (outbuf);
-    GST_AUDIO_DECODER_ERROR (dec, 1, STREAM, DECODE, ("Error decoding stream"),
+    GST_AUDIO_DECODER_ERROR (dec, 1, STREAM, DECODE, (NULL),
         ("Decoding error (%d): %s", n, opus_strerror (n)), ret);
     return ret;
   }
@@ -647,11 +725,13 @@
   return res;
 
 creation_failed:
-  GST_ERROR_OBJECT (dec, "Failed to create Opus decoder: %d", err);
+  GST_ELEMENT_ERROR (dec, LIBRARY, INIT, ("Failed to create Opus decoder"),
+      ("Failed to create Opus decoder (%d): %s", err, opus_strerror (err)));
   return GST_FLOW_ERROR;
 
 buffer_failed:
-  GST_ERROR_OBJECT (dec, "Failed to create %u byte buffer", packet_size);
+  GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL),
+      ("Failed to create %u byte buffer", packet_size));
   return GST_FLOW_ERROR;
 }
 
diff --git a/ext/opus/gstopusdec.h b/ext/opus/gstopusdec.h
index df52cfb..de0dd17 100644
--- a/ext/opus/gstopusdec.h
+++ b/ext/opus/gstopusdec.h
@@ -73,6 +73,8 @@
   gboolean primed;
 
   guint64 leftover_plc_duration;
+
+  GstClockTime last_known_buffer_duration;
 };
 
 struct _GstOpusDecClass {
diff --git a/ext/opus/gstopusenc.c b/ext/opus/gstopusenc.c
index 604974e..e06b75c 100644
--- a/ext/opus/gstopusenc.c
+++ b/ext/opus/gstopusenc.c
@@ -271,10 +271,8 @@
   gobject_class->set_property = gst_opus_enc_set_property;
   gobject_class->get_property = gst_opus_enc_get_property;
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&src_factory));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sink_factory));
+  gst_element_class_add_static_pad_template (gstelement_class, &src_factory);
+  gst_element_class_add_static_pad_template (gstelement_class, &sink_factory);
   gst_element_class_set_static_metadata (gstelement_class, "Opus audio encoder",
       "Codec/Encoder/Audio",
       "Encodes audio in Opus format",
@@ -814,6 +812,9 @@
 
     caps = gst_caps_new_empty ();
 
+    /* The caps is cached */
+    GST_MINI_OBJECT_FLAG_SET (caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
+
     /* Generate our two template structures */
     g_value_init (&rate_array, GST_TYPE_LIST);
     g_value_init (&v, G_TYPE_INT);
@@ -1046,13 +1047,14 @@
   gst_buffer_unmap (outbuf, &omap);
 
   if (outsize < 0) {
-    GST_ERROR_OBJECT (enc, "Encoding failed: %d", outsize);
+    GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
+        ("Encoding failed (%d): %s", outsize, opus_strerror (outsize)));
     ret = GST_FLOW_ERROR;
     goto done;
   } else if (outsize > max_payload_size) {
-    GST_WARNING_OBJECT (enc,
-        "Encoded size %d is higher than max payload size (%d bytes)",
-        outsize, max_payload_size);
+    GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
+        ("Encoded size %d is higher than max payload size (%d bytes)",
+            outsize, max_payload_size));
     ret = GST_FLOW_ERROR;
     goto done;
   }
diff --git a/ext/pango/Makefile.in b/ext/pango/Makefile.in
index 848f15c..2f92a4c 100644
--- a/ext/pango/Makefile.in
+++ b/ext/pango/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -436,6 +437,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -449,6 +453,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -486,6 +493,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/ext/pango/gstbasetextoverlay.c b/ext/pango/gstbasetextoverlay.c
index e0bb169..d2cdc23 100644
--- a/ext/pango/gstbasetextoverlay.c
+++ b/ext/pango/gstbasetextoverlay.c
@@ -351,10 +351,10 @@
   gobject_class->set_property = gst_base_text_overlay_set_property;
   gobject_class->get_property = gst_base_text_overlay_get_property;
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&src_template_factory));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&video_sink_template_factory));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &src_template_factory);
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &video_sink_template_factory);
 
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_base_text_overlay_change_state);
@@ -2160,6 +2160,7 @@
     case GST_VIDEO_FORMAT_UYVY:
     case GST_VIDEO_FORMAT_YUY2:
     case GST_VIDEO_FORMAT_v308:
+    case GST_VIDEO_FORMAT_IYU2:
       gst_base_text_overlay_shade_packed_Y (overlay, frame, x0, x1, y0, y1);
       break;
     case GST_VIDEO_FORMAT_xRGB:
diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c
index d036579..453e51e 100644
--- a/ext/pango/gsttextoverlay.c
+++ b/ext/pango/gsttextoverlay.c
@@ -90,8 +90,8 @@
 {
   GstElementClass *element_class = (GstElementClass *) klass;
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&text_sink_template_factory));
+  gst_element_class_add_static_pad_template (element_class,
+      &text_sink_template_factory);
 
   gst_element_class_set_static_metadata (element_class, "Text overlay",
       "Filter/Editor/Video",
diff --git a/ext/pango/gsttextrender.c b/ext/pango/gsttextrender.c
index c16dce4..8d59a1b 100644
--- a/ext/pango/gsttextrender.c
+++ b/ext/pango/gsttextrender.c
@@ -188,10 +188,10 @@
   gobject_class->set_property = gst_text_render_set_property;
   gobject_class->get_property = gst_text_render_get_property;
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&src_template_factory));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sink_template_factory));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &src_template_factory);
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &sink_template_factory);
 
   gst_element_class_set_static_metadata (gstelement_class, "Text renderer",
       "Filter/Editor/Video",
diff --git a/ext/pango/gsttimeoverlay.c b/ext/pango/gsttimeoverlay.c
index 0cedd66..da943e7 100644
--- a/ext/pango/gsttimeoverlay.c
+++ b/ext/pango/gsttimeoverlay.c
@@ -74,6 +74,7 @@
     {GST_TIME_OVERLAY_TIME_LINE_BUFFER_TIME, "buffer-time", "buffer-time"},
     {GST_TIME_OVERLAY_TIME_LINE_STREAM_TIME, "stream-time", "stream-time"},
     {GST_TIME_OVERLAY_TIME_LINE_RUNNING_TIME, "running-time", "running-time"},
+    {GST_TIME_OVERLAY_TIME_LINE_TIME_CODE, "time-code", "time-code"},
     {0, NULL, NULL},
   };
 
@@ -105,39 +106,51 @@
     GstBuffer * video_frame)
 {
   GstTimeOverlayTimeLine time_line;
-  GstClockTime ts, ts_buffer;
-  GstSegment *segment = &overlay->segment;
   gchar *time_str, *txt, *ret;
 
   overlay->need_render = TRUE;
 
-  ts_buffer = GST_BUFFER_TIMESTAMP (video_frame);
-
-  if (!GST_CLOCK_TIME_IS_VALID (ts_buffer)) {
-    GST_DEBUG ("buffer without valid timestamp");
-    return g_strdup ("");
-  }
-
-  GST_DEBUG ("buffer with timestamp %" GST_TIME_FORMAT,
-      GST_TIME_ARGS (ts_buffer));
-
   time_line = g_atomic_int_get (&GST_TIME_OVERLAY_CAST (overlay)->time_line);
-  switch (time_line) {
-    case GST_TIME_OVERLAY_TIME_LINE_STREAM_TIME:
-      ts = gst_segment_to_stream_time (segment, GST_FORMAT_TIME, ts_buffer);
-      break;
-    case GST_TIME_OVERLAY_TIME_LINE_RUNNING_TIME:
-      ts = gst_segment_to_running_time (segment, GST_FORMAT_TIME, ts_buffer);
-      break;
-    case GST_TIME_OVERLAY_TIME_LINE_BUFFER_TIME:
-    default:
-      ts = ts_buffer;
-      break;
-  }
+  if (time_line == GST_TIME_OVERLAY_TIME_LINE_TIME_CODE) {
+    GstVideoTimeCodeMeta *tc_meta =
+        gst_buffer_get_video_time_code_meta (video_frame);
+    if (!tc_meta) {
+      GST_DEBUG ("buffer without valid timecode");
+      return g_strdup ("00:00:00:00");
+    }
+    time_str = gst_video_time_code_to_string (&tc_meta->tc);
+    GST_DEBUG ("buffer with timecode %s", time_str);
+  } else {
+    GstClockTime ts, ts_buffer;
+    GstSegment *segment = &overlay->segment;
 
+    ts_buffer = GST_BUFFER_TIMESTAMP (video_frame);
+
+    if (!GST_CLOCK_TIME_IS_VALID (ts_buffer)) {
+      GST_DEBUG ("buffer without valid timestamp");
+      return g_strdup ("");
+    }
+
+    GST_DEBUG ("buffer with timestamp %" GST_TIME_FORMAT,
+        GST_TIME_ARGS (ts_buffer));
+
+    switch (time_line) {
+      case GST_TIME_OVERLAY_TIME_LINE_STREAM_TIME:
+        ts = gst_segment_to_stream_time (segment, GST_FORMAT_TIME, ts_buffer);
+        break;
+      case GST_TIME_OVERLAY_TIME_LINE_RUNNING_TIME:
+        ts = gst_segment_to_running_time (segment, GST_FORMAT_TIME, ts_buffer);
+        break;
+      case GST_TIME_OVERLAY_TIME_LINE_BUFFER_TIME:
+      default:
+        ts = ts_buffer;
+        break;
+    }
+
+    time_str = gst_time_overlay_render_time (GST_TIME_OVERLAY (overlay), ts);
+  }
   txt = g_strdup (overlay->default_text);
 
-  time_str = gst_time_overlay_render_time (GST_TIME_OVERLAY (overlay), ts);
   if (txt != NULL && *txt != '\0') {
     ret = g_strdup_printf ("%s %s", txt, time_str);
   } else {
diff --git a/ext/pango/gsttimeoverlay.h b/ext/pango/gsttimeoverlay.h
index f895200..f633a05 100644
--- a/ext/pango/gsttimeoverlay.h
+++ b/ext/pango/gsttimeoverlay.h
@@ -44,7 +44,8 @@
 typedef enum {
   GST_TIME_OVERLAY_TIME_LINE_BUFFER_TIME,
   GST_TIME_OVERLAY_TIME_LINE_STREAM_TIME,
-  GST_TIME_OVERLAY_TIME_LINE_RUNNING_TIME
+  GST_TIME_OVERLAY_TIME_LINE_RUNNING_TIME,
+  GST_TIME_OVERLAY_TIME_LINE_TIME_CODE
 } GstTimeOverlayTimeLine;
 
 /**
diff --git a/ext/theora/Makefile.in b/ext/theora/Makefile.in
index 8045cea..dd19bdc 100644
--- a/ext/theora/Makefile.in
+++ b/ext/theora/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -436,6 +437,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -449,6 +453,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -486,6 +493,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/ext/theora/gsttheoradec.c b/ext/theora/gsttheoradec.c
index e9e70e1..45c777e 100644
--- a/ext/theora/gsttheoradec.c
+++ b/ext/theora/gsttheoradec.c
@@ -172,13 +172,12 @@
             G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   }
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&theora_dec_src_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&theora_dec_sink_factory));
-  gst_element_class_set_static_metadata (element_class,
-      "Theora video decoder", "Codec/Decoder/Video",
-      "decode raw theora streams to raw YUV video",
+  gst_element_class_add_static_pad_template (element_class,
+      &theora_dec_src_factory);
+  gst_element_class_add_static_pad_template (element_class,
+      &theora_dec_sink_factory);
+  gst_element_class_set_static_metadata (element_class, "Theora video decoder",
+      "Codec/Decoder/Video", "decode raw theora streams to raw YUV video",
       "Benjamin Otte <otte@gnome.org>, Wim Taymans <wim@fluendo.com>");
 
   video_decoder_class->start = GST_DEBUG_FUNCPTR (theora_dec_start);
diff --git a/ext/theora/gsttheoraenc.c b/ext/theora/gsttheoraenc.c
index ce692f2..d291221 100644
--- a/ext/theora/gsttheoraenc.c
+++ b/ext/theora/gsttheoraenc.c
@@ -212,13 +212,12 @@
   gobject_class->get_property = theora_enc_get_property;
   gobject_class->finalize = theora_enc_finalize;
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&theora_enc_src_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&theora_enc_sink_factory));
-  gst_element_class_set_static_metadata (element_class,
-      "Theora video encoder", "Codec/Encoder/Video",
-      "encode raw YUV video to a theora stream",
+  gst_element_class_add_static_pad_template (element_class,
+      &theora_enc_src_factory);
+  gst_element_class_add_static_pad_template (element_class,
+      &theora_enc_sink_factory);
+  gst_element_class_set_static_metadata (element_class, "Theora video encoder",
+      "Codec/Encoder/Video", "encode raw YUV video to a theora stream",
       "Wim Taymans <wim@fluendo.com>");
 
   gstvideo_encoder_class->start = GST_DEBUG_FUNCPTR (theora_enc_start);
diff --git a/ext/theora/gsttheoraparse.c b/ext/theora/gsttheoraparse.c
index 5c58644..12a5fb1 100644
--- a/ext/theora/gsttheoraparse.c
+++ b/ext/theora/gsttheoraparse.c
@@ -135,13 +135,13 @@
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 #endif
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&theora_parse_src_factory));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&theora_parse_sink_factory));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &theora_parse_src_factory);
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &theora_parse_sink_factory);
   gst_element_class_set_static_metadata (gstelement_class,
-      "Theora video parser", "Codec/Parser/Video",
-      "parse raw theora streams", "Andy Wingo <wingo@pobox.com>");
+      "Theora video parser", "Codec/Parser/Video", "parse raw theora streams",
+      "Andy Wingo <wingo@pobox.com>");
 
   gstelement_class->change_state = theora_parse_change_state;
 
diff --git a/ext/vorbis/Makefile.in b/ext/vorbis/Makefile.in
index e062bf6..88b3b17 100644
--- a/ext/vorbis/Makefile.in
+++ b/ext/vorbis/Makefile.in
@@ -100,6 +100,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -462,6 +463,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -475,6 +479,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -512,6 +519,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/ext/vorbis/gstvorbisdec.c b/ext/vorbis/gstvorbisdec.c
index bc0a20f..afe32ca 100644
--- a/ext/vorbis/gstvorbisdec.c
+++ b/ext/vorbis/gstvorbisdec.c
@@ -83,18 +83,16 @@
 static void
 gst_vorbis_dec_class_init (GstVorbisDecClass * klass)
 {
-  GstPadTemplate *src_template, *sink_template;
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
   GstAudioDecoderClass *base_class = GST_AUDIO_DECODER_CLASS (klass);
 
   gobject_class->finalize = vorbis_dec_finalize;
 
-  src_template = gst_static_pad_template_get (&vorbis_dec_src_factory);
-  gst_element_class_add_pad_template (element_class, src_template);
-
-  sink_template = gst_static_pad_template_get (&vorbis_dec_sink_factory);
-  gst_element_class_add_pad_template (element_class, sink_template);
+  gst_element_class_add_static_pad_template (element_class,
+      &vorbis_dec_src_factory);
+  gst_element_class_add_static_pad_template (element_class,
+      &vorbis_dec_sink_factory);
 
   gst_element_class_set_static_metadata (element_class,
       "Vorbis audio decoder", "Codec/Decoder/Audio",
diff --git a/ext/vorbis/gstvorbisenc.c b/ext/vorbis/gstvorbisenc.c
index 818a010..57f193f 100644
--- a/ext/vorbis/gstvorbisenc.c
+++ b/ext/vorbis/gstvorbisenc.c
@@ -162,8 +162,8 @@
   gst_element_class_add_pad_template (gstelement_class, sink_templ);
   gst_caps_unref (sink_caps);
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&vorbis_enc_src_factory));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &vorbis_enc_src_factory);
 
   gst_element_class_set_static_metadata (gstelement_class,
       "Vorbis audio encoder", "Codec/Encoder/Audio",
@@ -775,27 +775,6 @@
     while (vorbis_bitrate_flushpacket (&vorbisenc->vd, &op)) {
       GstBuffer *buf;
 
-      if (op.e_o_s) {
-        GstAudioEncoder *enc = GST_AUDIO_ENCODER (vorbisenc);
-        GstClockTime duration;
-
-        GST_DEBUG_OBJECT (vorbisenc, "Got EOS packet from libvorbis");
-        GST_AUDIO_ENCODER_STREAM_LOCK (enc);
-        if (!GST_CLOCK_TIME_IS_VALID (enc->output_segment.stop)) {
-          GST_DEBUG_OBJECT (vorbisenc,
-              "Output segment has no end time, setting");
-          duration =
-              gst_util_uint64_scale (op.granulepos, GST_SECOND,
-              vorbisenc->frequency);
-          enc->output_segment.stop = enc->output_segment.start + duration;
-          GST_DEBUG_OBJECT (enc, "new output segment %" GST_SEGMENT_FORMAT,
-              &enc->output_segment);
-          gst_pad_push_event (GST_AUDIO_ENCODER_SRC_PAD (enc),
-              gst_event_new_segment (&enc->output_segment));
-        }
-        GST_AUDIO_ENCODER_STREAM_UNLOCK (enc);
-      }
-
       GST_LOG_OBJECT (vorbisenc, "pushing out a data packet");
       buf =
           gst_audio_encoder_allocate_output_buffer (GST_AUDIO_ENCODER
diff --git a/ext/vorbis/gstvorbisparse.c b/ext/vorbis/gstvorbisparse.c
index f9f9198..dd357a1 100644
--- a/ext/vorbis/gstvorbisparse.c
+++ b/ext/vorbis/gstvorbisparse.c
@@ -93,13 +93,12 @@
 
   gstelement_class->change_state = vorbis_parse_change_state;
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&vorbis_parse_src_factory));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&vorbis_parse_sink_factory));
-  gst_element_class_set_static_metadata (gstelement_class,
-      "VorbisParse", "Codec/Parser/Audio",
-      "parse raw vorbis streams",
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &vorbis_parse_src_factory);
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &vorbis_parse_sink_factory);
+  gst_element_class_set_static_metadata (gstelement_class, "VorbisParse",
+      "Codec/Parser/Audio", "parse raw vorbis streams",
       "Thomas Vander Stichele <thomas at apestaart dot org>");
 
   klass->parse_packet = GST_DEBUG_FUNCPTR (vorbis_parse_parse_packet);
diff --git a/gst-libs/Makefile.in b/gst-libs/Makefile.in
index d183a75..3f1b9ea 100644
--- a/gst-libs/Makefile.in
+++ b/gst-libs/Makefile.in
@@ -96,6 +96,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -405,6 +406,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -418,6 +422,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -455,6 +462,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst-libs/gst/Makefile.in b/gst-libs/gst/Makefile.in
index 1d8c925..42cb21e 100644
--- a/gst-libs/gst/Makefile.in
+++ b/gst-libs/gst/Makefile.in
@@ -97,6 +97,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -408,6 +409,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -421,6 +425,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -458,6 +465,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst-libs/gst/allocators/Makefile.in b/gst-libs/gst/allocators/Makefile.in
index 140b71b..e222ce1 100644
--- a/gst-libs/gst/allocators/Makefile.in
+++ b/gst-libs/gst/allocators/Makefile.in
@@ -99,6 +99,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -423,6 +424,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -436,6 +440,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -473,6 +480,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst-libs/gst/allocators/gstfdmemory.c b/gst-libs/gst/allocators/gstfdmemory.c
index 7a7f05b..a15859a 100644
--- a/gst-libs/gst/allocators/gstfdmemory.c
+++ b/gst-libs/gst/allocators/gstfdmemory.c
@@ -65,7 +65,8 @@
 
     munmap ((void *) mem->data, gmem->maxsize);
   }
-  if (mem->fd >= 0 && gmem->parent == NULL)
+  if (mem->fd >= 0 && gmem->parent == NULL
+      && !(mem->flags & GST_FD_MEMORY_FLAG_DONT_CLOSE))
     close (mem->fd);
   g_mutex_clear (&mem->lock);
   g_slice_free (GstFdMemory, mem);
@@ -201,7 +202,7 @@
   allocator_class->free = gst_fd_mem_free;
 
   GST_DEBUG_CATEGORY_INIT (gst_fdmemory_debug, "fdmemory", 0,
-    "GstFdMemory and GstFdAllocator");
+      "GstFdMemory and GstFdAllocator");
 }
 
 static void
@@ -245,7 +246,8 @@
  * Return a %GstMemory that wraps a generic file descriptor.
  *
  * Returns: (transfer full): a GstMemory based on @allocator.
- * When the buffer will be released the allocator will close the @fd.
+ * When the buffer will be released the allocator will close the @fd unless
+ * the %GST_FD_MEMORY_FLAG_DONT_CLOSE flag is specified.
  * The memory is only mmapped on gst_buffer_mmap() request.
  *
  * Since: 1.6
diff --git a/gst-libs/gst/allocators/gstfdmemory.h b/gst-libs/gst/allocators/gstfdmemory.h
index 75efae2..40c90d0 100644
--- a/gst-libs/gst/allocators/gstfdmemory.h
+++ b/gst-libs/gst/allocators/gstfdmemory.h
@@ -45,6 +45,8 @@
  *        keep it mapped until the memory is destroyed.
  * @GST_FD_MEMORY_FLAG_MAP_PRIVATE: do a private mapping instead of
  *        the default shared mapping.
+ * @GST_FD_MEMORY_FLAG_DONT_CLOSE: don't close the file descriptor when
+ *        the memory is freed. Since: 1.10.
  *
  * Various flags to control the operation of the fd backed memory.
  *
@@ -54,6 +56,7 @@
   GST_FD_MEMORY_FLAG_NONE = 0,
   GST_FD_MEMORY_FLAG_KEEP_MAPPED = (1 << 0),
   GST_FD_MEMORY_FLAG_MAP_PRIVATE = (1 << 1),
+  GST_FD_MEMORY_FLAG_DONT_CLOSE  = (1 << 2),
 } GstFdMemoryFlags;
 
 /**
diff --git a/gst-libs/gst/app/Makefile.am b/gst-libs/gst/app/Makefile.am
index 776c21e..0033371 100644
--- a/gst-libs/gst/app/Makefile.am
+++ b/gst-libs/gst/app/Makefile.am
@@ -6,14 +6,6 @@
 
 include $(top_srcdir)/common/gst-glib-gen.mak
 
-built_sources = gstapp-marshal.c
-built_headers = gstapp-marshal.h
-
-BUILT_SOURCES = $(built_sources) $(built_headers)
-
-nodist_libgstapp_@GST_API_VERSION@_la_SOURCES = \
-             $(built_sources)
-
 libgstapp_@GST_API_VERSION@_la_SOURCES = gstappsrc.c gstappsink.c 
 libgstapp_@GST_API_VERSION@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \
 	$(GST_BASE_CFLAGS) $(GST_CFLAGS)
@@ -26,10 +18,6 @@
 	gstappsrc.h \
 	gstappsink.h
 
-CLEANFILES = $(BUILT_SOURCES)
-
-EXTRA_DIST = gstapp-marshal.list
-
 if HAVE_INTROSPECTION
 BUILT_GIRSOURCES = GstApp-@GST_API_VERSION@.gir
 
@@ -81,5 +69,5 @@
 		--includedir=`PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" $(PKG_CONFIG) --variable=girdir gstreamer-base-@GST_API_VERSION@` \
 		$(INTROSPECTION_COMPILER_OPTS) $< -o $(@F)
 
-CLEANFILES += $(BUILT_GIRSOURCES) $(typelibs_DATA)
+CLEANFILES = $(BUILT_GIRSOURCES) $(typelibs_DATA)
 endif
diff --git a/gst-libs/gst/app/Makefile.in b/gst-libs/gst/app/Makefile.in
index 2dc3181..1c900f4 100644
--- a/gst-libs/gst/app/Makefile.in
+++ b/gst-libs/gst/app/Makefile.in
@@ -99,7 +99,6 @@
 build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
-@HAVE_INTROSPECTION_TRUE@am__append_1 = $(BUILT_GIRSOURCES) $(typelibs_DATA)
 subdir = gst-libs/gst/app
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/common/m4/as-ac-expand.m4 \
@@ -108,6 +107,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -179,11 +179,8 @@
 am_libgstapp_@GST_API_VERSION@_la_OBJECTS =  \
 	libgstapp_@GST_API_VERSION@_la-gstappsrc.lo \
 	libgstapp_@GST_API_VERSION@_la-gstappsink.lo
-am__objects_1 = libgstapp_@GST_API_VERSION@_la-gstapp-marshal.lo
-nodist_libgstapp_@GST_API_VERSION@_la_OBJECTS = $(am__objects_1)
 libgstapp_@GST_API_VERSION@_la_OBJECTS =  \
-	$(am_libgstapp_@GST_API_VERSION@_la_OBJECTS) \
-	$(nodist_libgstapp_@GST_API_VERSION@_la_OBJECTS)
+	$(am_libgstapp_@GST_API_VERSION@_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
 am__v_lt_0 = --silent
@@ -226,8 +223,7 @@
 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = $(libgstapp_@GST_API_VERSION@_la_SOURCES) \
-	$(nodist_libgstapp_@GST_API_VERSION@_la_SOURCES)
+SOURCES = $(libgstapp_@GST_API_VERSION@_la_SOURCES)
 DIST_SOURCES = $(libgstapp_@GST_API_VERSION@_la_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
@@ -434,6 +430,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -447,6 +446,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -484,6 +486,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -539,12 +542,6 @@
 glib_gen_prefix = __gst_app
 glib_gen_basename = gstapp
 enum_headers = $(foreach h,$(glib_enum_headers),\n\#include \"$(h)\")
-built_sources = gstapp-marshal.c
-built_headers = gstapp-marshal.h
-BUILT_SOURCES = $(built_sources) $(built_headers)
-nodist_libgstapp_@GST_API_VERSION@_la_SOURCES = \
-             $(built_sources)
-
 libgstapp_@GST_API_VERSION@_la_SOURCES = gstappsrc.c gstappsink.c 
 libgstapp_@GST_API_VERSION@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \
 	$(GST_BASE_CFLAGS) $(GST_CFLAGS)
@@ -557,8 +554,6 @@
 	gstappsrc.h \
 	gstappsink.h
 
-CLEANFILES = $(BUILT_SOURCES) $(am__append_1)
-EXTRA_DIST = gstapp-marshal.list
 @HAVE_INTROSPECTION_TRUE@BUILT_GIRSOURCES = GstApp-@GST_API_VERSION@.gir
 @HAVE_INTROSPECTION_TRUE@gir_headers = $(patsubst %,$(srcdir)/%, $(libgstapp_@GST_API_VERSION@include_HEADERS))
 @HAVE_INTROSPECTION_TRUE@gir_sources = $(patsubst %,$(srcdir)/%, \
@@ -572,8 +567,8 @@
 @HAVE_INTROSPECTION_TRUE@gir_DATA = $(BUILT_GIRSOURCES)
 @HAVE_INTROSPECTION_TRUE@typelibsdir = $(libdir)/girepository-1.0/
 @HAVE_INTROSPECTION_TRUE@typelibs_DATA = $(BUILT_GIRSOURCES:.gir=.typelib)
-all: $(BUILT_SOURCES)
-	$(MAKE) $(AM_MAKEFLAGS) all-am
+@HAVE_INTROSPECTION_TRUE@CLEANFILES = $(BUILT_GIRSOURCES) $(typelibs_DATA)
+all: all-am
 
 .SUFFIXES:
 .SUFFIXES: .c .lo .o .obj
@@ -652,7 +647,6 @@
 distclean-compile:
 	-rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstapp_@GST_API_VERSION@_la-gstapp-marshal.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstapp_@GST_API_VERSION@_la-gstappsink.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstapp_@GST_API_VERSION@_la-gstappsrc.Plo@am__quote@
 
@@ -694,13 +688,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 $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstapp_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -c -o libgstapp_@GST_API_VERSION@_la-gstappsink.lo `test -f 'gstappsink.c' || echo '$(srcdir)/'`gstappsink.c
 
-libgstapp_@GST_API_VERSION@_la-gstapp-marshal.lo: gstapp-marshal.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstapp_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -MT libgstapp_@GST_API_VERSION@_la-gstapp-marshal.lo -MD -MP -MF $(DEPDIR)/libgstapp_@GST_API_VERSION@_la-gstapp-marshal.Tpo -c -o libgstapp_@GST_API_VERSION@_la-gstapp-marshal.lo `test -f 'gstapp-marshal.c' || echo '$(srcdir)/'`gstapp-marshal.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstapp_@GST_API_VERSION@_la-gstapp-marshal.Tpo $(DEPDIR)/libgstapp_@GST_API_VERSION@_la-gstapp-marshal.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gstapp-marshal.c' object='libgstapp_@GST_API_VERSION@_la-gstapp-marshal.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 $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstapp_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -c -o libgstapp_@GST_API_VERSION@_la-gstapp-marshal.lo `test -f 'gstapp-marshal.c' || echo '$(srcdir)/'`gstapp-marshal.c
-
 mostlyclean-libtool:
 	-rm -f *.lo
 
@@ -807,15 +794,13 @@
 	  fi; \
 	done
 check-am: all-am
-check: $(BUILT_SOURCES)
-	$(MAKE) $(AM_MAKEFLAGS) check-am
+check: check-am
 all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS)
 installdirs:
 	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(girdir)" "$(DESTDIR)$(typelibsdir)" "$(DESTDIR)$(libgstapp_@GST_API_VERSION@includedir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
-install: $(BUILT_SOURCES)
-	$(MAKE) $(AM_MAKEFLAGS) install-am
+install: install-am
 install-exec: install-exec-am
 install-data: install-data-am
 uninstall: uninstall-am
@@ -846,7 +831,6 @@
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "it deletes files that may require special tools to rebuild."
-	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
 clean: clean-am
 
 clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
@@ -921,7 +905,7 @@
 	uninstall-libgstapp_@GST_API_VERSION@includeHEADERS \
 	uninstall-typelibsDATA
 
-.MAKE: all check install install-am install-strip
+.MAKE: install-am install-strip
 
 .PHONY: all all-am check check-am clean clean-generic \
 	clean-libLTLIBRARIES clean-libtool cscopelist-am ctags-am \
diff --git a/gst-libs/gst/app/gstapp-marshal.list b/gst-libs/gst/app/gstapp-marshal.list
deleted file mode 100644
index d5fefd8..0000000
--- a/gst-libs/gst/app/gstapp-marshal.list
+++ /dev/null
@@ -1,6 +0,0 @@
-BOOLEAN:UINT64
-ENUM:BOXED
-ENUM:VOID
-BOXED:VOID
-VOID:UINT
-
diff --git a/gst-libs/gst/app/gstappsink.c b/gst-libs/gst/app/gstappsink.c
index e5293ee..7b8d481 100644
--- a/gst-libs/gst/app/gstappsink.c
+++ b/gst-libs/gst/app/gstappsink.c
@@ -33,7 +33,9 @@
  * The normal way of retrieving samples from appsink is by using the
  * gst_app_sink_pull_sample() and gst_app_sink_pull_preroll() methods.
  * These methods block until a sample becomes available in the sink or when the
- * sink is shut down or reaches EOS.
+ * sink is shut down or reaches EOS. There are also timed variants of these
+ * methods, gst_app_sink_try_pull_sample() and gst_app_sink_try_pull_preroll(),
+ * which accept a timeout parameter to limit the amount of time to wait.
  *
  * Appsink will internally use a queue to collect buffers from the streaming
  * thread. If the application is not pulling samples fast enough, this queue
@@ -69,7 +71,6 @@
 
 #include <string.h>
 
-#include "gstapp-marshal.h"
 #include "gstappsink.h"
 
 struct _GstAppSinkPrivate
@@ -112,6 +113,8 @@
   /* actions */
   SIGNAL_PULL_PREROLL,
   SIGNAL_PULL_SAMPLE,
+  SIGNAL_TRY_PULL_PREROLL,
+  SIGNAL_TRY_PULL_SAMPLE,
 
   LAST_SIGNAL
 };
@@ -259,8 +262,7 @@
   gst_app_sink_signals[SIGNAL_NEW_PREROLL] =
       g_signal_new ("new-preroll", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
       G_STRUCT_OFFSET (GstAppSinkClass, new_preroll),
-      NULL, NULL, __gst_app_marshal_ENUM__VOID, GST_TYPE_FLOW_RETURN, 0,
-      G_TYPE_NONE);
+      NULL, NULL, NULL, GST_TYPE_FLOW_RETURN, 0, G_TYPE_NONE);
   /**
    * GstAppSink::new-sample:
    * @appsink: the appsink element that emited the signal
@@ -280,8 +282,7 @@
   gst_app_sink_signals[SIGNAL_NEW_SAMPLE] =
       g_signal_new ("new-sample", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
       G_STRUCT_OFFSET (GstAppSinkClass, new_sample),
-      NULL, NULL, __gst_app_marshal_ENUM__VOID, GST_TYPE_FLOW_RETURN, 0,
-      G_TYPE_NONE);
+      NULL, NULL, NULL, GST_TYPE_FLOW_RETURN, 0, G_TYPE_NONE);
 
   /**
    * GstAppSink::pull-preroll:
@@ -309,8 +310,7 @@
   gst_app_sink_signals[SIGNAL_PULL_PREROLL] =
       g_signal_new ("pull-preroll", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstAppSinkClass,
-          pull_preroll), NULL, NULL, __gst_app_marshal_BOXED__VOID,
-      GST_TYPE_SAMPLE, 0, G_TYPE_NONE);
+          pull_preroll), NULL, NULL, NULL, GST_TYPE_SAMPLE, 0, G_TYPE_NONE);
   /**
    * GstAppSink::pull-sample:
    * @appsink: the appsink element to emit this signal on
@@ -335,15 +335,76 @@
   gst_app_sink_signals[SIGNAL_PULL_SAMPLE] =
       g_signal_new ("pull-sample", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstAppSinkClass,
-          pull_sample), NULL, NULL, __gst_app_marshal_BOXED__VOID,
-      GST_TYPE_SAMPLE, 0, G_TYPE_NONE);
+          pull_sample), NULL, NULL, NULL, GST_TYPE_SAMPLE, 0, G_TYPE_NONE);
+  /**
+   * GstAppSink::try-pull-preroll:
+   * @appsink: the appsink element to emit this signal on
+   * @timeout: the maximum amount of time to wait for the preroll sample
+   *
+   * Get the last preroll sample in @appsink. This was the sample that caused the
+   * appsink to preroll in the PAUSED state. This sample can be pulled many times
+   * and remains available to the application even after EOS.
+   *
+   * This function is typically used when dealing with a pipeline in the PAUSED
+   * state. Calling this function after doing a seek will give the sample right
+   * after the seek position.
+   *
+   * Note that the preroll sample will also be returned as the first sample
+   * when calling gst_app_sink_pull_sample() or the "pull-sample" action signal.
+   *
+   * If an EOS event was received before any buffers or the timeout expires,
+   * this function returns %NULL. Use gst_app_sink_is_eos () to check for the EOS
+   * condition.
+   *
+   * This function blocks until a preroll sample or EOS is received, the appsink
+   * element is set to the READY/NULL state, or the timeout expires.
+   *
+   * Returns: a #GstSample or NULL when the appsink is stopped or EOS or the timeout expires.
+   *
+   * Since: 1.10
+   */
+  gst_app_sink_signals[SIGNAL_TRY_PULL_PREROLL] =
+      g_signal_new ("try-pull-preroll", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+      G_STRUCT_OFFSET (GstAppSinkClass, try_pull_preroll), NULL, NULL, NULL,
+      GST_TYPE_SAMPLE, 1, GST_TYPE_CLOCK_TIME);
+  /**
+   * GstAppSink::try-pull-sample:
+   * @appsink: the appsink element to emit this signal on
+   * @timeout: the maximum amount of time to wait for a sample
+   *
+   * This function blocks until a sample or EOS becomes available or the appsink
+   * element is set to the READY/NULL state or the timeout expires.
+   *
+   * This function will only return samples when the appsink is in the PLAYING
+   * state. All rendered samples will be put in a queue so that the application
+   * can pull samples at its own rate.
+   *
+   * Note that when the application does not pull samples fast enough, the
+   * queued samples could consume a lot of memory, especially when dealing with
+   * raw video frames. It's possible to control the behaviour of the queue with
+   * the "drop" and "max-buffers" properties.
+   *
+   * If an EOS event was received before any buffers or the timeout expires,
+   * this function returns %NULL. Use gst_app_sink_is_eos () to check
+   * for the EOS condition.
+   *
+   * Returns: a #GstSample or NULL when the appsink is stopped or EOS or the timeout expires.
+   *
+   * Since: 1.10
+   */
+  gst_app_sink_signals[SIGNAL_TRY_PULL_SAMPLE] =
+      g_signal_new ("try-pull-sample", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+      G_STRUCT_OFFSET (GstAppSinkClass, try_pull_sample), NULL, NULL, NULL,
+      GST_TYPE_SAMPLE, 1, GST_TYPE_CLOCK_TIME);
 
   gst_element_class_set_static_metadata (element_class, "AppSink",
       "Generic/Sink", "Allow the application to get access to raw buffer",
       "David Schleef <ds@schleef.org>, Wim Taymans <wim.taymans@gmail.com>");
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_app_sink_template));
+  gst_element_class_add_static_pad_template (element_class,
+      &gst_app_sink_template);
 
   basesink_class->unlock = gst_app_sink_unlock_start;
   basesink_class->unlock_stop = gst_app_sink_unlock_stop;
@@ -358,6 +419,8 @@
 
   klass->pull_preroll = gst_app_sink_pull_preroll;
   klass->pull_sample = gst_app_sink_pull_sample;
+  klass->try_pull_preroll = gst_app_sink_try_pull_preroll;
+  klass->try_pull_sample = gst_app_sink_try_pull_sample;
 
   g_type_class_add_private (klass, sizeof (GstAppSinkPrivate));
 }
@@ -1202,51 +1265,7 @@
 GstSample *
 gst_app_sink_pull_preroll (GstAppSink * appsink)
 {
-  GstSample *sample = NULL;
-  GstAppSinkPrivate *priv;
-
-  g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL);
-
-  priv = appsink->priv;
-
-  g_mutex_lock (&priv->mutex);
-
-  while (TRUE) {
-    GST_DEBUG_OBJECT (appsink, "trying to grab a buffer");
-    if (!priv->started)
-      goto not_started;
-
-    if (priv->preroll != NULL)
-      break;
-
-    if (priv->is_eos)
-      goto eos;
-
-    /* nothing to return, wait */
-    GST_DEBUG_OBJECT (appsink, "waiting for the preroll buffer");
-    g_cond_wait (&priv->cond, &priv->mutex);
-  }
-  sample =
-      gst_sample_new (priv->preroll, priv->preroll_caps, &priv->preroll_segment,
-      NULL);
-  GST_DEBUG_OBJECT (appsink, "we have the preroll sample %p", sample);
-  g_mutex_unlock (&priv->mutex);
-
-  return sample;
-
-  /* special conditions */
-eos:
-  {
-    GST_DEBUG_OBJECT (appsink, "we are EOS, return NULL");
-    g_mutex_unlock (&priv->mutex);
-    return NULL;
-  }
-not_started:
-  {
-    GST_DEBUG_OBJECT (appsink, "we are stopped, return NULL");
-    g_mutex_unlock (&priv->mutex);
-    return NULL;
-  }
+  return gst_app_sink_try_pull_preroll (appsink, GST_CLOCK_TIME_NONE);
 }
 
 /**
@@ -1268,18 +1287,151 @@
  * Returns: (transfer full): a #GstSample or NULL when the appsink is stopped or EOS.
  *          Call gst_sample_unref() after usage.
  */
-
 GstSample *
 gst_app_sink_pull_sample (GstAppSink * appsink)
 {
-  GstSample *sample = NULL;
-  GstBuffer *buffer;
+  return gst_app_sink_try_pull_sample (appsink, GST_CLOCK_TIME_NONE);
+}
+
+/**
+ * gst_app_sink_try_pull_preroll:
+ * @appsink: a #GstAppSink
+ * @timeout: the maximum amount of time to wait for the preroll sample
+ *
+ * Get the last preroll sample in @appsink. This was the sample that caused the
+ * appsink to preroll in the PAUSED state. This sample can be pulled many times
+ * and remains available to the application even after EOS.
+ *
+ * This function is typically used when dealing with a pipeline in the PAUSED
+ * state. Calling this function after doing a seek will give the sample right
+ * after the seek position.
+ *
+ * Note that the preroll sample will also be returned as the first sample
+ * when calling gst_app_sink_pull_sample().
+ *
+ * If an EOS event was received before any buffers or the timeout expires,
+ * this function returns %NULL. Use gst_app_sink_is_eos () to check for the EOS
+ * condition.
+ *
+ * This function blocks until a preroll sample or EOS is received, the appsink
+ * element is set to the READY/NULL state, or the timeout expires.
+ *
+ * Returns: (transfer full): a #GstSample or NULL when the appsink is stopped or EOS or the timeout expires.
+ *          Call gst_sample_unref() after usage.
+ *
+ * Since: 1.10
+ */
+GstSample *
+gst_app_sink_try_pull_preroll (GstAppSink * appsink, GstClockTime timeout)
+{
   GstAppSinkPrivate *priv;
+  GstSample *sample = NULL;
+  gboolean timeout_valid;
+  gint64 end_time;
 
   g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL);
 
   priv = appsink->priv;
 
+  timeout_valid = GST_CLOCK_TIME_IS_VALID (timeout);
+
+  if (timeout_valid)
+    end_time =
+        g_get_monotonic_time () + timeout / (GST_SECOND / G_TIME_SPAN_SECOND);
+
+  g_mutex_lock (&priv->mutex);
+
+  while (TRUE) {
+    GST_DEBUG_OBJECT (appsink, "trying to grab a buffer");
+    if (!priv->started)
+      goto not_started;
+
+    if (priv->preroll != NULL)
+      break;
+
+    if (priv->is_eos)
+      goto eos;
+
+    /* nothing to return, wait */
+    GST_DEBUG_OBJECT (appsink, "waiting for the preroll buffer");
+    if (timeout_valid) {
+      if (!g_cond_wait_until (&priv->cond, &priv->mutex, end_time))
+        goto expired;
+    } else {
+      g_cond_wait (&priv->cond, &priv->mutex);
+    }
+  }
+  sample =
+      gst_sample_new (priv->preroll, priv->preroll_caps, &priv->preroll_segment,
+      NULL);
+  GST_DEBUG_OBJECT (appsink, "we have the preroll sample %p", sample);
+  g_mutex_unlock (&priv->mutex);
+
+  return sample;
+
+  /* special conditions */
+expired:
+  {
+    GST_DEBUG_OBJECT (appsink, "timeout expired, return NULL");
+    g_mutex_unlock (&priv->mutex);
+    return NULL;
+  }
+eos:
+  {
+    GST_DEBUG_OBJECT (appsink, "we are EOS, return NULL");
+    g_mutex_unlock (&priv->mutex);
+    return NULL;
+  }
+not_started:
+  {
+    GST_DEBUG_OBJECT (appsink, "we are stopped, return NULL");
+    g_mutex_unlock (&priv->mutex);
+    return NULL;
+  }
+}
+
+/**
+ * gst_app_sink_try_pull_sample:
+ * @appsink: a #GstAppSink
+ * @timeout: the maximum amount of time to wait for a sample
+ *
+ * This function blocks until a sample or EOS becomes available or the appsink
+ * element is set to the READY/NULL state or the timeout expires.
+ *
+ * This function will only return samples when the appsink is in the PLAYING
+ * state. All rendered buffers will be put in a queue so that the application
+ * can pull samples at its own rate. Note that when the application does not
+ * pull samples fast enough, the queued buffers could consume a lot of memory,
+ * especially when dealing with raw video frames.
+ *
+ * If an EOS event was received before any buffers or the timeout expires,
+ * this function returns %NULL. Use gst_app_sink_is_eos () to check for the EOS
+ * condition.
+ *
+ * Returns: (transfer full): a #GstSample or NULL when the appsink is stopped or EOS or the timeout expires.
+ * Call gst_sample_unref() after usage.
+ *
+ * Since: 1.10
+ */
+GstSample *
+gst_app_sink_try_pull_sample (GstAppSink * appsink, GstClockTime timeout)
+{
+  GstAppSinkPrivate *priv;
+  GstSample *sample = NULL;
+  GstBuffer *buffer;
+  gboolean timeout_valid;
+  gint64 end_time;
+
+  g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL);
+
+  timeout_valid = GST_CLOCK_TIME_IS_VALID (timeout);
+
+  if (timeout_valid)
+    end_time =
+        g_get_monotonic_time () + timeout / (GST_SECOND / G_TIME_SPAN_SECOND);
+
+  priv = appsink->priv;
+
   g_mutex_lock (&priv->mutex);
 
   while (TRUE) {
@@ -1295,7 +1447,12 @@
 
     /* nothing to return, wait */
     GST_DEBUG_OBJECT (appsink, "waiting for a buffer");
-    g_cond_wait (&priv->cond, &priv->mutex);
+    if (timeout_valid) {
+      if (!g_cond_wait_until (&priv->cond, &priv->mutex, end_time))
+        goto expired;
+    } else {
+      g_cond_wait (&priv->cond, &priv->mutex);
+    }
   }
   buffer = dequeue_buffer (appsink);
   GST_DEBUG_OBJECT (appsink, "we have a buffer %p", buffer);
@@ -1308,6 +1465,12 @@
   return sample;
 
   /* special conditions */
+expired:
+  {
+    GST_DEBUG_OBJECT (appsink, "timeout expired, return NULL");
+    g_mutex_unlock (&priv->mutex);
+    return NULL;
+  }
 eos:
   {
     GST_DEBUG_OBJECT (appsink, "we are EOS, return NULL");
diff --git a/gst-libs/gst/app/gstappsink.h b/gst-libs/gst/app/gstappsink.h
index e268b62..8217d26 100644
--- a/gst-libs/gst/app/gstappsink.h
+++ b/gst-libs/gst/app/gstappsink.h
@@ -94,9 +94,11 @@
   /* actions */
   GstSample *   (*pull_preroll)      (GstAppSink *appsink);
   GstSample *   (*pull_sample)       (GstAppSink *appsink);
+  GstSample *   (*try_pull_preroll)  (GstAppSink *appsink, GstClockTime timeout);
+  GstSample *   (*try_pull_sample)   (GstAppSink *appsink, GstClockTime timeout);
 
   /*< private >*/
-  gpointer     _gst_reserved[GST_PADDING];
+  gpointer     _gst_reserved[GST_PADDING - 2];
 };
 
 GType gst_app_sink_get_type(void);
@@ -120,6 +122,8 @@
 
 GstSample *     gst_app_sink_pull_preroll     (GstAppSink *appsink);
 GstSample *     gst_app_sink_pull_sample      (GstAppSink *appsink);
+GstSample *     gst_app_sink_try_pull_preroll (GstAppSink *appsink, GstClockTime timeout);
+GstSample *     gst_app_sink_try_pull_sample  (GstAppSink *appsink, GstClockTime timeout);
 
 void            gst_app_sink_set_callbacks    (GstAppSink * appsink,
                                                GstAppSinkCallbacks *callbacks,
diff --git a/gst-libs/gst/app/gstappsrc.c b/gst-libs/gst/app/gstappsrc.c
index d06fca1..5a44a45 100644
--- a/gst-libs/gst/app/gstappsrc.c
+++ b/gst-libs/gst/app/gstappsrc.c
@@ -66,10 +66,10 @@
  * ways:
  *
  * The push mode, in which the application repeatedly calls the push-buffer/push-sample
- * method with a new buffer/sample. Optionally, the queue size in the appsrc 
- * can be controlled with the enough-data and need-data signals by respectively 
- * stopping/starting the push-buffer/push-sample calls. This is a typical 
- * mode of operation for the stream-type "stream" and "seekable". Use this 
+ * method with a new buffer/sample. Optionally, the queue size in the appsrc
+ * can be controlled with the enough-data and need-data signals by respectively
+ * stopping/starting the push-buffer/push-sample calls. This is a typical
+ * mode of operation for the stream-type "stream" and "seekable". Use this
  * mode when implementing various network protocols or hardware devices.
  *
  * The pull mode, in which the need-data signal triggers the next push-buffer call.
@@ -98,7 +98,6 @@
 
 #include <string.h>
 
-#include "gstapp-marshal.h"
 #include "gstappsrc.h"
 
 struct _GstAppSrcPrivate
@@ -111,6 +110,7 @@
   GstCaps *current_caps;
 
   gint64 size;
+  GstClockTime duration;
   GstAppStreamType stream_type;
   guint64 max_bytes;
   GstFormat format;
@@ -163,6 +163,7 @@
 #define DEFAULT_PROP_EMIT_SIGNALS  TRUE
 #define DEFAULT_PROP_MIN_PERCENT   0
 #define DEFAULT_PROP_CURRENT_LEVEL_BYTES   0
+#define DEFAULT_PROP_DURATION      GST_CLOCK_TIME_NONE
 
 enum
 {
@@ -179,6 +180,7 @@
   PROP_EMIT_SIGNALS,
   PROP_MIN_PERCENT,
   PROP_CURRENT_LEVEL_BYTES,
+  PROP_DURATION,
   PROP_LAST
 };
 
@@ -402,6 +404,19 @@
           0, G_MAXUINT64, DEFAULT_PROP_CURRENT_LEVEL_BYTES,
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
+  /**
+   * GstAppSrc::duration:
+   *
+   * The total duration in nanoseconds of the data stream. If the total duration is known, it
+   * is recommended to configure it with this property.
+   *
+   * Since: 1.10
+   */
+  g_object_class_install_property (gobject_class, PROP_DURATION,
+      g_param_spec_uint64 ("duration", "Duration",
+          "The duration of the data stream in nanoseconds (GST_CLOCK_TIME_NONE if unknown)",
+          0, G_MAXUINT64, DEFAULT_PROP_DURATION,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   /**
    * GstAppSrc::need-data:
@@ -420,7 +435,7 @@
   gst_app_src_signals[SIGNAL_NEED_DATA] =
       g_signal_new ("need-data", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
       G_STRUCT_OFFSET (GstAppSrcClass, need_data),
-      NULL, NULL, __gst_app_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
+      NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_UINT);
 
   /**
    * GstAppSrc::enough-data:
@@ -449,8 +464,7 @@
   gst_app_src_signals[SIGNAL_SEEK_DATA] =
       g_signal_new ("seek-data", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
       G_STRUCT_OFFSET (GstAppSrcClass, seek_data),
-      NULL, NULL, __gst_app_marshal_BOOLEAN__UINT64, G_TYPE_BOOLEAN, 1,
-      G_TYPE_UINT64);
+      NULL, NULL, NULL, G_TYPE_BOOLEAN, 1, G_TYPE_UINT64);
 
    /**
     * GstAppSrc::push-buffer:
@@ -467,7 +481,7 @@
   gst_app_src_signals[SIGNAL_PUSH_BUFFER] =
       g_signal_new ("push-buffer", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstAppSrcClass,
-          push_buffer), NULL, NULL, __gst_app_marshal_ENUM__BOXED,
+          push_buffer), NULL, NULL, NULL,
       GST_TYPE_FLOW_RETURN, 1, GST_TYPE_BUFFER);
 
   /**
@@ -475,25 +489,25 @@
     * @appsrc: the appsrc
     * @sample: a sample from which extract buffer to push
     *
-    * Extract a buffer from the provided sample and adds the extracted buffer 
+    * Extract a buffer from the provided sample and adds the extracted buffer
     * to the queue of buffers that the appsrc element will
     * push to its source pad. This function set the appsrc caps based on the caps
-    * in the sample and reset the caps if they change. 
-    * Only the caps and the buffer of the provided sample are used and not 
-    * for example the segment in the sample. 
+    * in the sample and reset the caps if they change.
+    * Only the caps and the buffer of the provided sample are used and not
+    * for example the segment in the sample.
     * This function does not take ownership of the
     * sample so the sample needs to be unreffed after calling this function.
     *
     * When the block property is TRUE, this function can block until free space
     * becomes available in the queue.
-    * 
+    *
     * Since: 1.6
-    * 
+    *
     */
   gst_app_src_signals[SIGNAL_PUSH_SAMPLE] =
       g_signal_new ("push-sample", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstAppSrcClass,
-          push_sample), NULL, NULL, __gst_app_marshal_ENUM__BOXED,
+          push_sample), NULL, NULL, NULL,
       GST_TYPE_FLOW_RETURN, 1, GST_TYPE_SAMPLE);
 
 
@@ -506,15 +520,15 @@
   gst_app_src_signals[SIGNAL_END_OF_STREAM] =
       g_signal_new ("end-of-stream", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstAppSrcClass,
-          end_of_stream), NULL, NULL, __gst_app_marshal_ENUM__VOID,
+          end_of_stream), NULL, NULL, NULL,
       GST_TYPE_FLOW_RETURN, 0, G_TYPE_NONE);
 
   gst_element_class_set_static_metadata (element_class, "AppSrc",
       "Generic/Source", "Allow the application to feed buffers to a pipeline",
       "David Schleef <ds@schleef.org>, Wim Taymans <wim.taymans@gmail.com>");
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_app_src_template));
+  gst_element_class_add_static_pad_template (element_class,
+      &gst_app_src_template);
 
   element_class->send_event = gst_app_src_send_event;
 
@@ -551,6 +565,7 @@
   priv->queue = g_queue_new ();
 
   priv->size = DEFAULT_PROP_SIZE;
+  priv->duration = DEFAULT_PROP_DURATION;
   priv->stream_type = DEFAULT_PROP_STREAM_TYPE;
   priv->max_bytes = DEFAULT_PROP_MAX_BYTES;
   priv->format = DEFAULT_PROP_FORMAT;
@@ -703,6 +718,9 @@
     case PROP_MIN_PERCENT:
       priv->min_percent = g_value_get_uint (value);
       break;
+    case PROP_DURATION:
+      gst_app_src_set_duration (appsrc, g_value_get_uint64 (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -763,6 +781,9 @@
     case PROP_CURRENT_LEVEL_BYTES:
       g_value_set_uint64 (value, gst_app_src_get_current_level_bytes (appsrc));
       break;
+    case PROP_DURATION:
+      g_value_set_uint64 (value, gst_app_src_get_duration (appsrc));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -935,6 +956,9 @@
       if (format == GST_FORMAT_BYTES) {
         gst_query_set_duration (query, format, priv->size);
         res = TRUE;
+      } else if (format == GST_FORMAT_TIME) {
+        gst_query_set_duration (query, format, priv->duration);
+        res = TRUE;
       } else {
         res = FALSE;
       }
@@ -1100,6 +1124,16 @@
 
     gst_element_post_message (GST_ELEMENT (appsrc),
         gst_message_new_duration_changed (GST_OBJECT (appsrc)));
+  } else if (G_UNLIKELY (priv->duration != bsrc->segment.duration &&
+          bsrc->segment.format == GST_FORMAT_TIME)) {
+    GST_DEBUG_OBJECT (appsrc,
+        "Duration changed from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
+        GST_TIME_ARGS (bsrc->segment.duration), GST_TIME_ARGS (priv->duration));
+    bsrc->segment.duration = priv->duration;
+    GST_OBJECT_UNLOCK (appsrc);
+
+    gst_element_post_message (GST_ELEMENT (appsrc),
+        gst_message_new_duration_changed (GST_OBJECT (appsrc)));
   } else {
     GST_OBJECT_UNLOCK (appsrc);
   }
@@ -1357,6 +1391,62 @@
 }
 
 /**
+ * gst_app_src_set_duration:
+ * @appsrc: a #GstAppSrc
+ * @duration: the duration to set
+ *
+ * Set the duration of the stream in nanoseconds. A value of GST_CLOCK_TIME_NONE means that the duration is
+ * not known.
+ *
+ * Since: 1.10
+ */
+void
+gst_app_src_set_duration (GstAppSrc * appsrc, GstClockTime duration)
+{
+  GstAppSrcPrivate *priv;
+
+  g_return_if_fail (GST_IS_APP_SRC (appsrc));
+
+  priv = appsrc->priv;
+
+  GST_OBJECT_LOCK (appsrc);
+  GST_DEBUG_OBJECT (appsrc, "setting duration of %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (duration));
+  priv->duration = duration;
+  GST_OBJECT_UNLOCK (appsrc);
+}
+
+/**
+ * gst_app_src_get_duration:
+ * @appsrc: a #GstAppSrc
+ *
+ * Get the duration of the stream in nanoseconds. A value of GST_CLOCK_TIME_NONE means that the duration is
+ * not known.
+ *
+ * Returns: the duration of the stream previously set with gst_app_src_set_duration();
+ *
+ * Since: 1.10
+ */
+GstClockTime
+gst_app_src_get_duration (GstAppSrc * appsrc)
+{
+  GstClockTime duration;
+  GstAppSrcPrivate *priv;
+
+  g_return_val_if_fail (GST_IS_APP_SRC (appsrc), GST_CLOCK_TIME_NONE);
+
+  priv = appsrc->priv;
+
+  GST_OBJECT_LOCK (appsrc);
+  duration = priv->duration;
+  GST_DEBUG_OBJECT (appsrc, "getting duration of %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (duration));
+  GST_OBJECT_UNLOCK (appsrc);
+
+  return duration;
+}
+
+/**
  * gst_app_src_set_stream_type:
  * @appsrc: a #GstAppSrc
  * @type: the new state
@@ -1617,6 +1707,40 @@
 
   priv = appsrc->priv;
 
+  if (GST_BUFFER_DTS (buffer) == GST_CLOCK_TIME_NONE &&
+      GST_BUFFER_PTS (buffer) == GST_CLOCK_TIME_NONE &&
+      gst_base_src_get_do_timestamp (GST_BASE_SRC_CAST (appsrc))) {
+    GstClock *clock;
+
+    clock = gst_element_get_clock (GST_ELEMENT_CAST (appsrc));
+    if (clock) {
+      GstClockTime now;
+      GstClockTime base_time =
+          gst_element_get_base_time (GST_ELEMENT_CAST (appsrc));
+
+      now = gst_clock_get_time (clock);
+      if (now > base_time)
+        now -= base_time;
+      else
+        now = 0;
+      gst_object_unref (clock);
+
+      if (!steal_ref)
+        buffer = gst_buffer_copy (buffer);
+      else
+        buffer = gst_buffer_make_writable (buffer);
+
+      GST_BUFFER_PTS (buffer) = now;
+      GST_BUFFER_DTS (buffer) = now;
+      steal_ref = TRUE;
+    } else {
+      GST_WARNING_OBJECT (appsrc,
+          "do-timestamp=TRUE but buffers are provided before "
+          "reaching the PLAYING state and having a clock. Timestamps will "
+          "not be accurate!");
+    }
+  }
+
   g_mutex_lock (&priv->mutex);
 
   while (TRUE) {
@@ -1745,8 +1869,8 @@
  * @sample: (transfer none): a #GstSample from which buffer and caps may be
  * extracted
  *
- * Extract a buffer from the provided sample and adds it to the queue of 
- * buffers that the appsrc element will push to its source pad. Any 
+ * Extract a buffer from the provided sample and adds it to the queue of
+ * buffers that the appsrc element will push to its source pad. Any
  * previous caps that were set on appsrc will be replaced by the caps
  * associated with the sample if not equal.
  *
@@ -1756,9 +1880,9 @@
  * Returns: #GST_FLOW_OK when the buffer was successfuly queued.
  * #GST_FLOW_FLUSHING when @appsrc is not PAUSED or PLAYING.
  * #GST_FLOW_EOS when EOS occured.
- * 
+ *
  * Since: 1.6
- * 
+ *
  */
 GstFlowReturn
 gst_app_src_push_sample (GstAppSrc * appsrc, GstSample * sample)
diff --git a/gst-libs/gst/app/gstappsrc.h b/gst-libs/gst/app/gstappsrc.h
index d37edae..8fadbcb 100644
--- a/gst-libs/gst/app/gstappsrc.h
+++ b/gst-libs/gst/app/gstappsrc.h
@@ -127,6 +127,9 @@
 void             gst_app_src_set_size                (GstAppSrc *appsrc, gint64 size);
 gint64           gst_app_src_get_size                (GstAppSrc *appsrc);
 
+void             gst_app_src_set_duration            (GstAppSrc *appsrc, GstClockTime duration);
+GstClockTime     gst_app_src_get_duration            (GstAppSrc *appsrc);
+
 void             gst_app_src_set_stream_type         (GstAppSrc *appsrc, GstAppStreamType type);
 GstAppStreamType gst_app_src_get_stream_type         (GstAppSrc *appsrc);
 
@@ -157,4 +160,3 @@
 G_END_DECLS
 
 #endif
-
diff --git a/gst-libs/gst/audio/Makefile.am b/gst-libs/gst/audio/Makefile.am
index 59ea402..41f9c4d 100644
--- a/gst-libs/gst/audio/Makefile.am
+++ b/gst-libs/gst/audio/Makefile.am
@@ -10,6 +10,7 @@
 	audio-converter.h 	\
 	audio-info.h			\
 	audio-quantize.h			\
+	audio-resampler.h			\
 	gstaudioringbuffer.h
 
 glib_enum_define = GST_AUDIO
@@ -25,6 +26,8 @@
 
 CLEANFILES = $(BUILT_SOURCES)
 
+EXTRA_DIST += dbesi0.c
+
 libgstaudio_@GST_API_VERSION@_la_SOURCES = \
 	audio.c \
 	audio-format.c \
@@ -33,6 +36,7 @@
 	audio-converter.c \
 	audio-info.c \
 	audio-quantize.c \
+	audio-resampler.c \
 	gstaudioringbuffer.c \
 	gstaudioclock.c \
 	gstaudiocdsrc.c \
@@ -59,6 +63,7 @@
 	audio-converter.h \
 	audio-info.h \
 	audio-quantize.h \
+	audio-resampler.h \
 	gstaudioringbuffer.h \
 	gstaudioclock.h \
 	gstaudiofilter.h \
@@ -76,7 +81,15 @@
 nodist_libgstaudio_@GST_API_VERSION@include_HEADERS = \
 	audio-enumtypes.h
 
-noinst_HEADERS = gstaudioutilsprivate.h
+noinst_HEADERS = \
+	gstaudioutilsprivate.h 		\
+	audio-resampler-private.h 	\
+	audio-resampler-macros.h 	\
+	audio-resampler-x86.h 		\
+	audio-resampler-x86-sse.h	\
+	audio-resampler-x86-sse2.h	\
+	audio-resampler-x86-sse41.h	\
+	audio-resampler-neon.h
 
 libgstaudio_@GST_API_VERSION@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) \
 		$(ORC_CFLAGS)
@@ -85,6 +98,50 @@
   $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM) $(ORC_LIBS)
 libgstaudio_@GST_API_VERSION@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
 
+
+# Arch-specific bits
+
+noinst_LTLIBRARIES =
+
+if HAVE_X86
+# Don't use full GST_LT_LDFLAGS in LDFLAGS because we get things like
+# -version-info that cause a warning on private libs
+
+noinst_LTLIBRARIES += libaudio_resampler_sse.la
+libaudio_resampler_sse_la_SOURCES = audio-resampler-x86-sse.c
+libaudio_resampler_sse_la_CFLAGS = \
+	$(libgstaudio_@GST_API_VERSION@_la_CFLAGS) \
+	$(SSE_CFLAGS)
+libaudio_resampler_sse_la_LDFLAGS = \
+	$(GST_LIB_LDFLAGS) \
+	$(GST_ALL_LDFLAGS)
+libgstaudio_@GST_API_VERSION@_la_LIBADD += libaudio_resampler_sse.la
+
+noinst_LTLIBRARIES += libaudio_resampler_sse2.la
+libaudio_resampler_sse2_la_SOURCES = audio-resampler-x86-sse2.c
+libaudio_resampler_sse2_la_CFLAGS = \
+	$(libgstaudio_@GST_API_VERSION@_la_CFLAGS) \
+	$(SSE2_CFLAGS)
+libaudio_resampler_sse2_la_LDFLAGS = \
+	$(GST_LIB_LDFLAGS) \
+	$(GST_ALL_LDFLAGS)
+libgstaudio_@GST_API_VERSION@_la_LIBADD += libaudio_resampler_sse2.la
+
+noinst_LTLIBRARIES += libaudio_resampler_sse41.la
+libaudio_resampler_sse41_la_SOURCES = audio-resampler-x86-sse41.c
+libaudio_resampler_sse41_la_CFLAGS = \
+	$(libgstaudio_@GST_API_VERSION@_la_CFLAGS) \
+	$(SSE41_CFLAGS)
+libaudio_resampler_sse41_la_LDFLAGS = \
+	$(GST_LIB_LDFLAGS) \
+	$(GST_ALL_LDFLAGS)
+libgstaudio_@GST_API_VERSION@_la_LIBADD += libaudio_resampler_sse41.la
+
+endif
+
+
+# Introspection
+
 include $(top_srcdir)/common/gst-glib-gen.mak
 
 if HAVE_INTROSPECTION
diff --git a/gst-libs/gst/audio/Makefile.in b/gst-libs/gst/audio/Makefile.in
index 746cf91..add64b1 100644
--- a/gst-libs/gst/audio/Makefile.in
+++ b/gst-libs/gst/audio/Makefile.in
@@ -121,7 +121,16 @@
 build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
-@HAVE_INTROSPECTION_TRUE@am__append_1 = $(BUILT_GIRSOURCES) $(typelibs_DATA)
+
+# Don't use full GST_LT_LDFLAGS in LDFLAGS because we get things like
+# -version-info that cause a warning on private libs
+@HAVE_X86_TRUE@am__append_1 = libaudio_resampler_sse.la \
+@HAVE_X86_TRUE@	libaudio_resampler_sse2.la \
+@HAVE_X86_TRUE@	libaudio_resampler_sse41.la
+@HAVE_X86_TRUE@am__append_2 = libaudio_resampler_sse.la \
+@HAVE_X86_TRUE@	libaudio_resampler_sse2.la \
+@HAVE_X86_TRUE@	libaudio_resampler_sse41.la
+@HAVE_INTROSPECTION_TRUE@am__append_3 = $(BUILT_GIRSOURCES) $(typelibs_DATA)
 subdir = gst-libs/gst/audio
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/common/m4/as-ac-expand.m4 \
@@ -130,6 +139,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -196,11 +206,48 @@
 	"$(DESTDIR)$(typelibsdir)" \
 	"$(DESTDIR)$(libgstaudio_@GST_API_VERSION@includedir)" \
 	"$(DESTDIR)$(libgstaudio_@GST_API_VERSION@includedir)"
-LTLIBRARIES = $(lib_LTLIBRARIES)
+LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
+libaudio_resampler_sse_la_LIBADD =
+am__libaudio_resampler_sse_la_SOURCES_DIST =  \
+	audio-resampler-x86-sse.c
+@HAVE_X86_TRUE@am_libaudio_resampler_sse_la_OBJECTS = libaudio_resampler_sse_la-audio-resampler-x86-sse.lo
+libaudio_resampler_sse_la_OBJECTS =  \
+	$(am_libaudio_resampler_sse_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+libaudio_resampler_sse_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(libaudio_resampler_sse_la_CFLAGS) $(CFLAGS) \
+	$(libaudio_resampler_sse_la_LDFLAGS) $(LDFLAGS) -o $@
+@HAVE_X86_TRUE@am_libaudio_resampler_sse_la_rpath =
+libaudio_resampler_sse2_la_LIBADD =
+am__libaudio_resampler_sse2_la_SOURCES_DIST =  \
+	audio-resampler-x86-sse2.c
+@HAVE_X86_TRUE@am_libaudio_resampler_sse2_la_OBJECTS = libaudio_resampler_sse2_la-audio-resampler-x86-sse2.lo
+libaudio_resampler_sse2_la_OBJECTS =  \
+	$(am_libaudio_resampler_sse2_la_OBJECTS)
+libaudio_resampler_sse2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(libaudio_resampler_sse2_la_CFLAGS) $(CFLAGS) \
+	$(libaudio_resampler_sse2_la_LDFLAGS) $(LDFLAGS) -o $@
+@HAVE_X86_TRUE@am_libaudio_resampler_sse2_la_rpath =
+libaudio_resampler_sse41_la_LIBADD =
+am__libaudio_resampler_sse41_la_SOURCES_DIST =  \
+	audio-resampler-x86-sse41.c
+@HAVE_X86_TRUE@am_libaudio_resampler_sse41_la_OBJECTS = libaudio_resampler_sse41_la-audio-resampler-x86-sse41.lo
+libaudio_resampler_sse41_la_OBJECTS =  \
+	$(am_libaudio_resampler_sse41_la_OBJECTS)
+libaudio_resampler_sse41_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(libaudio_resampler_sse41_la_CFLAGS) $(CFLAGS) \
+	$(libaudio_resampler_sse41_la_LDFLAGS) $(LDFLAGS) -o $@
+@HAVE_X86_TRUE@am_libaudio_resampler_sse41_la_rpath =
 am__DEPENDENCIES_1 =
 libgstaudio_@GST_API_VERSION@_la_DEPENDENCIES = $(top_builddir)/gst-libs/gst/tag/libgsttag-@GST_API_VERSION@.la \
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) $(am__append_2)
 am_libgstaudio_@GST_API_VERSION@_la_OBJECTS =  \
 	libgstaudio_@GST_API_VERSION@_la-audio.lo \
 	libgstaudio_@GST_API_VERSION@_la-audio-format.lo \
@@ -209,6 +256,7 @@
 	libgstaudio_@GST_API_VERSION@_la-audio-converter.lo \
 	libgstaudio_@GST_API_VERSION@_la-audio-info.lo \
 	libgstaudio_@GST_API_VERSION@_la-audio-quantize.lo \
+	libgstaudio_@GST_API_VERSION@_la-audio-resampler.lo \
 	libgstaudio_@GST_API_VERSION@_la-gstaudioringbuffer.lo \
 	libgstaudio_@GST_API_VERSION@_la-gstaudioclock.lo \
 	libgstaudio_@GST_API_VERSION@_la-gstaudiocdsrc.lo \
@@ -231,10 +279,6 @@
 libgstaudio_@GST_API_VERSION@_la_OBJECTS =  \
 	$(am_libgstaudio_@GST_API_VERSION@_la_OBJECTS) \
 	$(nodist_libgstaudio_@GST_API_VERSION@_la_OBJECTS)
-AM_V_lt = $(am__v_lt_@AM_V@)
-am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
-am__v_lt_0 = --silent
-am__v_lt_1 = 
 libgstaudio_@GST_API_VERSION@_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
 	$(libgstaudio_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) \
@@ -273,9 +317,15 @@
 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = $(libgstaudio_@GST_API_VERSION@_la_SOURCES) \
+SOURCES = $(libaudio_resampler_sse_la_SOURCES) \
+	$(libaudio_resampler_sse2_la_SOURCES) \
+	$(libaudio_resampler_sse41_la_SOURCES) \
+	$(libgstaudio_@GST_API_VERSION@_la_SOURCES) \
 	$(nodist_libgstaudio_@GST_API_VERSION@_la_SOURCES)
-DIST_SOURCES = $(libgstaudio_@GST_API_VERSION@_la_SOURCES)
+DIST_SOURCES = $(am__libaudio_resampler_sse_la_SOURCES_DIST) \
+	$(am__libaudio_resampler_sse2_la_SOURCES_DIST) \
+	$(am__libaudio_resampler_sse41_la_SOURCES_DIST) \
+	$(libgstaudio_@GST_API_VERSION@_la_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -502,6 +552,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -515,6 +568,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -552,6 +608,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -605,7 +662,7 @@
 
 # variables used for enum/marshal generation
 ORC_SOURCE = gstaudiopack
-EXTRA_DIST = $(ORC_SOURCE).orc
+EXTRA_DIST = $(ORC_SOURCE).orc dbesi0.c
 ORC_NODIST_SOURCES = tmp-orc.c $(ORC_SOURCE).h
 BUILT_SOURCES = tmp-orc.c $(ORC_SOURCE).h $(built_sources) \
 	$(built_headers)
@@ -623,6 +680,7 @@
 	audio-converter.h 	\
 	audio-info.h			\
 	audio-quantize.h			\
+	audio-resampler.h			\
 	gstaudioringbuffer.h
 
 glib_enum_define = GST_AUDIO
@@ -633,7 +691,7 @@
 lib_LTLIBRARIES = \
 	libgstaudio-@GST_API_VERSION@.la
 
-CLEANFILES = $(BUILT_SOURCES) $(am__append_1)
+CLEANFILES = $(BUILT_SOURCES) $(am__append_3)
 libgstaudio_@GST_API_VERSION@_la_SOURCES = \
 	audio.c \
 	audio-format.c \
@@ -642,6 +700,7 @@
 	audio-converter.c \
 	audio-info.c \
 	audio-quantize.c \
+	audio-resampler.c \
 	gstaudioringbuffer.c \
 	gstaudioclock.c \
 	gstaudiocdsrc.c \
@@ -667,6 +726,7 @@
 	audio-converter.h \
 	audio-info.h \
 	audio-quantize.h \
+	audio-resampler.h \
 	gstaudioringbuffer.h \
 	gstaudioclock.h \
 	gstaudiofilter.h \
@@ -684,16 +744,56 @@
 nodist_libgstaudio_@GST_API_VERSION@include_HEADERS = \
 	audio-enumtypes.h
 
-noinst_HEADERS = gstaudioutilsprivate.h
+noinst_HEADERS = \
+	gstaudioutilsprivate.h 		\
+	audio-resampler-private.h 	\
+	audio-resampler-macros.h 	\
+	audio-resampler-x86.h 		\
+	audio-resampler-x86-sse.h	\
+	audio-resampler-x86-sse2.h	\
+	audio-resampler-x86-sse41.h	\
+	audio-resampler-neon.h
+
 libgstaudio_@GST_API_VERSION@_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) \
 		$(ORC_CFLAGS)
 
-libgstaudio_@GST_API_VERSION@_la_LIBADD = \
-  $(top_builddir)/gst-libs/gst/tag/libgsttag-@GST_API_VERSION@.la \
-  $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM) $(ORC_LIBS)
-
+libgstaudio_@GST_API_VERSION@_la_LIBADD = $(top_builddir)/gst-libs/gst/tag/libgsttag-@GST_API_VERSION@.la \
+	$(GST_BASE_LIBS) $(GST_LIBS) $(LIBM) $(ORC_LIBS) \
+	$(am__append_2)
 libgstaudio_@GST_API_VERSION@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
+
+# Arch-specific bits
+noinst_LTLIBRARIES = $(am__append_1)
+@HAVE_X86_TRUE@libaudio_resampler_sse_la_SOURCES = audio-resampler-x86-sse.c
+@HAVE_X86_TRUE@libaudio_resampler_sse_la_CFLAGS = \
+@HAVE_X86_TRUE@	$(libgstaudio_@GST_API_VERSION@_la_CFLAGS) \
+@HAVE_X86_TRUE@	$(SSE_CFLAGS)
+
+@HAVE_X86_TRUE@libaudio_resampler_sse_la_LDFLAGS = \
+@HAVE_X86_TRUE@	$(GST_LIB_LDFLAGS) \
+@HAVE_X86_TRUE@	$(GST_ALL_LDFLAGS)
+
+@HAVE_X86_TRUE@libaudio_resampler_sse2_la_SOURCES = audio-resampler-x86-sse2.c
+@HAVE_X86_TRUE@libaudio_resampler_sse2_la_CFLAGS = \
+@HAVE_X86_TRUE@	$(libgstaudio_@GST_API_VERSION@_la_CFLAGS) \
+@HAVE_X86_TRUE@	$(SSE2_CFLAGS)
+
+@HAVE_X86_TRUE@libaudio_resampler_sse2_la_LDFLAGS = \
+@HAVE_X86_TRUE@	$(GST_LIB_LDFLAGS) \
+@HAVE_X86_TRUE@	$(GST_ALL_LDFLAGS)
+
+@HAVE_X86_TRUE@libaudio_resampler_sse41_la_SOURCES = audio-resampler-x86-sse41.c
+@HAVE_X86_TRUE@libaudio_resampler_sse41_la_CFLAGS = \
+@HAVE_X86_TRUE@	$(libgstaudio_@GST_API_VERSION@_la_CFLAGS) \
+@HAVE_X86_TRUE@	$(SSE41_CFLAGS)
+
+@HAVE_X86_TRUE@libaudio_resampler_sse41_la_LDFLAGS = \
+@HAVE_X86_TRUE@	$(GST_LIB_LDFLAGS) \
+@HAVE_X86_TRUE@	$(GST_ALL_LDFLAGS)
+
 enum_headers = $(foreach h,$(glib_enum_headers),\n\#include \"$(h)\")
+
+# Introspection
 @HAVE_INTROSPECTION_TRUE@BUILT_GIRSOURCES = GstAudio-@GST_API_VERSION@.gir
 @HAVE_INTROSPECTION_TRUE@gir_headers = $(patsubst %,$(srcdir)/%, \
 @HAVE_INTROSPECTION_TRUE@	$(libgstaudio_@GST_API_VERSION@include_HEADERS)) \
@@ -781,6 +881,26 @@
 	  rm -f $${locs}; \
 	}
 
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+libaudio_resampler_sse.la: $(libaudio_resampler_sse_la_OBJECTS) $(libaudio_resampler_sse_la_DEPENDENCIES) $(EXTRA_libaudio_resampler_sse_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libaudio_resampler_sse_la_LINK) $(am_libaudio_resampler_sse_la_rpath) $(libaudio_resampler_sse_la_OBJECTS) $(libaudio_resampler_sse_la_LIBADD) $(LIBS)
+
+libaudio_resampler_sse2.la: $(libaudio_resampler_sse2_la_OBJECTS) $(libaudio_resampler_sse2_la_DEPENDENCIES) $(EXTRA_libaudio_resampler_sse2_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libaudio_resampler_sse2_la_LINK) $(am_libaudio_resampler_sse2_la_rpath) $(libaudio_resampler_sse2_la_OBJECTS) $(libaudio_resampler_sse2_la_LIBADD) $(LIBS)
+
+libaudio_resampler_sse41.la: $(libaudio_resampler_sse41_la_OBJECTS) $(libaudio_resampler_sse41_la_DEPENDENCIES) $(EXTRA_libaudio_resampler_sse41_la_DEPENDENCIES) 
+	$(AM_V_CCLD)$(libaudio_resampler_sse41_la_LINK) $(am_libaudio_resampler_sse41_la_rpath) $(libaudio_resampler_sse41_la_OBJECTS) $(libaudio_resampler_sse41_la_LIBADD) $(LIBS)
+
 libgstaudio-@GST_API_VERSION@.la: $(libgstaudio_@GST_API_VERSION@_la_OBJECTS) $(libgstaudio_@GST_API_VERSION@_la_DEPENDENCIES) $(EXTRA_libgstaudio_@GST_API_VERSION@_la_DEPENDENCIES) 
 	$(AM_V_CCLD)$(libgstaudio_@GST_API_VERSION@_la_LINK) -rpath $(libdir) $(libgstaudio_@GST_API_VERSION@_la_OBJECTS) $(libgstaudio_@GST_API_VERSION@_la_LIBADD) $(LIBS)
 
@@ -790,6 +910,9 @@
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaudio_resampler_sse2_la-audio-resampler-x86-sse2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaudio_resampler_sse41_la-audio-resampler-x86-sse41.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libaudio_resampler_sse_la-audio-resampler-x86-sse.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-audio-channel-mixer.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-audio-channels.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-audio-converter.Plo@am__quote@
@@ -797,6 +920,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-audio-format.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-audio-info.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-audio-quantize.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-audio-resampler.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-audio.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-gstaudiobasesink.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-gstaudiobasesrc.Plo@am__quote@
@@ -838,6 +962,27 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
+libaudio_resampler_sse_la-audio-resampler-x86-sse.lo: audio-resampler-x86-sse.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaudio_resampler_sse_la_CFLAGS) $(CFLAGS) -MT libaudio_resampler_sse_la-audio-resampler-x86-sse.lo -MD -MP -MF $(DEPDIR)/libaudio_resampler_sse_la-audio-resampler-x86-sse.Tpo -c -o libaudio_resampler_sse_la-audio-resampler-x86-sse.lo `test -f 'audio-resampler-x86-sse.c' || echo '$(srcdir)/'`audio-resampler-x86-sse.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libaudio_resampler_sse_la-audio-resampler-x86-sse.Tpo $(DEPDIR)/libaudio_resampler_sse_la-audio-resampler-x86-sse.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='audio-resampler-x86-sse.c' object='libaudio_resampler_sse_la-audio-resampler-x86-sse.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 $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaudio_resampler_sse_la_CFLAGS) $(CFLAGS) -c -o libaudio_resampler_sse_la-audio-resampler-x86-sse.lo `test -f 'audio-resampler-x86-sse.c' || echo '$(srcdir)/'`audio-resampler-x86-sse.c
+
+libaudio_resampler_sse2_la-audio-resampler-x86-sse2.lo: audio-resampler-x86-sse2.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaudio_resampler_sse2_la_CFLAGS) $(CFLAGS) -MT libaudio_resampler_sse2_la-audio-resampler-x86-sse2.lo -MD -MP -MF $(DEPDIR)/libaudio_resampler_sse2_la-audio-resampler-x86-sse2.Tpo -c -o libaudio_resampler_sse2_la-audio-resampler-x86-sse2.lo `test -f 'audio-resampler-x86-sse2.c' || echo '$(srcdir)/'`audio-resampler-x86-sse2.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libaudio_resampler_sse2_la-audio-resampler-x86-sse2.Tpo $(DEPDIR)/libaudio_resampler_sse2_la-audio-resampler-x86-sse2.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='audio-resampler-x86-sse2.c' object='libaudio_resampler_sse2_la-audio-resampler-x86-sse2.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 $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaudio_resampler_sse2_la_CFLAGS) $(CFLAGS) -c -o libaudio_resampler_sse2_la-audio-resampler-x86-sse2.lo `test -f 'audio-resampler-x86-sse2.c' || echo '$(srcdir)/'`audio-resampler-x86-sse2.c
+
+libaudio_resampler_sse41_la-audio-resampler-x86-sse41.lo: audio-resampler-x86-sse41.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaudio_resampler_sse41_la_CFLAGS) $(CFLAGS) -MT libaudio_resampler_sse41_la-audio-resampler-x86-sse41.lo -MD -MP -MF $(DEPDIR)/libaudio_resampler_sse41_la-audio-resampler-x86-sse41.Tpo -c -o libaudio_resampler_sse41_la-audio-resampler-x86-sse41.lo `test -f 'audio-resampler-x86-sse41.c' || echo '$(srcdir)/'`audio-resampler-x86-sse41.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libaudio_resampler_sse41_la-audio-resampler-x86-sse41.Tpo $(DEPDIR)/libaudio_resampler_sse41_la-audio-resampler-x86-sse41.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='audio-resampler-x86-sse41.c' object='libaudio_resampler_sse41_la-audio-resampler-x86-sse41.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 $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libaudio_resampler_sse41_la_CFLAGS) $(CFLAGS) -c -o libaudio_resampler_sse41_la-audio-resampler-x86-sse41.lo `test -f 'audio-resampler-x86-sse41.c' || echo '$(srcdir)/'`audio-resampler-x86-sse41.c
+
 libgstaudio_@GST_API_VERSION@_la-audio.lo: audio.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstaudio_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -MT libgstaudio_@GST_API_VERSION@_la-audio.lo -MD -MP -MF $(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-audio.Tpo -c -o libgstaudio_@GST_API_VERSION@_la-audio.lo `test -f 'audio.c' || echo '$(srcdir)/'`audio.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-audio.Tpo $(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-audio.Plo
@@ -887,6 +1032,13 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstaudio_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -c -o libgstaudio_@GST_API_VERSION@_la-audio-quantize.lo `test -f 'audio-quantize.c' || echo '$(srcdir)/'`audio-quantize.c
 
+libgstaudio_@GST_API_VERSION@_la-audio-resampler.lo: audio-resampler.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstaudio_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -MT libgstaudio_@GST_API_VERSION@_la-audio-resampler.lo -MD -MP -MF $(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-audio-resampler.Tpo -c -o libgstaudio_@GST_API_VERSION@_la-audio-resampler.lo `test -f 'audio-resampler.c' || echo '$(srcdir)/'`audio-resampler.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-audio-resampler.Tpo $(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-audio-resampler.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='audio-resampler.c' object='libgstaudio_@GST_API_VERSION@_la-audio-resampler.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 $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstaudio_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -c -o libgstaudio_@GST_API_VERSION@_la-audio-resampler.lo `test -f 'audio-resampler.c' || echo '$(srcdir)/'`audio-resampler.c
+
 libgstaudio_@GST_API_VERSION@_la-gstaudioringbuffer.lo: gstaudioringbuffer.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstaudio_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -MT libgstaudio_@GST_API_VERSION@_la-gstaudioringbuffer.lo -MD -MP -MF $(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-gstaudioringbuffer.Tpo -c -o libgstaudio_@GST_API_VERSION@_la-gstaudioringbuffer.lo `test -f 'gstaudioringbuffer.c' || echo '$(srcdir)/'`gstaudioringbuffer.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-gstaudioringbuffer.Tpo $(DEPDIR)/libgstaudio_@GST_API_VERSION@_la-gstaudioringbuffer.Plo
@@ -1218,7 +1370,7 @@
 clean: clean-am
 
 clean-am: clean-generic clean-libLTLIBRARIES clean-libtool clean-local \
-	mostlyclean-am
+	clean-noinstLTLIBRARIES mostlyclean-am
 
 distclean: distclean-am
 	-rm -rf ./$(DEPDIR)
@@ -1295,14 +1447,14 @@
 .MAKE: all check install install-am install-strip
 
 .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
-	clean-libLTLIBRARIES clean-libtool clean-local cscopelist-am \
-	ctags ctags-am dist-hook distclean distclean-compile \
-	distclean-generic distclean-libtool distclean-tags distdir dvi \
-	dvi-am html html-am info info-am install install-am \
-	install-data install-data-am install-dvi install-dvi-am \
-	install-exec install-exec-am install-girDATA install-html \
-	install-html-am install-info install-info-am \
-	install-libLTLIBRARIES \
+	clean-libLTLIBRARIES clean-libtool clean-local \
+	clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am dist-hook \
+	distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-girDATA install-html install-html-am \
+	install-info install-info-am install-libLTLIBRARIES \
 	install-libgstaudio_@GST_API_VERSION@includeHEADERS \
 	install-man \
 	install-nodist_libgstaudio_@GST_API_VERSION@includeHEADERS \
diff --git a/gst-libs/gst/audio/audio-channels.c b/gst-libs/gst/audio/audio-channels.c
index 8e03455..5ce2f5c 100644
--- a/gst-libs/gst/audio/audio-channels.c
+++ b/gst-libs/gst/audio/audio-channels.c
@@ -538,3 +538,108 @@
 
   return default_masks[channels - 1];
 }
+
+static const gchar *
+position_to_string (GstAudioChannelPosition pos)
+{
+  switch (pos) {
+    case GST_AUDIO_CHANNEL_POSITION_NONE:
+      return "NONE";
+    case GST_AUDIO_CHANNEL_POSITION_MONO:
+      return "MONO";
+    case GST_AUDIO_CHANNEL_POSITION_INVALID:
+      return "INVALID";
+    case GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT:
+      return "FL";
+    case GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT:
+      return "FR";
+    case GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER:
+      return "FC";
+    case GST_AUDIO_CHANNEL_POSITION_LFE1:
+      return "LFE1";
+    case GST_AUDIO_CHANNEL_POSITION_REAR_LEFT:
+      return "RL";
+    case GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT:
+      return "RR";
+    case GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER:
+      return "FLoC";
+    case GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER:
+      return "FRoC";
+    case GST_AUDIO_CHANNEL_POSITION_REAR_CENTER:
+      return "RC";
+    case GST_AUDIO_CHANNEL_POSITION_LFE2:
+      return "LF2";
+    case GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT:
+      return "SL";
+    case GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT:
+      return "SR";
+    case GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT:
+      return "TFL";
+    case GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT:
+      return "TFR";
+    case GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER:
+      return "TFC";
+    case GST_AUDIO_CHANNEL_POSITION_TOP_CENTER:
+      return "TFC";
+    case GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT:
+      return "TRL";
+    case GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT:
+      return "TRR";
+    case GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_LEFT:
+      return "TSL";
+    case GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_RIGHT:
+      return "TSR";
+    case GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER:
+      return "TRC";
+    case GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_CENTER:
+      return "BFC";
+    case GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_LEFT:
+      return "BFL";
+    case GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_RIGHT:
+      return "BFR";
+    case GST_AUDIO_CHANNEL_POSITION_WIDE_LEFT:
+      return "WL";
+    case GST_AUDIO_CHANNEL_POSITION_WIDE_RIGHT:
+      return "WR";
+    case GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT:
+      return "SL";
+    case GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT:
+      return "SR";
+    default:
+      break;
+  }
+
+  return "UNKNOWN";
+}
+
+/**
+ * gst_audio_channel_positions_to_string:
+ * @position: (array length=channels): The %GstAudioChannelPositions
+ *   to convert.
+ * @channels: The number of channels.
+ *
+ * Converts @position to a human-readable string representation for
+ * debugging purposes.
+ *
+ * Returns: (transfer full): a newly allocated string representing
+ * @position
+ *
+ * Since 1.10
+ */
+gchar *
+gst_audio_channel_positions_to_string (const GstAudioChannelPosition * position,
+    gint channels)
+{
+  guint i;
+  GString *tmp;
+
+  g_return_val_if_fail (channels > 0, FALSE);
+  g_return_val_if_fail (position != NULL, FALSE);
+
+  tmp = g_string_new ("[");
+  for (i = 0; i < channels; i++)
+    g_string_append_printf (tmp, " %s", position_to_string (position[i]));
+  g_string_append (tmp, " ]");
+
+  return g_string_free (tmp, FALSE);
+}
diff --git a/gst-libs/gst/audio/audio-channels.h b/gst-libs/gst/audio/audio-channels.h
index 4aa00de..cd57898 100644
--- a/gst-libs/gst/audio/audio-channels.h
+++ b/gst-libs/gst/audio/audio-channels.h
@@ -162,6 +162,9 @@
                                                   gint *reorder_map);
 guint64        gst_audio_channel_get_fallback_mask (gint channels);
 
+gchar*         gst_audio_channel_positions_to_string (const GstAudioChannelPosition * position,
+                                                      gint channels);
+
 G_END_DECLS
 
 #endif /* __GST_AUDIO_CHANNELS_H__ */
diff --git a/gst-libs/gst/audio/audio-converter.c b/gst-libs/gst/audio/audio-converter.c
index 31f2a0e..1f0b450 100644
--- a/gst-libs/gst/audio/audio-converter.c
+++ b/gst-libs/gst/audio/audio-converter.c
@@ -127,6 +127,10 @@
   GstAudioChannelMixer *mix;
   AudioChain *mix_chain;
 
+  /* resample */
+  GstAudioResampler *resampler;
+  AudioChain *resample_chain;
+
   /* convert out */
   AudioConvertFunc convert_out;
   AudioChain *convert_out_chain;
@@ -264,10 +268,14 @@
   return res;
 }
 
+#define DEFAULT_OPT_RESAMPLER_METHOD GST_AUDIO_RESAMPLER_METHOD_BLACKMAN_NUTTALL
 #define DEFAULT_OPT_DITHER_METHOD GST_AUDIO_DITHER_NONE
 #define DEFAULT_OPT_NOISE_SHAPING_METHOD GST_AUDIO_NOISE_SHAPING_NONE
 #define DEFAULT_OPT_QUANTIZATION 1
 
+#define GET_OPT_RESAMPLER_METHOD(c) get_opt_enum(c, \
+    GST_AUDIO_CONVERTER_OPT_RESAMPLER_METHOD, GST_TYPE_AUDIO_RESAMPLER_METHOD, \
+    DEFAULT_OPT_RESAMPLER_METHOD)
 #define GET_OPT_DITHER_METHOD(c) get_opt_enum(c, \
     GST_AUDIO_CONVERTER_OPT_DITHER_METHOD, GST_TYPE_AUDIO_DITHER_METHOD, \
     DEFAULT_OPT_DITHER_METHOD)
@@ -296,7 +304,7 @@
  *
  * Set @in_rate, @out_rate and @config as extra configuration for @convert.
  *
- * in_rate and @out_rate specify the new sample rates of input and output
+ * @in_rate and @out_rate specify the new sample rates of input and output
  * formats. A value of 0 leaves the sample rate unchanged.
  *
  * @config can be %NULL, in which case, the current configuration is not
@@ -329,6 +337,9 @@
   convert->in.rate = in_rate;
   convert->out.rate = out_rate;
 
+  if (convert->resampler)
+    gst_audio_resampler_update (convert->resampler, in_rate, out_rate, config);
+
   if (config) {
     gst_structure_foreach (config, copy_config, convert);
     gst_structure_free (config);
@@ -385,7 +396,7 @@
     gsize stride = GST_ROUND_UP_N (num_samples * chain->stride, ALIGN);
     /* first part contains the pointers, second part the data, add some extra bytes
      * for alignement */
-    gsize needed = (stride + sizeof (gpointer)) * chain->blocks + ALIGN;
+    gsize needed = (stride + sizeof (gpointer)) * chain->blocks + ALIGN - 1;
 
     GST_DEBUG ("alloc samples %d %" G_GSIZE_FORMAT " %" G_GSIZE_FORMAT,
         chain->stride, num_samples, needed);
@@ -458,8 +469,8 @@
 static gboolean
 do_convert_in (AudioChain * chain, gpointer user_data)
 {
-  GstAudioConverter *convert = user_data;
   gsize num_samples;
+  GstAudioConverter *convert = user_data;
   gpointer *in, *out;
   gint i;
 
@@ -478,8 +489,8 @@
 static gboolean
 do_mix (AudioChain * chain, gpointer user_data)
 {
-  GstAudioConverter *convert = user_data;
   gsize num_samples;
+  GstAudioConverter *convert = user_data;
   gpointer *in, *out;
 
   in = audio_chain_get_samples (chain->prev, &num_samples);
@@ -494,6 +505,28 @@
 }
 
 static gboolean
+do_resample (AudioChain * chain, gpointer user_data)
+{
+  GstAudioConverter *convert = user_data;
+  gpointer *in, *out;
+  gsize in_frames, out_frames;
+
+  in = audio_chain_get_samples (chain->prev, &in_frames);
+  out_frames = convert->out_frames;
+  out = (chain->allow_ip ? in : audio_chain_alloc_samples (chain, out_frames));
+
+  GST_LOG ("resample %p %p,%" G_GSIZE_FORMAT " %" G_GSIZE_FORMAT, in,
+      out, in_frames, out_frames);
+
+  gst_audio_resampler_resample (convert->resampler, in, in_frames, out,
+      out_frames);
+
+  audio_chain_set_samples (chain, out, out_frames);
+
+  return TRUE;
+}
+
+static gboolean
 do_convert_out (AudioChain * chain, gpointer user_data)
 {
   GstAudioConverter *convert = user_data;
@@ -503,7 +536,7 @@
 
   in = audio_chain_get_samples (chain->prev, &num_samples);
   out = (chain->allow_ip ? in : audio_chain_alloc_samples (chain, num_samples));
-  GST_LOG ("convert out %p, %p, %" G_GSIZE_FORMAT, in, out, num_samples);
+  GST_LOG ("convert out %p, %p %" G_GSIZE_FORMAT, in, out, num_samples);
 
   for (i = 0; i < chain->blocks; i++)
     convert->convert_out (out[i], in[i], num_samples * chain->inc);
@@ -522,7 +555,7 @@
 
   in = audio_chain_get_samples (chain->prev, &num_samples);
   out = (chain->allow_ip ? in : audio_chain_alloc_samples (chain, num_samples));
-  GST_LOG ("quantize %p, %p, %" G_GSIZE_FORMAT, in, out, num_samples);
+  GST_LOG ("quantize %p, %p %" G_GSIZE_FORMAT, in, out, num_samples);
 
   gst_audio_quantize_samples (convert->quant, in, out, num_samples);
 
@@ -632,6 +665,42 @@
 }
 
 static AudioChain *
+chain_resample (GstAudioConverter * convert, AudioChain * prev)
+{
+  GstAudioInfo *in = &convert->in;
+  GstAudioInfo *out = &convert->out;
+  GstAudioResamplerMethod method;
+  GstAudioResamplerFlags flags;
+  GstAudioFormat format = convert->current_format;
+  gint channels = convert->current_channels;
+  gboolean variable_rate;
+
+  variable_rate = convert->flags & GST_AUDIO_CONVERTER_FLAG_VARIABLE_RATE;
+
+  if (in->rate != out->rate || variable_rate) {
+    method = GET_OPT_RESAMPLER_METHOD (convert);
+
+    flags = 0;
+    if (convert->current_layout == GST_AUDIO_LAYOUT_NON_INTERLEAVED) {
+      flags |= GST_AUDIO_RESAMPLER_FLAG_NON_INTERLEAVED_IN;
+      flags |= GST_AUDIO_RESAMPLER_FLAG_NON_INTERLEAVED_OUT;
+    }
+    if (variable_rate)
+      flags |= GST_AUDIO_RESAMPLER_FLAG_VARIABLE_RATE;
+
+    convert->resampler =
+        gst_audio_resampler_new (method, flags, format, channels, in->rate,
+        out->rate, convert->config);
+
+    prev = convert->resample_chain = audio_chain_new (prev, convert);
+    prev->allow_ip = FALSE;
+    prev->pass_alloc = FALSE;
+    audio_chain_set_make_func (prev, do_resample, convert, NULL);
+  }
+  return prev;
+}
+
+static AudioChain *
 chain_convert_out (GstAudioConverter * convert, AudioChain * prev)
 {
   gboolean in_int, out_int;
@@ -781,7 +850,6 @@
     for (i = 0; i < chain->blocks; i++)
       gst_audio_format_fill_silence (convert->in.finfo, out[i], samples);
   }
-
   return TRUE;
 }
 
@@ -816,9 +884,20 @@
   return TRUE;
 }
 
+static gboolean
+converter_resample (GstAudioConverter * convert,
+    GstAudioConverterFlags flags, gpointer in[], gsize in_frames,
+    gpointer out[], gsize out_frames)
+{
+  gst_audio_resampler_resample (convert->resampler, in, in_frames, out,
+      out_frames);
+
+  return TRUE;
+}
+
 /**
  * gst_audio_converter_new: (skip)
- * @flags: #GstAudioConverterFlags
+ * @flags: extra #GstAudioConverterFlags
  * @in_info: a source #GstAudioInfo
  * @out_info: a destination #GstAudioInfo
  * @config: (transfer full): a #GstStructure with configuration options
@@ -840,7 +919,6 @@
 
   g_return_val_if_fail (in_info != NULL, FALSE);
   g_return_val_if_fail (out_info != NULL, FALSE);
-  g_return_val_if_fail (in_info->rate == out_info->rate, FALSE);
   g_return_val_if_fail (in_info->layout == GST_AUDIO_LAYOUT_INTERLEAVED, FALSE);
   g_return_val_if_fail (in_info->layout == out_info->layout, FALSE);
 
@@ -868,21 +946,30 @@
   prev = chain_convert_in (convert, prev);
   /* step 3, channel mix */
   prev = chain_mix (convert, prev);
-  /* step 4, optional convert for quantize */
+  /* step 4, resample */
+  prev = chain_resample (convert, prev);
+  /* step 5, optional convert for quantize */
   prev = chain_convert_out (convert, prev);
-  /* step 5, optional quantize */
+  /* step 6, optional quantize */
   prev = chain_quantize (convert, prev);
-  /* step 6, pack */
+  /* step 7, pack */
   convert->pack_chain = chain_pack (convert, prev);
 
+  convert->convert = converter_generic;
+
   /* optimize */
   if (out_info->finfo->format == in_info->finfo->format
       && convert->mix_passthrough) {
-    GST_INFO ("same formats and passthrough mixing -> passthrough");
-    convert->convert = converter_passthrough;
-  } else {
-    GST_INFO ("do full conversion");
-    convert->convert = converter_generic;
+    if (convert->resampler == NULL) {
+      GST_INFO
+          ("same formats, no resampler and passthrough mixing -> passthrough");
+      convert->convert = converter_passthrough;
+    } else {
+      if (is_intermediate_format (in_info->finfo->format)) {
+        GST_INFO ("same formats, and passthrough mixing -> only resampling");
+        convert->convert = converter_resample;
+      }
+    }
   }
 
   setup_allocators (convert);
@@ -914,15 +1001,18 @@
     audio_chain_free (convert->convert_in_chain);
   if (convert->mix_chain)
     audio_chain_free (convert->mix_chain);
+  if (convert->resample_chain)
+    audio_chain_free (convert->resample_chain);
   if (convert->convert_out_chain)
     audio_chain_free (convert->convert_out_chain);
   if (convert->quant_chain)
     audio_chain_free (convert->quant_chain);
-
   if (convert->quant)
     gst_audio_quantize_free (convert->quant);
   if (convert->mix)
     gst_audio_channel_mixer_free (convert->mix);
+  if (convert->resampler)
+    gst_audio_resampler_free (convert->resampler);
   gst_audio_info_init (&convert->in);
   gst_audio_info_init (&convert->out);
 
@@ -945,7 +1035,10 @@
 gst_audio_converter_get_out_frames (GstAudioConverter * convert,
     gsize in_frames)
 {
-  return in_frames;
+  if (convert->resampler)
+    return gst_audio_resampler_get_out_frames (convert->resampler, in_frames);
+  else
+    return in_frames;
 }
 
 /**
@@ -962,7 +1055,10 @@
 gst_audio_converter_get_in_frames (GstAudioConverter * convert,
     gsize out_frames)
 {
-  return out_frames;
+  if (convert->resampler)
+    return gst_audio_resampler_get_in_frames (convert->resampler, out_frames);
+  else
+    return out_frames;
 }
 
 /**
@@ -978,7 +1074,10 @@
 gsize
 gst_audio_converter_get_max_latency (GstAudioConverter * convert)
 {
-  return 0;
+  if (convert->resampler)
+    return gst_audio_resampler_get_max_latency (convert->resampler);
+  else
+    return 0;
 }
 
 /**
@@ -991,6 +1090,8 @@
 void
 gst_audio_converter_reset (GstAudioConverter * convert)
 {
+  if (convert->resampler)
+    gst_audio_resampler_reset (convert->resampler);
   if (convert->quant)
     gst_audio_quantize_reset (convert->quant);
 }
@@ -1031,8 +1132,6 @@
   g_return_val_if_fail (convert != NULL, FALSE);
   g_return_val_if_fail (out != NULL, FALSE);
 
-  in_frames = MIN (in_frames, out_frames);
-
   if (in_frames == 0) {
     GST_LOG ("skipping empty buffer");
     return TRUE;
diff --git a/gst-libs/gst/audio/audio-converter.h b/gst-libs/gst/audio/audio-converter.h
index 6d037db..1f6ddc5 100644
--- a/gst-libs/gst/audio/audio-converter.h
+++ b/gst-libs/gst/audio/audio-converter.h
@@ -29,6 +29,15 @@
 typedef struct _GstAudioConverter GstAudioConverter;
 
 /**
+ * GST_AUDIO_CONVERTER_OPT_RESAMPLER_METHOD:
+ *
+ * #GST_TYPE_AUDIO_RESAMPLER_METHOD, The resampler method to use when
+ * changing sample rates.
+ * Default is #GST_AUDIO_RESAMPLER_METHOD_BLACKMAN_NUTTALL.
+ */
+#define GST_AUDIO_CONVERTER_OPT_RESAMPLER_METHOD   "GstAudioConverter.resampler-method"
+
+/**
  * GST_AUDIO_CONVERTER_OPT_DITHER_METHOD:
  *
  * #GST_TYPE_AUDIO_DITHER_METHOD, The dither method to use when
@@ -94,7 +103,6 @@
 
 gsize                gst_audio_converter_get_max_latency (GstAudioConverter *convert);
 
-
 gboolean             gst_audio_converter_samples         (GstAudioConverter * convert,
                                                           GstAudioConverterFlags flags,
                                                           gpointer in[], gsize in_frames,
diff --git a/gst-libs/gst/audio/audio-resampler-macros.h b/gst-libs/gst/audio/audio-resampler-macros.h
new file mode 100644
index 0000000..fd6652c
--- /dev/null
+++ b/gst-libs/gst/audio/audio-resampler-macros.h
@@ -0,0 +1,108 @@
+/* GStreamer
+ * Copyright (C) <2015> Wim Taymans <wim.taymans@gmail.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.
+ */
+
+#ifndef __GST_AUDIO_RESAMPLER_MACROS_H__
+#define __GST_AUDIO_RESAMPLER_MACROS_H__
+
+#include <string.h>
+
+#include "audio-resampler-private.h"
+
+#define PRECISION_S16 15
+#define PRECISION_S32 31
+
+#define DECL_GET_TAPS_FULL_FUNC(type)                           \
+gpointer                                                        \
+get_taps_##type##_full (GstAudioResampler * resampler,          \
+    gint *samp_index, gint *samp_phase, type icoeff[4])
+
+DECL_GET_TAPS_FULL_FUNC (gint16);
+DECL_GET_TAPS_FULL_FUNC (gint32);
+DECL_GET_TAPS_FULL_FUNC (gfloat);
+DECL_GET_TAPS_FULL_FUNC (gdouble);
+
+
+#define DECL_GET_TAPS_INTERPOLATE_FUNC(type, inter)             \
+gpointer                                                        \
+get_taps_##type##_##inter (GstAudioResampler * resampler,       \
+    gint *samp_index, gint *samp_phase, type icoeff[4])         \
+
+DECL_GET_TAPS_INTERPOLATE_FUNC (gint16, linear);
+DECL_GET_TAPS_INTERPOLATE_FUNC (gint32, linear);
+DECL_GET_TAPS_INTERPOLATE_FUNC (gfloat, linear);
+DECL_GET_TAPS_INTERPOLATE_FUNC (gdouble, linear);
+
+DECL_GET_TAPS_INTERPOLATE_FUNC (gint16, cubic);
+DECL_GET_TAPS_INTERPOLATE_FUNC (gint32, cubic);
+DECL_GET_TAPS_INTERPOLATE_FUNC (gfloat, cubic);
+DECL_GET_TAPS_INTERPOLATE_FUNC (gdouble, cubic);
+
+
+#define DECL_RESAMPLE_FUNC(type,inter,channels,arch)                    \
+void                                                                    \
+resample_ ##type## _ ##inter## _ ##channels## _ ##arch (GstAudioResampler * resampler,      \
+    gpointer in[], gsize in_len,  gpointer out[], gsize out_len,        \
+    gsize * consumed)
+
+#define MAKE_RESAMPLE_FUNC(type,inter,channels,arch)            \
+DECL_RESAMPLE_FUNC (type, inter, channels, arch)                \
+{                                                               \
+  gint c, di = 0;                                               \
+  gint n_taps = resampler->n_taps;                              \
+  gint blocks = resampler->blocks;                              \
+  gint ostride = resampler->ostride;                            \
+  gint taps_stride = resampler->taps_stride;                    \
+  gint samp_index = 0;                                          \
+  gint samp_phase = 0;                                          \
+                                                                \
+  for (c = 0; c < blocks; c++) {                                \
+    type *ip = in[c];                                           \
+    type *op = ostride == 1 ? out[c] : (type *)out[0] + c;      \
+                                                                \
+    samp_index = resampler->samp_index;                         \
+    samp_phase = resampler->samp_phase;                         \
+                                                                \
+    for (di = 0; di < out_len; di++) {                          \
+      type *ipp, icoeff[4], *taps;                              \
+                                                                \
+      ipp = &ip[samp_index * channels];                         \
+                                                                \
+      taps = get_taps_ ##type##_##inter                         \
+              (resampler, &samp_index, &samp_phase, icoeff);    \
+      inner_product_ ##type##_##inter##_##channels##_##arch     \
+              (op, ipp, taps, n_taps, icoeff, taps_stride);     \
+      op += ostride;                                            \
+    }                                                           \
+    if (in_len > samp_index)                                    \
+      memmove (ip, &ip[samp_index * channels],                  \
+          (in_len - samp_index) * sizeof(type) * channels);     \
+  }                                                             \
+  *consumed = samp_index - resampler->samp_index;               \
+                                                                \
+  resampler->samp_index = 0;                                    \
+  resampler->samp_phase = samp_phase;                           \
+}
+
+#define DECL_RESAMPLE_FUNC_STATIC(type,inter,channels,arch)     \
+static DECL_RESAMPLE_FUNC (type, inter, channels, arch)
+
+#define MAKE_RESAMPLE_FUNC_STATIC(type,inter,channels,arch)     \
+static MAKE_RESAMPLE_FUNC (type, inter, channels, arch)
+
+#endif /* __GST_AUDIO_RESAMPLER_MACROS_H__ */
diff --git a/gst-libs/gst/audio/audio-resampler-neon.h b/gst-libs/gst/audio/audio-resampler-neon.h
new file mode 100644
index 0000000..5863e18
--- /dev/null
+++ b/gst-libs/gst/audio/audio-resampler-neon.h
@@ -0,0 +1,691 @@
+/* GStreamer
+ * Copyright (C) <2016> Wim Taymans <wim.taymans@gmail.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.
+ */
+
+static inline void
+inner_product_gint16_full_1_neon (gint16 * o, const gint16 * a,
+    const gint16 * b, gint len, const gint16 * icoeff, gint bstride)
+{
+    uint32_t remainder = len % 16;
+    len = len - remainder;
+
+    asm volatile ("      vmov.s32 q0, #0\n"
+                  "      cmp %[len], #0\n"
+                  "      beq 2f\n"
+                  "      vmov.s32 q1, #0\n"
+                  "1:"
+                  "      vld1.16 {d16, d17, d18, d19}, [%[b]]!\n"
+                  "      vld1.16 {d20, d21, d22, d23}, [%[a]]!\n"
+                  "      subs %[len], %[len], #16\n"
+                  "      vmlal.s16 q0, d16, d20\n"
+                  "      vmlal.s16 q1, d17, d21\n"
+                  "      vmlal.s16 q0, d18, d22\n"
+                  "      vmlal.s16 q1, d19, d23\n"
+                  "      bne 1b\n"
+                  "      vadd.s32 q0, q0, q1\n"
+                  "2:"
+                  "      cmp %[remainder], #0\n"
+                  "      beq 4f\n"
+                  "3:"
+                  "      vld1.16 {d16}, [%[b]]!\n"
+                  "      vld1.16 {d20}, [%[a]]!\n"
+                  "      subs %[remainder], %[remainder], #4\n"
+                  "      vmlal.s16 q0, d16, d20\n"
+                  "      bne 3b\n"
+                  "4:"
+                  "      vadd.s32 d0, d0, d1\n"
+                  "      vpadd.s32 d0, d0, d0\n"
+                  "      vqrshrn.s32 d0, q0, #15\n"
+                  "      vst1.16 d0[0], [%[o]]\n"
+                  : [a] "+r" (a), [b] "+r" (b),
+                    [len] "+r" (len), [remainder] "+r" (remainder)
+                  : [o] "r" (o)
+                  : "cc", "q0", "q1",
+                    "d16", "d17", "d18", "d19",
+                    "d20", "d21", "d22", "d23");
+}
+
+static inline void
+inner_product_gint16_linear_1_neon (gint16 * o, const gint16 * a,
+    const gint16 * b, gint len, const gint16 * icoeff, gint bstride)
+{
+    uint32_t remainder = len % 16;
+    const gint16 *c[2] = {(gint16*)((gint8*)b + 0*bstride),
+                          (gint16*)((gint8*)b + 1*bstride)};
+    len = len - remainder;
+
+    asm volatile ("      vmov.s16 q0, #0\n"
+                  "      vmov.s16 q1, #0\n"
+                  "      cmp %[len], #0\n"
+                  "      beq 2f\n"
+                  "1:"
+                  "      vld1.16 {d16, d17, d18, d19}, [%[c0]]!\n"
+                  "      vld1.16 {d20, d21, d22, d23}, [%[c1]]!\n"
+                  "      vld1.16 {d24, d25, d26, d27}, [%[a]]!\n"
+                  "      subs %[len], %[len], #16\n"
+                  "      vmlal.s16 q0, d16, d24\n"
+                  "      vmlal.s16 q1, d20, d24\n"
+                  "      vmlal.s16 q0, d17, d25\n"
+                  "      vmlal.s16 q1, d21, d25\n"
+                  "      vmlal.s16 q0, d18, d26\n"
+                  "      vmlal.s16 q1, d22, d26\n"
+                  "      vmlal.s16 q0, d19, d27\n"
+                  "      vmlal.s16 q1, d23, d27\n"
+                  "      bne 1b\n"
+                  "2:"
+                  "      cmp %[remainder], #0\n"
+                  "      beq 4f\n"
+                  "3:"
+                  "      vld1.16 {d16}, [%[c0]]!\n"
+                  "      vld1.16 {d20}, [%[c1]]!\n"
+                  "      vld1.16 {d24}, [%[a]]!\n"
+                  "      subs %[remainder], %[remainder], #4\n"
+                  "      vmlal.s16 q0, d16, d24\n"
+                  "      vmlal.s16 q1, d20, d24\n"
+                  "      bne 3b\n"
+                  "4:"
+                  "      vld2.16 {d20[], d21[]}, [%[ic]]\n"
+                  "      vshrn.s32 d0, q0, #15\n"
+                  "      vshrn.s32 d2, q1, #15\n"
+                  "      vmull.s16 q0, d0, d20\n"
+                  "      vmlal.s16 q0, d2, d21\n"
+                  "      vadd.s32 d0, d0, d1\n"
+                  "      vpadd.s32 d0, d0, d0\n"
+                  "      vqrshrn.s32 d0, q0, #15\n"
+                  "      vst1.16 d0[0], [%[o]]\n"
+                  : [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
+                    [len] "+r" (len), [remainder] "+r" (remainder)
+                  : [o] "r" (o), [ic] "r" (icoeff)
+                  : "cc", "q0", "q1",
+                    "d16", "d17", "d18", "d19",
+                    "d20", "d21", "d22", "d23",
+                    "d24", "d25", "d26", "d27", "memory");
+}
+
+static inline void
+inner_product_gint16_cubic_1_neon (gint16 * o, const gint16 * a,
+    const gint16 * b, gint len, const gint16 * icoeff, gint bstride)
+{
+    const gint16 *c[4] = {(gint16*)((gint8*)b + 0*bstride),
+                          (gint16*)((gint8*)b + 1*bstride),
+                          (gint16*)((gint8*)b + 2*bstride),
+                          (gint16*)((gint8*)b + 3*bstride)};
+
+    asm volatile ("      vmov.s32 q0, #0\n"
+                  "      vmov.s32 q1, #0\n"
+                  "      vmov.s32 q2, #0\n"
+                  "      vmov.s32 q3, #0\n"
+                  "      cmp %[len], #0\n"
+                  "      beq 2f\n"
+                  "1:"
+                  "      vld1.16 {d16, d17}, [%[c0]]!\n"
+                  "      vld1.16 {d18, d19}, [%[c1]]!\n"
+                  "      vld1.16 {d20, d21}, [%[c2]]!\n"
+                  "      vld1.16 {d22, d23}, [%[c3]]!\n"
+                  "      vld1.16 {d24, d25}, [%[a]]!\n"
+                  "      subs %[len], %[len], #8\n"
+                  "      vmlal.s16 q0, d16, d24\n"
+                  "      vmlal.s16 q1, d18, d24\n"
+                  "      vmlal.s16 q2, d20, d24\n"
+                  "      vmlal.s16 q3, d22, d24\n"
+                  "      vmlal.s16 q0, d17, d25\n"
+                  "      vmlal.s16 q1, d19, d25\n"
+                  "      vmlal.s16 q2, d21, d25\n"
+                  "      vmlal.s16 q3, d23, d25\n"
+                  "      bne 1b\n"
+                  "2:"
+                  "      vld4.16 {d20[], d21[], d22[], d23[]}, [%[ic]]\n"
+                  "      vshrn.s32 d0, q0, #15\n"
+                  "      vshrn.s32 d2, q1, #15\n"
+                  "      vshrn.s32 d4, q2, #15\n"
+                  "      vshrn.s32 d6, q3, #15\n"
+                  "      vmull.s16 q0, d0, d20\n"
+                  "      vmlal.s16 q0, d2, d21\n"
+                  "      vmlal.s16 q0, d4, d22\n"
+                  "      vmlal.s16 q0, d6, d23\n"
+                  "      vadd.s32 d0, d0, d1\n"
+                  "      vpadd.s32 d0, d0, d0\n"
+                  "      vqrshrn.s32 d0, q0, #15\n"
+                  "      vst1.16 d0[0], [%[o]]\n"
+                  : [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
+                    [c2] "+r" (c[2]), [c3] "+r" (c[3]), [len] "+r" (len)
+                  : [o] "r" (o), [ic] "r" (icoeff)
+                  : "cc", "q0", "q1", "q2", "q3",
+                    "d16", "d17", "d18", "d19",
+                    "d20", "d21", "d22", "d23",
+                    "d24", "d25", "memory");
+}
+
+static inline void
+interpolate_gint16_linear_neon (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride)
+{
+    gint16 *o = op, *a = ap, *ic = icp;
+    const gint16 *c[2] = {(gint16*)((gint8*)a + 0*astride),
+                          (gint16*)((gint8*)a + 1*astride)};
+
+    asm volatile ("      cmp %[len], #0\n"
+                  "      beq 2f\n"
+                  "      vld2.16 {d20[], d21[]}, [%[ic]]\n"
+                  "1:"
+                  "      vld1.16 {d16, d17}, [%[c0]]!\n"
+                  "      vld1.16 {d18, d19}, [%[c1]]!\n"
+                  "      subs %[len], %[len], #8\n"
+                  "      vmull.s16 q0, d16, d20\n"
+                  "      vmull.s16 q1, d17, d20\n"
+                  "      vmlal.s16 q0, d18, d21\n"
+                  "      vmlal.s16 q1, d19, d21\n"
+                  "      vqrshrn.s32 d0, q0, #15\n"
+                  "      vqrshrn.s32 d1, q1, #15\n"
+                  "      vst1.16 {d0, d1}, [%[o]]!\n"
+                  "      bne 1b\n"
+                  "2:"
+                  : [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
+                    [len] "+r" (len), [o] "+r" (o)
+                  : [ic] "r" (ic)
+                  : "cc", "q0", "q1",
+                    "d16", "d17", "d18", "d19", "d20", "d21", "memory");
+}
+
+static inline void
+interpolate_gint16_cubic_neon (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride)
+{
+    gint16 *o = op, *a = ap, *ic = icp;
+    const gint16 *c[4] = {(gint16*)((gint8*)a + 0*astride),
+                          (gint16*)((gint8*)a + 1*astride),
+                          (gint16*)((gint8*)a + 2*astride),
+                          (gint16*)((gint8*)a + 3*astride)};
+
+    asm volatile ("      cmp %[len], #0\n"
+                  "      beq 2f\n"
+                  "      vld4.16 {d24[], d25[], d26[], d27[]}, [%[ic]]\n"
+                  "1:"
+                  "      vld1.16 {d16, d17}, [%[c0]]!\n"
+                  "      vld1.16 {d18, d19}, [%[c1]]!\n"
+                  "      vld1.16 {d20, d21}, [%[c2]]!\n"
+                  "      vld1.16 {d22, d23}, [%[c3]]!\n"
+                  "      subs %[len], %[len], #8\n"
+                  "      vmull.s16 q0, d16, d24\n"
+                  "      vmull.s16 q1, d17, d24\n"
+                  "      vmlal.s16 q0, d18, d25\n"
+                  "      vmlal.s16 q1, d19, d25\n"
+                  "      vmlal.s16 q0, d20, d26\n"
+                  "      vmlal.s16 q1, d21, d26\n"
+                  "      vmlal.s16 q0, d22, d27\n"
+                  "      vmlal.s16 q1, d23, d27\n"
+                  "      vqrshrn.s32 d0, q0, #15\n"
+                  "      vqrshrn.s32 d1, q1, #15\n"
+                  "      vst1.16 {d0, d1}, [%[o]]!\n"
+                  "      bne 1b\n"
+                  "2:"
+                  : [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]), [c2] "+r" (c[2]), [c3] "+r" (c[3]),
+                    [len] "+r" (len), [o] "+r" (o)
+                  : [ic] "r" (ic)
+                  : "cc", "q0", "q1",
+                    "d16", "d17", "d18", "d19", "d20", "d21", "d22",
+                    "d23", "d24", "d25", "d26", "d27", "memory");
+}
+
+static inline void
+inner_product_gint32_full_1_neon (gint32 * o, const gint32 * a,
+    const gint32 * b, gint len, const gint32 * icoeff, gint bstride)
+{
+    uint32_t remainder = len % 8;
+    len = len - remainder;
+
+    asm volatile ("      vmov.s64 q0, #0\n"
+                  "      cmp %[len], #0\n"
+                  "      beq 2f\n"
+                  "      vmov.s64 q1, #0\n"
+                  "1:"
+                  "      vld1.32 {d16, d17, d18, d19}, [%[b]]!\n"
+                  "      vld1.32 {d20, d21, d22, d23}, [%[a]]!\n"
+                  "      subs %[len], %[len], #8\n"
+                  "      vmlal.s32 q0, d16, d20\n"
+                  "      vmlal.s32 q1, d17, d21\n"
+                  "      vmlal.s32 q0, d18, d22\n"
+                  "      vmlal.s32 q1, d19, d23\n"
+                  "      bne 1b\n"
+                  "      vadd.s64 q0, q0, q1\n"
+                  "2:"
+                  "      cmp %[remainder], #0\n"
+                  "      beq 4f\n"
+                  "3:"
+                  "      vld1.32 {d16, d17}, [%[b]]!\n"
+                  "      vld1.32 {d20, d21}, [%[a]]!\n"
+                  "      subs %[remainder], %[remainder], #4\n"
+                  "      vmlal.s32 q0, d16, d20\n"
+                  "      vmlal.s32 q0, d17, d21\n"
+                  "      bne 3b\n"
+                  "4:"
+                  "      vadd.s64 d0, d0, d1\n"
+                  "      vqrshrn.s64 d0, q0, #31\n"
+                  "      vst1.32 d0[0], [%[o]]\n"
+                  : [a] "+r" (a), [b] "+r" (b),
+                    [len] "+r" (len), [remainder] "+r" (remainder)
+                  : [o] "r" (o)
+                  : "cc", "q0", "q1",
+                    "d16", "d17", "d18", "d19",
+                    "d20", "d21", "d22", "d23");
+}
+
+static inline void
+inner_product_gint32_linear_1_neon (gint32 * o, const gint32 * a,
+    const gint32 * b, gint len, const gint32 * icoeff, gint bstride)
+{
+    const gint32 *c[2] = {(gint32*)((gint8*)b + 0*bstride),
+                          (gint32*)((gint8*)b + 1*bstride)};
+
+    asm volatile ("      vmov.s64 q0, #0\n"
+                  "      vmov.s64 q1, #0\n"
+                  "      cmp %[len], #0\n"
+                  "      beq 2f\n"
+                  "1:"
+                  "      vld1.32 {d16, d17, d18, d19}, [%[c0]]!\n"
+                  "      vld1.32 {d20, d21, d22, d23}, [%[c1]]!\n"
+                  "      vld1.32 {d24, d25, d26, d27}, [%[a]]!\n"
+                  "      subs %[len], %[len], #8\n"
+                  "      vmlal.s32 q0, d16, d24\n"
+                  "      vmlal.s32 q1, d20, d24\n"
+                  "      vmlal.s32 q0, d17, d25\n"
+                  "      vmlal.s32 q1, d21, d25\n"
+                  "      vmlal.s32 q0, d18, d26\n"
+                  "      vmlal.s32 q1, d22, d26\n"
+                  "      vmlal.s32 q0, d19, d27\n"
+                  "      vmlal.s32 q1, d23, d27\n"
+                  "      bne 1b\n"
+                  "2:"
+                  "      vld2.32 {d20[], d21[]}, [%[ic]]\n"
+                  "      vshrn.s64 d0, q0, #31\n"
+                  "      vshrn.s64 d2, q1, #31\n"
+                  "      vmull.s32 q0, d0, d20\n"
+                  "      vmlal.s32 q0, d2, d21\n"
+                  "      vadd.s64 d0, d0, d1\n"
+                  "      vqrshrn.s64 d0, q0, #31\n"
+                  "      vst1.32 d0[0], [%[o]]\n"
+                  : [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
+                    [len] "+r" (len)
+                  : [o] "r" (o), [ic] "r" (icoeff)
+                  : "cc", "q0", "q1",
+                    "d16", "d17", "d18", "d19",
+                    "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "memory");
+}
+
+static inline void
+inner_product_gint32_cubic_1_neon (gint32 * o, const gint32 * a,
+    const gint32 * b, gint len, const gint32 * icoeff, gint bstride)
+{
+    const gint32 *c[4] = {(gint32*)((gint8*)b + 0*bstride),
+                          (gint32*)((gint8*)b + 1*bstride),
+                          (gint32*)((gint8*)b + 2*bstride),
+                          (gint32*)((gint8*)b + 3*bstride)};
+
+    asm volatile ("      vmov.s64 q0, #0\n"
+                  "      vmov.s64 q1, #0\n"
+                  "      vmov.s64 q2, #0\n"
+                  "      vmov.s64 q3, #0\n"
+                  "      cmp %[len], #0\n"
+                  "      beq 2f\n"
+                  "1:"
+                  "      vld1.32 {d16, d17}, [%[c0]]!\n"
+                  "      vld1.32 {d18, d19}, [%[c1]]!\n"
+                  "      vld1.32 {d20, d21}, [%[c2]]!\n"
+                  "      vld1.32 {d22, d23}, [%[c3]]!\n"
+                  "      vld1.32 {d24, d25}, [%[a]]!\n"
+                  "      subs %[len], %[len], #4\n"
+                  "      vmlal.s32 q0, d16, d24\n"
+                  "      vmlal.s32 q1, d18, d24\n"
+                  "      vmlal.s32 q2, d20, d24\n"
+                  "      vmlal.s32 q3, d22, d24\n"
+                  "      vmlal.s32 q0, d17, d25\n"
+                  "      vmlal.s32 q1, d19, d25\n"
+                  "      vmlal.s32 q2, d21, d25\n"
+                  "      vmlal.s32 q3, d23, d25\n"
+                  "      bne 1b\n"
+                  "2:"
+                  "      vld4.32 {d20[], d21[], d22[], d23[]}, [%[ic]]\n"
+                  "      vshrn.s64 d0, q0, #31\n"
+                  "      vshrn.s64 d2, q1, #31\n"
+                  "      vshrn.s64 d4, q2, #31\n"
+                  "      vshrn.s64 d6, q3, #31\n"
+                  "      vmull.s32 q0, d0, d20\n"
+                  "      vmlal.s32 q0, d2, d21\n"
+                  "      vmlal.s32 q0, d4, d22\n"
+                  "      vmlal.s32 q0, d6, d23\n"
+                  "      vadd.s64 d0, d0, d1\n"
+                  "      vqrshrn.s64 d0, q0, #31\n"
+                  "      vst1.32 d0[0], [%[o]]\n"
+                  : [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
+                    [c2] "+r" (c[2]), [c3] "+r" (c[3]), [len] "+r" (len)
+                  : [o] "r" (o), [ic] "r" (icoeff)
+                  : "cc", "q0", "q1", "q2", "q3",
+                    "d16", "d17", "d18", "d19",
+                    "d20", "d21", "d22", "d23", "d24", "d25", "memory");
+}
+
+static inline void
+interpolate_gint32_linear_neon (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride)
+{
+    gint32 *o = op, *a = ap, *ic = icp;
+    const gint32 *c[2] = {(gint32*)((gint8*)a + 0*astride),
+                          (gint32*)((gint8*)a + 1*astride)};
+
+    asm volatile ("      cmp %[len], #0\n"
+                  "      beq 2f\n"
+                  "      vld2.32 {d24[], d25[]}, [%[ic]]!\n"
+                  "1:"
+                  "      vld1.32 {d16, d17, d18, d19}, [%[c0]]!\n"
+                  "      vld1.32 {d20, d21, d22, d23}, [%[c1]]!\n"
+                  "      subs %[len], %[len], #8\n"
+                  "      vmull.s32 q0, d16, d24\n"
+                  "      vmull.s32 q1, d17, d24\n"
+                  "      vmull.s32 q2, d18, d24\n"
+                  "      vmull.s32 q3, d19, d24\n"
+                  "      vmlal.s32 q0, d20, d25\n"
+                  "      vmlal.s32 q1, d21, d25\n"
+                  "      vmlal.s32 q2, d22, d25\n"
+                  "      vmlal.s32 q3, d23, d25\n"
+                  "      vqrshrn.s64 d0, q0, #31\n"
+                  "      vqrshrn.s64 d1, q1, #31\n"
+                  "      vqrshrn.s64 d2, q2, #31\n"
+                  "      vqrshrn.s64 d3, q3, #31\n"
+                  "      vst1.32 {d0, d1, d2, d3}, [%[o]]!\n"
+                  "      bne 1b\n"
+                  "2:"
+                  : [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
+                    [len] "+r" (len), [o] "+r" (o)
+                  : [ic] "r" (ic)
+                  : "cc", "q0", "q1", "q2", "q3",
+                    "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "memory");
+}
+
+static inline void
+interpolate_gint32_cubic_neon (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride)
+{
+    gint32 *o = op, *a = ap, *ic = icp;
+    const gint32 *c[4] = {(gint32*)((gint8*)a + 0*astride),
+                          (gint32*)((gint8*)a + 1*astride),
+                          (gint32*)((gint8*)a + 2*astride),
+                          (gint32*)((gint8*)a + 3*astride)};
+
+    asm volatile ("      cmp %[len], #0\n"
+                  "      beq 2f\n"
+                  "      vld4.32 {d24[], d25[], d26[], d27[]}, [%[ic]]!\n"
+                  "1:"
+                  "      vld1.32 {d16, d17}, [%[c0]]!\n"
+                  "      vld1.32 {d18, d19}, [%[c1]]!\n"
+                  "      vld1.32 {d20, d21}, [%[c2]]!\n"
+                  "      vld1.32 {d22, d23}, [%[c3]]!\n"
+                  "      subs %[len], %[len], #4\n"
+                  "      vmull.s32 q0, d16, d24\n"
+                  "      vmull.s32 q1, d17, d24\n"
+                  "      vmlal.s32 q0, d18, d25\n"
+                  "      vmlal.s32 q1, d19, d25\n"
+                  "      vmlal.s32 q0, d20, d26\n"
+                  "      vmlal.s32 q1, d21, d26\n"
+                  "      vmlal.s32 q0, d22, d27\n"
+                  "      vmlal.s32 q1, d23, d27\n"
+                  "      vqrshrn.s64 d0, q0, #31\n"
+                  "      vqrshrn.s64 d1, q1, #31\n"
+                  "      vst1.32 {d0, d1}, [%[o]]!\n"
+                  "      bne 1b\n"
+                  "2:"
+                  : [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
+                    [c2] "+r" (c[2]), [c3] "+r" (c[3]), [len] "+r" (len), [o] "+r" (o)
+                  : [ic] "r" (ic)
+                  : "cc", "q0", "q1",
+                    "d16", "d17", "d18", "d19", "d20",
+                    "d21", "d22", "d23", "d24", "d25", "d26", "d27", "memory");
+}
+
+static inline void
+inner_product_gfloat_full_1_neon (gfloat * o, const gfloat * a,
+    const gfloat * b, gint len, const gfloat * icoeff, gint bstride)
+{
+    uint32_t remainder = len % 16;
+    len = len - remainder;
+
+    asm volatile ("      vmov.f32 q0, #0.0\n"
+                  "      cmp %[len], #0\n"
+                  "      beq 2f\n"
+                  "      vmov.f32 q1, #0.0\n"
+                  "1:"
+                  "      vld1.32 {q4, q5}, [%[b]]!\n"
+                  "      vld1.32 {q8, q9}, [%[a]]!\n"
+                  "      vld1.32 {q6, q7}, [%[b]]!\n"
+                  "      vld1.32 {q10, q11}, [%[a]]!\n"
+                  "      subs %[len], %[len], #16\n"
+                  "      vmla.f32 q0, q4, q8\n"
+                  "      vmla.f32 q1, q5, q9\n"
+                  "      vmla.f32 q0, q6, q10\n"
+                  "      vmla.f32 q1, q7, q11\n"
+                  "      bne 1b\n"
+                  "      vadd.f32 q0, q0, q1\n"
+                  "2:"
+                  "      cmp %[remainder], #0\n"
+                  "      beq 4f\n"
+                  "3:"
+                  "      vld1.32 {q6}, [%[b]]!\n"
+                  "      vld1.32 {q10}, [%[a]]!\n"
+                  "      subs %[remainder], %[remainder], #4\n"
+                  "      vmla.f32 q0, q6, q10\n"
+                  "      bne 3b\n"
+                  "4:"
+                  "      vadd.f32 d0, d0, d1\n"
+                  "      vpadd.f32 d0, d0, d0\n"
+                  "      vst1.32 d0[0], [%[o]]\n"
+                  : [a] "+r" (a), [b] "+r" (b),
+                    [len] "+r" (len), [remainder] "+r" (remainder)
+                  : [o] "r" (o)
+                  : "cc", "q0", "q1", "q4", "q5", "q6", "q7", "q8",
+                    "q9", "q10", "q11");
+}
+
+static inline void
+inner_product_gfloat_linear_1_neon (gfloat * o, const gfloat * a,
+    const gfloat * b, gint len, const gfloat * icoeff, gint bstride)
+{
+    const gfloat *c[2] = {(gfloat*)((gint8*)b + 0*bstride),
+                          (gfloat*)((gint8*)b + 1*bstride)};
+
+    asm volatile ("      vmov.f32 q0, #0.0\n"
+                  "      vmov.f32 q1, #0.0\n"
+                  "      cmp %[len], #0\n"
+                  "      beq 2f\n"
+                  "1:"
+                  "      vld1.32 {q8, q9}, [%[c0]]!\n"
+                  "      vld1.32 {q10, q11}, [%[c1]]!\n"
+                  "      vld1.32 {q12, q13}, [%[a]]!\n"
+                  "      subs %[len], %[len], #8\n"
+                  "      vmla.f32 q0, q8, q12\n"
+                  "      vmla.f32 q1, q10, q12\n"
+                  "      vmla.f32 q0, q9, q13\n"
+                  "      vmla.f32 q1, q11, q13\n"
+                  "      bne 1b\n"
+                  "2:"
+                  "      vld2.32 {d20[], d21[]}, [%[ic]]\n"
+                  "      vmul.f32 d0, d0, d20\n"
+                  "      vmla.f32 d0, d1, d20\n"
+                  "      vmla.f32 d0, d2, d21\n"
+                  "      vmla.f32 d0, d3, d21\n"
+                  "      vpadd.f32 d0, d0, d0\n"
+                  "      vst1.32 d0[0], [%[o]]\n"
+                  : [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
+                    [len] "+r" (len)
+                  : [o] "r" (o), [ic] "r" (icoeff)
+                  : "cc", "q0", "q1",
+                    "q8", "q9", "q10", "q11", "q12", "q13", "memory");
+}
+
+static inline void
+inner_product_gfloat_cubic_1_neon (gfloat * o, const gfloat * a,
+    const gfloat * b, gint len, const gfloat * icoeff, gint bstride)
+{
+    const gfloat *c[4] = {(gfloat*)((gint8*)b + 0*bstride),
+                          (gfloat*)((gint8*)b + 1*bstride),
+                          (gfloat*)((gint8*)b + 2*bstride),
+                          (gfloat*)((gint8*)b + 3*bstride)};
+
+    asm volatile ("      vmov.f32 q0, #0.0\n"
+                  "      vmov.f32 q1, #0.0\n"
+                  "      vmov.f32 q2, #0.0\n"
+                  "      vmov.f32 q3, #0.0\n"
+                  "      cmp %[len], #0\n"
+                  "      beq 2f\n"
+                  "1:"
+                  "      vld1.32 {q8}, [%[c0]]!\n"
+                  "      vld1.32 {q9}, [%[c1]]!\n"
+                  "      vld1.32 {q10}, [%[c2]]!\n"
+                  "      vld1.32 {q11}, [%[c3]]!\n"
+                  "      vld1.32 {q12}, [%[a]]!\n"
+                  "      subs %[len], %[len], #4\n"
+                  "      vmla.f32 q0, q8, q12\n"
+                  "      vmla.f32 q1, q9, q12\n"
+                  "      vmla.f32 q2, q10, q12\n"
+                  "      vmla.f32 q3, q11, q12\n"
+                  "      bne 1b\n"
+                  "2:"
+                  "      vld4.32 {d20[], d21[], d22[], d23[]}, [%[ic]]\n"
+                  "      vmul.f32 d0, d0, d20\n"
+                  "      vmla.f32 d0, d1, d20\n"
+                  "      vmla.f32 d0, d2, d21\n"
+                  "      vmla.f32 d0, d3, d21\n"
+                  "      vmla.f32 d0, d4, d22\n"
+                  "      vmla.f32 d0, d5, d22\n"
+                  "      vmla.f32 d0, d6, d23\n"
+                  "      vmla.f32 d0, d7, d23\n"
+                  "      vpadd.f32 d0, d0, d0\n"
+                  "      vst1.32 d0[0], [%[o]]\n"
+                  : [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
+                    [c2] "+r" (c[2]), [c3] "+r" (c[3]), [len] "+r" (len), [o] "+r" (o)
+                  : [ic] "r" (icoeff)
+                  : "cc", "q0", "q1", "q2", "q3",
+                    "q8", "q9", "q10", "q11", "q12", "memory");
+}
+
+static inline void
+interpolate_gfloat_linear_neon (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride)
+{
+    gfloat *o = op, *a = ap, *ic = icp;
+    const gfloat *c[2] = {(gfloat*)((gint8*)a + 0*astride),
+                          (gfloat*)((gint8*)a + 1*astride)};
+
+    asm volatile ("      cmp %[len], #0\n"
+                  "      beq 2f\n"
+                  "      vld2.32 {d24[], d26[]}, [%[ic]]!\n"
+                  "      vmov.32 d25, d24\n"
+                  "      vmov.32 d27, d26\n"
+                  "1:"
+                  "      vld1.32 {q8, q9}, [%[c0]]!\n"
+                  "      vld1.32 {q10, q11}, [%[c1]]!\n"
+                  "      subs %[len], %[len], #8\n"
+                  "      vmul.f32 q0, q8, q12\n"
+                  "      vmul.f32 q1, q9, q12\n"
+                  "      vmla.f32 q0, q10, q13\n"
+                  "      vmla.f32 q1, q11, q13\n"
+                  "      vst1.32 {q0, q1}, [%[o]]!\n"
+                  "      bne 1b\n"
+                  "2:"
+                  : [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
+                    [len] "+r" (len), [o] "+r" (o)
+                  : [ic] "r" (ic)
+                  : "cc", "q0", "q1", "q8", "q9",
+                    "q10", "q11", "q12", "q13", "memory");
+}
+
+static inline void
+interpolate_gfloat_cubic_neon (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride)
+{
+    gfloat *o = op, *a = ap, *ic = icp;
+    const gfloat *c[4] = {(gfloat*)((gint8*)a + 0*astride),
+                          (gfloat*)((gint8*)a + 1*astride),
+                          (gfloat*)((gint8*)a + 2*astride),
+                          (gfloat*)((gint8*)a + 3*astride)};
+
+    asm volatile ("      cmp %[len], #0\n"
+                  "      beq 2f\n"
+                  "      vld4.32 {d24[], d26[], d28[], d30[]}, [%[ic]]!\n"
+                  "      vmov.32 d25, d24\n"
+                  "      vmov.32 d27, d26\n"
+                  "      vmov.32 d29, d28\n"
+                  "      vmov.32 d31, d30\n"
+                  "1:"
+                  "      vld1.32 {q8}, [%[c0]]!\n"
+                  "      vld1.32 {q9}, [%[c1]]!\n"
+                  "      vld1.32 {q10}, [%[c2]]!\n"
+                  "      vld1.32 {q11}, [%[c3]]!\n"
+                  "      subs %[len], %[len], #4\n"
+                  "      vmul.f32 q0, q8, q12\n"
+                  "      vmla.f32 q0, q9, q13\n"
+                  "      vmla.f32 q0, q10, q14\n"
+                  "      vmla.f32 q0, q11, q15\n"
+                  "      vst1.32 {q0}, [%[o]]!\n"
+                  "      bne 1b\n"
+                  "2:"
+                  : [a] "+r" (a), [c0] "+r" (c[0]), [c1] "+r" (c[1]),
+                    [c2] "+r" (c[2]), [c3] "+r" (c[3]),
+                    [len] "+r" (len), [o] "+r" (o)
+                  : [ic] "r" (ic)
+                  : "cc", "q0", "q8", "q9",
+                    "q10", "q11", "q12", "q13", "q14", "q15", "memory");
+}
+
+MAKE_RESAMPLE_FUNC_STATIC (gint16, full, 1, neon);
+MAKE_RESAMPLE_FUNC_STATIC (gint16, linear, 1, neon);
+MAKE_RESAMPLE_FUNC_STATIC (gint16, cubic, 1, neon);
+
+MAKE_RESAMPLE_FUNC_STATIC (gint32, full, 1, neon);
+MAKE_RESAMPLE_FUNC_STATIC (gint32, linear, 1, neon);
+MAKE_RESAMPLE_FUNC_STATIC (gint32, cubic, 1, neon);
+
+MAKE_RESAMPLE_FUNC_STATIC (gfloat, full, 1, neon);
+MAKE_RESAMPLE_FUNC_STATIC (gfloat, linear, 1, neon);
+MAKE_RESAMPLE_FUNC_STATIC (gfloat, cubic, 1, neon);
+
+static void
+audio_resampler_check_neon (const gchar *option)
+{
+  if (!strcmp (option, "neon")) {
+    GST_DEBUG ("enable NEON optimisations");
+    resample_gint16_full_1 = resample_gint16_full_1_neon;
+    resample_gint16_linear_1 = resample_gint16_linear_1_neon;
+    resample_gint16_cubic_1 = resample_gint16_cubic_1_neon;
+
+    interpolate_gint16_linear = interpolate_gint16_linear_neon;
+    interpolate_gint16_cubic = interpolate_gint16_cubic_neon;
+
+    resample_gint32_full_1 = resample_gint32_full_1_neon;
+    resample_gint32_linear_1 = resample_gint32_linear_1_neon;
+    resample_gint32_cubic_1 = resample_gint32_cubic_1_neon;
+
+    interpolate_gint32_linear = interpolate_gint32_linear_neon;
+    interpolate_gint32_cubic = interpolate_gint32_cubic_neon;
+
+    resample_gfloat_full_1 = resample_gfloat_full_1_neon;
+    resample_gfloat_linear_1 = resample_gfloat_linear_1_neon;
+    resample_gfloat_cubic_1 = resample_gfloat_cubic_1_neon;
+
+    interpolate_gfloat_linear = interpolate_gfloat_linear_neon;
+    interpolate_gfloat_cubic = interpolate_gfloat_cubic_neon;
+  }
+}
diff --git a/gst-libs/gst/audio/audio-resampler-private.h b/gst-libs/gst/audio/audio-resampler-private.h
new file mode 100644
index 0000000..c8d1a7e
--- /dev/null
+++ b/gst-libs/gst/audio/audio-resampler-private.h
@@ -0,0 +1,113 @@
+/* GStreamer
+ * Copyright (C) <2015> Wim Taymans <wim.taymans@gmail.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.
+ */
+
+#ifndef __GST_AUDIO_RESAMPLER_PRIVATE_H__
+#define __GST_AUDIO_RESAMPLER_PRIVATE_H__
+
+#include "audio-resampler.h"
+
+/* Contains a collection of all things found in other resamplers:
+ * speex (filter construction, optimizations), ffmpeg (fixed phase filter, blackman filter),
+ * SRC (linear interpolation, fixed precomputed tables),...
+ *
+ *  Supports:
+ *   - S16, S32, F32 and F64 formats
+ *   - nearest, linear and cubic interpolation
+ *   - sinc based interpolation with kaiser or blackman-nutall windows
+ *   - fully configurable kaiser parameters
+ *   - dynamic linear or cubic interpolation of filter table, this can
+ *     use less memory but more CPU
+ *   - full filter table, generated from optionally linear or cubic
+ *     interpolation of filter table
+ *   - fixed filter table size with nearest neighbour phase, optionally
+ *     using a precomputed tables
+ *   - dynamic samplerate changes
+ *   - x86 and neon optimizations
+ */
+typedef void (*ConvertTapsFunc) (gdouble * tmp_taps, gpointer taps,
+    gdouble weight, gint n_taps);
+typedef void (*InterpolateFunc) (gpointer o, const gpointer a, gint len,
+    const gpointer icoeff, gint astride);
+typedef void (*ResampleFunc) (GstAudioResampler * resampler, gpointer in[],
+    gsize in_len, gpointer out[], gsize out_len, gsize * consumed);
+typedef void (*DeinterleaveFunc) (GstAudioResampler * resampler,
+    gpointer * sbuf, gpointer in[], gsize in_frames);
+
+struct _GstAudioResampler
+{
+  GstAudioResamplerMethod method;
+  GstAudioResamplerFlags flags;
+  GstAudioFormat format;
+  GstStructure *options;
+  gint format_index;
+  gint channels;
+  gint in_rate;
+  gint out_rate;
+
+  gint bps;
+  gint ostride;
+
+  GstAudioResamplerFilterMode filter_mode;
+  guint filter_threshold;
+  GstAudioResamplerFilterInterpolation filter_interpolation;
+
+  gdouble cutoff;
+  gdouble kaiser_beta;
+  /* for cubic */
+  gdouble b, c;
+
+  /* temp taps */
+  gpointer tmp_taps;
+
+  /* oversampled main filter table */
+  gint oversample;
+  gint n_taps;
+  gpointer taps;
+  gpointer taps_mem;
+  gsize taps_stride;
+  gint n_phases;
+  gint alloc_taps;
+  gint alloc_phases;
+
+  /* cached taps */
+  gpointer *cached_phases;
+  gpointer cached_taps;
+  gpointer cached_taps_mem;
+  gsize cached_taps_stride;
+
+  ConvertTapsFunc convert_taps;
+  InterpolateFunc interpolate;
+  DeinterleaveFunc deinterleave;
+  ResampleFunc resample;
+
+  gint blocks;
+  gint inc;
+  gint samp_inc;
+  gint samp_frac;
+  gint samp_index;
+  gint samp_phase;
+  gint skip;
+
+  gpointer samples;
+  gsize samples_len;
+  gsize samples_avail;
+  gpointer *sbuf;
+};
+
+#endif /* __GST_AUDIO_RESAMPLER_PRIVATE_H__ */
diff --git a/gst-libs/gst/audio/audio-resampler-x86-sse.c b/gst-libs/gst/audio/audio-resampler-x86-sse.c
new file mode 100644
index 0000000..d100c59
--- /dev/null
+++ b/gst-libs/gst/audio/audio-resampler-x86-sse.c
@@ -0,0 +1,168 @@
+/* GStreamer
+ * Copyright (C) <2016> Wim Taymans <wim.taymans@gmail.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 "audio-resampler-x86-sse.h"
+
+#if defined (HAVE_XMMINTRIN_H) && defined(__SSE__)
+#include <xmmintrin.h>
+
+static inline void
+inner_product_gfloat_full_1_sse (gfloat * o, const gfloat * a,
+    const gfloat * b, gint len, const gfloat * icoeff, gint bstride)
+{
+  gint i = 0;
+  __m128 sum = _mm_setzero_ps ();
+
+  for (; i < len; i += 8) {
+    sum =
+        _mm_add_ps (sum, _mm_mul_ps (_mm_loadu_ps (a + i + 0),
+            _mm_load_ps (b + i + 0)));
+    sum =
+        _mm_add_ps (sum, _mm_mul_ps (_mm_loadu_ps (a + i + 4),
+            _mm_load_ps (b + i + 4)));
+  }
+  sum = _mm_add_ps (sum, _mm_movehl_ps (sum, sum));
+  sum = _mm_add_ss (sum, _mm_shuffle_ps (sum, sum, 0x55));
+  _mm_store_ss (o, sum);
+}
+
+static inline void
+inner_product_gfloat_linear_1_sse (gfloat * o, const gfloat * a,
+    const gfloat * b, gint len, const gfloat * icoeff, gint bstride)
+{
+  gint i = 0;
+  __m128 sum[2], t;
+  const gfloat *c[2] = { (gfloat *) ((gint8 *) b + 0 * bstride),
+    (gfloat *) ((gint8 *) b + 1 * bstride)
+  };
+
+  sum[0] = sum[1] = _mm_setzero_ps ();
+
+  for (; i < len; i += 8) {
+    t = _mm_loadu_ps (a + i + 0);
+    sum[0] = _mm_add_ps (sum[0], _mm_mul_ps (t, _mm_load_ps (c[0] + i + 0)));
+    sum[1] = _mm_add_ps (sum[1], _mm_mul_ps (t, _mm_load_ps (c[1] + i + 0)));
+    t = _mm_loadu_ps (a + i + 4);
+    sum[0] = _mm_add_ps (sum[0], _mm_mul_ps (t, _mm_load_ps (c[0] + i + 4)));
+    sum[1] = _mm_add_ps (sum[1], _mm_mul_ps (t, _mm_load_ps (c[1] + i + 4)));
+  }
+  sum[0] = _mm_mul_ps (_mm_sub_ps (sum[0], sum[1]), _mm_load1_ps (icoeff));
+  sum[0] = _mm_add_ps (sum[0], sum[1]);
+  sum[0] = _mm_add_ps (sum[0], _mm_movehl_ps (sum[0], sum[0]));
+  sum[0] = _mm_add_ss (sum[0], _mm_shuffle_ps (sum[0], sum[0], 0x55));
+  _mm_store_ss (o, sum[0]);
+}
+
+static inline void
+inner_product_gfloat_cubic_1_sse (gfloat * o, const gfloat * a,
+    const gfloat * b, gint len, const gfloat * icoeff, gint bstride)
+{
+  gint i = 0;
+  __m128 sum[4];
+  __m128 t, f = _mm_loadu_ps (icoeff);
+  const gfloat *c[4] = { (gfloat *) ((gint8 *) b + 0 * bstride),
+    (gfloat *) ((gint8 *) b + 1 * bstride),
+    (gfloat *) ((gint8 *) b + 2 * bstride),
+    (gfloat *) ((gint8 *) b + 3 * bstride)
+  };
+
+  sum[0] = sum[1] = sum[2] = sum[3] = _mm_setzero_ps ();
+
+  for (; i < len; i += 4) {
+    t = _mm_loadu_ps (a + i);
+    sum[0] = _mm_add_ps (sum[0], _mm_mul_ps (t, _mm_load_ps (c[0] + i)));
+    sum[1] = _mm_add_ps (sum[1], _mm_mul_ps (t, _mm_load_ps (c[1] + i)));
+    sum[2] = _mm_add_ps (sum[2], _mm_mul_ps (t, _mm_load_ps (c[2] + i)));
+    sum[3] = _mm_add_ps (sum[3], _mm_mul_ps (t, _mm_load_ps (c[3] + i)));
+  }
+  sum[0] = _mm_mul_ps (sum[0], _mm_shuffle_ps (f, f, 0x00));
+  sum[1] = _mm_mul_ps (sum[1], _mm_shuffle_ps (f, f, 0x55));
+  sum[2] = _mm_mul_ps (sum[2], _mm_shuffle_ps (f, f, 0xaa));
+  sum[3] = _mm_mul_ps (sum[3], _mm_shuffle_ps (f, f, 0xff));
+  sum[0] = _mm_add_ps (sum[0], sum[1]);
+  sum[2] = _mm_add_ps (sum[2], sum[3]);
+  sum[0] = _mm_add_ps (sum[0], sum[2]);
+  sum[0] = _mm_add_ps (sum[0], _mm_movehl_ps (sum[0], sum[0]));
+  sum[0] = _mm_add_ss (sum[0], _mm_shuffle_ps (sum[0], sum[0], 0x55));
+  _mm_store_ss (o, sum[0]);
+}
+
+MAKE_RESAMPLE_FUNC (gfloat, full, 1, sse);
+MAKE_RESAMPLE_FUNC (gfloat, linear, 1, sse);
+MAKE_RESAMPLE_FUNC (gfloat, cubic, 1, sse);
+
+void
+interpolate_gfloat_linear_sse (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride)
+{
+  gint i;
+  gfloat *o = op, *a = ap, *ic = icp;
+  __m128 f[2], t1, t2;
+  const gfloat *c[2] = { (gfloat *) ((gint8 *) a + 0 * astride),
+    (gfloat *) ((gint8 *) a + 1 * astride)
+  };
+
+  f[0] = _mm_load1_ps (ic + 0);
+  f[1] = _mm_load1_ps (ic + 1);
+
+  for (i = 0; i < len; i += 8) {
+    t1 = _mm_mul_ps (_mm_load_ps (c[0] + i + 0), f[0]);
+    t2 = _mm_mul_ps (_mm_load_ps (c[1] + i + 0), f[1]);
+    _mm_store_ps (o + i + 0, _mm_add_ps (t1, t2));
+
+    t1 = _mm_mul_ps (_mm_load_ps (c[0] + i + 4), f[0]);
+    t2 = _mm_mul_ps (_mm_load_ps (c[1] + i + 4), f[1]);
+    _mm_store_ps (o + i + 4, _mm_add_ps (t1, t2));
+  }
+}
+
+void
+interpolate_gfloat_cubic_sse (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride)
+{
+  gint i;
+  gfloat *o = op, *a = ap, *ic = icp;
+  __m128 f[4], t[4];
+  const gfloat *c[4] = { (gfloat *) ((gint8 *) a + 0 * astride),
+    (gfloat *) ((gint8 *) a + 1 * astride),
+    (gfloat *) ((gint8 *) a + 2 * astride),
+    (gfloat *) ((gint8 *) a + 3 * astride)
+  };
+
+  f[0] = _mm_load1_ps (ic + 0);
+  f[1] = _mm_load1_ps (ic + 1);
+  f[2] = _mm_load1_ps (ic + 2);
+  f[3] = _mm_load1_ps (ic + 3);
+
+  for (i = 0; i < len; i += 4) {
+    t[0] = _mm_mul_ps (_mm_load_ps (c[0] + i + 0), f[0]);
+    t[1] = _mm_mul_ps (_mm_load_ps (c[1] + i + 0), f[1]);
+    t[2] = _mm_mul_ps (_mm_load_ps (c[2] + i + 0), f[2]);
+    t[3] = _mm_mul_ps (_mm_load_ps (c[3] + i + 0), f[3]);
+    t[0] = _mm_add_ps (t[0], t[1]);
+    t[2] = _mm_add_ps (t[2], t[3]);
+    _mm_store_ps (o + i + 0, _mm_add_ps (t[0], t[2]));
+  }
+}
+
+#endif
diff --git a/gst-libs/gst/audio/audio-resampler-x86-sse.h b/gst-libs/gst/audio/audio-resampler-x86-sse.h
new file mode 100644
index 0000000..1d3e9a4
--- /dev/null
+++ b/gst-libs/gst/audio/audio-resampler-x86-sse.h
@@ -0,0 +1,35 @@
+/* GStreamer
+ * Copyright (C) <2016> Wim Taymans <wim.taymans@gmail.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.
+ */
+
+#ifndef AUDIO_RESAMPLER_X86_SSE_H
+#define AUDIO_RESAMPLER_X86_SSE_H
+
+#include "audio-resampler-macros.h"
+
+DECL_RESAMPLE_FUNC (gfloat, full, 1, sse);
+DECL_RESAMPLE_FUNC (gfloat, linear, 1, sse);
+DECL_RESAMPLE_FUNC (gfloat, cubic, 1, sse);
+
+void interpolate_gfloat_linear_sse (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride);
+
+void interpolate_gfloat_cubic_sse (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride);
+
+#endif /* AUDIO_RESAMPLER_X86_SSE_H */
diff --git a/gst-libs/gst/audio/audio-resampler-x86-sse2.c b/gst-libs/gst/audio/audio-resampler-x86-sse2.c
new file mode 100644
index 0000000..a89fb41
--- /dev/null
+++ b/gst-libs/gst/audio/audio-resampler-x86-sse2.c
@@ -0,0 +1,399 @@
+/* GStreamer
+ * Copyright (C) <2016> Wim Taymans <wim.taymans@gmail.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 "audio-resampler-x86-sse2.h"
+
+#if defined (HAVE_EMMINTRIN_H) && defined(__SSE2__)
+#include <emmintrin.h>
+
+static inline void
+inner_product_gint16_full_1_sse2 (gint16 * o, const gint16 * a,
+    const gint16 * b, gint len, const gint16 * icoeff, gint bstride)
+{
+  gint i;
+  __m128i sum, t;
+
+  sum = _mm_setzero_si128 ();
+
+  for (i = 0; i < len; i += 16) {
+    t = _mm_loadu_si128 ((__m128i *) (a + i));
+    sum =
+        _mm_add_epi32 (sum, _mm_madd_epi16 (t,
+            _mm_load_si128 ((__m128i *) (b + i + 0))));
+
+    t = _mm_loadu_si128 ((__m128i *) (a + i + 8));
+    sum =
+        _mm_add_epi32 (sum, _mm_madd_epi16 (t,
+            _mm_load_si128 ((__m128i *) (b + i + 8))));
+  }
+  sum = _mm_add_epi32 (sum, _mm_shuffle_epi32 (sum, _MM_SHUFFLE (2, 3, 2, 3)));
+  sum = _mm_add_epi32 (sum, _mm_shuffle_epi32 (sum, _MM_SHUFFLE (1, 1, 1, 1)));
+
+  sum = _mm_add_epi32 (sum, _mm_set1_epi32 (1 << (PRECISION_S16 - 1)));
+  sum = _mm_srai_epi32 (sum, PRECISION_S16);
+  sum = _mm_packs_epi32 (sum, sum);
+  *o = _mm_extract_epi16 (sum, 0);
+}
+
+static inline void
+inner_product_gint16_linear_1_sse2 (gint16 * o, const gint16 * a,
+    const gint16 * b, gint len, const gint16 * icoeff, gint bstride)
+{
+  gint i = 0;
+  __m128i sum[2], t;
+  __m128i f = _mm_set_epi64x (0, *((gint64 *) icoeff));
+  const gint16 *c[2] = { (gint16 *) ((gint8 *) b + 0 * bstride),
+    (gint16 *) ((gint8 *) b + 1 * bstride)
+  };
+
+  sum[0] = sum[1] = _mm_setzero_si128 ();
+  f = _mm_unpacklo_epi16 (f, sum[0]);
+
+  for (; i < len; i += 16) {
+    t = _mm_loadu_si128 ((__m128i *) (a + i + 0));
+    sum[0] =
+        _mm_add_epi32 (sum[0], _mm_madd_epi16 (t,
+            _mm_load_si128 ((__m128i *) (c[0] + i + 0))));
+    sum[1] =
+        _mm_add_epi32 (sum[1], _mm_madd_epi16 (t,
+            _mm_load_si128 ((__m128i *) (c[1] + i + 0))));
+
+    t = _mm_loadu_si128 ((__m128i *) (a + i + 8));
+    sum[0] =
+        _mm_add_epi32 (sum[0], _mm_madd_epi16 (t,
+            _mm_load_si128 ((__m128i *) (c[0] + i + 8))));
+    sum[1] =
+        _mm_add_epi32 (sum[1], _mm_madd_epi16 (t,
+            _mm_load_si128 ((__m128i *) (c[1] + i + 8))));
+  }
+  sum[0] = _mm_srai_epi32 (sum[0], PRECISION_S16);
+  sum[1] = _mm_srai_epi32 (sum[1], PRECISION_S16);
+
+  sum[0] =
+      _mm_madd_epi16 (sum[0], _mm_shuffle_epi32 (f, _MM_SHUFFLE (0, 0, 0, 0)));
+  sum[1] =
+      _mm_madd_epi16 (sum[1], _mm_shuffle_epi32 (f, _MM_SHUFFLE (1, 1, 1, 1)));
+  sum[0] = _mm_add_epi32 (sum[0], sum[1]);
+
+  sum[0] =
+      _mm_add_epi32 (sum[0], _mm_shuffle_epi32 (sum[0], _MM_SHUFFLE (2, 3, 2,
+              3)));
+  sum[0] =
+      _mm_add_epi32 (sum[0], _mm_shuffle_epi32 (sum[0], _MM_SHUFFLE (1, 1, 1,
+              1)));
+
+  sum[0] = _mm_add_epi32 (sum[0], _mm_set1_epi32 (1 << (PRECISION_S16 - 1)));
+  sum[0] = _mm_srai_epi32 (sum[0], PRECISION_S16);
+  sum[0] = _mm_packs_epi32 (sum[0], sum[0]);
+  *o = _mm_extract_epi16 (sum[0], 0);
+}
+
+static inline void
+inner_product_gint16_cubic_1_sse2 (gint16 * o, const gint16 * a,
+    const gint16 * b, gint len, const gint16 * icoeff, gint bstride)
+{
+  gint i = 0;
+  __m128i sum[4], t[4];
+  __m128i f = _mm_set_epi64x (0, *((long long *) icoeff));
+  const gint16 *c[4] = { (gint16 *) ((gint8 *) b + 0 * bstride),
+    (gint16 *) ((gint8 *) b + 1 * bstride),
+    (gint16 *) ((gint8 *) b + 2 * bstride),
+    (gint16 *) ((gint8 *) b + 3 * bstride)
+  };
+
+  sum[0] = sum[1] = sum[2] = sum[3] = _mm_setzero_si128 ();
+  f = _mm_unpacklo_epi16 (f, sum[0]);
+
+  for (; i < len; i += 8) {
+    t[0] = _mm_loadu_si128 ((__m128i *) (a + i));
+    sum[0] =
+        _mm_add_epi32 (sum[0], _mm_madd_epi16 (t[0],
+            _mm_load_si128 ((__m128i *) (c[0] + i))));
+    sum[1] =
+        _mm_add_epi32 (sum[1], _mm_madd_epi16 (t[0],
+            _mm_load_si128 ((__m128i *) (c[1] + i))));
+    sum[2] =
+        _mm_add_epi32 (sum[2], _mm_madd_epi16 (t[0],
+            _mm_load_si128 ((__m128i *) (c[2] + i))));
+    sum[3] =
+        _mm_add_epi32 (sum[3], _mm_madd_epi16 (t[0],
+            _mm_load_si128 ((__m128i *) (c[3] + i))));
+  }
+  t[0] = _mm_unpacklo_epi32 (sum[0], sum[1]);
+  t[1] = _mm_unpacklo_epi32 (sum[2], sum[3]);
+  t[2] = _mm_unpackhi_epi32 (sum[0], sum[1]);
+  t[3] = _mm_unpackhi_epi32 (sum[2], sum[3]);
+
+  sum[0] =
+      _mm_add_epi32 (_mm_unpacklo_epi64 (t[0], t[1]), _mm_unpackhi_epi64 (t[0],
+          t[1]));
+  sum[2] =
+      _mm_add_epi32 (_mm_unpacklo_epi64 (t[2], t[3]), _mm_unpackhi_epi64 (t[2],
+          t[3]));
+  sum[0] = _mm_add_epi32 (sum[0], sum[2]);
+
+  sum[0] = _mm_srai_epi32 (sum[0], PRECISION_S16);
+  sum[0] = _mm_madd_epi16 (sum[0], f);
+
+  sum[0] =
+      _mm_add_epi32 (sum[0], _mm_shuffle_epi32 (sum[0], _MM_SHUFFLE (2, 3, 2,
+              3)));
+  sum[0] =
+      _mm_add_epi32 (sum[0], _mm_shuffle_epi32 (sum[0], _MM_SHUFFLE (1, 1, 1,
+              1)));
+
+  sum[0] = _mm_add_epi32 (sum[0], _mm_set1_epi32 (1 << (PRECISION_S16 - 1)));
+  sum[0] = _mm_srai_epi32 (sum[0], PRECISION_S16);
+  sum[0] = _mm_packs_epi32 (sum[0], sum[0]);
+  *o = _mm_extract_epi16 (sum[0], 0);
+}
+
+static inline void
+inner_product_gdouble_full_1_sse2 (gdouble * o, const gdouble * a,
+    const gdouble * b, gint len, const gdouble * icoeff, gint bstride)
+{
+  gint i = 0;
+  __m128d sum = _mm_setzero_pd ();
+
+  for (; i < len; i += 8) {
+    sum =
+        _mm_add_pd (sum, _mm_mul_pd (_mm_loadu_pd (a + i + 0),
+            _mm_load_pd (b + i + 0)));
+    sum =
+        _mm_add_pd (sum, _mm_mul_pd (_mm_loadu_pd (a + i + 2),
+            _mm_load_pd (b + i + 2)));
+    sum =
+        _mm_add_pd (sum, _mm_mul_pd (_mm_loadu_pd (a + i + 4),
+            _mm_load_pd (b + i + 4)));
+    sum =
+        _mm_add_pd (sum, _mm_mul_pd (_mm_loadu_pd (a + i + 6),
+            _mm_load_pd (b + i + 6)));
+  }
+  sum = _mm_add_sd (sum, _mm_unpackhi_pd (sum, sum));
+  _mm_store_sd (o, sum);
+}
+
+static inline void
+inner_product_gdouble_linear_1_sse2 (gdouble * o, const gdouble * a,
+    const gdouble * b, gint len, const gdouble * icoeff, gint bstride)
+{
+  gint i = 0;
+  __m128d sum[2], t;
+  const gdouble *c[2] = { (gdouble *) ((gint8 *) b + 0 * bstride),
+    (gdouble *) ((gint8 *) b + 1 * bstride)
+  };
+
+  sum[0] = sum[1] = _mm_setzero_pd ();
+
+  for (; i < len; i += 4) {
+    t = _mm_loadu_pd (a + i + 0);
+    sum[0] = _mm_add_pd (sum[0], _mm_mul_pd (t, _mm_load_pd (c[0] + i + 0)));
+    sum[1] = _mm_add_pd (sum[1], _mm_mul_pd (t, _mm_load_pd (c[1] + i + 0)));
+    t = _mm_loadu_pd (a + i + 2);
+    sum[0] = _mm_add_pd (sum[0], _mm_mul_pd (t, _mm_load_pd (c[0] + i + 2)));
+    sum[1] = _mm_add_pd (sum[1], _mm_mul_pd (t, _mm_load_pd (c[1] + i + 2)));
+  }
+  sum[0] = _mm_mul_pd (_mm_sub_pd (sum[0], sum[1]), _mm_load1_pd (icoeff));
+  sum[0] = _mm_add_pd (sum[0], sum[1]);
+  sum[0] = _mm_add_sd (sum[0], _mm_unpackhi_pd (sum[0], sum[0]));
+  _mm_store_sd (o, sum[0]);
+}
+
+static inline void
+inner_product_gdouble_cubic_1_sse2 (gdouble * o, const gdouble * a,
+    const gdouble * b, gint len, const gdouble * icoeff, gint bstride)
+{
+  gint i;
+  __m128d f[2], sum[4], t;
+  const gdouble *c[4] = { (gdouble *) ((gint8 *) b + 0 * bstride),
+    (gdouble *) ((gint8 *) b + 1 * bstride),
+    (gdouble *) ((gint8 *) b + 2 * bstride),
+    (gdouble *) ((gint8 *) b + 3 * bstride)
+  };
+
+  f[0] = _mm_loadu_pd (icoeff + 0);
+  f[1] = _mm_loadu_pd (icoeff + 2);
+  sum[0] = sum[1] = sum[2] = sum[3] = _mm_setzero_pd ();
+
+  for (i = 0; i < len; i += 2) {
+    t = _mm_loadu_pd (a + i + 0);
+    sum[0] = _mm_add_pd (sum[0], _mm_mul_pd (t, _mm_load_pd (c[0] + i)));
+    sum[1] = _mm_add_pd (sum[1], _mm_mul_pd (t, _mm_load_pd (c[1] + i)));
+    sum[2] = _mm_add_pd (sum[2], _mm_mul_pd (t, _mm_load_pd (c[2] + i)));
+    sum[3] = _mm_add_pd (sum[3], _mm_mul_pd (t, _mm_load_pd (c[3] + i)));
+  }
+  sum[0] =
+      _mm_mul_pd (sum[0], _mm_shuffle_pd (f[0], f[0], _MM_SHUFFLE2 (0, 0)));
+  sum[1] =
+      _mm_mul_pd (sum[1], _mm_shuffle_pd (f[0], f[0], _MM_SHUFFLE2 (1, 1)));
+  sum[2] =
+      _mm_mul_pd (sum[2], _mm_shuffle_pd (f[1], f[1], _MM_SHUFFLE2 (0, 0)));
+  sum[3] =
+      _mm_mul_pd (sum[3], _mm_shuffle_pd (f[1], f[1], _MM_SHUFFLE2 (1, 1)));
+  sum[0] = _mm_add_pd (sum[0], sum[1]);
+  sum[2] = _mm_add_pd (sum[2], sum[3]);
+  sum[0] = _mm_add_pd (sum[0], sum[2]);
+  sum[0] = _mm_add_sd (sum[0], _mm_unpackhi_pd (sum[0], sum[0]));
+  _mm_store_sd (o, sum[0]);
+}
+
+MAKE_RESAMPLE_FUNC (gint16, full, 1, sse2);
+MAKE_RESAMPLE_FUNC (gint16, linear, 1, sse2);
+MAKE_RESAMPLE_FUNC (gint16, cubic, 1, sse2);
+
+MAKE_RESAMPLE_FUNC (gdouble, full, 1, sse2);
+MAKE_RESAMPLE_FUNC (gdouble, linear, 1, sse2);
+MAKE_RESAMPLE_FUNC (gdouble, cubic, 1, sse2);
+
+void
+interpolate_gint16_linear_sse2 (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride)
+{
+  gint i = 0;
+  gint16 *o = op, *a = ap, *ic = icp;
+  __m128i ta, tb, t1, t2;
+  __m128i f = _mm_set_epi64x (0, *((gint64 *) ic));
+  const gint16 *c[2] = { (gint16 *) ((gint8 *) a + 0 * astride),
+    (gint16 *) ((gint8 *) a + 1 * astride)
+  };
+
+  f = _mm_unpacklo_epi32 (f, f);
+  f = _mm_unpacklo_epi64 (f, f);
+
+  for (; i < len; i += 8) {
+    ta = _mm_load_si128 ((__m128i *) (c[0] + i));
+    tb = _mm_load_si128 ((__m128i *) (c[1] + i));
+
+    t1 = _mm_madd_epi16 (_mm_unpacklo_epi16 (ta, tb), f);
+    t2 = _mm_madd_epi16 (_mm_unpackhi_epi16 (ta, tb), f);
+
+    t1 = _mm_add_epi32 (t1, _mm_set1_epi32 (1 << (PRECISION_S16 - 1)));
+    t2 = _mm_add_epi32 (t2, _mm_set1_epi32 (1 << (PRECISION_S16 - 1)));
+
+    t1 = _mm_srai_epi32 (t1, PRECISION_S16);
+    t2 = _mm_srai_epi32 (t2, PRECISION_S16);
+
+    t1 = _mm_packs_epi32 (t1, t2);
+    _mm_store_si128 ((__m128i *) (o + i), t1);
+  }
+}
+
+void
+interpolate_gint16_cubic_sse2 (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride)
+{
+  gint i = 0;
+  gint16 *o = op, *a = ap, *ic = icp;
+  __m128i ta, tb, tl1, tl2, th1, th2;
+  __m128i f[2];
+  const gint16 *c[4] = { (gint16 *) ((gint8 *) a + 0 * astride),
+    (gint16 *) ((gint8 *) a + 1 * astride),
+    (gint16 *) ((gint8 *) a + 2 * astride),
+    (gint16 *) ((gint8 *) a + 3 * astride)
+  };
+
+  f[0] = _mm_set_epi16 (ic[1], ic[0], ic[1], ic[0], ic[1], ic[0], ic[1], ic[0]);
+  f[1] = _mm_set_epi16 (ic[3], ic[2], ic[3], ic[2], ic[3], ic[2], ic[3], ic[2]);
+
+  for (; i < len; i += 8) {
+    ta = _mm_load_si128 ((__m128i *) (c[0] + i));
+    tb = _mm_load_si128 ((__m128i *) (c[1] + i));
+
+    tl1 = _mm_madd_epi16 (_mm_unpacklo_epi16 (ta, tb), f[0]);
+    th1 = _mm_madd_epi16 (_mm_unpackhi_epi16 (ta, tb), f[0]);
+
+    ta = _mm_load_si128 ((__m128i *) (c[2] + i));
+    tb = _mm_load_si128 ((__m128i *) (c[3] + i));
+
+    tl2 = _mm_madd_epi16 (_mm_unpacklo_epi16 (ta, tb), f[1]);
+    th2 = _mm_madd_epi16 (_mm_unpackhi_epi16 (ta, tb), f[1]);
+
+    tl1 = _mm_add_epi32 (tl1, tl2);
+    th1 = _mm_add_epi32 (th1, th2);
+
+    tl1 = _mm_add_epi32 (tl1, _mm_set1_epi32 (1 << (PRECISION_S16 - 1)));
+    th1 = _mm_add_epi32 (th1, _mm_set1_epi32 (1 << (PRECISION_S16 - 1)));
+
+    tl1 = _mm_srai_epi32 (tl1, PRECISION_S16);
+    th1 = _mm_srai_epi32 (th1, PRECISION_S16);
+
+    tl1 = _mm_packs_epi32 (tl1, th1);
+    _mm_store_si128 ((__m128i *) (o + i), tl1);
+  }
+}
+
+void
+interpolate_gdouble_linear_sse2 (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride)
+{
+  gint i;
+  gdouble *o = op, *a = ap, *ic = icp;
+  __m128d f[2], t1, t2;
+  const gdouble *c[2] = { (gdouble *) ((gint8 *) a + 0 * astride),
+    (gdouble *) ((gint8 *) a + 1 * astride)
+  };
+
+  f[0] = _mm_load1_pd (ic + 0);
+  f[1] = _mm_load1_pd (ic + 1);
+
+  for (i = 0; i < len; i += 4) {
+    t1 = _mm_mul_pd (_mm_load_pd (c[0] + i + 0), f[0]);
+    t2 = _mm_mul_pd (_mm_load_pd (c[1] + i + 0), f[1]);
+    _mm_store_pd (o + i + 0, _mm_add_pd (t1, t2));
+
+    t1 = _mm_mul_pd (_mm_load_pd (c[0] + i + 2), f[0]);
+    t2 = _mm_mul_pd (_mm_load_pd (c[1] + i + 2), f[1]);
+    _mm_store_pd (o + i + 2, _mm_add_pd (t1, t2));
+  }
+}
+
+void
+interpolate_gdouble_cubic_sse2 (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride)
+{
+  gint i;
+  gdouble *o = op, *a = ap, *ic = icp;
+  __m128d f[4], t[4];
+  const gdouble *c[4] = { (gdouble *) ((gint8 *) a + 0 * astride),
+    (gdouble *) ((gint8 *) a + 1 * astride),
+    (gdouble *) ((gint8 *) a + 2 * astride),
+    (gdouble *) ((gint8 *) a + 3 * astride)
+  };
+
+  f[0] = _mm_load1_pd (ic + 0);
+  f[1] = _mm_load1_pd (ic + 1);
+  f[2] = _mm_load1_pd (ic + 2);
+  f[3] = _mm_load1_pd (ic + 3);
+
+  for (i = 0; i < len; i += 2) {
+    t[0] = _mm_mul_pd (_mm_load_pd (c[0] + i + 0), f[0]);
+    t[1] = _mm_mul_pd (_mm_load_pd (c[1] + i + 0), f[1]);
+    t[2] = _mm_mul_pd (_mm_load_pd (c[2] + i + 0), f[2]);
+    t[3] = _mm_mul_pd (_mm_load_pd (c[3] + i + 0), f[3]);
+    t[0] = _mm_add_pd (t[0], t[1]);
+    t[2] = _mm_add_pd (t[2], t[3]);
+    _mm_store_pd (o + i + 0, _mm_add_pd (t[0], t[2]));
+  }
+}
+
+#endif
diff --git a/gst-libs/gst/audio/audio-resampler-x86-sse2.h b/gst-libs/gst/audio/audio-resampler-x86-sse2.h
new file mode 100644
index 0000000..3bbf5cd
--- /dev/null
+++ b/gst-libs/gst/audio/audio-resampler-x86-sse2.h
@@ -0,0 +1,49 @@
+/* GStreamer
+ * Copyright (C) <2016> Wim Taymans <wim.taymans@gmail.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.
+ */
+
+#ifndef AUDIO_RESAMPLER_X86_SSE2_H
+#define AUDIO_RESAMPLER_X86_SSE2_H
+
+#include "audio-resampler-macros.h"
+
+DECL_RESAMPLE_FUNC (gint16, full, 1, sse2);
+DECL_RESAMPLE_FUNC (gint16, linear, 1, sse2);
+DECL_RESAMPLE_FUNC (gint16, cubic, 1, sse2);
+
+DECL_RESAMPLE_FUNC (gdouble, full, 1, sse2);
+DECL_RESAMPLE_FUNC (gdouble, linear, 1, sse2);
+DECL_RESAMPLE_FUNC (gdouble, cubic, 1, sse2);
+
+void
+interpolate_gint16_linear_sse2 (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride);
+
+void
+interpolate_gint16_cubic_sse2 (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride);
+
+void
+interpolate_gdouble_linear_sse2 (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride);
+
+void
+interpolate_gdouble_cubic_sse2 (gpointer op, const gpointer ap,
+    gint len, const gpointer icp, gint astride);
+
+#endif /* AUDIO_RESAMPLER_X86_SSE2_H */
diff --git a/gst-libs/gst/audio/audio-resampler-x86-sse41.c b/gst-libs/gst/audio/audio-resampler-x86-sse41.c
new file mode 100644
index 0000000..ce1cc24
--- /dev/null
+++ b/gst-libs/gst/audio/audio-resampler-x86-sse41.c
@@ -0,0 +1,188 @@
+/* GStreamer
+ * Copyright (C) <2016> Wim Taymans <wim.taymans@gmail.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 "audio-resampler-x86-sse41.h"
+
+#if 0
+#define __SSE4_1__
+#pragma GCC target("sse4.1")
+#endif
+
+#if defined (__x86_64__) && \
+    defined (HAVE_SMMINTRIN_H) && defined (HAVE_EMMINTRIN_H) && \
+    defined (__SSE4_1__)
+
+#include <emmintrin.h>
+#include <smmintrin.h>
+
+static inline void
+inner_product_gint32_full_1_sse41 (gint32 * o, const gint32 * a,
+    const gint32 * b, gint len, const gint32 * icoeff, gint bstride)
+{
+  gint i = 0;
+  __m128i sum, ta, tb;
+  gint64 res;
+
+  sum = _mm_setzero_si128 ();
+
+  for (; i < len; i += 8) {
+    ta = _mm_loadu_si128 ((__m128i *) (a + i));
+    tb = _mm_load_si128 ((__m128i *) (b + i));
+
+    sum =
+        _mm_add_epi64 (sum, _mm_mul_epi32 (_mm_unpacklo_epi32 (ta, ta),
+            _mm_unpacklo_epi32 (tb, tb)));
+    sum =
+        _mm_add_epi64 (sum, _mm_mul_epi32 (_mm_unpackhi_epi32 (ta, ta),
+            _mm_unpackhi_epi32 (tb, tb)));
+
+    ta = _mm_loadu_si128 ((__m128i *) (a + i + 4));
+    tb = _mm_load_si128 ((__m128i *) (b + i + 4));
+
+    sum =
+        _mm_add_epi64 (sum, _mm_mul_epi32 (_mm_unpacklo_epi32 (ta, ta),
+            _mm_unpacklo_epi32 (tb, tb)));
+    sum =
+        _mm_add_epi64 (sum, _mm_mul_epi32 (_mm_unpackhi_epi32 (ta, ta),
+            _mm_unpackhi_epi32 (tb, tb)));
+  }
+  sum = _mm_add_epi64 (sum, _mm_unpackhi_epi64 (sum, sum));
+  res = _mm_cvtsi128_si64 (sum);
+
+  res = (res + (1 << (PRECISION_S32 - 1))) >> PRECISION_S32;
+  *o = CLAMP (res, -(1L << 31), (1L << 31) - 1);
+}
+
+static inline void
+inner_product_gint32_linear_1_sse41 (gint32 * o, const gint32 * a,
+    const gint32 * b, gint len, const gint32 * icoeff, gint bstride)
+{
+  gint i = 0;
+  gint64 res;
+  __m128i sum[2], ta, tb;
+  __m128i f = _mm_loadu_si128 ((__m128i *) icoeff);
+  const gint32 *c[2] = { (gint32 *) ((gint8 *) b + 0 * bstride),
+    (gint32 *) ((gint8 *) b + 1 * bstride)
+  };
+
+  sum[0] = sum[1] = _mm_setzero_si128 ();
+
+  for (; i < len; i += 4) {
+    ta = _mm_loadu_si128 ((__m128i *) (a + i));
+
+    tb = _mm_load_si128 ((__m128i *) (c[0] + i));
+    sum[0] = _mm_add_epi64 (sum[0], _mm_mul_epi32 (_mm_unpacklo_epi32 (ta, ta),
+            _mm_unpacklo_epi32 (tb, tb)));
+    sum[0] = _mm_add_epi64 (sum[0], _mm_mul_epi32 (_mm_unpackhi_epi32 (ta, ta),
+            _mm_unpackhi_epi32 (tb, tb)));
+
+    tb = _mm_load_si128 ((__m128i *) (c[1] + i));
+    sum[1] = _mm_add_epi64 (sum[1], _mm_mul_epi32 (_mm_unpacklo_epi32 (ta, ta),
+            _mm_unpacklo_epi32 (tb, tb)));
+    sum[1] = _mm_add_epi64 (sum[1], _mm_mul_epi32 (_mm_unpackhi_epi32 (ta, ta),
+            _mm_unpackhi_epi32 (tb, tb)));
+  }
+  sum[0] = _mm_srli_epi64 (sum[0], PRECISION_S32);
+  sum[1] = _mm_srli_epi64 (sum[1], PRECISION_S32);
+  sum[0] =
+      _mm_mul_epi32 (sum[0], _mm_shuffle_epi32 (f, _MM_SHUFFLE (0, 0, 0, 0)));
+  sum[1] =
+      _mm_mul_epi32 (sum[1], _mm_shuffle_epi32 (f, _MM_SHUFFLE (1, 1, 1, 1)));
+  sum[0] = _mm_add_epi64 (sum[0], sum[1]);
+  sum[0] = _mm_add_epi64 (sum[0], _mm_unpackhi_epi64 (sum[0], sum[0]));
+  res = _mm_cvtsi128_si64 (sum[0]);
+
+  res = (res + (1 << (PRECISION_S32 - 1))) >> PRECISION_S32;
+  *o = CLAMP (res, -(1L << 31), (1L << 31) - 1);
+}
+
+static inline void
+inner_product_gint32_cubic_1_sse41 (gint32 * o, const gint32 * a,
+    const gint32 * b, gint len, const gint32 * icoeff, gint bstride)
+{
+  gint i = 0;
+  gint64 res;
+  __m128i sum[4], ta, tb;
+  __m128i f = _mm_loadu_si128 ((__m128i *) icoeff);
+  const gint32 *c[4] = { (gint32 *) ((gint8 *) b + 0 * bstride),
+    (gint32 *) ((gint8 *) b + 1 * bstride),
+    (gint32 *) ((gint8 *) b + 2 * bstride),
+    (gint32 *) ((gint8 *) b + 3 * bstride)
+  };
+
+  sum[0] = sum[1] = sum[2] = sum[3] = _mm_setzero_si128 ();
+
+  for (; i < len; i += 4) {
+    ta = _mm_loadu_si128 ((__m128i *) (a + i));
+
+    tb = _mm_load_si128 ((__m128i *) (c[0] + i));
+    sum[0] = _mm_add_epi64 (sum[0], _mm_mul_epi32 (_mm_unpacklo_epi32 (ta, ta),
+            _mm_unpacklo_epi32 (tb, tb)));
+    sum[0] = _mm_add_epi64 (sum[0], _mm_mul_epi32 (_mm_unpackhi_epi32 (ta, ta),
+            _mm_unpackhi_epi32 (tb, tb)));
+
+    tb = _mm_load_si128 ((__m128i *) (c[1] + i));
+    sum[1] = _mm_add_epi64 (sum[1], _mm_mul_epi32 (_mm_unpacklo_epi32 (ta, ta),
+            _mm_unpacklo_epi32 (tb, tb)));
+    sum[1] = _mm_add_epi64 (sum[1], _mm_mul_epi32 (_mm_unpackhi_epi32 (ta, ta),
+            _mm_unpackhi_epi32 (tb, tb)));
+
+    tb = _mm_load_si128 ((__m128i *) (c[2] + i));
+    sum[2] = _mm_add_epi64 (sum[2], _mm_mul_epi32 (_mm_unpacklo_epi32 (ta, ta),
+            _mm_unpacklo_epi32 (tb, tb)));
+    sum[2] = _mm_add_epi64 (sum[2], _mm_mul_epi32 (_mm_unpackhi_epi32 (ta, ta),
+            _mm_unpackhi_epi32 (tb, tb)));
+
+    tb = _mm_load_si128 ((__m128i *) (c[3] + i));
+    sum[3] = _mm_add_epi64 (sum[3], _mm_mul_epi32 (_mm_unpacklo_epi32 (ta, ta),
+            _mm_unpacklo_epi32 (tb, tb)));
+    sum[3] = _mm_add_epi64 (sum[3], _mm_mul_epi32 (_mm_unpackhi_epi32 (ta, ta),
+            _mm_unpackhi_epi32 (tb, tb)));
+  }
+  sum[0] = _mm_srli_epi64 (sum[0], PRECISION_S32);
+  sum[1] = _mm_srli_epi64 (sum[1], PRECISION_S32);
+  sum[2] = _mm_srli_epi64 (sum[2], PRECISION_S32);
+  sum[3] = _mm_srli_epi64 (sum[3], PRECISION_S32);
+  sum[0] =
+      _mm_mul_epi32 (sum[0], _mm_shuffle_epi32 (f, _MM_SHUFFLE (0, 0, 0, 0)));
+  sum[1] =
+      _mm_mul_epi32 (sum[1], _mm_shuffle_epi32 (f, _MM_SHUFFLE (1, 1, 1, 1)));
+  sum[2] =
+      _mm_mul_epi32 (sum[2], _mm_shuffle_epi32 (f, _MM_SHUFFLE (2, 2, 2, 2)));
+  sum[3] =
+      _mm_mul_epi32 (sum[3], _mm_shuffle_epi32 (f, _MM_SHUFFLE (3, 3, 3, 3)));
+  sum[0] = _mm_add_epi64 (sum[0], sum[1]);
+  sum[2] = _mm_add_epi64 (sum[2], sum[3]);
+  sum[0] = _mm_add_epi64 (sum[0], sum[2]);
+  sum[0] = _mm_add_epi64 (sum[0], _mm_unpackhi_epi64 (sum[0], sum[0]));
+  res = _mm_cvtsi128_si64 (sum[0]);
+
+  res = (res + (1 << (PRECISION_S32 - 1))) >> PRECISION_S32;
+  *o = CLAMP (res, -(1L << 31), (1L << 31) - 1);
+}
+
+MAKE_RESAMPLE_FUNC (gint32, full, 1, sse41);
+MAKE_RESAMPLE_FUNC (gint32, linear, 1, sse41);
+MAKE_RESAMPLE_FUNC (gint32, cubic, 1, sse41);
+
+#endif
diff --git a/gst/audioresample/speex_resampler_float.c b/gst-libs/gst/audio/audio-resampler-x86-sse41.h
similarity index 67%
rename from gst/audioresample/speex_resampler_float.c
rename to gst-libs/gst/audio/audio-resampler-x86-sse41.h
index 4f11197..d8706b0 100644
--- a/gst/audioresample/speex_resampler_float.c
+++ b/gst-libs/gst/audio/audio-resampler-x86-sse41.h
@@ -1,5 +1,5 @@
 /* GStreamer
- * Copyright (C) 2007-2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * Copyright (C) <2016> Wim Taymans <wim.taymans@gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -17,11 +17,13 @@
  * Boston, MA 02110-1301, USA.
  */
 
-#define _USE_SSE
-#define _USE_SSE2
-#define _USE_NEON
-#define FLOATING_POINT
-#define OUTSIDE_SPEEX
-#define RANDOM_PREFIX resample_float
+#ifndef AUDIO_RESAMPLER_X86_SSE41_H
+#define AUDIO_RESAMPLER_X86_SSE41_H
 
-#include "resample.c"
+#include "audio-resampler-macros.h"
+
+DECL_RESAMPLE_FUNC (gint32, full, 1, sse41);
+DECL_RESAMPLE_FUNC (gint32, linear, 1, sse41);
+DECL_RESAMPLE_FUNC (gint32, cubic, 1, sse41);
+
+#endif /* AUDIO_RESAMPLER_X86_SSE41_H */
diff --git a/gst-libs/gst/audio/audio-resampler-x86.h b/gst-libs/gst/audio/audio-resampler-x86.h
new file mode 100644
index 0000000..47bc430
--- /dev/null
+++ b/gst-libs/gst/audio/audio-resampler-x86.h
@@ -0,0 +1,71 @@
+/* GStreamer
+ * Copyright (C) <2016> Wim Taymans <wim.taymans@gmail.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.
+ */
+
+#include "audio-resampler-macros.h"
+#include "audio-resampler-x86-sse.h"
+#include "audio-resampler-x86-sse2.h"
+#include "audio-resampler-x86-sse41.h"
+
+static void
+audio_resampler_check_x86 (const gchar *option)
+{
+  if (!strcmp (option, "sse")) {
+#if defined (HAVE_XMMINTRIN_H) && HAVE_SSE
+    GST_DEBUG ("enable SSE optimisations");
+    resample_gfloat_full_1 = resample_gfloat_full_1_sse;
+    resample_gfloat_linear_1 = resample_gfloat_linear_1_sse;
+    resample_gfloat_cubic_1 = resample_gfloat_cubic_1_sse;
+
+    interpolate_gfloat_linear = interpolate_gfloat_linear_sse;
+    interpolate_gfloat_cubic = interpolate_gfloat_cubic_sse;
+#else
+    GST_DEBUG ("SSE optimisations not enabled");
+#endif
+  } else if (!strcmp (option, "sse2")) {
+#if defined (HAVE_EMMINTRIN_H) && HAVE_SSE2
+    GST_DEBUG ("enable SSE2 optimisations");
+    resample_gint16_full_1 = resample_gint16_full_1_sse2;
+    resample_gint16_linear_1 = resample_gint16_linear_1_sse2;
+    resample_gint16_cubic_1 = resample_gint16_cubic_1_sse2;
+
+    interpolate_gint16_linear = interpolate_gint16_linear_sse2;
+    interpolate_gint16_cubic = interpolate_gint16_cubic_sse2;
+
+    resample_gdouble_full_1 = resample_gdouble_full_1_sse2;
+    resample_gdouble_linear_1 = resample_gdouble_linear_1_sse2;
+    resample_gdouble_cubic_1 = resample_gdouble_cubic_1_sse2;
+
+    interpolate_gdouble_linear = interpolate_gdouble_linear_sse2;
+    interpolate_gdouble_cubic = interpolate_gdouble_cubic_sse2;
+#else
+    GST_DEBUG ("SSE2 optimisations not enabled");
+#endif
+  } else if (!strcmp (option, "sse41")) {
+#if defined (__x86_64__) && \
+    defined (HAVE_SMMINTRIN_H) && defined (HAVE_EMMINTRIN_H) && \
+    HAVE_SSE41
+    GST_DEBUG ("enable SSE41 optimisations");
+    resample_gint32_full_1 = resample_gint32_full_1_sse41;
+    resample_gint32_linear_1 = resample_gint32_linear_1_sse41;
+    resample_gint32_cubic_1 = resample_gint32_cubic_1_sse41;
+#else
+    GST_DEBUG ("SSE41 optimisations not enabled");
+#endif
+  }
+}
diff --git a/gst-libs/gst/audio/audio-resampler.c b/gst-libs/gst/audio/audio-resampler.c
new file mode 100644
index 0000000..8cb562c
--- /dev/null
+++ b/gst-libs/gst/audio/audio-resampler.c
@@ -0,0 +1,1781 @@
+/* GStreamer
+ * Copyright (C) <2015> Wim Taymans <wim.taymans@gmail.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 <string.h>
+#include <stdio.h>
+#include <math.h>
+
+#ifdef HAVE_ORC
+#include <orc/orc.h>
+#endif
+
+#include "audio-resampler.h"
+#include "audio-resampler-private.h"
+#include "audio-resampler-macros.h"
+
+#define MEM_ALIGN(m,a) ((gint8 *)((guintptr)((gint8 *)(m) + ((a)-1)) & ~((a)-1)))
+#define ALIGN 16
+#define TAPS_OVERREAD 16
+
+GST_DEBUG_CATEGORY_STATIC (audio_resampler_debug);
+#define GST_CAT_DEFAULT audio_resampler_debug
+
+/**
+ * SECTION:gstaudioresampler
+ * @short_description: Utility structure for resampler information
+ *
+ * #GstAudioResampler is a structure which holds the information
+ * required to perform various kinds of resampling filtering.
+ *
+ */
+
+static const gint oversample_qualities[] = {
+  4, 4, 4, 8, 8, 16, 16, 16, 16, 32, 32
+};
+
+typedef struct
+{
+  gdouble cutoff;
+  gdouble downsample_cutoff_factor;
+  gdouble stopband_attenuation;
+  gdouble transition_bandwidth;
+} KaiserQualityMap;
+
+static const KaiserQualityMap kaiser_qualities[] = {
+  {0.860, 0.96511, 60, 0.7},    /* 8 taps */
+  {0.880, 0.96591, 65, 0.29},   /* 16 taps */
+  {0.910, 0.96923, 70, 0.145},  /* 32 taps */
+  {0.920, 0.97600, 80, 0.105},  /* 48 taps */
+  {0.940, 0.97979, 85, 0.087},  /* 64 taps default quality */
+  {0.940, 0.98085, 95, 0.077},  /* 80 taps */
+  {0.945, 0.99471, 100, 0.068}, /* 96 taps */
+  {0.950, 1.0, 105, 0.055},     /* 128 taps */
+  {0.960, 1.0, 110, 0.045},     /* 160 taps */
+  {0.968, 1.0, 115, 0.039},     /* 192 taps */
+  {0.975, 1.0, 120, 0.0305}     /* 256 taps */
+};
+
+typedef struct
+{
+  gint n_taps;
+  gdouble cutoff;
+} BlackmanQualityMap;
+
+static const BlackmanQualityMap blackman_qualities[] = {
+  {8, 0.5,},
+  {16, 0.6,},
+  {24, 0.72,},
+  {32, 0.8,},
+  {48, 0.85,},                  /* default */
+  {64, 0.90,},
+  {80, 0.92,},
+  {96, 0.933,},
+  {128, 0.950,},
+  {148, 0.955,},
+  {160, 0.960,}
+};
+
+#define DEFAULT_RESAMPLER_METHOD GST_AUDIO_RESAMPLER_METHOD_KAISER
+#define DEFAULT_QUALITY GST_AUDIO_RESAMPLER_QUALITY_DEFAULT
+#define DEFAULT_OPT_CUBIC_B 1.0
+#define DEFAULT_OPT_CUBIC_C 0.0
+#define DEFAULT_OPT_FILTER_MODE GST_AUDIO_RESAMPLER_FILTER_MODE_AUTO
+#define DEFAULT_OPT_FILTER_MODE_THRESHOLD 1048576
+#define DEFAULT_OPT_FILTER_INTERPOLATION GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_CUBIC
+#define DEFAULT_OPT_FILTER_OVERSAMPLE 8
+#define DEFAULT_OPT_MAX_PHASE_ERROR 0.1
+
+static gdouble
+get_opt_double (GstStructure * options, const gchar * name, gdouble def)
+{
+  gdouble res;
+  if (!options || !gst_structure_get_double (options, name, &res))
+    res = def;
+  return res;
+}
+
+static gint
+get_opt_int (GstStructure * options, const gchar * name, gint def)
+{
+  gint res;
+  if (!options || !gst_structure_get_int (options, name, &res))
+    res = def;
+  return res;
+}
+
+static gint
+get_opt_enum (GstStructure * options, const gchar * name, GType type, gint def)
+{
+  gint res;
+  if (!options || !gst_structure_get_enum (options, name, type, &res))
+    res = def;
+  return res;
+}
+
+
+#define GET_OPT_CUTOFF(options,def) get_opt_double(options, \
+    GST_AUDIO_RESAMPLER_OPT_CUTOFF,def)
+#define GET_OPT_DOWN_CUTOFF_FACTOR(options,def) get_opt_double(options, \
+    GST_AUDIO_RESAMPLER_OPT_DOWN_CUTOFF_FACTOR, def)
+#define GET_OPT_STOP_ATTENUATION(options,def) get_opt_double(options, \
+    GST_AUDIO_RESAMPLER_OPT_STOP_ATTENUATION, def)
+#define GET_OPT_TRANSITION_BANDWIDTH(options,def) get_opt_double(options, \
+    GST_AUDIO_RESAMPLER_OPT_TRANSITION_BANDWIDTH, def)
+#define GET_OPT_CUBIC_B(options) get_opt_double(options, \
+    GST_AUDIO_RESAMPLER_OPT_CUBIC_B, DEFAULT_OPT_CUBIC_B)
+#define GET_OPT_CUBIC_C(options) get_opt_double(options, \
+    GST_AUDIO_RESAMPLER_OPT_CUBIC_C, DEFAULT_OPT_CUBIC_C)
+#define GET_OPT_N_TAPS(options,def) get_opt_int(options, \
+    GST_AUDIO_RESAMPLER_OPT_N_TAPS, def)
+#define GET_OPT_FILTER_MODE(options) get_opt_enum(options, \
+    GST_AUDIO_RESAMPLER_OPT_FILTER_MODE, GST_TYPE_AUDIO_RESAMPLER_FILTER_MODE, \
+    DEFAULT_OPT_FILTER_MODE)
+#define GET_OPT_FILTER_MODE_THRESHOLD(options) get_opt_int(options, \
+    GST_AUDIO_RESAMPLER_OPT_FILTER_MODE_THRESHOLD, DEFAULT_OPT_FILTER_MODE_THRESHOLD)
+#define GET_OPT_FILTER_INTERPOLATION(options) get_opt_enum(options, \
+    GST_AUDIO_RESAMPLER_OPT_FILTER_INTERPOLATION, GST_TYPE_AUDIO_RESAMPLER_FILTER_INTERPOLATION, \
+    DEFAULT_OPT_FILTER_INTERPOLATION)
+#define GET_OPT_FILTER_OVERSAMPLE(options) get_opt_int(options, \
+    GST_AUDIO_RESAMPLER_OPT_FILTER_OVERSAMPLE, DEFAULT_OPT_FILTER_OVERSAMPLE)
+#define GET_OPT_MAX_PHASE_ERROR(options) get_opt_double(options, \
+    GST_AUDIO_RESAMPLER_OPT_MAX_PHASE_ERROR, DEFAULT_OPT_MAX_PHASE_ERROR)
+
+#include "dbesi0.c"
+#define bessel dbesi0
+
+static inline gdouble
+get_linear_tap (gdouble x, gint n_taps)
+{
+  gdouble res = GST_ROUND_UP_2 (n_taps) / 2 - fabs (x);
+  return res;
+}
+
+static inline gdouble
+get_cubic_tap (gdouble x, gint n_taps, gdouble b, gdouble c)
+{
+  gdouble res, a, a2, a3;
+
+  a = fabs (x * 4.0) / n_taps;
+  a2 = a * a;
+  a3 = a2 * a;
+
+  if (a <= 1.0)
+    res = ((12.0 - 9.0 * b - 6.0 * c) * a3 +
+        (-18.0 + 12.0 * b + 6.0 * c) * a2 + (6.0 - 2.0 * b)) / 6.0;
+  else if (a <= 2.0)
+    res = ((-b - 6.0 * c) * a3 +
+        (6.0 * b + 30.0 * c) * a2 +
+        (-12.0 * b - 48.0 * c) * a + (8.0 * b + 24.0 * c)) / 6.0;
+  else
+    res = 0.0;
+
+  return res;
+}
+
+static inline gdouble
+get_blackman_nuttall_tap (gdouble x, gint n_taps, gdouble Fc)
+{
+  gdouble s, y, w;
+
+  y = G_PI * x;
+  s = (y == 0.0 ? Fc : sin (y * Fc) / y);
+
+  w = 2.0 * y / n_taps + G_PI;
+  return s * (0.3635819 - 0.4891775 * cos (w) + 0.1365995 * cos (2 * w) -
+      0.0106411 * cos (3 * w));
+}
+
+static inline gdouble
+get_kaiser_tap (gdouble x, gint n_taps, gdouble Fc, gdouble beta)
+{
+  gdouble s, y, w;
+
+  y = G_PI * x;
+  s = (y == 0.0 ? Fc : sin (y * Fc) / y);
+
+  w = 2.0 * x / n_taps;
+  return s * bessel (beta * sqrt (MAX (1 - w * w, 0)));
+}
+
+#define MAKE_CONVERT_TAPS_INT_FUNC(type, precision)                     \
+static void                                                             \
+convert_taps_##type##_c (gdouble *tmp_taps, gpointer taps,              \
+    gdouble weight, gint n_taps)                                        \
+{                                                                       \
+  gint64 one = (1LL << precision) - 1;                                  \
+  type *t = taps;                                                       \
+  gdouble multiplier = one;                                             \
+  gint i, j;                                                            \
+  gdouble offset, l_offset, h_offset;                                   \
+  gboolean exact = FALSE;                                               \
+  /* Round to integer, but with an adjustable bias that we use to */    \
+  /* eliminate the DC error. */                                         \
+  l_offset = 0.0;                                                       \
+  h_offset = 1.0;                                                       \
+  offset = 0.5;                                                         \
+  for (i = 0; i < 32; i++) {                                            \
+    gint64 sum = 0;                                                     \
+    for (j = 0; j < n_taps; j++)                                        \
+      sum += floor (offset + tmp_taps[j] * multiplier / weight);        \
+    if (sum == one) {                                                   \
+      exact = TRUE;                                                     \
+      break;                                                            \
+    }                                                                   \
+    if (l_offset == h_offset)                                           \
+      break;                                                            \
+    if (sum < one) {                                                    \
+      if (offset > l_offset)                                            \
+        l_offset = offset;                                              \
+      offset += (h_offset - l_offset) / 2;                              \
+    } else {                                                            \
+      if (offset < h_offset)                                            \
+        h_offset = offset;                                              \
+      offset -= (h_offset - l_offset) / 2;                              \
+    }                                                                   \
+  }                                                                     \
+  for (j = 0; j < n_taps; j++)                                          \
+    t[j] = floor (offset + tmp_taps[j] * multiplier / weight);          \
+  if (!exact)                                                           \
+    GST_WARNING ("can't find exact taps");                              \
+}
+
+#define MAKE_CONVERT_TAPS_FLOAT_FUNC(type)                              \
+static void                                                             \
+convert_taps_##type##_c (gdouble *tmp_taps, gpointer taps,              \
+    gdouble weight, gint n_taps)                                        \
+{                                                                       \
+  gint i;                                                               \
+  type *t = taps;                                                       \
+  for (i = 0; i < n_taps; i++)                                          \
+    t[i] = tmp_taps[i] / weight;                                        \
+}
+
+MAKE_CONVERT_TAPS_INT_FUNC (gint16, PRECISION_S16);
+MAKE_CONVERT_TAPS_INT_FUNC (gint32, PRECISION_S32);
+MAKE_CONVERT_TAPS_FLOAT_FUNC (gfloat);
+MAKE_CONVERT_TAPS_FLOAT_FUNC (gdouble);
+
+static ConvertTapsFunc convert_taps_funcs[] = {
+  convert_taps_gint16_c,
+  convert_taps_gint32_c,
+  convert_taps_gfloat_c,
+  convert_taps_gdouble_c
+};
+
+#define convert_taps_gint16   convert_taps_funcs[0]
+#define convert_taps_gint32   convert_taps_funcs[1]
+#define convert_taps_gfloat   convert_taps_funcs[2]
+#define convert_taps_gdouble  convert_taps_funcs[3]
+
+static void
+make_taps (GstAudioResampler * resampler, gdouble * res, gdouble x, gint n_taps)
+{
+  gdouble weight = 0.0, *tmp_taps = resampler->tmp_taps;
+  gint i;
+
+  switch (resampler->method) {
+    case GST_AUDIO_RESAMPLER_METHOD_NEAREST:
+      break;
+
+    case GST_AUDIO_RESAMPLER_METHOD_LINEAR:
+      for (i = 0; i < n_taps; i++)
+        weight += tmp_taps[i] = get_linear_tap (x + i, resampler->n_taps);
+      break;
+
+    case GST_AUDIO_RESAMPLER_METHOD_CUBIC:
+      for (i = 0; i < n_taps; i++)
+        weight += tmp_taps[i] = get_cubic_tap (x + i, resampler->n_taps,
+            resampler->b, resampler->c);
+      break;
+
+    case GST_AUDIO_RESAMPLER_METHOD_BLACKMAN_NUTTALL:
+      for (i = 0; i < n_taps; i++)
+        weight += tmp_taps[i] =
+            get_blackman_nuttall_tap (x + i,
+            resampler->n_taps, resampler->cutoff);
+      break;
+
+    case GST_AUDIO_RESAMPLER_METHOD_KAISER:
+      for (i = 0; i < n_taps; i++)
+        weight += tmp_taps[i] =
+            get_kaiser_tap (x + i, resampler->n_taps,
+            resampler->cutoff, resampler->kaiser_beta);
+      break;
+  }
+  resampler->convert_taps (tmp_taps, res, weight, n_taps);
+}
+
+#define MAKE_COEFF_LINEAR_INT_FUNC(type,type2,prec)                     \
+static inline void                                                      \
+make_coeff_##type##_linear (gint num, gint denom, type *icoeff)         \
+{                                                                       \
+  type x = ((gint64)num << prec) / denom;                               \
+  icoeff[0] = icoeff[2] = x;                                            \
+  icoeff[1] = icoeff[3] = (type)(((type2)1 << prec)-1)  - x;            \
+}
+#define MAKE_COEFF_LINEAR_FLOAT_FUNC(type)                              \
+static inline void                                                      \
+make_coeff_##type##_linear (gint num, gint denom, type *icoeff)         \
+{                                                                       \
+  type x = (type)num / denom;                                           \
+  icoeff[0] = icoeff[2] = x;                                            \
+  icoeff[1] = icoeff[3] = (type)1.0 - x;                                \
+}
+MAKE_COEFF_LINEAR_INT_FUNC (gint16, gint32, PRECISION_S16);
+MAKE_COEFF_LINEAR_INT_FUNC (gint32, gint64, PRECISION_S32);
+MAKE_COEFF_LINEAR_FLOAT_FUNC (gfloat);
+MAKE_COEFF_LINEAR_FLOAT_FUNC (gdouble);
+
+#define MAKE_COEFF_CUBIC_INT_FUNC(type,type2,prec)                      \
+static inline void                                                      \
+make_coeff_##type##_cubic (gint num, gint denom, type *icoeff)          \
+{                                                                       \
+  type2 one = ((type2)1 << prec) - 1;                                   \
+  type2 x = ((gint64) num << prec) / denom;                             \
+  type2 x2 = (x * x) >> prec;                                           \
+  type2 x3 = (x2 * x) >> prec;                                          \
+  icoeff[0] = (((x3 - x) << prec) / 6) >> prec;                         \
+  icoeff[1] = x + ((x2 - x3) >> 1);                                     \
+  icoeff[3] = -(((x << prec) / 3) >> prec) +                            \
+            (x2 >> 1) - (((x3 << prec) / 6) >> prec);                   \
+  icoeff[2] = one - icoeff[0] - icoeff[1] - icoeff[3];                  \
+}
+#define MAKE_COEFF_CUBIC_FLOAT_FUNC(type)                               \
+static inline void                                                      \
+make_coeff_##type##_cubic (gint num, gint denom, type *icoeff)          \
+{                                                                       \
+  type x = (type) num / denom, x2 = x * x, x3 = x2 * x;                 \
+  icoeff[0] = 0.16667f * (x3 - x);                                      \
+  icoeff[1] = x + 0.5f * (x2 - x3);                                     \
+  icoeff[3] = -0.33333f * x + 0.5f * x2 - 0.16667f * x3;                \
+  icoeff[2] = (type)1.0 - icoeff[0] - icoeff[1] - icoeff[3];            \
+}
+MAKE_COEFF_CUBIC_INT_FUNC (gint16, gint32, PRECISION_S16);
+MAKE_COEFF_CUBIC_INT_FUNC (gint32, gint64, PRECISION_S32);
+MAKE_COEFF_CUBIC_FLOAT_FUNC (gfloat);
+MAKE_COEFF_CUBIC_FLOAT_FUNC (gdouble);
+
+#define INTERPOLATE_INT_LINEAR_FUNC(type,type2,prec,limit)      \
+static inline void                                              \
+interpolate_##type##_linear_c (gpointer op, const gpointer ap,  \
+    gint len, const gpointer icp, gint astride)                 \
+{                                                               \
+  gint i;                                                       \
+  type *o = op, *a = ap, *ic = icp;                             \
+  type2 tmp, c0 = ic[0];                                        \
+  const type *c[2] = {(type*)((gint8*)a + 0*astride),           \
+                      (type*)((gint8*)a + 1*astride)};          \
+                                                                \
+  for (i = 0; i < len; i++) {                                   \
+    tmp = ((type2)c[0][i] - (type2)c[1][i]) * c0 +              \
+         (((type2)c[1][i]) << (prec));                          \
+    o[i] = (tmp + ((type2)1 << ((prec) - 1))) >> (prec);        \
+  }                                                             \
+}
+#define INTERPOLATE_FLOAT_LINEAR_FUNC(type)                     \
+static inline void                                              \
+interpolate_##type##_linear_c (gpointer op, const gpointer ap,  \
+    gint len, const gpointer icp, gint astride)                 \
+{                                                               \
+  gint i;                                                       \
+  type *o = op, *a = ap, *ic = icp;                             \
+  type c0 = ic[0];                                              \
+  const type *c[2] = {(type*)((gint8*)a + 0*astride),           \
+                      (type*)((gint8*)a + 1*astride)};          \
+                                                                \
+  for (i = 0; i < len; i++) {                                   \
+    o[i] = (c[0][i] - c[1][i]) * c0 + c[1][i];                  \
+  }                                                             \
+}
+
+INTERPOLATE_INT_LINEAR_FUNC (gint16, gint32, PRECISION_S16, (gint32) 1 << 15);
+INTERPOLATE_INT_LINEAR_FUNC (gint32, gint64, PRECISION_S32, (gint64) 1 << 31);
+INTERPOLATE_FLOAT_LINEAR_FUNC (gfloat);
+INTERPOLATE_FLOAT_LINEAR_FUNC (gdouble);
+
+#define INTERPOLATE_INT_CUBIC_FUNC(type,type2,prec,limit)       \
+static inline void                                              \
+interpolate_##type##_cubic_c (gpointer op, const gpointer ap,   \
+    gint len, const gpointer icp, gint astride)                 \
+{                                                               \
+  gint i;                                                       \
+  type *o = op, *a = ap, *ic = icp;                             \
+  type2 tmp, c0 = ic[0], c1 = ic[1], c2 = ic[2], c3 = ic[3];    \
+  const type *c[4] = {(type*)((gint8*)a + 0*astride),           \
+                      (type*)((gint8*)a + 1*astride),           \
+                      (type*)((gint8*)a + 2*astride),           \
+                      (type*)((gint8*)a + 3*astride)};          \
+                                                                \
+  for (i = 0; i < len; i++) {                                   \
+    tmp = (type2)c[0][i] * c0 + (type2)c[1][i] * c1 +           \
+          (type2)c[2][i] * c2 + (type2)c[3][i] * c3;            \
+    tmp = (tmp + ((type2)1 << ((prec) - 1))) >> (prec);         \
+    o[i] = CLAMP (tmp, -(limit), (limit) - 1);                  \
+  }                                                             \
+}
+#define INTERPOLATE_FLOAT_CUBIC_FUNC(type)                      \
+static inline void                                              \
+interpolate_##type##_cubic_c (gpointer op, const gpointer ap,   \
+    gint len, const gpointer icp, gint astride)                 \
+{                                                               \
+  gint i;                                                       \
+  type *o = op, *a = ap, *ic = icp;                             \
+  type c0 = ic[0], c1 = ic[1], c2 = ic[2], c3 = ic[3];          \
+  const type *c[4] = {(type*)((gint8*)a + 0*astride),           \
+                      (type*)((gint8*)a + 1*astride),           \
+                      (type*)((gint8*)a + 2*astride),           \
+                      (type*)((gint8*)a + 3*astride)};          \
+                                                                \
+  for (i = 0; i < len; i++) {                                   \
+    o[i] = c[0][i] * c0 + c[1][i] * c1 +                        \
+           c[2][i] * c2 + c[3][i] * c3;                         \
+  }                                                             \
+}
+
+INTERPOLATE_INT_CUBIC_FUNC (gint16, gint32, PRECISION_S16, (gint32) 1 << 15);
+INTERPOLATE_INT_CUBIC_FUNC (gint32, gint64, PRECISION_S32, (gint64) 1 << 31);
+INTERPOLATE_FLOAT_CUBIC_FUNC (gfloat);
+INTERPOLATE_FLOAT_CUBIC_FUNC (gdouble);
+
+static InterpolateFunc interpolate_funcs[] = {
+  interpolate_gint16_linear_c,
+  interpolate_gint32_linear_c,
+  interpolate_gfloat_linear_c,
+  interpolate_gdouble_linear_c,
+
+  interpolate_gint16_cubic_c,
+  interpolate_gint32_cubic_c,
+  interpolate_gfloat_cubic_c,
+  interpolate_gdouble_cubic_c,
+};
+
+#define interpolate_gint16_linear  interpolate_funcs[0]
+#define interpolate_gint32_linear  interpolate_funcs[1]
+#define interpolate_gfloat_linear  interpolate_funcs[2]
+#define interpolate_gdouble_linear interpolate_funcs[3]
+
+#define interpolate_gint16_cubic   interpolate_funcs[4]
+#define interpolate_gint32_cubic   interpolate_funcs[5]
+#define interpolate_gfloat_cubic   interpolate_funcs[6]
+#define interpolate_gdouble_cubic  interpolate_funcs[7]
+
+#define GET_TAPS_NEAREST_FUNC(type)                                             \
+static inline gpointer                                                          \
+get_taps_##type##_nearest (GstAudioResampler * resampler,                       \
+    gint *samp_index, gint *samp_phase, type icoeff[4])                         \
+{                                                                               \
+  gint out_rate = resampler->out_rate;                                          \
+  *samp_index += resampler->samp_inc;                                           \
+  *samp_phase += resampler->samp_frac;                                          \
+  if (*samp_phase >= out_rate) {                                                \
+    *samp_phase -= out_rate;                                                    \
+    *samp_index += 1;                                                           \
+  }                                                                             \
+  return NULL;                                                                  \
+}
+GET_TAPS_NEAREST_FUNC (gint16);
+GET_TAPS_NEAREST_FUNC (gint32);
+GET_TAPS_NEAREST_FUNC (gfloat);
+GET_TAPS_NEAREST_FUNC (gdouble);
+
+#define get_taps_gint16_nearest get_taps_gint16_nearest
+#define get_taps_gint32_nearest get_taps_gint32_nearest
+#define get_taps_gfloat_nearest get_taps_gfloat_nearest
+#define get_taps_gdouble_nearest get_taps_gdouble_nearest
+
+#define GET_TAPS_FULL_FUNC(type)                                                \
+DECL_GET_TAPS_FULL_FUNC(type)                                                   \
+{                                                                               \
+  gpointer res;                                                                 \
+  gint out_rate = resampler->out_rate;                                          \
+  gint n_phases = resampler->n_phases;                                          \
+  gint phase = (n_phases == out_rate ? *samp_phase :                            \
+      ((gint64)*samp_phase * n_phases) / out_rate);                             \
+                                                                                \
+  res = resampler->cached_phases[phase];                                        \
+  if (G_UNLIKELY (res == NULL)) {                                               \
+    res = (gint8 *) resampler->cached_taps +                                    \
+                        phase * resampler->cached_taps_stride;                  \
+    switch (resampler->filter_interpolation) {                                  \
+      case GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_NONE:                       \
+      {                                                                         \
+        gdouble x;                                                              \
+        gint n_taps = resampler->n_taps;                                        \
+                                                                                \
+        x = 1.0 - n_taps / 2 - (gdouble) phase / n_phases;                      \
+        make_taps (resampler, res, x, n_taps);                                  \
+        break;                                                                  \
+      }                                                                         \
+      default:                                                                  \
+      {                                                                         \
+        gint offset, pos, frac;                                                 \
+        gint oversample = resampler->oversample;                                \
+        gint taps_stride = resampler->taps_stride;                              \
+        gint n_taps = resampler->n_taps;                                        \
+        type ic[4], *taps;                                                      \
+                                                                                \
+        pos = phase * oversample;                                               \
+        offset = (oversample - 1) - pos / n_phases;                             \
+        frac = pos % n_phases;                                                  \
+                                                                                \
+        taps = (type *) ((gint8 *) resampler->taps + offset * taps_stride);     \
+                                                                                \
+        switch (resampler->filter_interpolation) {                              \
+          default:                                                              \
+          case GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_LINEAR:                 \
+            make_coeff_##type##_linear (frac, n_phases, ic);                    \
+            break;                                                              \
+          case GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_CUBIC:                  \
+            make_coeff_##type##_cubic (frac, n_phases, ic);                     \
+            break;                                                              \
+        }                                                                       \
+        resampler->interpolate (res, taps, n_taps, ic, taps_stride);            \
+      }                                                                         \
+    }                                                                           \
+    resampler->cached_phases[phase] = res;                                      \
+  }                                                                             \
+  *samp_index += resampler->samp_inc;                                           \
+  *samp_phase += resampler->samp_frac;                                          \
+  if (*samp_phase >= out_rate) {                                                \
+    *samp_phase -= out_rate;                                                    \
+    *samp_index += 1;                                                           \
+  }                                                                             \
+  return res;                                                                   \
+}
+GET_TAPS_FULL_FUNC (gint16);
+GET_TAPS_FULL_FUNC (gint32);
+GET_TAPS_FULL_FUNC (gfloat);
+GET_TAPS_FULL_FUNC (gdouble);
+
+#define GET_TAPS_INTERPOLATE_FUNC(type,inter)                   \
+DECL_GET_TAPS_INTERPOLATE_FUNC (type, inter)                    \
+{                                                               \
+  gpointer res;                                                 \
+  gint out_rate = resampler->out_rate;                          \
+  gint offset, frac, pos;                                       \
+  gint oversample = resampler->oversample;                      \
+  gint taps_stride = resampler->taps_stride;                    \
+                                                                \
+  pos = *samp_phase * oversample;                               \
+  offset = (oversample - 1) - pos / out_rate;                   \
+  frac = pos % out_rate;                                        \
+                                                                \
+  res = (gint8 *) resampler->taps + offset * taps_stride;       \
+  make_coeff_##type##_##inter (frac, out_rate, icoeff);         \
+                                                                \
+  *samp_index += resampler->samp_inc;                           \
+  *samp_phase += resampler->samp_frac;                          \
+  if (*samp_phase >= out_rate) {                                \
+    *samp_phase -= out_rate;                                    \
+    *samp_index += 1;                                           \
+  }                                                             \
+  return res;                                                   \
+}
+
+GET_TAPS_INTERPOLATE_FUNC (gint16, linear);
+GET_TAPS_INTERPOLATE_FUNC (gint32, linear);
+GET_TAPS_INTERPOLATE_FUNC (gfloat, linear);
+GET_TAPS_INTERPOLATE_FUNC (gdouble, linear);
+
+GET_TAPS_INTERPOLATE_FUNC (gint16, cubic);
+GET_TAPS_INTERPOLATE_FUNC (gint32, cubic);
+GET_TAPS_INTERPOLATE_FUNC (gfloat, cubic);
+GET_TAPS_INTERPOLATE_FUNC (gdouble, cubic);
+
+#define INNER_PRODUCT_NEAREST_FUNC(type)                        \
+static inline void                                              \
+inner_product_##type##_nearest_1_c (type * o, const type * a,   \
+    const type * b, gint len, const type *ic, gint bstride)     \
+{                                                               \
+  *o = *a;                                                      \
+}
+INNER_PRODUCT_NEAREST_FUNC (gint16);
+INNER_PRODUCT_NEAREST_FUNC (gint32);
+INNER_PRODUCT_NEAREST_FUNC (gfloat);
+INNER_PRODUCT_NEAREST_FUNC (gdouble);
+
+#define INNER_PRODUCT_INT_FULL_FUNC(type,type2,prec,limit)      \
+static inline void                                              \
+inner_product_##type##_full_1_c (type * o, const type * a,      \
+    const type * b, gint len, const type *ic, gint bstride)     \
+{                                                               \
+  gint i;                                                       \
+  type2 res[4] = { 0, 0, 0, 0 };                                \
+                                                                \
+  for (i = 0; i < len; i += 4) {                                \
+    res[0] += (type2) a[i + 0] * (type2) b[i + 0];              \
+    res[1] += (type2) a[i + 1] * (type2) b[i + 1];              \
+    res[2] += (type2) a[i + 2] * (type2) b[i + 2];              \
+    res[3] += (type2) a[i + 3] * (type2) b[i + 3];              \
+  }                                                             \
+  res[0] = res[0] + res[1] + res[2] + res[3];                   \
+  res[0] = (res[0] + ((type2)1 << ((prec) - 1))) >> (prec);     \
+  *o = CLAMP (res[0], -(limit), (limit) - 1);                   \
+}
+
+INNER_PRODUCT_INT_FULL_FUNC (gint16, gint32, PRECISION_S16, (gint32) 1 << 15);
+INNER_PRODUCT_INT_FULL_FUNC (gint32, gint64, PRECISION_S32, (gint64) 1 << 31);
+
+#define INNER_PRODUCT_INT_LINEAR_FUNC(type,type2,prec,limit)    \
+static inline void                                              \
+inner_product_##type##_linear_1_c (type * o, const type * a,    \
+    const type * b, gint len, const type *ic, gint bstride)     \
+{                                                               \
+  gint i;                                                       \
+  type2 res[4] = { 0, 0, 0, 0 }, c0 = ic[0];                    \
+  const type *c[2] = {(type*)((gint8*)b + 0*bstride),           \
+                      (type*)((gint8*)b + 1*bstride)};          \
+                                                                \
+  for (i = 0; i < len; i += 2) {                                \
+    res[0] += (type2) a[i + 0] * (type2) c[0][i + 0];           \
+    res[1] += (type2) a[i + 0] * (type2) c[1][i + 0];           \
+    res[2] += (type2) a[i + 1] * (type2) c[0][i + 1];           \
+    res[3] += (type2) a[i + 1] * (type2) c[1][i + 1];           \
+  }                                                             \
+  res[0] = (res[0] + res[2]) >> (prec);                         \
+  res[1] = (res[1] + res[3]) >> (prec);                         \
+  res[0] = ((type2)(type)res[0] - (type2)(type)res[1]) * c0 +   \
+           ((type2)(type)res[1] << (prec));                     \
+  res[0] = (res[0] + ((type2)1 << ((prec) - 1))) >> (prec);     \
+  *o = CLAMP (res[0], -(limit), (limit) - 1);                   \
+}
+
+INNER_PRODUCT_INT_LINEAR_FUNC (gint16, gint32, PRECISION_S16, (gint32) 1 << 15);
+INNER_PRODUCT_INT_LINEAR_FUNC (gint32, gint64, PRECISION_S32, (gint64) 1 << 31);
+
+#define INNER_PRODUCT_INT_CUBIC_FUNC(type,type2,prec,limit)     \
+static inline void                                              \
+inner_product_##type##_cubic_1_c (type * o, const type * a,     \
+    const type * b, gint len, const type *ic, gint bstride)     \
+{                                                               \
+  gint i;                                                       \
+  type2 res[4] = { 0, 0, 0, 0 };                                \
+  const type *c[4] = {(type*)((gint8*)b + 0*bstride),           \
+                      (type*)((gint8*)b + 1*bstride),           \
+                      (type*)((gint8*)b + 2*bstride),           \
+                      (type*)((gint8*)b + 3*bstride)};          \
+                                                                \
+  for (i = 0; i < len; i++) {                                   \
+    res[0] += (type2) a[i] * (type2) c[0][i];                   \
+    res[1] += (type2) a[i] * (type2) c[1][i];                   \
+    res[2] += (type2) a[i] * (type2) c[2][i];                   \
+    res[3] += (type2) a[i] * (type2) c[3][i];                   \
+  }                                                             \
+  res[0] = (type2)(type)(res[0] >> (prec)) * (type2) ic[0] +    \
+           (type2)(type)(res[1] >> (prec)) * (type2) ic[1] +    \
+           (type2)(type)(res[2] >> (prec)) * (type2) ic[2] +    \
+           (type2)(type)(res[3] >> (prec)) * (type2) ic[3];     \
+  res[0] = (res[0] + ((type2)1 << ((prec) - 1))) >> (prec);     \
+  *o = CLAMP (res[0], -(limit), (limit) - 1);                   \
+}
+
+INNER_PRODUCT_INT_CUBIC_FUNC (gint16, gint32, PRECISION_S16, (gint32) 1 << 15);
+INNER_PRODUCT_INT_CUBIC_FUNC (gint32, gint64, PRECISION_S32, (gint64) 1 << 31);
+
+#define INNER_PRODUCT_FLOAT_FULL_FUNC(type)                     \
+static inline void                                              \
+inner_product_##type##_full_1_c (type * o, const type * a,      \
+    const type * b, gint len, const type *ic, gint bstride)     \
+{                                                               \
+  gint i;                                                       \
+  type res[4] = { 0.0, 0.0, 0.0, 0.0 };                         \
+                                                                \
+  for (i = 0; i < len; i += 4) {                                \
+    res[0] += a[i + 0] * b[i + 0];                              \
+    res[1] += a[i + 1] * b[i + 1];                              \
+    res[2] += a[i + 2] * b[i + 2];                              \
+    res[3] += a[i + 3] * b[i + 3];                              \
+  }                                                             \
+  *o = res[0] + res[1] + res[2] + res[3];                       \
+}
+
+INNER_PRODUCT_FLOAT_FULL_FUNC (gfloat);
+INNER_PRODUCT_FLOAT_FULL_FUNC (gdouble);
+
+#define INNER_PRODUCT_FLOAT_LINEAR_FUNC(type)                   \
+static inline void                                              \
+inner_product_##type##_linear_1_c (type * o, const type * a,    \
+    const type * b, gint len, const type *ic, gint bstride)     \
+{                                                               \
+  gint i;                                                       \
+  type res[4] = { 0.0, 0.0, 0.0, 0.0 };                         \
+  const type *c[2] = {(type*)((gint8*)b + 0*bstride),           \
+                      (type*)((gint8*)b + 1*bstride)};          \
+                                                                \
+  for (i = 0; i < len; i += 2) {                                \
+    res[0] += a[i + 0] * c[0][i + 0];                           \
+    res[1] += a[i + 0] * c[1][i + 0];                           \
+    res[2] += a[i + 1] * c[0][i + 1];                           \
+    res[3] += a[i + 1] * c[1][i + 1];                           \
+  }                                                             \
+  res[0] += res[2];                                             \
+  res[1] += res[3];                                             \
+  *o = (res[0] - res[1]) * ic[0] + res[1];                      \
+}
+INNER_PRODUCT_FLOAT_LINEAR_FUNC (gfloat);
+INNER_PRODUCT_FLOAT_LINEAR_FUNC (gdouble);
+
+#define INNER_PRODUCT_FLOAT_CUBIC_FUNC(type)                    \
+static inline void                                              \
+inner_product_##type##_cubic_1_c (type * o, const type * a,     \
+    const type * b, gint len, const type *ic, gint bstride)     \
+{                                                               \
+  gint i;                                                       \
+  type res[4] = { 0.0, 0.0, 0.0, 0.0 };                         \
+  const type *c[4] = {(type*)((gint8*)b + 0*bstride),           \
+                      (type*)((gint8*)b + 1*bstride),           \
+                      (type*)((gint8*)b + 2*bstride),           \
+                      (type*)((gint8*)b + 3*bstride)};          \
+                                                                \
+  for (i = 0; i < len; i++) {                                   \
+    res[0] += a[i] * c[0][i];                                   \
+    res[1] += a[i] * c[1][i];                                   \
+    res[2] += a[i] * c[2][i];                                   \
+    res[3] += a[i] * c[3][i];                                   \
+  }                                                             \
+  *o = res[0] * ic[0] + res[1] * ic[1] +                        \
+       res[2] * ic[2] + res[3] * ic[3];                         \
+}
+INNER_PRODUCT_FLOAT_CUBIC_FUNC (gfloat);
+INNER_PRODUCT_FLOAT_CUBIC_FUNC (gdouble);
+
+MAKE_RESAMPLE_FUNC_STATIC (gint16, nearest, 1, c);
+MAKE_RESAMPLE_FUNC_STATIC (gint32, nearest, 1, c);
+MAKE_RESAMPLE_FUNC_STATIC (gfloat, nearest, 1, c);
+MAKE_RESAMPLE_FUNC_STATIC (gdouble, nearest, 1, c);
+
+MAKE_RESAMPLE_FUNC_STATIC (gint16, full, 1, c);
+MAKE_RESAMPLE_FUNC_STATIC (gint32, full, 1, c);
+MAKE_RESAMPLE_FUNC_STATIC (gfloat, full, 1, c);
+MAKE_RESAMPLE_FUNC_STATIC (gdouble, full, 1, c);
+
+MAKE_RESAMPLE_FUNC_STATIC (gint16, linear, 1, c);
+MAKE_RESAMPLE_FUNC_STATIC (gint32, linear, 1, c);
+MAKE_RESAMPLE_FUNC_STATIC (gfloat, linear, 1, c);
+MAKE_RESAMPLE_FUNC_STATIC (gdouble, linear, 1, c);
+
+MAKE_RESAMPLE_FUNC_STATIC (gint16, cubic, 1, c);
+MAKE_RESAMPLE_FUNC_STATIC (gint32, cubic, 1, c);
+MAKE_RESAMPLE_FUNC_STATIC (gfloat, cubic, 1, c);
+MAKE_RESAMPLE_FUNC_STATIC (gdouble, cubic, 1, c);
+
+static ResampleFunc resample_funcs[] = {
+  resample_gint16_nearest_1_c,
+  resample_gint32_nearest_1_c,
+  resample_gfloat_nearest_1_c,
+  resample_gdouble_nearest_1_c,
+
+  resample_gint16_full_1_c,
+  resample_gint32_full_1_c,
+  resample_gfloat_full_1_c,
+  resample_gdouble_full_1_c,
+
+  resample_gint16_linear_1_c,
+  resample_gint32_linear_1_c,
+  resample_gfloat_linear_1_c,
+  resample_gdouble_linear_1_c,
+
+  resample_gint16_cubic_1_c,
+  resample_gint32_cubic_1_c,
+  resample_gfloat_cubic_1_c,
+  resample_gdouble_cubic_1_c,
+};
+
+#define resample_gint16_nearest_1 resample_funcs[0]
+#define resample_gint32_nearest_1 resample_funcs[1]
+#define resample_gfloat_nearest_1 resample_funcs[2]
+#define resample_gdouble_nearest_1 resample_funcs[3]
+
+#define resample_gint16_full_1 resample_funcs[4]
+#define resample_gint32_full_1 resample_funcs[5]
+#define resample_gfloat_full_1 resample_funcs[6]
+#define resample_gdouble_full_1 resample_funcs[7]
+
+#define resample_gint16_linear_1 resample_funcs[8]
+#define resample_gint32_linear_1 resample_funcs[9]
+#define resample_gfloat_linear_1 resample_funcs[10]
+#define resample_gdouble_linear_1 resample_funcs[11]
+
+#define resample_gint16_cubic_1 resample_funcs[12]
+#define resample_gint32_cubic_1 resample_funcs[13]
+#define resample_gfloat_cubic_1 resample_funcs[14]
+#define resample_gdouble_cubic_1 resample_funcs[15]
+
+#if defined HAVE_ORC && !defined DISABLE_ORC
+# if defined (HAVE_ARM_NEON)
+#  define CHECK_NEON
+#  include "audio-resampler-neon.h"
+# endif
+# if defined (__i386__) || defined (__x86_64__)
+#  define CHECK_X86
+#  include "audio-resampler-x86.h"
+# endif
+#endif
+
+static void
+audio_resampler_init (void)
+{
+  static gsize init_gonce = 0;
+
+  if (g_once_init_enter (&init_gonce)) {
+
+    GST_DEBUG_CATEGORY_INIT (audio_resampler_debug, "audio-resampler", 0,
+        "audio-resampler object");
+
+#if defined HAVE_ORC && !defined DISABLE_ORC
+    orc_init ();
+    {
+      OrcTarget *target = orc_target_get_default ();
+      gint i;
+
+      if (target) {
+        const gchar *name;
+        unsigned int flags = orc_target_get_default_flags (target);
+
+        for (i = -1; i < 32; ++i) {
+          if (i == -1) {
+            name = orc_target_get_name (target);
+            GST_DEBUG ("target %s, default flags %08x", name, flags);
+          } else if (flags & (1U << i)) {
+            name = orc_target_get_flag_name (target, i);
+            GST_DEBUG ("target flag %s", name);
+          } else
+            name = NULL;
+
+          if (name) {
+#ifdef CHECK_X86
+            audio_resampler_check_x86 (name);
+#endif
+#ifdef CHECK_NEON
+            audio_resampler_check_neon (name);
+#endif
+          }
+        }
+      }
+    }
+#endif
+    g_once_init_leave (&init_gonce, 1);
+  }
+}
+
+#define MAKE_DEINTERLEAVE_FUNC(type)                                    \
+static void                                                             \
+deinterleave_ ##type (GstAudioResampler * resampler, gpointer sbuf[],   \
+    gpointer in[], gsize in_frames)                                     \
+{                                                                       \
+  gint i, c, channels = resampler->channels;                            \
+  gsize samples_avail = resampler->samples_avail;                       \
+  for (c = 0; c < channels; c++) {                                      \
+    type *s = (type *) sbuf[c] + samples_avail;                         \
+    if (G_UNLIKELY (in == NULL)) {                                      \
+      for (i = 0; i < in_frames; i++)                                   \
+        s[i] = 0;                                                       \
+    } else {                                                            \
+      type *ip = (type *) in[0] + c;                                    \
+      for (i = 0; i < in_frames; i++, ip += channels)                   \
+        s[i] = *ip;                                                     \
+    }                                                                   \
+  }                                                                     \
+}
+
+MAKE_DEINTERLEAVE_FUNC (gint16);
+MAKE_DEINTERLEAVE_FUNC (gint32);
+MAKE_DEINTERLEAVE_FUNC (gfloat);
+MAKE_DEINTERLEAVE_FUNC (gdouble);
+
+static DeinterleaveFunc deinterleave_funcs[] = {
+  deinterleave_gint16,
+  deinterleave_gint32,
+  deinterleave_gfloat,
+  deinterleave_gdouble
+};
+
+static void
+calculate_kaiser_params (GstAudioResampler * resampler)
+{
+  gdouble A, B, dw, tr_bw, Fc;
+  gint n;
+  const KaiserQualityMap *q = &kaiser_qualities[DEFAULT_QUALITY];
+
+  /* default cutoff */
+  Fc = q->cutoff;
+  if (resampler->out_rate < resampler->in_rate)
+    Fc *= q->downsample_cutoff_factor;
+
+  Fc = GET_OPT_CUTOFF (resampler->options, Fc);
+  A = GET_OPT_STOP_ATTENUATION (resampler->options, q->stopband_attenuation);
+  tr_bw =
+      GET_OPT_TRANSITION_BANDWIDTH (resampler->options,
+      q->transition_bandwidth);
+
+  GST_LOG ("Fc %f, A %f, tr_bw %f", Fc, A, tr_bw);
+
+  /* calculate Beta */
+  if (A > 50)
+    B = 0.1102 * (A - 8.7);
+  else if (A >= 21)
+    B = 0.5842 * pow (A - 21, 0.4) + 0.07886 * (A - 21);
+  else
+    B = 0.0;
+  /* calculate transition width in radians */
+  dw = 2 * G_PI * (tr_bw);
+  /* order of the filter */
+  n = (A - 8.0) / (2.285 * dw);
+
+  resampler->kaiser_beta = B;
+  resampler->n_taps = n + 1;
+  resampler->cutoff = Fc;
+
+  GST_LOG ("using Beta %f n_taps %d cutoff %f", resampler->kaiser_beta,
+      resampler->n_taps, resampler->cutoff);
+}
+
+static void
+alloc_taps_mem (GstAudioResampler * resampler, gint bps, gint n_taps,
+    gint n_phases)
+{
+  if (resampler->alloc_taps >= n_taps && resampler->alloc_phases >= n_phases)
+    return;
+
+  GST_DEBUG ("allocate bps %d n_taps %d n_phases %d", bps, n_taps, n_phases);
+
+  resampler->tmp_taps =
+      g_realloc_n (resampler->tmp_taps, n_taps, sizeof (gdouble));
+
+  resampler->taps_stride = GST_ROUND_UP_32 (bps * (n_taps + TAPS_OVERREAD));
+
+  g_free (resampler->taps_mem);
+  resampler->taps_mem =
+      g_malloc0 (n_phases * resampler->taps_stride + ALIGN - 1);
+  resampler->taps = MEM_ALIGN ((gint8 *) resampler->taps_mem, ALIGN);
+  resampler->alloc_taps = n_taps;
+  resampler->alloc_phases = n_phases;
+}
+
+static void
+alloc_cache_mem (GstAudioResampler * resampler, gint bps, gint n_taps,
+    gint n_phases)
+{
+  gsize phases_size;
+
+  resampler->tmp_taps =
+      g_realloc_n (resampler->tmp_taps, n_taps, sizeof (gdouble));
+
+  resampler->cached_taps_stride =
+      GST_ROUND_UP_32 (bps * (n_taps + TAPS_OVERREAD));
+
+  phases_size = sizeof (gpointer) * n_phases;
+
+  g_free (resampler->cached_taps_mem);
+  resampler->cached_taps_mem =
+      g_malloc0 (phases_size + n_phases * resampler->cached_taps_stride +
+      ALIGN - 1);
+  resampler->cached_taps =
+      MEM_ALIGN ((gint8 *) resampler->cached_taps_mem + phases_size, ALIGN);
+  resampler->cached_phases = resampler->cached_taps_mem;
+}
+
+static void
+setup_functions (GstAudioResampler * resampler)
+{
+  gint index, fidx;
+
+  index = resampler->format_index;
+
+  if (resampler->in_rate == resampler->out_rate)
+    resampler->resample = resample_funcs[index];
+  else {
+    switch (resampler->filter_interpolation) {
+      default:
+      case GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_NONE:
+        fidx = 0;
+        break;
+      case GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_LINEAR:
+        GST_DEBUG ("using linear interpolation for filter coefficients");
+        fidx = 0;
+        break;
+      case GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_CUBIC:
+        GST_DEBUG ("using cubic interpolation for filter coefficients");
+        fidx = 4;
+        break;
+    }
+    GST_DEBUG ("using filter interpolate function %d", index + fidx);
+    resampler->interpolate = interpolate_funcs[index + fidx];
+
+    switch (resampler->method) {
+      case GST_AUDIO_RESAMPLER_METHOD_NEAREST:
+        GST_DEBUG ("using nearest filter function");
+        break;
+      default:
+        index += 4;
+        switch (resampler->filter_mode) {
+          default:
+          case GST_AUDIO_RESAMPLER_FILTER_MODE_FULL:
+            GST_DEBUG ("using full filter function");
+            break;
+          case GST_AUDIO_RESAMPLER_FILTER_MODE_INTERPOLATED:
+            index += 4 + fidx;
+            GST_DEBUG ("using interpolated filter function");
+            break;
+        }
+        break;
+    }
+    GST_DEBUG ("using resample function %d", index);
+    resampler->resample = resample_funcs[index];
+  }
+}
+
+static void
+resampler_calculate_taps (GstAudioResampler * resampler)
+{
+  gint bps;
+  gint n_taps, oversample;
+  gint in_rate, out_rate;
+  gboolean scale = TRUE, sinc_table = FALSE;
+  GstAudioResamplerFilterInterpolation filter_interpolation;
+
+  switch (resampler->method) {
+    case GST_AUDIO_RESAMPLER_METHOD_NEAREST:
+      resampler->n_taps = 2;
+      scale = FALSE;
+      break;
+    case GST_AUDIO_RESAMPLER_METHOD_LINEAR:
+      resampler->n_taps = GET_OPT_N_TAPS (resampler->options, 2);
+      break;
+    case GST_AUDIO_RESAMPLER_METHOD_CUBIC:
+      resampler->n_taps = GET_OPT_N_TAPS (resampler->options, 4);
+      resampler->b = GET_OPT_CUBIC_B (resampler->options);
+      resampler->c = GET_OPT_CUBIC_C (resampler->options);;
+      break;
+    case GST_AUDIO_RESAMPLER_METHOD_BLACKMAN_NUTTALL:
+    {
+      const BlackmanQualityMap *q = &blackman_qualities[DEFAULT_QUALITY];
+      resampler->n_taps = GET_OPT_N_TAPS (resampler->options, q->n_taps);
+      resampler->cutoff = GET_OPT_CUTOFF (resampler->options, q->cutoff);
+      sinc_table = TRUE;
+      break;
+    }
+    case GST_AUDIO_RESAMPLER_METHOD_KAISER:
+      calculate_kaiser_params (resampler);
+      sinc_table = TRUE;
+      break;
+  }
+
+  in_rate = resampler->in_rate;
+  out_rate = resampler->out_rate;
+
+  if (out_rate < in_rate && scale) {
+    resampler->cutoff = resampler->cutoff * out_rate / in_rate;
+    resampler->n_taps =
+        gst_util_uint64_scale_int (resampler->n_taps, in_rate, out_rate);
+  }
+
+  if (sinc_table) {
+    resampler->n_taps = GST_ROUND_UP_8 (resampler->n_taps);
+    resampler->filter_mode = GET_OPT_FILTER_MODE (resampler->options);
+    resampler->filter_threshold =
+        GET_OPT_FILTER_MODE_THRESHOLD (resampler->options);
+    filter_interpolation = GET_OPT_FILTER_INTERPOLATION (resampler->options);
+
+  } else {
+    resampler->filter_mode = GST_AUDIO_RESAMPLER_FILTER_MODE_FULL;
+    filter_interpolation = GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_NONE;
+  }
+
+  /* calculate oversampling for interpolated filter */
+  if (filter_interpolation != GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_NONE) {
+    gint mult = 2;
+
+    oversample = GET_OPT_FILTER_OVERSAMPLE (resampler->options);
+    while (oversample > 1) {
+      if (mult * out_rate >= in_rate)
+        break;
+
+      mult *= 2;
+      oversample >>= 1;
+    }
+
+    switch (filter_interpolation) {
+      case GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_LINEAR:
+        oversample *= 11;
+        break;
+      default:
+        break;
+    }
+  } else {
+    oversample = 1;
+  }
+  resampler->oversample = oversample;
+
+  n_taps = resampler->n_taps;
+  bps = resampler->bps;
+
+  GST_LOG ("using n_taps %d cutoff %f oversample %d", n_taps, resampler->cutoff,
+      oversample);
+
+  if (resampler->filter_mode == GST_AUDIO_RESAMPLER_FILTER_MODE_AUTO) {
+    if (out_rate <= oversample
+        && !(resampler->flags & GST_AUDIO_RESAMPLER_FLAG_VARIABLE_RATE)) {
+      /* don't interpolate if we need to calculate at least the same amount
+       * of filter coefficients than the full table case */
+      resampler->filter_mode = GST_AUDIO_RESAMPLER_FILTER_MODE_FULL;
+      GST_DEBUG ("automatically selected full filter, %d <= %d", out_rate,
+          oversample);
+    } else if (bps * n_taps * out_rate < resampler->filter_threshold) {
+      /* switch to full filter when memory is below threshold */
+      resampler->filter_mode = GST_AUDIO_RESAMPLER_FILTER_MODE_FULL;
+      GST_DEBUG ("automatically selected full filter, memory %d <= %d",
+          bps * n_taps * out_rate, resampler->filter_threshold);
+    } else {
+      GST_DEBUG ("automatically selected interpolated filter");
+      resampler->filter_mode = GST_AUDIO_RESAMPLER_FILTER_MODE_INTERPOLATED;
+    }
+  }
+  /* interpolated table but no interpolation given, assume default */
+  if (resampler->filter_mode != GST_AUDIO_RESAMPLER_FILTER_MODE_FULL &&
+      filter_interpolation == GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_NONE)
+    filter_interpolation = DEFAULT_OPT_FILTER_INTERPOLATION;
+
+  resampler->filter_interpolation = filter_interpolation;
+
+  if (resampler->filter_mode == GST_AUDIO_RESAMPLER_FILTER_MODE_FULL &&
+      resampler->method != GST_AUDIO_RESAMPLER_METHOD_NEAREST) {
+    GST_DEBUG ("setting up filter cache");
+    resampler->n_phases = out_rate;
+    alloc_cache_mem (resampler, bps, n_taps, out_rate);
+  }
+
+  if (resampler->filter_interpolation !=
+      GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_NONE) {
+    gint i, isize;
+    gdouble x;
+    gpointer taps;
+
+    switch (resampler->filter_interpolation) {
+      default:
+      case GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_LINEAR:
+        GST_DEBUG ("using linear interpolation to build filter");
+        isize = 2;
+        break;
+      case GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_CUBIC:
+        GST_DEBUG ("using cubic interpolation to build filter");
+        isize = 4;
+        break;
+    }
+
+    alloc_taps_mem (resampler, bps, n_taps, oversample + isize);
+
+    for (i = 0; i < oversample + isize; i++) {
+      x = -(n_taps / 2) + i / (gdouble) oversample;
+      taps = (gint8 *) resampler->taps + i * resampler->taps_stride;
+      make_taps (resampler, taps, x, n_taps);
+    }
+  }
+}
+
+#define PRINT_TAPS(type,print)                          \
+G_STMT_START {                                          \
+  type sum = 0.0, *taps;                                \
+  type icoeff[4];                                       \
+  gint samp_index = 0, samp_phase = i;                  \
+                                                        \
+  taps = get_taps_##type##_full (resampler, &samp_index,\
+      &samp_phase, icoeff);                             \
+                                                        \
+  for (j = 0; j < n_taps; j++) {                        \
+    type tap = taps[j];                                 \
+    fprintf (stderr, "\t%" print " ", tap);             \
+    sum += tap;                                         \
+  }                                                     \
+  fprintf (stderr, "\t: sum %" print "\n", sum);        \
+} G_STMT_END
+
+static void
+resampler_dump (GstAudioResampler * resampler)
+{
+#if 0
+  gint i, n_taps, out_rate;
+  gint64 a;
+
+  out_rate = resampler->out_rate;
+  n_taps = resampler->n_taps;
+
+  fprintf (stderr, "out size %d, max taps %d\n", out_rate, n_taps);
+
+  a = g_get_monotonic_time ();
+
+  for (i = 0; i < out_rate; i++) {
+    gint j;
+
+    //fprintf (stderr, "%u: %d %d\t ", i, t->sample_inc, t->next_phase);
+    switch (resampler->format) {
+      case GST_AUDIO_FORMAT_F64:
+        PRINT_TAPS (gdouble, "f");
+        break;
+      case GST_AUDIO_FORMAT_F32:
+        PRINT_TAPS (gfloat, "f");
+        break;
+      case GST_AUDIO_FORMAT_S32:
+        PRINT_TAPS (gint32, "d");
+        break;
+      case GST_AUDIO_FORMAT_S16:
+        PRINT_TAPS (gint16, "d");
+        break;
+      default:
+        break;
+    }
+  }
+  fprintf (stderr, "time %" G_GUINT64_FORMAT "\n", g_get_monotonic_time () - a);
+#endif
+}
+
+/**
+ * gst_audio_resampler_options_set_quality:
+ * @method: a #GstAudioResamplerMethod
+ * @quality: the quality
+ * @in_rate: the input rate
+ * @out_rate: the output rate
+ * @options: a #GstStructure
+ *
+ * Set the parameters for resampling from @in_rate to @out_rate using @method
+ * for @quality in @options.
+ */
+void
+gst_audio_resampler_options_set_quality (GstAudioResamplerMethod method,
+    guint quality, gint in_rate, gint out_rate, GstStructure * options)
+{
+  g_return_if_fail (options != NULL);
+  g_return_if_fail (quality <= GST_AUDIO_RESAMPLER_QUALITY_MAX);
+  g_return_if_fail (in_rate > 0 && out_rate > 0);
+
+  switch (method) {
+    case GST_AUDIO_RESAMPLER_METHOD_NEAREST:
+      break;
+    case GST_AUDIO_RESAMPLER_METHOD_LINEAR:
+      gst_structure_set (options,
+          GST_AUDIO_RESAMPLER_OPT_N_TAPS, G_TYPE_INT, 2, NULL);
+      break;
+    case GST_AUDIO_RESAMPLER_METHOD_CUBIC:
+      gst_structure_set (options,
+          GST_AUDIO_RESAMPLER_OPT_N_TAPS, G_TYPE_INT, 4,
+          GST_AUDIO_RESAMPLER_OPT_CUBIC_B, G_TYPE_DOUBLE, DEFAULT_OPT_CUBIC_B,
+          GST_AUDIO_RESAMPLER_OPT_CUBIC_C, G_TYPE_DOUBLE, DEFAULT_OPT_CUBIC_C,
+          NULL);
+      break;
+    case GST_AUDIO_RESAMPLER_METHOD_BLACKMAN_NUTTALL:
+    {
+      const BlackmanQualityMap *map = &blackman_qualities[quality];
+      gst_structure_set (options,
+          GST_AUDIO_RESAMPLER_OPT_N_TAPS, G_TYPE_INT, map->n_taps,
+          GST_AUDIO_RESAMPLER_OPT_CUTOFF, G_TYPE_DOUBLE, map->cutoff, NULL);
+      break;
+    }
+    case GST_AUDIO_RESAMPLER_METHOD_KAISER:
+    {
+      const KaiserQualityMap *map = &kaiser_qualities[quality];
+      gdouble cutoff;
+
+      cutoff = map->cutoff;
+      if (out_rate < in_rate)
+        cutoff *= map->downsample_cutoff_factor;
+
+      gst_structure_set (options,
+          GST_AUDIO_RESAMPLER_OPT_CUTOFF, G_TYPE_DOUBLE, cutoff,
+          GST_AUDIO_RESAMPLER_OPT_STOP_ATTENUATION, G_TYPE_DOUBLE,
+          map->stopband_attenuation,
+          GST_AUDIO_RESAMPLER_OPT_TRANSITION_BANDWIDTH, G_TYPE_DOUBLE,
+          map->transition_bandwidth, NULL);
+      break;
+    }
+  }
+  gst_structure_set (options,
+      GST_AUDIO_RESAMPLER_OPT_FILTER_OVERSAMPLE, G_TYPE_INT,
+      oversample_qualities[quality], NULL);
+}
+
+/**
+ * gst_audio_resampler_new:
+ * @method: a #GstAudioResamplerMethod
+ * @flags: #GstAudioResamplerFlags
+ * @in_rate: input rate
+ * @out_rate: output rate
+ * @options: extra options
+ *
+ * Make a new resampler.
+ *
+ * Returns: (skip) (transfer full): %TRUE on success
+ */
+GstAudioResampler *
+gst_audio_resampler_new (GstAudioResamplerMethod method,
+    GstAudioResamplerFlags flags,
+    GstAudioFormat format, gint channels,
+    gint in_rate, gint out_rate, GstStructure * options)
+{
+  gboolean non_interleaved;
+  GstAudioResampler *resampler;
+  const GstAudioFormatInfo *info;
+  GstStructure *def_options = NULL;
+
+  g_return_val_if_fail (method >= GST_AUDIO_RESAMPLER_METHOD_NEAREST
+      && method <= GST_AUDIO_RESAMPLER_METHOD_KAISER, NULL);
+  g_return_val_if_fail (format == GST_AUDIO_FORMAT_S16 ||
+      format == GST_AUDIO_FORMAT_S32 || format == GST_AUDIO_FORMAT_F32 ||
+      format == GST_AUDIO_FORMAT_F64, NULL);
+  g_return_val_if_fail (channels > 0, NULL);
+  g_return_val_if_fail (in_rate > 0, NULL);
+  g_return_val_if_fail (out_rate > 0, NULL);
+
+  audio_resampler_init ();
+
+  resampler = g_slice_new0 (GstAudioResampler);
+  resampler->method = method;
+  resampler->flags = flags;
+  resampler->format = format;
+  resampler->channels = channels;
+
+  switch (format) {
+    case GST_AUDIO_FORMAT_S16:
+      resampler->format_index = 0;
+      break;
+    case GST_AUDIO_FORMAT_S32:
+      resampler->format_index = 1;
+      break;
+    case GST_AUDIO_FORMAT_F32:
+      resampler->format_index = 2;
+      break;
+    case GST_AUDIO_FORMAT_F64:
+      resampler->format_index = 3;
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+  }
+
+  info = gst_audio_format_get_info (format);
+  resampler->bps = GST_AUDIO_FORMAT_INFO_WIDTH (info) / 8;
+  resampler->sbuf = g_malloc0 (sizeof (gpointer) * channels);
+
+  non_interleaved =
+      (resampler->flags & GST_AUDIO_RESAMPLER_FLAG_NON_INTERLEAVED_OUT);
+
+  /* we resample each channel separately */
+  resampler->blocks = resampler->channels;
+  resampler->inc = 1;
+  resampler->ostride = non_interleaved ? 1 : resampler->channels;
+  resampler->deinterleave = deinterleave_funcs[resampler->format_index];
+  resampler->convert_taps = convert_taps_funcs[resampler->format_index];
+
+  GST_DEBUG ("method %d, bps %d, channels %d", method, resampler->bps,
+      resampler->channels);
+
+  if (options == NULL) {
+    options = def_options =
+        gst_structure_new_empty ("GstAudioResampler.options");
+    gst_audio_resampler_options_set_quality (DEFAULT_RESAMPLER_METHOD,
+        GST_AUDIO_RESAMPLER_QUALITY_DEFAULT, in_rate, out_rate, options);
+  }
+
+  gst_audio_resampler_update (resampler, in_rate, out_rate, options);
+  gst_audio_resampler_reset (resampler);
+
+  if (def_options)
+    gst_structure_free (def_options);
+
+  return resampler;
+}
+
+/* make the buffers to hold the (deinterleaved) samples */
+static inline gpointer *
+get_sample_bufs (GstAudioResampler * resampler, gsize need)
+{
+  if (G_LIKELY (resampler->samples_len < need)) {
+    gint c, blocks = resampler->blocks;
+    gsize bytes, to_move = 0;
+    gint8 *ptr, *samples;
+
+    GST_LOG ("realloc %d -> %d", (gint) resampler->samples_len, (gint) need);
+
+    bytes = GST_ROUND_UP_N (need * resampler->bps * resampler->inc, ALIGN);
+
+    samples = g_malloc0 (blocks * bytes + ALIGN - 1);
+    ptr = MEM_ALIGN (samples, ALIGN);
+
+    /* if we had some data, move history */
+    if (resampler->samples_len > 0)
+      to_move = resampler->samples_avail * resampler->bps * resampler->inc;
+
+    /* set up new pointers */
+    for (c = 0; c < blocks; c++) {
+      memcpy (ptr + (c * bytes), resampler->sbuf[c], to_move);
+      resampler->sbuf[c] = ptr + (c * bytes);
+    }
+    g_free (resampler->samples);
+    resampler->samples = samples;
+    resampler->samples_len = need;
+  }
+  return resampler->sbuf;
+}
+
+/**
+ * gst_audio_resampler_reset:
+ * @resampler: a #GstAudioResampler
+ *
+ * Reset @resampler to the state it was when it was first created, discarding
+ * all sample history.
+ */
+void
+gst_audio_resampler_reset (GstAudioResampler * resampler)
+{
+  g_return_if_fail (resampler != NULL);
+
+  if (resampler->samples) {
+    gsize bytes;
+    gint c, blocks, bpf;
+
+    bpf = resampler->bps * resampler->inc;
+    bytes = (resampler->n_taps / 2) * bpf;
+    blocks = resampler->blocks;
+
+    for (c = 0; c < blocks; c++)
+      memset (resampler->sbuf[c], 0, bytes);
+  }
+  /* half of the filter is filled with 0 */
+  resampler->samp_index = 0;
+  resampler->samples_avail = resampler->n_taps / 2 - 1;
+}
+
+/**
+ * gst_audio_resampler_update:
+ * @resampler: a #GstAudioResampler
+ * @in_rate: new input rate
+ * @out_rate: new output rate
+ * @options: new options or %NULL
+ *
+ * Update the resampler parameters for @resampler. This function should
+ * not be called concurrently with any other function on @resampler.
+ *
+ * When @in_rate or @out_rate is 0, its value is unchanged.
+ *
+ * When @options is %NULL, the previously configured options are reused.
+ *
+ * Returns: %TRUE if the new parameters could be set
+ */
+gboolean
+gst_audio_resampler_update (GstAudioResampler * resampler,
+    gint in_rate, gint out_rate, GstStructure * options)
+{
+  gint gcd, samp_phase, old_n_taps;
+  gdouble max_error;
+
+  g_return_val_if_fail (resampler != NULL, FALSE);
+
+  if (in_rate <= 0)
+    in_rate = resampler->in_rate;
+  if (out_rate <= 0)
+    out_rate = resampler->out_rate;
+
+  if (resampler->out_rate > 0) {
+    GST_INFO ("old phase %d/%d", resampler->samp_phase, resampler->out_rate);
+    samp_phase =
+        gst_util_uint64_scale_int (resampler->samp_phase, out_rate,
+        resampler->out_rate);
+  } else
+    samp_phase = 0;
+
+  gcd = gst_util_greatest_common_divisor (in_rate, out_rate);
+
+  max_error = GET_OPT_MAX_PHASE_ERROR (resampler->options);
+
+  if (max_error < 1.0e-8) {
+    GST_INFO ("using exact phase divider");
+    gcd = gst_util_greatest_common_divisor (gcd, samp_phase);
+  } else {
+    while (gcd > 1) {
+      gdouble ph1 = (gdouble) samp_phase / out_rate;
+      gint factor = 2;
+
+      /* reduce the factor until we have a phase error of less than 10% */
+      gdouble ph2 = (gdouble) (samp_phase / gcd) / (out_rate / gcd);
+
+      if (fabs (ph1 - ph2) < max_error)
+        break;
+
+      while (gcd % factor != 0)
+        factor++;
+      gcd /= factor;
+
+      GST_INFO ("divide by factor %d, gcd %d", factor, gcd);
+    }
+  }
+
+  GST_INFO ("phase %d out_rate %d, in_rate %d, gcd %d", samp_phase, out_rate,
+      in_rate, gcd);
+
+  resampler->samp_phase = samp_phase /= gcd;
+  resampler->in_rate = in_rate /= gcd;
+  resampler->out_rate = out_rate /= gcd;
+
+  GST_INFO ("new phase %d/%d", resampler->samp_phase, resampler->out_rate);
+
+  resampler->samp_inc = in_rate / out_rate;
+  resampler->samp_frac = in_rate % out_rate;
+
+  if (options) {
+    GST_INFO ("have new options, reconfigure filter");
+
+    if (resampler->options)
+      gst_structure_free (resampler->options);
+    resampler->options = gst_structure_copy (options);
+
+    old_n_taps = resampler->n_taps;
+
+    resampler_calculate_taps (resampler);
+    resampler_dump (resampler);
+
+    if (old_n_taps > 0 && old_n_taps != resampler->n_taps) {
+      gpointer *sbuf;
+      gint i, bpf, bytes, soff, doff, diff;
+
+      sbuf = get_sample_bufs (resampler, resampler->n_taps);
+
+      bpf = resampler->bps * resampler->inc;
+      bytes = resampler->samples_avail * bpf;
+      soff = doff = resampler->samp_index * bpf;
+
+      diff = ((gint) resampler->n_taps - old_n_taps) / 2;
+
+      GST_DEBUG ("taps %d->%d, %d", old_n_taps, resampler->n_taps, diff);
+
+      if (diff < 0) {
+        /* diff < 0, decrease taps, adjust source */
+        soff += -diff * bpf;
+        bytes -= -diff * bpf;
+      } else {
+        /* diff > 0, increase taps, adjust dest */
+        doff += diff * bpf;
+      }
+
+      /* now shrink or enlarge the history buffer, when we enlarge we
+       * just leave the old samples in there. FIXME, probably do something better
+       * like mirror or fill with zeroes. */
+      for (i = 0; i < resampler->blocks; i++)
+        memmove ((gint8 *) sbuf[i] + doff, (gint8 *) sbuf[i] + soff, bytes);
+
+      resampler->samples_avail += diff;
+    }
+  } else if (resampler->filter_mode == GST_AUDIO_RESAMPLER_FILTER_MODE_FULL) {
+    GST_DEBUG ("setting up filter cache");
+    resampler->n_phases = resampler->out_rate;
+    alloc_cache_mem (resampler, resampler->bps, resampler->n_taps,
+        resampler->n_phases);
+  }
+  setup_functions (resampler);
+
+  return TRUE;
+}
+
+/**
+ * gst_audio_resampler_free:
+ * @resampler: a #GstAudioResampler
+ *
+ * Free a previously allocated #GstAudioResampler @resampler.
+ *
+ * Since: 1.6
+ */
+void
+gst_audio_resampler_free (GstAudioResampler * resampler)
+{
+  g_return_if_fail (resampler != NULL);
+
+  g_free (resampler->cached_taps_mem);
+  g_free (resampler->taps_mem);
+  g_free (resampler->tmp_taps);
+  g_free (resampler->samples);
+  g_free (resampler->sbuf);
+  if (resampler->options)
+    gst_structure_free (resampler->options);
+  g_slice_free (GstAudioResampler, resampler);
+}
+
+/**
+ * gst_audio_resampler_get_out_frames:
+ * @resampler: a #GstAudioResampler
+ * @in_frames: number of input frames
+ *
+ * Get the number of output frames that would be currently available when
+ * @in_frames are given to @resampler.
+ *
+ * Returns: The number of frames that would be availabe after giving
+ * @in_frames as input to @resampler.
+ */
+gsize
+gst_audio_resampler_get_out_frames (GstAudioResampler * resampler,
+    gsize in_frames)
+{
+  gsize need, avail, out;
+
+  g_return_val_if_fail (resampler != NULL, 0);
+
+  need = resampler->n_taps + resampler->samp_index + resampler->skip;
+  avail = resampler->samples_avail + in_frames;
+  GST_LOG ("need %d = %d + %d + %d, avail %d = %d + %d", (gint) need,
+      resampler->n_taps, resampler->samp_index, resampler->skip,
+      (gint) avail, (gint) resampler->samples_avail, (gint) in_frames);
+  if (avail < need)
+    return 0;
+
+  out = (avail - need) * resampler->out_rate;
+  if (out < resampler->samp_phase)
+    return 0;
+
+  out = ((out - resampler->samp_phase) / resampler->in_rate) + 1;
+  GST_LOG ("out %d = ((%d * %d - %d) / %d) + 1", (gint) out,
+      (gint) (avail - need), resampler->out_rate, resampler->samp_phase,
+      resampler->in_rate);
+
+  return out;
+}
+
+/**
+ * gst_audio_resampler_get_in_frames:
+ * @resampler: a #GstAudioResampler
+ * @out_frames: number of input frames
+ *
+ * Get the number of input frames that would currently be needed
+ * to produce @out_frames from @resampler.
+ *
+ * Returns: The number of input frames needed for producing
+ * @out_frames of data from @resampler.
+ */
+gsize
+gst_audio_resampler_get_in_frames (GstAudioResampler * resampler,
+    gsize out_frames)
+{
+  gsize in_frames;
+
+  g_return_val_if_fail (resampler != NULL, 0);
+
+  in_frames =
+      (resampler->samp_phase +
+      out_frames * resampler->samp_frac) / resampler->out_rate;
+  in_frames += out_frames * resampler->samp_inc;
+
+  return in_frames;
+}
+
+/**
+ * gst_audio_resampler_get_max_latency:
+ * @resampler: a #GstAudioResampler
+ *
+ * Get the maximum number of input samples that the resampler would
+ * need before producing output.
+ *
+ * Returns: the latency of @resampler as expressed in the number of
+ * frames.
+ */
+gsize
+gst_audio_resampler_get_max_latency (GstAudioResampler * resampler)
+{
+  g_return_val_if_fail (resampler != NULL, 0);
+
+  return resampler->n_taps / 2;
+}
+
+/**
+ * gst_audio_resampler_resample:
+ * @resampler: a #GstAudioResampler
+ * @in: input samples
+ * @in_frames: number of input frames
+ * @out: output samples
+ * @out_frames: number of output frames
+ *
+ * Perform resampling on @in_frames frames in @in and write @out_frames to @out.
+ *
+ * In case the samples are interleaved, @in and @out must point to an
+ * array with a single element pointing to a block of interleaved samples.
+ *
+ * If non-interleaved samples are used, @in and @out must point to an
+ * array with pointers to memory blocks, one for each channel.
+ *
+ * @in may be %NULL, in which case @in_frames of silence samples are pushed
+ * into the resampler.
+ *
+ * This function always produces @out_frames of output and consumes @in_frames of
+ * input. Use gst_audio_resampler_get_out_frames() and
+ * gst_audio_resampler_get_in_frames() to make sure @in_frames and @out_frames
+ * are matching and @in and @out point to enough memory.
+ */
+void
+gst_audio_resampler_resample (GstAudioResampler * resampler,
+    gpointer in[], gsize in_frames, gpointer out[], gsize out_frames)
+{
+  gsize samples_avail;
+  gsize need, consumed;
+  gpointer *sbuf;
+
+  /* do sample skipping */
+  if (G_UNLIKELY (resampler->skip >= in_frames)) {
+    /* we need tp skip all input */
+    resampler->skip -= in_frames;
+    return;
+  }
+  /* skip the last samples by advancing the sample index */
+  resampler->samp_index += resampler->skip;
+
+  samples_avail = resampler->samples_avail;
+
+  /* make sure we have enough space to copy our samples */
+  sbuf = get_sample_bufs (resampler, in_frames + samples_avail);
+
+  /* copy/deinterleave the samples */
+  resampler->deinterleave (resampler, sbuf, in, in_frames);
+
+  /* update new amount of samples in our buffer */
+  resampler->samples_avail = samples_avail += in_frames;
+
+  need = resampler->n_taps + resampler->samp_index;
+  if (G_UNLIKELY (samples_avail < need)) {
+    /* not enough samples to start */
+    return;
+  }
+
+  /* resample all channels */
+  resampler->resample (resampler, sbuf, samples_avail, out, out_frames,
+      &consumed);
+
+  GST_LOG ("in %" G_GSIZE_FORMAT ", avail %" G_GSIZE_FORMAT ", consumed %"
+      G_GSIZE_FORMAT, in_frames, samples_avail, consumed);
+
+  /* update pointers */
+  if (G_LIKELY (consumed > 0)) {
+    gssize left = samples_avail - consumed;
+    if (left > 0) {
+      /* we consumed part of our samples */
+      resampler->samples_avail = left;
+    } else {
+      /* we consumed all our samples, empty our buffers */
+      resampler->samples_avail = 0;
+      resampler->skip = -left;
+    }
+  }
+}
diff --git a/gst-libs/gst/audio/audio-resampler.h b/gst-libs/gst/audio/audio-resampler.h
new file mode 100644
index 0000000..1664e68
--- /dev/null
+++ b/gst-libs/gst/audio/audio-resampler.h
@@ -0,0 +1,235 @@
+/* GStreamer
+ * Copyright (C) <2015> Wim Taymans <wim.taymans@gmail.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.
+ */
+
+#ifndef __GST_AUDIO_RESAMPLER_H__
+#define __GST_AUDIO_RESAMPLER_H__
+
+#include <gst/gst.h>
+#include <gst/audio/audio.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GstAudioResampler GstAudioResampler;
+
+/**
+ * GST_AUDIO_RESAMPLER_OPT_CUTOFF
+ *
+ * G_TYPE_DOUBLE, Cutoff parameter for the filter. 0.940 is the default.
+ */
+#define GST_AUDIO_RESAMPLER_OPT_CUTOFF      "GstAudioResampler.cutoff"
+/**
+ * GST_AUDIO_RESAMPLER_OPT_STOP_ATTENUTATION
+ *
+ * G_TYPE_DOUBLE, stopband attenuation in debibels. The attenutation
+ * after the stopband for the kaiser window. 85 dB is the default.
+ */
+#define GST_AUDIO_RESAMPLER_OPT_STOP_ATTENUATION "GstAudioResampler.stop-attenutation"
+/**
+ * GST_AUDIO_RESAMPLER_OPT_TRANSITION_BANDWIDTH
+ *
+ * G_TYPE_DOUBLE, transition bandwidth. The width of the
+ * transition band for the kaiser window. 0.087 is the default.
+ */
+#define GST_AUDIO_RESAMPLER_OPT_TRANSITION_BANDWIDTH "GstAudioResampler.transition-bandwidth"
+
+/**
+ * GST_AUDIO_RESAMPLER_OPT_CUBIC_B:
+ *
+ * G_TYPE_DOUBLE, B parameter of the cubic filter.
+ * Values between 0.0 and 2.0 are accepted. 1.0 is the default.
+ *
+ * Below are some values of popular filters:
+ *                    B       C
+ * Hermite           0.0     0.0
+ * Spline            1.0     0.0
+ * Catmull-Rom       0.0     1/2
+ */
+#define GST_AUDIO_RESAMPLER_OPT_CUBIC_B      "GstAudioResampler.cubic-b"
+/**
+ * GST_AUDIO_RESAMPLER_OPT_CUBIC_C:
+ *
+ * G_TYPE_DOUBLE, C parameter of the cubic filter.
+ * Values between 0.0 and 2.0 are accepted. 0.0 is the default.
+ *
+ * See #GST_AUDIO_RESAMPLER_OPT_CUBIC_B for some more common values
+ */
+#define GST_AUDIO_RESAMPLER_OPT_CUBIC_C      "GstAudioResampler.cubic-c"
+
+/**
+ * GST_AUDIO_RESAMPLER_OPT_N_TAPS:
+ *
+ * G_TYPE_INT: the number of taps to use for the filter.
+ * 0 is the default and selects the taps automatically.
+ */
+#define GST_AUDIO_RESAMPLER_OPT_N_TAPS      "GstAudioResampler.n-taps"
+
+/**
+ * GstAudioResamplerFilterMode:
+ * @GST_AUDIO_RESAMPLER_FILTER_MODE_INTERPOLATED: Use interpolated filter tables. This
+ *     uses less memory but more CPU and is slightly less accurate but it allows for more
+ *     efficient variable rate resampling with gst_audio_resampler_update().
+ * @GST_AUDIO_RESAMPLER_FILTER_MODE_FULL: Use full filter table. This uses more memory
+ *     but less CPU.
+ * @GST_AUDIO_RESAMPLER_FILTER_MODE_AUTO: Automatically choose between interpolated
+ *     and full filter tables.
+ *
+ * Select for the filter tables should be set up.
+ */
+typedef enum {
+  GST_AUDIO_RESAMPLER_FILTER_MODE_INTERPOLATED = (0),
+  GST_AUDIO_RESAMPLER_FILTER_MODE_FULL,
+  GST_AUDIO_RESAMPLER_FILTER_MODE_AUTO,
+} GstAudioResamplerFilterMode;
+/**
+ * GST_AUDIO_RESAMPLER_OPT_FILTER_MODE:
+ *
+ * GST_TYPE_AUDIO_RESAMPLER_FILTER_MODE: how the filter tables should be
+ * constructed.
+ * GST_AUDIO_RESAMPLER_FILTER_MODE_AUTO is the default.
+ */
+#define GST_AUDIO_RESAMPLER_OPT_FILTER_MODE      "GstAudioResampler.filter-mode"
+/**
+ * GST_AUDIO_RESAMPLER_OPT_FILTER_MODE_THRESHOLD:
+ *
+ * G_TYPE_UINT: the amount of memory to use for full filter tables before
+ * switching to interpolated filter tables.
+ * 1048576 is the default.
+ */
+#define GST_AUDIO_RESAMPLER_OPT_FILTER_MODE_THRESHOLD "GstAudioResampler.filter-mode-threshold"
+
+/**
+ * GstAudioResamplerFilterInterpolation:
+ * @GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_NONE: no interpolation
+ * @GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_LINEAR: linear interpolation of the
+ *   filter coeficients.
+ * @GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_CUBIC: cubic interpolation of the
+ *   filter coeficients.
+ *
+ * The different filter interpolation methods.
+ */
+typedef enum {
+  GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_NONE = (0),
+  GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_LINEAR,
+  GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_CUBIC,
+} GstAudioResamplerFilterInterpolation;
+/**
+ * GST_AUDIO_RESAMPLER_OPT_FILTER_INTERPOLATION:
+ *
+ * GST_TYPE_AUDIO_RESAMPLER_INTERPOLATION: how the filter coeficients should be
+ *    interpolated.
+ * GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_CUBIC is default.
+ */
+#define GST_AUDIO_RESAMPLER_OPT_FILTER_INTERPOLATION "GstAudioResampler.filter-interpolation"
+/**
+ * GST_AUDIO_RESAMPLER_OPT_FILTER_OVERSAMPLE
+ *
+ * G_TYPE_UINT, oversampling to use when interpolating filters
+ * 8 is the default.
+ */
+#define GST_AUDIO_RESAMPLER_OPT_FILTER_OVERSAMPLE "GstAudioResampler.filter-oversample"
+
+/**
+ * GST_AUDIO_RESAMPLER_OPT_MAX_PHASE_ERROR:
+ *
+ * G_TYPE_DOUBLE: The maximum allowed phase error when switching sample
+ * rates.
+ * 0.1 is the default.
+ */
+#define GST_AUDIO_RESAMPLER_OPT_MAX_PHASE_ERROR "GstAudioResampler.max-phase-error"
+
+/**
+ * GstAudioResamplerMethod:
+ * @GST_AUDIO_RESAMPLER_METHOD_NEAREST: Duplicates the samples when
+ *    upsampling and drops when downsampling
+ * @GST_AUDIO_RESAMPLER_METHOD_LINEAR: Uses linear interpolation to reconstruct
+ *    missing samples and averaging to downsample
+ * @GST_AUDIO_RESAMPLER_METHOD_CUBIC: Uses cubic interpolation
+ * @GST_AUDIO_RESAMPLER_METHOD_BLACKMAN_NUTTALL: Uses Blackman-Nuttall windowed sinc interpolation
+ * @GST_AUDIO_RESAMPLER_METHOD_KAISER: Uses Kaiser windowed sinc interpolation
+ *
+ * Different subsampling and upsampling methods
+ *
+ * Since: 1.6
+ */
+typedef enum {
+  GST_AUDIO_RESAMPLER_METHOD_NEAREST,
+  GST_AUDIO_RESAMPLER_METHOD_LINEAR,
+  GST_AUDIO_RESAMPLER_METHOD_CUBIC,
+  GST_AUDIO_RESAMPLER_METHOD_BLACKMAN_NUTTALL,
+  GST_AUDIO_RESAMPLER_METHOD_KAISER
+} GstAudioResamplerMethod;
+
+/**
+ * GstAudioResamplerFlags:
+ * @GST_AUDIO_RESAMPLER_FLAG_NONE: no flags
+ * @GST_AUDIO_RESAMPLER_FLAG_NON_INTERLEAVED_IN: input samples are non-interleaved.
+ *    an array of blocks of samples, one for each channel, should be passed to the
+ *    resample function.
+ * @GST_AUDIO_RESAMPLER_FLAG_NON_INTERLEAVED_OUT: output samples are non-interleaved.
+ *    an array of blocks of samples, one for each channel, should be passed to the
+ *    resample function.
+ * @GST_AUDIO_RESAMPLER_FLAG_VARIABLE_RATE: optimize for dynamic updates of the sample
+ *    rates with gst_audio_resampler_update(). This will select an interpolating filter
+ *    when #GST_AUDIO_RESAMPLER_FILTER_MODE_AUTO is configured.
+ *
+ * Different resampler flags.
+ */
+typedef enum {
+  GST_AUDIO_RESAMPLER_FLAG_NONE                 = (0),
+  GST_AUDIO_RESAMPLER_FLAG_NON_INTERLEAVED_IN   = (1 << 0),
+  GST_AUDIO_RESAMPLER_FLAG_NON_INTERLEAVED_OUT  = (1 << 1),
+  GST_AUDIO_RESAMPLER_FLAG_VARIABLE_RATE        = (1 << 2),
+} GstAudioResamplerFlags;
+
+#define GST_AUDIO_RESAMPLER_QUALITY_MIN 0
+#define GST_AUDIO_RESAMPLER_QUALITY_MAX 10
+#define GST_AUDIO_RESAMPLER_QUALITY_DEFAULT 4
+
+void           gst_audio_resampler_options_set_quality   (GstAudioResamplerMethod method,
+                                                          guint quality,
+                                                          gint in_rate, gint out_rate,
+                                                          GstStructure *options);
+
+GstAudioResampler * gst_audio_resampler_new              (GstAudioResamplerMethod method,
+                                                          GstAudioResamplerFlags flags,
+                                                          GstAudioFormat format, gint channels,
+                                                          gint in_rate, gint out_rate,
+                                                          GstStructure *options);
+void                gst_audio_resampler_free             (GstAudioResampler *resampler);
+
+void                gst_audio_resampler_reset            (GstAudioResampler *resampler);
+
+gboolean            gst_audio_resampler_update           (GstAudioResampler *resampler,
+                                                          gint in_rate, gint out_rate,
+                                                          GstStructure *options);
+
+gsize               gst_audio_resampler_get_out_frames   (GstAudioResampler *resampler,
+                                                          gsize in_frames);
+gsize               gst_audio_resampler_get_in_frames    (GstAudioResampler *resampler,
+                                                          gsize out_frames);
+
+gsize               gst_audio_resampler_get_max_latency  (GstAudioResampler *resampler);
+
+void                gst_audio_resampler_resample         (GstAudioResampler * resampler,
+                                                          gpointer in[], gsize in_frames,
+                                                          gpointer out[], gsize out_frames);
+
+G_END_DECLS
+
+#endif /* __GST_AUDIO_RESAMPLER_H__ */
diff --git a/gst-libs/gst/audio/audio.c b/gst-libs/gst/audio/audio.c
index 5f3556f..a005e45 100644
--- a/gst-libs/gst/audio/audio.c
+++ b/gst-libs/gst/audio/audio.c
@@ -75,8 +75,8 @@
  * is not clipped
  */
 GstBuffer *
-gst_audio_buffer_clip (GstBuffer * buffer, GstSegment * segment, gint rate,
-    gint bpf)
+gst_audio_buffer_clip (GstBuffer * buffer, const GstSegment * segment,
+    gint rate, gint bpf)
 {
   GstBuffer *ret;
   GstClockTime timestamp = GST_CLOCK_TIME_NONE, duration = GST_CLOCK_TIME_NONE;
diff --git a/gst-libs/gst/audio/audio.h b/gst-libs/gst/audio/audio.h
index 0aa83bd..ac45b2e 100644
--- a/gst-libs/gst/audio/audio.h
+++ b/gst-libs/gst/audio/audio.h
@@ -30,6 +30,7 @@
 #include <gst/audio/audio-info.h>
 #include <gst/audio/audio-quantize.h>
 #include <gst/audio/audio-converter.h>
+#include <gst/audio/audio-resampler.h>
 
 G_BEGIN_DECLS
 
@@ -87,7 +88,8 @@
  * handling
  */
 
-GstBuffer *    gst_audio_buffer_clip     (GstBuffer *buffer, GstSegment *segment,
+GstBuffer *    gst_audio_buffer_clip     (GstBuffer *buffer,
+                                          const GstSegment *segment,
                                           gint rate, gint bpf);
 
 
diff --git a/gst-libs/gst/audio/dbesi0.c b/gst-libs/gst/audio/dbesi0.c
new file mode 100644
index 0000000..958eba7
--- /dev/null
+++ b/gst-libs/gst/audio/dbesi0.c
@@ -0,0 +1,147 @@
+/*  Copyright(C) 1996 Takuya OOURA
+
+You may use, copy, modify this code for any purpose and
+without fee.
+
+Package home:  http://www.kurims.kyoto-u.ac.jp/~ooura/bessel.html
+*/
+
+/* Bessel I_0(x) function in double precision */
+
+#include <math.h>
+
+static double
+dbesi0 (double x)
+{
+  int k;
+  double w, t, y;
+  static double a[65] = {
+    8.5246820682016865877e-11, 2.5966600546497407288e-9,
+    7.9689994568640180274e-8, 1.9906710409667748239e-6,
+    4.0312469446528002532e-5, 6.4499871606224265421e-4,
+    0.0079012345761930579108, 0.071111111109207045212,
+    0.444444444444724909, 1.7777777777777532045,
+    4.0000000000000011182, 3.99999999999999998,
+    1.0000000000000000001,
+    1.1520919130377195927e-10, 2.2287613013610985225e-9,
+    8.1903951930694585113e-8, 1.9821560631611544984e-6,
+    4.0335461940910133184e-5, 6.4495330974432203401e-4,
+    0.0079013012611467520626, 0.071111038160875566622,
+    0.44444450319062699316, 1.7777777439146450067,
+    4.0000000132337935071, 3.9999999968569015366,
+    1.0000000003426703174,
+    1.5476870780515238488e-10, 1.2685004214732975355e-9,
+    9.2776861851114223267e-8, 1.9063070109379044378e-6,
+    4.0698004389917945832e-5, 6.4370447244298070713e-4,
+    0.0079044749458444976958, 0.071105052411749363882,
+    0.44445280640924755082, 1.7777694934432109713,
+    4.0000055808824003386, 3.9999977081165740932,
+    1.0000004333949319118,
+    2.0675200625006793075e-10, -6.1689554705125681442e-10,
+    1.2436765915401571654e-7, 1.5830429403520613423e-6,
+    4.2947227560776583326e-5, 6.3249861665073441312e-4,
+    0.0079454472840953930811, 0.070994327785661860575,
+    0.44467219586283000332, 1.7774588182255374745,
+    4.0003038986252717972, 3.9998233869142057195,
+    1.0000472932961288324,
+    2.7475684794982708655e-10, -3.8991472076521332023e-9,
+    1.9730170483976049388e-7, 5.9651531561967674521e-7,
+    5.1992971474748995357e-5, 5.7327338675433770752e-4,
+    0.0082293143836530412024, 0.069990934858728039037,
+    0.44726764292723985087, 1.7726685170014087784,
+    4.0062907863712704432, 3.9952750700487845355,
+    1.0016354346654179322
+  };
+  static double b[70] = {
+    6.7852367144945531383e-8, 4.6266061382821826854e-7,
+    6.9703135812354071774e-6, 7.6637663462953234134e-5,
+    7.9113515222612691636e-4, 0.0073401204731103808981,
+    0.060677114958668837046, 0.43994941411651569622,
+    2.7420017097661750609, 14.289661921740860534,
+    59.820609640320710779, 188.78998681199150629,
+    399.8731367825601118, 427.56411572180478514,
+    1.8042097874891098754e-7, 1.2277164312044637357e-6,
+    1.8484393221474274861e-5, 2.0293995900091309208e-4,
+    0.0020918539850246207459, 0.019375315654033949297,
+    0.15985869016767185908, 1.1565260527420641724,
+    7.1896341224206072113, 37.354773811947484532,
+    155.80993164266268457, 489.5211371158540918,
+    1030.9147225169564806, 1093.5883545113746958,
+    4.8017305613187493564e-7, 3.261317843912380074e-6,
+    4.9073137508166159639e-5, 5.3806506676487583755e-4,
+    0.0055387918291051866561, 0.051223717488786549025,
+    0.42190298621367914765, 3.0463625987357355872,
+    18.895299447327733204, 97.915189029455461554,
+    407.13940115493494659, 1274.3088990480582632,
+    2670.9883037012547506, 2815.7166284662544712,
+    1.2789926338424623394e-6, 8.6718263067604918916e-6,
+    1.3041508821299929489e-4, 0.001428224737372747892,
+    0.014684070635768789378, 0.13561403190404185755,
+    1.1152592585977393953, 8.0387088559465389038,
+    49.761318895895479206, 257.2684232313529138,
+    1066.8543146269566231, 3328.3874581009636362,
+    6948.8586598121634874, 7288.4893398212481055,
+    3.409350368197032893e-6, 2.3079025203103376076e-5,
+    3.4691373283901830239e-4, 0.003794994977222908545,
+    0.038974209677945602145, 0.3594948380414878371,
+    2.9522878893539528226, 21.246564609514287056,
+    131.28727387146173141, 677.38107093296675421,
+    2802.3724744545046518, 8718.5731420798254081,
+    18141.348781638832286, 18948.925349296308859
+  };
+  static double c[45] = {
+    2.5568678676452702768e-15, 3.0393953792305924324e-14,
+    6.3343751991094840009e-13, 1.5041298011833009649e-11,
+    4.4569436918556541414e-10, 1.746393051427167951e-8,
+    1.0059224011079852317e-6, 1.0729838945088577089e-4,
+    0.05150322693642527738,
+    5.2527963991711562216e-15, 7.202118481421005641e-15,
+    7.2561421229904797156e-13, 1.482312146673104251e-11,
+    4.4602670450376245434e-10, 1.7463600061788679671e-8,
+    1.005922609132234756e-6, 1.0729838937545111487e-4,
+    0.051503226936437300716,
+    1.3365917359358069908e-14, -1.2932643065888544835e-13,
+    1.7450199447905602915e-12, 1.0419051209056979788e-11,
+    4.58047881980598326e-10, 1.7442405450073548966e-8,
+    1.0059461453281292278e-6, 1.0729837434500161228e-4,
+    0.051503226940658446941,
+    5.3771611477352308649e-14, -1.1396193006413731702e-12,
+    1.2858641335221653409e-11, -5.9802086004570057703e-11,
+    7.3666894305929510222e-10, 1.6731837150730356448e-8,
+    1.0070831435812128922e-6, 1.0729733111203704813e-4,
+    0.051503227360726294675,
+    3.7819492084858931093e-14, -4.8600496888588034879e-13,
+    1.6898350504817224909e-12, 4.5884624327524255865e-11,
+    1.2521615963377513729e-10, 1.8959658437754727957e-8,
+    1.0020716710561353622e-6, 1.073037119856927559e-4,
+    0.05150322383300230775
+  };
+
+  w = fabs (x);
+  if (w < 8.5) {
+    t = w * w * 0.0625;
+    k = 13 * ((int) t);
+    y = (((((((((((a[k] * t + a[k + 1]) * t +
+                                            a[k + 2]) * t + a[k + 3]) * t +
+                                    a[k + 4]) * t + a[k + 5]) * t + a[k +
+                                6]) * t + a[k + 7]) * t + a[k + 8]) * t + a[k +
+                    9]) * t + a[k + 10]) * t + a[k + 11]) * t + a[k + 12];
+  } else if (w < 12.5) {
+    k = (int) w;
+    t = w - k;
+    k = 14 * (k - 8);
+    y = ((((((((((((b[k] * t + b[k + 1]) * t + b[k + 2]) * t + b[k + 3]) * t +
+                                        b[k + 4]) * t + b[k + 5]) * t + b[k +
+                                    6]) * t + b[k + 7]) * t + b[k + 8]) * t +
+                    b[k + 9]) * t + b[k + 10]) * t + b[k + 11]) * t + b[k +
+            12]) * t + b[k + 13];
+  } else {
+    t = 60 / w;
+    k = 9 * ((int) t);
+    y = ((((((((c[k] * t + c[k + 1]) * t +
+                                c[k + 2]) * t + c[k + 3]) * t + c[k + 4]) * t +
+                    c[k + 5]) * t + c[k + 6]) * t + c[k + 7]) * t +
+        c[k + 8]) * sqrt (t) * exp (w);
+  }
+  return y;
+}
diff --git a/gst-libs/gst/audio/gstaudiocdsrc.c b/gst-libs/gst/audio/gstaudiocdsrc.c
index 5c4a056..79b7423 100644
--- a/gst-libs/gst/audio/gstaudiocdsrc.c
+++ b/gst-libs/gst/audio/gstaudiocdsrc.c
@@ -291,8 +291,8 @@
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 #endif
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_audio_cd_src_src_template));
+  gst_element_class_add_static_pad_template (element_class,
+      &gst_audio_cd_src_src_template);
 
 #if 0
   element_class->set_index = GST_DEBUG_FUNCPTR (gst_audio_cd_src_set_index);
diff --git a/gst-libs/gst/audio/gstaudioclock.c b/gst-libs/gst/audio/gstaudioclock.c
index 9d37ad2..edd9a32 100644
--- a/gst-libs/gst/audio/gstaudioclock.c
+++ b/gst-libs/gst/audio/gstaudioclock.c
@@ -136,8 +136,8 @@
   clock->time_offset = time_offset;
 
   GST_DEBUG_OBJECT (clock,
-      "reset clock to %" GST_TIME_FORMAT ", last %" GST_STIME_FORMAT
-      ", offset %" GST_TIME_FORMAT, GST_TIME_ARGS (time),
+      "reset clock to %" GST_TIME_FORMAT ", last %" GST_TIME_FORMAT
+      ", offset %" GST_STIME_FORMAT, GST_TIME_ARGS (time),
       GST_TIME_ARGS (clock->last_time), GST_STIME_ARGS (time_offset));
 }
 
diff --git a/gst-libs/gst/audio/gstaudiodecoder.c b/gst-libs/gst/audio/gstaudiodecoder.c
index 8c43cbb..e583e2f 100644
--- a/gst-libs/gst/audio/gstaudiodecoder.c
+++ b/gst-libs/gst/audio/gstaudiodecoder.c
@@ -203,6 +203,7 @@
   gboolean do_plc;
   gboolean do_estimate_rate;
   gint max_errors;
+  GstCaps *allocation_caps;
   /* MT-protected (with LOCK) */
   GstClockTime min_latency;
   GstClockTime max_latency;
@@ -241,6 +242,8 @@
   gboolean force;
   /* input_segment are output_segment identical */
   gboolean in_out_segment_sync;
+  /* expecting the buffer with DISCONT flag */
+  gboolean expecting_discont_buf;
 
 
   /* input bps estimatation */
@@ -528,6 +531,7 @@
 
     GST_OBJECT_LOCK (dec);
     gst_caps_replace (&dec->priv->ctx.input_caps, NULL);
+    gst_caps_replace (&dec->priv->ctx.allocation_caps, NULL);
 
     memset (&dec->priv->ctx, 0, sizeof (dec->priv->ctx));
 
@@ -643,6 +647,8 @@
   klass = GST_AUDIO_DECODER_GET_CLASS (dec);
 
   caps = gst_audio_info_to_caps (&dec->priv->ctx.info);
+  if (dec->priv->ctx.allocation_caps == NULL)
+    dec->priv->ctx.allocation_caps = gst_caps_ref (caps);
 
   GST_DEBUG_OBJECT (dec, "setting src caps %" GST_PTR_FORMAT, caps);
 
@@ -677,7 +683,7 @@
     goto done;
   dec->priv->ctx.output_format_changed = FALSE;
 
-  query = gst_query_new_allocation (caps, TRUE);
+  query = gst_query_new_allocation (dec->priv->ctx.allocation_caps, TRUE);
   if (!gst_pad_peer_query (dec->srcpad, query)) {
     GST_DEBUG_OBJECT (dec, "didn't get downstream ALLOCATION hints");
   }
@@ -1893,9 +1899,6 @@
 
   dec = GST_AUDIO_DECODER (parent);
 
-  if (G_UNLIKELY (!gst_pad_has_current_caps (pad) && dec->priv->needs_format))
-    goto not_negotiated;
-
   GST_LOG_OBJECT (dec,
       "received buffer of size %" G_GSIZE_FORMAT " with ts %" GST_TIME_FORMAT
       ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buffer),
@@ -1904,9 +1907,13 @@
 
   GST_AUDIO_DECODER_STREAM_LOCK (dec);
 
+  if (G_UNLIKELY (dec->priv->ctx.input_caps == NULL && dec->priv->needs_format))
+    goto not_negotiated;
+
   dec->priv->ctx.had_input_data = TRUE;
 
-  if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
+  if (!dec->priv->expecting_discont_buf &&
+      GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
     gint64 samples, ts;
 
     /* track present position */
@@ -1927,6 +1934,7 @@
       dec->priv->samples = samples;
     }
   }
+  dec->priv->expecting_discont_buf = FALSE;
 
   if (dec->input_segment.rate > 0.0)
     ret = gst_audio_decoder_chain_forward (dec, buffer);
@@ -1940,6 +1948,7 @@
   /* ERRORS */
 not_negotiated:
   {
+    GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
     GST_ELEMENT_ERROR (dec, CORE, NEGOTIATION, (NULL),
         ("decoder not initialized"));
     gst_buffer_unref (buffer);
@@ -2119,6 +2128,7 @@
     /* best effort, not much error handling */
     gst_audio_decoder_handle_frame (dec, klass, buf);
     ret = TRUE;
+    dec->priv->expecting_discont_buf = TRUE;
     gst_event_unref (event);
   } else {
     GstFlowReturn flowret;
@@ -3229,6 +3239,27 @@
 }
 
 /**
+ * gst_audio_decoder_set_allocation_caps:
+ * @dec: a #GstAudioDecoder
+ * @allocation_caps: (allow-none): a #GstCaps or %NULL
+ *
+ * Sets a caps in allocation query which are different from the set
+ * pad's caps. Use this function before calling
+ * gst_audio_decoder_negotiate(). Setting to %NULL the allocation
+ * query will use the caps from the pad.
+ *
+ * Since: 1.10
+ */
+void
+gst_audio_decoder_set_allocation_caps (GstAudioDecoder * dec,
+    GstCaps * allocation_caps)
+{
+  g_return_if_fail (GST_IS_AUDIO_DECODER (dec));
+
+  gst_caps_replace (&dec->priv->ctx.allocation_caps, allocation_caps);
+}
+
+/**
  * gst_audio_decoder_set_plc:
  * @dec: a #GstAudioDecoder
  * @enabled: new state
diff --git a/gst-libs/gst/audio/gstaudiodecoder.h b/gst-libs/gst/audio/gstaudiodecoder.h
index f364161..71e0ce7 100644
--- a/gst-libs/gst/audio/gstaudiodecoder.h
+++ b/gst-libs/gst/audio/gstaudiodecoder.h
@@ -360,6 +360,8 @@
                                                      gboolean        * sync,
                                                      gboolean        * eos);
 
+void              gst_audio_decoder_set_allocation_caps (GstAudioDecoder * dec,
+                                                         GstCaps         * allocation_caps);
 
 /* object properties */
 void              gst_audio_decoder_set_plc (GstAudioDecoder * dec,
diff --git a/gst-libs/gst/audio/gstaudioencoder.c b/gst-libs/gst/audio/gstaudioencoder.c
index 546c822..6b6d9ad 100644
--- a/gst-libs/gst/audio/gstaudioencoder.c
+++ b/gst-libs/gst/audio/gstaudioencoder.c
@@ -194,6 +194,7 @@
 
   /* output */
   GstCaps *caps;
+  GstCaps *allocation_caps;
   gboolean output_caps_changed;
   gint frame_samples_min, frame_samples_max;
   gint frame_max;
@@ -495,6 +496,7 @@
     GST_OBJECT_LOCK (enc);
     gst_caps_replace (&enc->priv->ctx.input_caps, NULL);
     gst_caps_replace (&enc->priv->ctx.caps, NULL);
+    gst_caps_replace (&enc->priv->ctx.allocation_caps, NULL);
 
     memset (&enc->priv->ctx, 0, sizeof (enc->priv->ctx));
     gst_audio_info_init (&enc->priv->ctx.info);
@@ -2334,6 +2336,27 @@
 }
 
 /**
+ * gst_audio_encoder_set_allocation_caps:
+ * @enc: a #GstAudioEncoder
+ * @allocation_caps: (allow-none): a #GstCaps or %NULL
+ *
+ * Sets a caps in allocation query which are different from the set
+ * pad's caps. Use this function before calling
+ * gst_audio_encoder_negotiate(). Setting to %NULL the allocation
+ * query will use the caps from the pad.
+ *
+ * Since: 1.10
+ */
+void
+gst_audio_encoder_set_allocation_caps (GstAudioEncoder * enc,
+    GstCaps * allocation_caps)
+{
+  g_return_if_fail (GST_IS_AUDIO_ENCODER (enc));
+
+  gst_caps_replace (&enc->priv->ctx.allocation_caps, allocation_caps);
+}
+
+/**
  * gst_audio_encoder_set_mark_granule:
  * @enc: a #GstAudioEncoder
  * @enabled: new state
@@ -2664,6 +2687,8 @@
   klass = GST_AUDIO_ENCODER_GET_CLASS (enc);
 
   caps = enc->priv->ctx.caps;
+  if (enc->priv->ctx.allocation_caps == NULL)
+    enc->priv->ctx.allocation_caps = gst_caps_ref (caps);
 
   GST_DEBUG_OBJECT (enc, "Setting srcpad caps %" GST_PTR_FORMAT, caps);
 
@@ -2698,7 +2723,7 @@
     goto done;
   enc->priv->ctx.output_caps_changed = FALSE;
 
-  query = gst_query_new_allocation (caps, TRUE);
+  query = gst_query_new_allocation (enc->priv->ctx.allocation_caps, TRUE);
   if (!gst_pad_peer_query (enc->srcpad, query)) {
     GST_DEBUG_OBJECT (enc, "didn't get downstream ALLOCATION hints");
   }
@@ -2784,7 +2809,7 @@
   return ret;
 }
 
-/*
+/**
  * gst_audio_encoder_set_output_format:
  * @enc: a #GstAudioEncoder
  * @caps: (transfer none): #GstCaps
@@ -2792,7 +2817,7 @@
  * Configure output caps on the srcpad of @enc.
  *
  * Returns: %TRUE on success.
- **/
+ */
 gboolean
 gst_audio_encoder_set_output_format (GstAudioEncoder * enc, GstCaps * caps)
 {
diff --git a/gst-libs/gst/audio/gstaudioencoder.h b/gst-libs/gst/audio/gstaudioencoder.h
index 47ca340..a186bd5 100644
--- a/gst-libs/gst/audio/gstaudioencoder.h
+++ b/gst-libs/gst/audio/gstaudioencoder.h
@@ -295,6 +295,9 @@
 void            gst_audio_encoder_set_headers (GstAudioEncoder * enc,
                                                GList           * headers);
 
+void            gst_audio_encoder_set_allocation_caps (GstAudioEncoder * enc,
+                                                       GstCaps         * allocation_caps);
+
 /* object properties */
 
 void            gst_audio_encoder_set_mark_granule (GstAudioEncoder * enc,
diff --git a/gst-libs/gst/audio/gstaudioringbuffer.c b/gst-libs/gst/audio/gstaudioringbuffer.c
index 14f3c22..a8c81a1 100644
--- a/gst-libs/gst/audio/gstaudioringbuffer.c
+++ b/gst-libs/gst/audio/gstaudioringbuffer.c
@@ -1940,6 +1940,23 @@
   g_atomic_int_set (&buf->may_start, allowed);
 }
 
+/* GST_AUDIO_CHANNEL_POSITION_NONE is used for position-less
+ * mutually exclusive channels. In this case we should not attempt
+ * to do any reordering.
+ */
+static gboolean
+position_less_channels (const GstAudioChannelPosition * pos, guint channels)
+{
+  guint i;
+
+  for (i = 0; i < channels; i++) {
+    if (pos[i] != GST_AUDIO_CHANNEL_POSITION_NONE)
+      return FALSE;
+  }
+
+  return TRUE;
+}
+
 /**
  * gst_audio_ring_buffer_set_channel_positions:
  * @buf: the #GstAudioRingBuffer
@@ -1965,6 +1982,11 @@
   if (memcmp (position, to, channels * sizeof (to[0])) == 0)
     return;
 
+  if (position_less_channels (position, channels)) {
+    GST_LOG_OBJECT (buf, "position-less channels, no need to reorder");
+    return;
+  }
+
   buf->need_reorder = FALSE;
   if (!gst_audio_get_channel_reorder_map (channels, position, to,
           buf->channel_reorder_map))
@@ -1972,6 +1994,19 @@
 
   for (i = 0; i < channels; i++) {
     if (buf->channel_reorder_map[i] != i) {
+#ifndef GST_DISABLE_GST_DEBUG
+      {
+        gchar *tmp1, *tmp2;
+
+        tmp1 = gst_audio_channel_positions_to_string (position, channels);
+        tmp2 = gst_audio_channel_positions_to_string (to, channels);
+        GST_LOG_OBJECT (buf, "may have to reorder channels: %s -> %s", tmp1,
+            tmp2);
+        g_free (tmp1);
+        g_free (tmp2);
+      }
+#endif /* GST_DISABLE_GST_DEBUG */
+
       buf->need_reorder = TRUE;
       break;
     }
diff --git a/gst-libs/gst/fft/Makefile.in b/gst-libs/gst/fft/Makefile.in
index 43b64bb..bff59a0 100644
--- a/gst-libs/gst/fft/Makefile.in
+++ b/gst-libs/gst/fft/Makefile.in
@@ -99,6 +99,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -451,6 +452,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -464,6 +468,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -501,6 +508,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst-libs/gst/fft/kiss_fft_s16.h b/gst-libs/gst/fft/kiss_fft_s16.h
index 4303127..7dd40a2 100644
--- a/gst-libs/gst/fft/kiss_fft_s16.h
+++ b/gst-libs/gst/fft/kiss_fft_s16.h
@@ -1,6 +1,14 @@
 #ifndef KISS_FFT_S16_H
 #define KISS_FFT_S16_H
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <math.h>
@@ -26,8 +34,6 @@
 
 #define KISS_FFT_S16_MALLOC g_malloc
 
-#include "_stdint.h"
-
 #define kiss_fft_s16_scalar int16_t
 
 typedef struct {
diff --git a/gst-libs/gst/fft/kiss_fft_s32.h b/gst-libs/gst/fft/kiss_fft_s32.h
index 8edd664..ad2f2b0 100644
--- a/gst-libs/gst/fft/kiss_fft_s32.h
+++ b/gst-libs/gst/fft/kiss_fft_s32.h
@@ -1,6 +1,14 @@
 #ifndef KISS_FFT_S32_H
 #define KISS_FFT_S32_H
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <math.h>
@@ -26,9 +34,6 @@
 
 #define KISS_FFT_S32_MALLOC g_malloc
 
-
-#include "_stdint.h"
-
 #define kiss_fft_s32_scalar int32_t
 
 typedef struct {
diff --git a/gst-libs/gst/pbutils/Makefile.in b/gst-libs/gst/pbutils/Makefile.in
index 7a62c92..cfe33ad 100644
--- a/gst-libs/gst/pbutils/Makefile.in
+++ b/gst-libs/gst/pbutils/Makefile.in
@@ -108,6 +108,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -468,6 +469,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -481,6 +485,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -518,6 +525,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst-libs/gst/pbutils/codec-utils.c b/gst-libs/gst/pbutils/codec-utils.c
index af1a788..09162bd 100644
--- a/gst-libs/gst/pbutils/codec-utils.c
+++ b/gst-libs/gst/pbutils/codec-utils.c
@@ -110,6 +110,59 @@
 }
 
 /**
+ * gst_codec_utils_aac_get_sample_rate:
+ * @audio_config: a pointer to the AudioSpecificConfig as specified in the
+ *                Elementary Stream Descriptor (esds) in ISO/IEC 14496-1.
+ * @len: Length of @audio_config in bytes
+ *
+ * Translates the sample rate index found in AAC headers to the actual sample
+ * rate.
+ *
+ * Returns: The sample rate if sr_idx is valid, 0 otherwise.
+ *
+ * Since 1.10
+ */
+guint
+gst_codec_utils_aac_get_sample_rate (const guint8 * audio_config, guint len)
+{
+  guint rate_index;
+
+  if (len < 2)
+    return 0;
+
+  rate_index = ((audio_config[0] & 0x7) << 1) | ((audio_config[1] & 0x80) >> 7);
+  return gst_codec_utils_aac_get_sample_rate_from_index (rate_index);
+}
+
+/**
+ * gst_codec_utils_aac_get_channels:
+ * @audio_config: a pointer to the AudioSpecificConfig as specified in the
+ *                Elementary Stream Descriptor (esds) in ISO/IEC 14496-1.
+ *
+ * Returns the channels of the given AAC stream.
+ *
+ * Returns: The channels or 0 if the channel could not be determined.
+ *
+ * Since 1.10
+ */
+guint
+gst_codec_utils_aac_get_channels (const guint8 * audio_config, guint len)
+{
+  guint channels;
+
+  if (len < 2)
+    return 0;
+
+  channels = (audio_config[1] & 0x7f) >> 3;
+  if (channels > 0 && channels < 7)
+    return channels;
+  else if (channels == 7)
+    return 8;
+  else
+    return 0;
+}
+
+/**
  * gst_codec_utils_aac_get_profile:
  * @audio_config: a pointer to the AudioSpecificConfig as specified in the
  *                Elementary Stream Descriptor (esds) in ISO/IEC 14496-1 (see
@@ -504,7 +557,12 @@
         profile = "scalable-baseline";
       break;
     case 86:
-      profile = "scalable-high";
+      if (csf3)
+        profile = "scalable-high-intra";
+      else if (csf5)
+        profile = "scalable-constrained-high";
+      else
+        profile = "scalable-high";
       break;
     default:
       return NULL;
diff --git a/gst-libs/gst/pbutils/codec-utils.h b/gst-libs/gst/pbutils/codec-utils.h
index e1def83..979abaf 100644
--- a/gst-libs/gst/pbutils/codec-utils.h
+++ b/gst-libs/gst/pbutils/codec-utils.h
@@ -35,6 +35,10 @@
 
 const gchar * gst_codec_utils_aac_get_level   (const guint8 * audio_config, guint len);
 
+guint         gst_codec_utils_aac_get_sample_rate (const guint8 * audio_config, guint len);
+
+guint         gst_codec_utils_aac_get_channels (const guint8 * audio_config, guint len);
+
 gboolean      gst_codec_utils_aac_caps_set_level_and_profile (GstCaps      * caps,
                                                               const guint8 * audio_config,
                                                               guint          len);
diff --git a/gst-libs/gst/pbutils/descriptions.c b/gst-libs/gst/pbutils/descriptions.c
index 83aa413..cdea6b7 100644
--- a/gst-libs/gst/pbutils/descriptions.c
+++ b/gst-libs/gst/pbutils/descriptions.c
@@ -287,6 +287,7 @@
   {"application/x-teletext", "Teletext", 0, ""},
   {"application/x-kate", "Kate", 0, ""},
   {"subtitle/x-kate", N_("Kate subtitle format"), FLAG_SUB, ""},
+  {"application/x-subtitle-vtt", N_("WebVTT subtitle format"), FLAG_SUB, ""},
   {"subpicture/x-dvb", "DVB subtitles", FLAG_SUB, ""},
   {"subpicture/x-pgs", "PGS subtitles", FLAG_SUB, ""},
   {"subpicture/x-xsub", "XSUB subtitles", FLAG_SUB, ""},
diff --git a/gst-libs/gst/pbutils/gstaudiovisualizer.c b/gst-libs/gst/pbutils/gstaudiovisualizer.c
index 39b6b8a..717c2be 100644
--- a/gst-libs/gst/pbutils/gstaudiovisualizer.c
+++ b/gst-libs/gst/pbutils/gstaudiovisualizer.c
@@ -1036,7 +1036,7 @@
   guint64 dist, ts;
   guint avail, sbpf;
   gpointer adata;
-  gint bps, channels, rate;
+  gint bpf, rate;
 
   scope = GST_AUDIO_VISUALIZER (parent);
   klass = GST_AUDIO_VISUALIZER_CLASS (G_OBJECT_GET_CLASS (scope));
@@ -1056,11 +1056,10 @@
     }
   }
 
-  channels = GST_AUDIO_INFO_CHANNELS (&scope->ainfo);
   rate = GST_AUDIO_INFO_RATE (&scope->ainfo);
-  bps = GST_AUDIO_INFO_BPS (&scope->ainfo);
+  bpf = GST_AUDIO_INFO_BPF (&scope->ainfo);
 
-  if (bps == 0) {
+  if (bpf == 0) {
     ret = GST_FLOW_NOT_NEGOTIATED;
     goto beach;
   }
@@ -1070,7 +1069,7 @@
   g_mutex_lock (&scope->priv->config_lock);
 
   /* this is what we want */
-  sbpf = scope->req_spf * channels * sizeof (gint16);
+  sbpf = scope->req_spf * bpf;
 
   inbuf = scope->priv->inbuf;
   /* FIXME: the timestamp in the adapter would be different */
@@ -1087,8 +1086,7 @@
     ts = gst_adapter_prev_pts (scope->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);
+      ts += gst_util_uint64_scale_int (dist, GST_SECOND, rate * bpf);
     }
 
     /* check for QoS, don't compute buffers that are known to be late */
@@ -1135,7 +1133,7 @@
     ret = default_prepare_output_buffer (scope, &outbuf);
     g_mutex_lock (&scope->priv->config_lock);
     /* recheck as the value could have changed */
-    sbpf = scope->req_spf * channels * sizeof (gint16);
+    sbpf = scope->req_spf * bpf;
 
     /* no buffer allocated, we don't care why. */
     if (ret != GST_FLOW_OK)
@@ -1145,7 +1143,7 @@
     if (GST_CLOCK_TIME_IS_VALID (ts))
       gst_object_sync_values (GST_OBJECT (scope), ts);
 
-    GST_BUFFER_TIMESTAMP (outbuf) = ts;
+    GST_BUFFER_PTS (outbuf) = ts;
     GST_BUFFER_DURATION (outbuf) = scope->priv->frame_duration;
 
     /* this can fail as the data size we need could have changed */
@@ -1193,7 +1191,7 @@
 
   skip:
     /* recheck as the value could have changed */
-    sbpf = scope->req_spf * channels * sizeof (gint16);
+    sbpf = scope->req_spf * bpf;
     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) {
diff --git a/gst-libs/gst/pbutils/gstdiscoverer-types.c b/gst-libs/gst/pbutils/gstdiscoverer-types.c
index e743430..60a49cc 100644
--- a/gst-libs/gst/pbutils/gstdiscoverer-types.c
+++ b/gst-libs/gst/pbutils/gstdiscoverer-types.c
@@ -410,6 +410,8 @@
         stream_map);
   }
   ret->duration = ptr->duration;
+  ret->result = ptr->result;
+  ret->seekable = ptr->seekable;
   if (ptr->misc)
     ret->misc = gst_structure_copy (ptr->misc);
 
diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c
index 45de5f5..d155323 100644
--- a/gst-libs/gst/pbutils/gstdiscoverer.c
+++ b/gst-libs/gst/pbutils/gstdiscoverer.c
@@ -1388,6 +1388,7 @@
          */
         if (dc->priv->current_info->misc)
           gst_structure_free (dc->priv->current_info->misc);
+        dc->priv->current_info->misc = gst_structure_copy (structure);
         g_ptr_array_add (dc->priv->current_info->missing_elements_details,
             gst_missing_plugin_message_get_installer_detail (msg));
       } else if (sttype == _STREAM_TOPOLOGY_QUARK) {
diff --git a/gst-libs/gst/pbutils/pbutils-private.h b/gst-libs/gst/pbutils/pbutils-private.h
index 7424243..ceaae4b 100644
--- a/gst-libs/gst/pbutils/pbutils-private.h
+++ b/gst-libs/gst/pbutils/pbutils-private.h
@@ -106,5 +106,5 @@
 };
 
 /* missing-plugins.c */
-
+G_GNUC_INTERNAL
 GstCaps *copy_and_clean_caps (const GstCaps * caps);
diff --git a/gst-libs/gst/riff/Makefile.in b/gst-libs/gst/riff/Makefile.in
index 81c6d1d..dd79477 100644
--- a/gst-libs/gst/riff/Makefile.in
+++ b/gst-libs/gst/riff/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -420,6 +421,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -433,6 +437,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -470,6 +477,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst-libs/gst/riff/riff-media.c b/gst-libs/gst/riff/riff-media.c
index 188360a..10573b3 100644
--- a/gst-libs/gst/riff/riff-media.c
+++ b/gst-libs/gst/riff/riff-media.c
@@ -1203,8 +1203,6 @@
 {
   gboolean block_align = FALSE, rate_chan = TRUE;
   GstCaps *caps = NULL;
-  gint rate_min = 1000, rate_max = 96000;
-  gint channels_max = 2;
   gint i;
 
   if (channel_reorder_map)
@@ -1213,9 +1211,6 @@
 
   switch (codec_id) {
     case GST_RIFF_WAVE_FORMAT_PCM:     /* PCM */
-      rate_max = 192000;
-      channels_max = 8;
-
       if (strf != NULL) {
         gint ba = strf->blockalign;
         gint ch = strf->channels;
@@ -1299,9 +1294,6 @@
       break;
 
     case GST_RIFF_WAVE_FORMAT_IEEE_FLOAT:
-      rate_max = 192000;
-      channels_max = 8;
-
       if (strf != NULL) {
         gint ba = strf->blockalign;
         gint ch = strf->channels;
@@ -1351,7 +1343,6 @@
           strf->av_bps = strf->blockalign * strf->rate;
         }
       }
-      rate_max = 48000;
       caps = gst_caps_new_empty_simple ("audio/x-alaw");
       if (codec_name)
         *codec_name = g_strdup ("A-law audio");
@@ -1389,7 +1380,6 @@
           strf->av_bps = strf->blockalign * strf->rate;
         }
       }
-      rate_max = 48000;
       caps = gst_caps_new_empty_simple ("audio/x-mulaw");
       if (codec_name)
         *codec_name = g_strdup ("Mu-law audio");
@@ -1420,9 +1410,6 @@
       break;
 
     case GST_RIFF_WAVE_FORMAT_ITU_G726_ADPCM:
-      rate_min = 8000;
-      rate_max = 8000;
-      channels_max = 1;
       if (strf != NULL) {
         gint bitrate;
         bitrate = 0;
@@ -1451,8 +1438,6 @@
       break;
 
     case GST_RIFF_WAVE_FORMAT_DSP_TRUESPEECH:
-      rate_min = 8000;
-      rate_max = 8000;
       caps = gst_caps_new_empty_simple ("audio/x-truespeech");
       if (codec_name)
         *codec_name = g_strdup ("DSP Group TrueSpeech");
@@ -1460,15 +1445,12 @@
 
     case GST_RIFF_WAVE_FORMAT_GSM610:
     case GST_RIFF_WAVE_FORMAT_MSN:
-      rate_min = 1;
       caps = gst_caps_new_empty_simple ("audio/ms-gsm");
       if (codec_name)
         *codec_name = g_strdup ("MS GSM audio");
       break;
 
     case GST_RIFF_WAVE_FORMAT_MPEGL12: /* mp1 or mp2 */
-      rate_min = 16000;
-      rate_max = 48000;
       caps = gst_caps_new_simple ("audio/mpeg",
           "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
       if (codec_name)
@@ -1476,8 +1458,6 @@
       break;
 
     case GST_RIFF_WAVE_FORMAT_MPEGL3:  /* mp3 */
-      rate_min = 8000;
-      rate_max = 48000;
       caps = gst_caps_new_simple ("audio/mpeg",
           "mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
       if (codec_name)
@@ -1485,18 +1465,12 @@
       break;
 
     case GST_RIFF_WAVE_FORMAT_AMR_NB:  /* amr-nb */
-      rate_min = 8000;
-      rate_max = 8000;
-      channels_max = 1;
       caps = gst_caps_new_empty_simple ("audio/AMR");
       if (codec_name)
         *codec_name = g_strdup ("AMR Narrow Band (NB)");
       break;
 
     case GST_RIFF_WAVE_FORMAT_AMR_WB:  /* amr-wb */
-      rate_min = 16000;
-      rate_max = 16000;
-      channels_max = 1;
       caps = gst_caps_new_empty_simple ("audio/AMR-WB");
       if (codec_name)
         *codec_name = g_strdup ("AMR Wide Band (WB)");
@@ -1508,20 +1482,17 @@
     case GST_RIFF_WAVE_FORMAT_VORBIS1PLUS:     /* ogg/vorbis mode 1+ */
     case GST_RIFF_WAVE_FORMAT_VORBIS2PLUS:     /* ogg/vorbis mode 2+ */
     case GST_RIFF_WAVE_FORMAT_VORBIS3PLUS:     /* ogg/vorbis mode 3+ */
-      rate_max = 192000;
       caps = gst_caps_new_empty_simple ("audio/x-vorbis");
       if (codec_name)
         *codec_name = g_strdup ("Vorbis");
       break;
 
     case GST_RIFF_WAVE_FORMAT_A52:
-      channels_max = 6;
       caps = gst_caps_new_empty_simple ("audio/x-ac3");
       if (codec_name)
         *codec_name = g_strdup ("AC-3 audio");
       break;
     case GST_RIFF_WAVE_FORMAT_DTS:
-      channels_max = 6;
       caps = gst_caps_new_empty_simple ("audio/x-dts");
       if (codec_name)
         *codec_name = g_strdup ("DTS audio");
@@ -1532,7 +1503,6 @@
     case GST_RIFF_WAVE_FORMAT_AAC_AC:
     case GST_RIFF_WAVE_FORMAT_AAC_pm:
     {
-      channels_max = 8;
       caps = gst_caps_new_simple ("audio/mpeg",
           "mpegversion", G_TYPE_INT, 4, NULL);
       if (codec_name)
@@ -1546,7 +1516,6 @@
     {
       gint version = (codec_id - GST_RIFF_WAVE_FORMAT_WMAV1) + 1;
 
-      channels_max = 8;
       block_align = TRUE;
 
       caps = gst_caps_new_simple ("audio/x-wma",
@@ -1583,9 +1552,6 @@
       break;
 
     case GST_RIFF_WAVE_FORMAT_ADPCM_IMA_DK4:
-      rate_min = 8000;
-      rate_max = 96000;
-      channels_max = 2;
       caps =
           gst_caps_new_simple ("audio/x-adpcm", "layout", G_TYPE_STRING, "dk4",
           NULL);
@@ -1593,9 +1559,6 @@
         *codec_name = g_strdup ("IMA/DK4 ADPCM");
       break;
     case GST_RIFF_WAVE_FORMAT_ADPCM_IMA_DK3:
-      rate_min = 8000;
-      rate_max = 96000;
-      channels_max = 2;
       caps =
           gst_caps_new_simple ("audio/x-adpcm", "layout", G_TYPE_STRING, "dk3",
           NULL);
@@ -1604,9 +1567,6 @@
       break;
 
     case GST_RIFF_WAVE_FORMAT_ADPCM_IMA_WAV:
-      rate_min = 8000;
-      rate_max = 96000;
-      channels_max = 2;
       caps =
           gst_caps_new_simple ("audio/x-adpcm", "layout", G_TYPE_STRING, "dvi",
           NULL);
@@ -1620,8 +1580,6 @@
       GstMapInfo info;
       gsize size;
 
-      channels_max = 8;
-
       /* should be at least 22 bytes */
       size = gst_buffer_get_size (strf_data);
 
@@ -1716,7 +1674,6 @@
               strf->blockalign = strf->av_bps * strf->channels;
             }
           }
-          rate_max = 48000;
           caps = gst_caps_new_empty_simple ("audio/x-alaw");
 
           if (codec_name)
@@ -1739,7 +1696,6 @@
               strf->blockalign = strf->av_bps * strf->channels;
             }
           }
-          rate_max = 48000;
           caps = gst_caps_new_empty_simple ("audio/x-mulaw");
           if (codec_name)
             *codec_name = g_strdup ("Mu-law audio");
@@ -1824,11 +1780,6 @@
 
   if (strf != NULL) {
     if (rate_chan) {
-      if (strf->channels > channels_max)
-        goto too_many_channels;
-      if (strf->rate < rate_min || strf->rate > rate_max)
-        goto invalid_rate;
-
       gst_caps_set_simple (caps,
           "rate", G_TYPE_INT, strf->rate,
           "channels", G_TYPE_INT, strf->channels, NULL);
@@ -1838,18 +1789,6 @@
           "block_align", G_TYPE_INT, strf->blockalign, NULL);
     }
   } else {
-    if (rate_chan) {
-      if (rate_min == rate_max)
-        gst_caps_set_simple (caps, "rate", G_TYPE_INT, rate_min, NULL);
-      else
-        gst_caps_set_simple (caps,
-            "rate", GST_TYPE_INT_RANGE, rate_min, rate_max, NULL);
-      if (channels_max == 1)
-        gst_caps_set_simple (caps, "channels", G_TYPE_INT, 1, NULL);
-      else
-        gst_caps_set_simple (caps,
-            "channels", GST_TYPE_INT_RANGE, 1, channels_max, NULL);
-    }
     if (block_align) {
       gst_caps_set_simple (caps,
           "block_align", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
@@ -1863,20 +1802,6 @@
   }
 
   return caps;
-
-  /* ERROR */
-too_many_channels:
-  GST_WARNING
-      ("Stream claims to contain %u channels, but format only supports %d",
-      strf->channels, channels_max);
-  gst_caps_unref (caps);
-  return NULL;
-invalid_rate:
-  GST_WARNING
-      ("Stream with sample_rate %u, but format only supports %d .. %d",
-      strf->rate, rate_min, rate_max);
-  gst_caps_unref (caps);
-  return NULL;
 }
 
 GstCaps *
diff --git a/gst-libs/gst/rtp/Makefile.in b/gst-libs/gst/rtp/Makefile.in
index bc1a112..df06537 100644
--- a/gst-libs/gst/rtp/Makefile.in
+++ b/gst-libs/gst/rtp/Makefile.in
@@ -108,6 +108,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -459,6 +460,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -472,6 +476,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -509,6 +516,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst-libs/gst/rtp/gstrtcpbuffer.c b/gst-libs/gst/rtp/gstrtcpbuffer.c
index e5e4ca7..e540576 100644
--- a/gst-libs/gst/rtp/gstrtcpbuffer.c
+++ b/gst-libs/gst/rtp/gstrtcpbuffer.c
@@ -956,6 +956,9 @@
       packet->type == GST_RTCP_TYPE_SR, FALSE);
   g_return_val_if_fail (packet->rtcp != NULL, FALSE);
   g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE, FALSE);
+  /* if profile-specific extension is added, fail for now!? */
+  g_return_val_if_fail (gst_rtcp_packet_get_profile_specific_ext_length (packet)
+      == 0, FALSE);
 
   if (packet->count >= GST_RTCP_MAX_RB_COUNT)
     goto no_space;
@@ -1040,6 +1043,156 @@
 
 
 /**
+ * gst_rtcp_packet_set_profile_specific_ext:
+ * @packet: a valid SR or RR #GstRTCPPacket
+ * @data: (array length=len) (transfer none): profile-specific data
+ * @len: length of the profile-specific data in bytes
+ *
+ * Add profile-specific extension @data to @packet. If @packet already
+ * contains profile-specific extension @data will be appended to the existing
+ * extension.
+ *
+ * Returns: %TRUE if the profile specific extension data was added.
+ */
+gboolean
+gst_rtcp_packet_add_profile_specific_ext (GstRTCPPacket * packet,
+    const guint8 * data, guint len)
+{
+  guint8 *bdata;
+  guint maxsize, offset;
+
+  g_return_val_if_fail (packet != NULL, FALSE);
+  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR ||
+      packet->type == GST_RTCP_TYPE_SR, FALSE);
+  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
+  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE, FALSE);
+  g_return_val_if_fail ((len & 0x03) == 0, FALSE);
+
+  bdata = packet->rtcp->map.data;
+  maxsize = packet->rtcp->map.maxsize;
+
+  /* skip to the end of the packet */
+  offset = packet->offset + (packet->length << 2) + 4;
+
+  /* we need 'len' free bytes now */
+  if (G_UNLIKELY (offset + len > maxsize))
+    return FALSE;
+
+  memcpy (&bdata[offset], data, len);
+  packet->length += len >> 2;
+  bdata[packet->offset + 2] = (packet->length) >> 8;
+  bdata[packet->offset + 3] = (packet->length) & 0xff;
+  packet->rtcp->map.size += len;
+
+  return TRUE;
+}
+
+/**
+ * gst_rtcp_packet_get_profile_specific_ext_length:
+ * @packet: a valid SR or RR #GstRTCPPacket
+ *
+ * Returns: The number of 32-bit words containing profile-specific extension
+ *          data from @packet.
+ */
+guint16
+gst_rtcp_packet_get_profile_specific_ext_length (GstRTCPPacket * packet)
+{
+  guint pse_offset = 2;
+
+  g_return_val_if_fail (packet != NULL, 0);
+  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR ||
+      packet->type == GST_RTCP_TYPE_SR, 0);
+  g_return_val_if_fail (packet->rtcp != NULL, 0);
+  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, 0);
+
+  if (packet->type == GST_RTCP_TYPE_SR)
+    pse_offset += 5;
+  pse_offset += (packet->count * 6);
+
+  if (pse_offset <= (packet->length + 1))
+    return packet->length + 1 - pse_offset;
+
+  /* This means that the packet is invalid! */
+  return 0;
+}
+
+/**
+ * gst_rtcp_packet_get_profile_specific_ext:
+ * @packet: a valid SR or RR #GstRTCPPacket
+ * @data: (out) (array length=len) (transfer none): result profile-specific data
+ * @len: (out): result length of the profile-specific data
+ *
+ * Returns: %TRUE if there was valid data.
+ */
+gboolean
+gst_rtcp_packet_get_profile_specific_ext (GstRTCPPacket * packet,
+    guint8 ** data, guint * len)
+{
+  guint16 pse_len;
+
+  g_return_val_if_fail (packet != NULL, FALSE);
+  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR ||
+      packet->type == GST_RTCP_TYPE_SR, FALSE);
+  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
+  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, FALSE);
+
+  pse_len = gst_rtcp_packet_get_profile_specific_ext_length (packet);
+  if (pse_len > 0) {
+    if (len != NULL)
+      *len = pse_len * sizeof (guint32);
+    if (data != NULL) {
+      *data = packet->rtcp->map.data;
+      *data += packet->offset;
+      *data += ((packet->length + 1 - pse_len) * sizeof (guint32));
+    }
+
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
+ * gst_rtcp_packet_copy_profile_specific_ext:
+ * @packet: a valid SR or RR #GstRTCPPacket
+ * @data: (out) (array length=len): result profile-specific data
+ * @len: (out): length of the profile-specific extension data
+ *
+ * The profile-specific extension data is copied into a new allocated
+ * memory area @data. This must be freed with g_free() after usage.
+ *
+ * Returns: %TRUE if there was valid data.
+ */
+gboolean
+gst_rtcp_packet_copy_profile_specific_ext (GstRTCPPacket * packet,
+    guint8 ** data, guint * len)
+{
+  guint16 pse_len;
+
+  g_return_val_if_fail (packet != NULL, FALSE);
+  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR ||
+      packet->type == GST_RTCP_TYPE_SR, FALSE);
+  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
+  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, FALSE);
+
+  pse_len = gst_rtcp_packet_get_profile_specific_ext_length (packet);
+  if (pse_len > 0) {
+    if (len != NULL)
+      *len = pse_len * sizeof (guint32);
+    if (data != NULL) {
+      guint8 *ptr = packet->rtcp->map.data + packet->offset;
+      ptr += ((packet->length + 1 - pse_len) * sizeof (guint32));
+      *data = g_memdup (ptr, pse_len * sizeof (guint32));
+    }
+
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+
+/**
  * gst_rtcp_packet_sdes_get_item_count:
  * @packet: a valid SDES #GstRTCPPacket
  *
@@ -2158,3 +2311,232 @@
 
   return data + 12;
 }
+
+/**
+ * gst_rtcp_packet_app_set_subtype:
+ * @packet: a valid APP #GstRTCPPacket
+ * @subtype: subtype of the packet
+ *
+ * Set the subtype field of the APP @packet.
+ *
+ * Since: 1.10
+ **/
+void
+gst_rtcp_packet_app_set_subtype (GstRTCPPacket * packet, guint8 subtype)
+{
+  guint8 *data;
+
+  g_return_if_fail (packet != NULL);
+  g_return_if_fail (packet->type == GST_RTCP_TYPE_APP);
+  g_return_if_fail (packet->rtcp != NULL);
+  g_return_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE);
+
+  data = packet->rtcp->map.data + packet->offset;
+  data[0] = (data[0] & 0xe0) | subtype;
+}
+
+/**
+ * gst_rtcp_packet_app_get_subtype:
+ * @packet: a valid APP #GstRTCPPacket
+ *
+ * Get the subtype field of the APP @packet.
+ *
+ * Returns: The subtype.
+ *
+ * Since: 1.10
+ */
+guint8
+gst_rtcp_packet_app_get_subtype (GstRTCPPacket * packet)
+{
+  guint8 *data;
+
+  g_return_val_if_fail (packet != NULL, 0);
+  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_APP, 0);
+  g_return_val_if_fail (packet->rtcp != NULL, 0);
+  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, 0);
+
+  data = packet->rtcp->map.data + packet->offset;
+
+  return data[0] & 0x1f;
+}
+
+/**
+ * gst_rtcp_packet_app_set_ssrc:
+ * @packet: a valid APP #GstRTCPPacket
+ * @ssrc: SSRC/CSRC of the packet
+ *
+ * Set the SSRC/CSRC field of the APP @packet.
+ *
+ * Since: 1.10
+ */
+void
+gst_rtcp_packet_app_set_ssrc (GstRTCPPacket * packet, guint32 ssrc)
+{
+  guint8 *data;
+
+  g_return_if_fail (packet != NULL);
+  g_return_if_fail (packet->type == GST_RTCP_TYPE_APP);
+  g_return_if_fail (packet->rtcp != NULL);
+  g_return_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE);
+
+  data = packet->rtcp->map.data + packet->offset + 4;
+  GST_WRITE_UINT32_BE (data, ssrc);
+}
+
+/**
+ * gst_rtcp_packet_app_get_ssrc:
+ * @packet: a valid APP #GstRTCPPacket
+ *
+ * Get the SSRC/CSRC field of the APP @packet.
+ *
+ * Returns: The SSRC/CSRC.
+ *
+ * Since: 1.10
+ */
+guint32
+gst_rtcp_packet_app_get_ssrc (GstRTCPPacket * packet)
+{
+  guint8 *data;
+
+  g_return_val_if_fail (packet != NULL, 0);
+  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_APP, 0);
+  g_return_val_if_fail (packet->rtcp != NULL, 0);
+  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, 0);
+
+  data = packet->rtcp->map.data + packet->offset + 4;
+
+  return GST_READ_UINT32_BE (data);
+}
+
+/**
+ * gst_rtcp_packet_app_set_name:
+ * @packet: a valid APP #GstRTCPPacket
+ * @name: 4-byte ASCII name
+ *
+ * Set the name field of the APP @packet.
+ *
+ * Since: 1.10
+ */
+void
+gst_rtcp_packet_app_set_name (GstRTCPPacket * packet, const gchar * name)
+{
+  guint8 *data;
+
+  g_return_if_fail (packet != NULL);
+  g_return_if_fail (packet->type == GST_RTCP_TYPE_APP);
+  g_return_if_fail (packet->rtcp != NULL);
+  g_return_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE);
+
+  data = packet->rtcp->map.data + packet->offset + 8;
+  memcpy (data, name, 4);
+}
+
+/**
+ * gst_rtcp_packet_app_get_name:
+ * @packet: a valid APP #GstRTCPPacket
+ *
+ * Get the name field of the APP @packet.
+ *
+ * Returns: The 4-byte name field, not zero-terminated.
+ *
+ * Since: 1.10
+ */
+const gchar *
+gst_rtcp_packet_app_get_name (GstRTCPPacket * packet)
+{
+  g_return_val_if_fail (packet != NULL, NULL);
+  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_APP, NULL);
+  g_return_val_if_fail (packet->rtcp != NULL, NULL);
+  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, NULL);
+
+  return (const gchar *) &packet->rtcp->map.data[packet->offset + 8];
+}
+
+/**
+ * gst_rtcp_packet_app_get_data_length:
+ * @packet: a valid APP #GstRTCPPacket
+ *
+ * Get the length of the application-dependent data attached to an APP
+ * @packet.
+ *
+ * Returns: The length of data in 32-bit words.
+ *
+ * Since: 1.10
+ */
+guint16
+gst_rtcp_packet_app_get_data_length (GstRTCPPacket * packet)
+{
+  guint8 *data;
+
+  g_return_val_if_fail (packet != NULL, 0);
+  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_APP, 0);
+  g_return_val_if_fail (packet->rtcp != NULL, 0);
+  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, 0);
+
+  data = packet->rtcp->map.data + packet->offset + 2;
+
+  return GST_READ_UINT16_BE (data) - 2;
+}
+
+/**
+ * gst_rtcp_packet_app_set_data_length:
+ * @packet: a valid APP #GstRTCPPacket
+ * @wordlen: Length of the data in 32-bit words
+ *
+ * Set the length of the application-dependent data attached to an APP
+ * @packet.
+ *
+ * Returns: %TRUE if there was enough space in the packet to add this much
+ * data.
+ *
+ * Since: 1.10
+ */
+gboolean
+gst_rtcp_packet_app_set_data_length (GstRTCPPacket * packet, guint16 wordlen)
+{
+  guint8 *data;
+
+  g_return_val_if_fail (packet != NULL, FALSE);
+  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_APP, FALSE);
+  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
+  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE, FALSE);
+
+  if (packet->rtcp->map.maxsize < packet->offset + ((wordlen + 3) * 4))
+    return FALSE;
+
+  data = packet->rtcp->map.data + packet->offset + 2;
+  wordlen += 2;
+  GST_WRITE_UINT16_BE (data, wordlen);
+
+  packet->rtcp->map.size = packet->offset + ((wordlen + 1) * 4);
+
+  return TRUE;
+}
+
+/**
+ * gst_rtcp_packet_app_get_data:
+ * @packet: a valid APP #GstRTCPPacket
+ *
+ * Get the application-dependent data attached to a RTPFB or PSFB @packet.
+ *
+ * Returns: A pointer to the data
+ *
+ * Since: 1.10
+ */
+guint8 *
+gst_rtcp_packet_app_get_data (GstRTCPPacket * packet)
+{
+  guint8 *data;
+
+  g_return_val_if_fail (packet != NULL, NULL);
+  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_APP, NULL);
+  g_return_val_if_fail (packet->rtcp != NULL, NULL);
+  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, NULL);
+
+  data = packet->rtcp->map.data + packet->offset;
+
+  if (GST_READ_UINT16_BE (data + 2) <= 2)
+    return NULL;
+
+  return data + 12;
+}
diff --git a/gst-libs/gst/rtp/gstrtcpbuffer.h b/gst-libs/gst/rtp/gstrtcpbuffer.h
index 328ecdd..c28fb8b 100644
--- a/gst-libs/gst/rtp/gstrtcpbuffer.h
+++ b/gst-libs/gst/rtp/gstrtcpbuffer.h
@@ -279,6 +279,15 @@
                                                        guint32 exthighestseq, guint32 jitter,
                                                        guint32 lsr, guint32 dlsr);
 
+/* profile-specific extensions for SR and RR */
+gboolean        gst_rtcp_packet_add_profile_specific_ext        (GstRTCPPacket * packet,
+                                                                 const guint8 * data, guint len);
+guint16         gst_rtcp_packet_get_profile_specific_ext_length (GstRTCPPacket * packet);
+gboolean        gst_rtcp_packet_get_profile_specific_ext        (GstRTCPPacket * packet,
+                                                                 guint8 ** data, guint * len);
+gboolean        gst_rtcp_packet_copy_profile_specific_ext       (GstRTCPPacket * packet,
+                                                                 guint8 ** data, guint * len);
+
 /* source description packet */
 guint           gst_rtcp_packet_sdes_get_item_count   (GstRTCPPacket *packet);
 gboolean        gst_rtcp_packet_sdes_first_item       (GstRTCPPacket *packet);
@@ -306,6 +315,17 @@
 gchar*          gst_rtcp_packet_bye_get_reason        (GstRTCPPacket *packet);
 gboolean        gst_rtcp_packet_bye_set_reason        (GstRTCPPacket *packet, const gchar *reason);
 
+/* app packets */
+void            gst_rtcp_packet_app_set_subtype       (GstRTCPPacket * packet, guint8 subtype);
+guint8          gst_rtcp_packet_app_get_subtype       (GstRTCPPacket * packet);
+void            gst_rtcp_packet_app_set_ssrc          (GstRTCPPacket * packet, guint32 ssrc);
+guint32         gst_rtcp_packet_app_get_ssrc          (GstRTCPPacket * packet);
+void            gst_rtcp_packet_app_set_name          (GstRTCPPacket * packet, const gchar *name);
+const gchar*    gst_rtcp_packet_app_get_name          (GstRTCPPacket * packet);
+guint16         gst_rtcp_packet_app_get_data_length   (GstRTCPPacket * packet);
+gboolean        gst_rtcp_packet_app_set_data_length   (GstRTCPPacket * packet, guint16 wordlen);
+guint8*         gst_rtcp_packet_app_get_data          (GstRTCPPacket * packet);
+
 /* feedback packets */
 guint32         gst_rtcp_packet_fb_get_sender_ssrc    (GstRTCPPacket *packet);
 void            gst_rtcp_packet_fb_set_sender_ssrc    (GstRTCPPacket *packet, guint32 ssrc);
diff --git a/gst-libs/gst/rtp/gstrtpbasedepayload.c b/gst-libs/gst/rtp/gstrtpbasedepayload.c
index 8a313af..dd490a4 100644
--- a/gst-libs/gst/rtp/gstrtpbasedepayload.c
+++ b/gst-libs/gst/rtp/gstrtpbasedepayload.c
@@ -46,6 +46,7 @@
   GstClockTime dts;
   GstClockTime duration;
 
+  guint32 last_ssrc;
   guint32 last_seqnum;
   guint32 last_rtptime;
   guint32 next_seqnum;
@@ -356,6 +357,7 @@
   GstRTPBaseDepayloadPrivate *priv;
   GstFlowReturn ret = GST_FLOW_OK;
   GstBuffer *out_buf;
+  guint32 ssrc;
   guint16 seqnum;
   guint32 rtptime;
   gboolean discont, buf_discont;
@@ -380,6 +382,7 @@
   priv->dts = GST_BUFFER_DTS (in);
   priv->duration = GST_BUFFER_DURATION (in);
 
+  ssrc = gst_rtp_buffer_get_ssrc (&rtp);
   seqnum = gst_rtp_buffer_get_seq (&rtp);
   rtptime = gst_rtp_buffer_get_timestamp (&rtp);
 
@@ -396,32 +399,40 @@
    * are strictly increasing, dropping anything that is out of the ordinary. We
    * can only do this when the next_seqnum is known. */
   if (G_LIKELY (priv->next_seqnum != -1)) {
-    gap = gst_rtp_buffer_compare_seqnum (seqnum, priv->next_seqnum);
+    if (ssrc != priv->last_ssrc) {
+      GST_LOG_OBJECT (filter,
+          "New ssrc %u (current ssrc %u), sender restarted",
+          ssrc, priv->last_ssrc);
+      discont = TRUE;
+    } else {
+      gap = gst_rtp_buffer_compare_seqnum (seqnum, priv->next_seqnum);
 
-    /* if we have no gap, all is fine */
-    if (G_UNLIKELY (gap != 0)) {
-      GST_LOG_OBJECT (filter, "got packet %u, expected %u, gap %d", seqnum,
-          priv->next_seqnum, gap);
-      if (gap < 0) {
-        /* seqnum > next_seqnum, we are missing some packets, this is always a
-         * DISCONT. */
-        GST_LOG_OBJECT (filter, "%d missing packets", gap);
-        discont = TRUE;
-      } else {
-        /* seqnum < next_seqnum, we have seen this packet before or the sender
-         * could be restarted. If the packet is not too old, we throw it away as
-         * a duplicate, otherwise we mark discont and continue. 100 misordered
-         * packets is a good threshold. See also RFC 4737. */
-        if (gap < 100)
-          goto dropping;
+      /* if we have no gap, all is fine */
+      if (G_UNLIKELY (gap != 0)) {
+        GST_LOG_OBJECT (filter, "got packet %u, expected %u, gap %d", seqnum,
+            priv->next_seqnum, gap);
+        if (gap < 0) {
+          /* seqnum > next_seqnum, we are missing some packets, this is always a
+           * DISCONT. */
+          GST_LOG_OBJECT (filter, "%d missing packets", gap);
+          discont = TRUE;
+        } else {
+          /* seqnum < next_seqnum, we have seen this packet before or the sender
+           * could be restarted. If the packet is not too old, we throw it away as
+           * a duplicate, otherwise we mark discont and continue. 100 misordered
+           * packets is a good threshold. See also RFC 4737. */
+          if (gap < 100)
+            goto dropping;
 
-        GST_LOG_OBJECT (filter,
-            "%d > 100, packet too old, sender likely restarted", gap);
-        discont = TRUE;
+          GST_LOG_OBJECT (filter,
+              "%d > 100, packet too old, sender likely restarted", gap);
+          discont = TRUE;
+        }
       }
     }
   }
   priv->next_seqnum = (seqnum + 1) & 0xffff;
+  priv->last_ssrc = ssrc;
 
   if (G_UNLIKELY (discont)) {
     priv->discont = TRUE;
@@ -602,6 +613,9 @@
     {
       GST_OBJECT_LOCK (filter);
       gst_event_copy_segment (event, &filter->segment);
+      if (filter->segment.format != GST_FORMAT_TIME)
+        GST_ERROR_OBJECT (filter,
+            "Non-TIME segments are not supported and will likely fail");
       GST_OBJECT_UNLOCK (filter);
 
       /* don't pass the event downstream, we generate our own segment including
@@ -706,8 +720,11 @@
   if (position == -1)
     position = start;
 
-  running_time = gst_segment_to_running_time (&filter->segment,
-      GST_FORMAT_TIME, start);
+  if (G_LIKELY (filter->segment.format == GST_FORMAT_TIME))
+    running_time = gst_segment_to_running_time (&filter->segment,
+        GST_FORMAT_TIME, start);
+  else
+    running_time = 0;
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
   segment.rate = priv->play_speed;
@@ -725,16 +742,9 @@
   return event;
 }
 
-typedef struct
-{
-  GstRTPBaseDepayload *depayload;
-  GstRTPBaseDepayloadClass *bclass;
-} HeaderData;
-
 static gboolean
-set_headers (GstBuffer ** buffer, guint idx, HeaderData * data)
+set_headers (GstBuffer ** buffer, guint idx, GstRTPBaseDepayload * depayload)
 {
-  GstRTPBaseDepayload *depayload = data->depayload;
   GstRTPBaseDepayloadPrivate *priv = depayload->priv;
   GstClockTime pts, dts, duration;
 
@@ -771,17 +781,12 @@
 gst_rtp_base_depayload_prepare_push (GstRTPBaseDepayload * filter,
     gboolean is_list, gpointer obj)
 {
-  HeaderData data;
-
-  data.depayload = filter;
-  data.bclass = GST_RTP_BASE_DEPAYLOAD_GET_CLASS (filter);
-
   if (is_list) {
     GstBufferList **blist = obj;
-    gst_buffer_list_foreach (*blist, (GstBufferListFunc) set_headers, &data);
+    gst_buffer_list_foreach (*blist, (GstBufferListFunc) set_headers, filter);
   } else {
     GstBuffer **buf = obj;
-    set_headers (buf, 0, &data);
+    set_headers (buf, 0, filter);
   }
 
   /* if this is the first buffer send a NEWSEGMENT */
diff --git a/gst-libs/gst/rtp/gstrtpbuffer.c b/gst-libs/gst/rtp/gstrtpbuffer.c
index d4c2edf..16e740c 100644
--- a/gst-libs/gst/rtp/gstrtpbuffer.c
+++ b/gst-libs/gst/rtp/gstrtpbuffer.c
@@ -1494,7 +1494,7 @@
 
 gboolean
 gst_rtp_buffer_add_extension_onebyte_header (GstRTPBuffer * rtp, guint8 id,
-    gpointer data, guint size)
+    gconstpointer data, guint size)
 {
   guint16 bits;
   guint8 *pdata = 0;
@@ -1593,7 +1593,7 @@
 
 gboolean
 gst_rtp_buffer_add_extension_twobytes_header (GstRTPBuffer * rtp,
-    guint8 appbits, guint8 id, gpointer data, guint size)
+    guint8 appbits, guint8 id, gconstpointer data, guint size)
 {
   guint16 bits;
   guint8 *pdata = 0;
diff --git a/gst-libs/gst/rtp/gstrtpbuffer.h b/gst-libs/gst/rtp/gstrtpbuffer.h
index f544f83..5a9049f 100644
--- a/gst-libs/gst/rtp/gstrtpbuffer.h
+++ b/gst-libs/gst/rtp/gstrtpbuffer.h
@@ -142,15 +142,34 @@
 
 gboolean       gst_rtp_buffer_add_extension_onebyte_header  (GstRTPBuffer *rtp,
                                                              guint8 id,
-                                                             gpointer data,
+                                                             gconstpointer data,
                                                              guint size);
 gboolean       gst_rtp_buffer_add_extension_twobytes_header (GstRTPBuffer *rtp,
                                                              guint8 appbits,
                                                              guint8 id,
-                                                             gpointer data,
+                                                             gconstpointer data,
                                                              guint size);
 
 /**
+ * GstRTPBufferFlags:
+ * @GST_RTP_BUFFER_FLAG_RETRANSMISSION: The #GstBuffer was once wrapped
+ *           in a retransmitted packet as specified by RFC 4588.
+ * @GST_RTP_BUFFER_FLAG_LAST:           Offset to define more flags.
+ *
+ * Additional RTP buffer flags. These flags can potentially be used on any
+ * buffers carrying RTP packets.
+ *
+ * Note that these are only valid for #GstCaps of type: application/x-rtp (x-rtcp).
+ * They can conflict with other extended buffer flags.
+ *
+ * Since: 1.10
+ */
+typedef enum {
+  GST_RTP_BUFFER_FLAG_RETRANSMISSION = (GST_BUFFER_FLAG_LAST << 0),
+  GST_RTP_BUFFER_FLAG_LAST           = (GST_BUFFER_FLAG_LAST << 8)
+} GstRTPBufferFlags;
+
+/**
  * GstRTPBufferMapFlags:
  * @GST_RTP_BUFFER_MAP_FLAG_SKIP_PADDING: Skip mapping and validation of RTP
  *           padding and RTP pad count when present. Useful for buffers where
diff --git a/gst-libs/gst/rtsp/Makefile.in b/gst-libs/gst/rtsp/Makefile.in
index 6dcfc3e..e3b944f 100644
--- a/gst-libs/gst/rtsp/Makefile.in
+++ b/gst-libs/gst/rtsp/Makefile.in
@@ -108,6 +108,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -458,6 +459,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -471,6 +475,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -508,6 +515,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst-libs/gst/sdp/Makefile.in b/gst-libs/gst/sdp/Makefile.in
index b612b9b..b6d57d6 100644
--- a/gst-libs/gst/sdp/Makefile.in
+++ b/gst-libs/gst/sdp/Makefile.in
@@ -99,6 +99,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -437,6 +438,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -450,6 +454,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -487,6 +494,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst-libs/gst/tag/Makefile.in b/gst-libs/gst/tag/Makefile.in
index e9103b5..6967b2f 100644
--- a/gst-libs/gst/tag/Makefile.in
+++ b/gst-libs/gst/tag/Makefile.in
@@ -100,6 +100,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -467,6 +468,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -480,6 +484,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -517,6 +524,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst-libs/gst/tag/gstexiftag.c b/gst-libs/gst/tag/gstexiftag.c
index 1f0528e..bcdcdde 100644
--- a/gst-libs/gst/tag/gstexiftag.c
+++ b/gst-libs/gst/tag/gstexiftag.c
@@ -311,6 +311,7 @@
 #define EXIF_TAG_EXPOSURE_MODE 0xA402
 #define EXIF_TAG_WHITE_BALANCE 0xA403
 #define EXIF_TAG_DIGITAL_ZOOM_RATIO 0xA404
+#define EXIF_TAG_FOCAL_LENGTH_IN_35_MM_FILM 0xa405
 #define EXIF_TAG_SCENE_CAPTURE_TYPE 0xA406
 #define EXIF_TAG_GAIN_CONTROL 0xA407
 #define EXIF_TAG_CONTRAST 0xA408
@@ -411,6 +412,8 @@
   {GST_TAG_CAPTURING_DIGITAL_ZOOM_RATIO, EXIF_TAG_DIGITAL_ZOOM_RATIO,
         EXIF_TYPE_RATIONAL, 0, NULL,
       NULL},
+  {GST_TAG_CAPTURING_FOCAL_LENGTH_35_MM, EXIF_TAG_FOCAL_LENGTH_IN_35_MM_FILM,
+      EXIF_TYPE_SHORT, 0, NULL, NULL},
   {GST_TAG_CAPTURING_SCENE_CAPTURE_TYPE, EXIF_TAG_SCENE_CAPTURE_TYPE,
         EXIF_TYPE_SHORT, 0, serialize_scene_capture_type,
       deserialize_scene_capture_type},
@@ -1048,6 +1051,9 @@
     case G_TYPE_INT:
       num = g_value_get_int (value);
       break;
+    case G_TYPE_DOUBLE:
+      num = (gint) g_value_get_double (value);
+      break;
     default:
       GST_WARNING ("Conversion from %s to int not supported",
           G_VALUE_TYPE_NAME (value));
@@ -1314,6 +1320,37 @@
 }
 
 static void
+parse_exif_short_tag (GstExifReader * reader, const GstExifTagMatch * tag,
+    guint32 count, guint32 offset, const guint8 * offset_as_data)
+{
+  GType tagtype;
+  guint16 value;
+
+  if (count > 1) {
+    GST_WARNING ("Short tags with more than one value are not supported");
+    return;
+  }
+
+  /* value is encoded into offset */
+  if (reader->byte_order == G_LITTLE_ENDIAN)
+    value = GST_READ_UINT16_LE (offset_as_data);
+  else
+    value = GST_READ_UINT16_BE (offset_as_data);
+
+  tagtype = gst_tag_get_type (tag->gst_tag);
+  if (tagtype == G_TYPE_INT) {
+    gst_tag_list_add (reader->taglist, GST_TAG_MERGE_REPLACE, tag->gst_tag,
+        value, NULL);
+  } else if (tagtype == G_TYPE_DOUBLE) {
+    gst_tag_list_add (reader->taglist, GST_TAG_MERGE_REPLACE, tag->gst_tag,
+        (gdouble) value, NULL);
+  } else {
+    GST_WARNING ("No parsing function associated to %x(%s)", tag->exif_tag,
+        tag->gst_tag);
+  }
+}
+
+static void
 parse_exif_long_tag (GstExifReader * reader, const GstExifTagMatch * tag,
     guint32 count, guint32 offset, const guint8 * offset_as_data)
 {
@@ -1763,6 +1800,10 @@
         parse_exif_long_tag (exif_reader, &tag_map[map_index],
             tagdata.count, tagdata.offset, tagdata.offset_as_data);
         break;
+      case EXIF_TYPE_SHORT:
+        parse_exif_short_tag (exif_reader, &tag_map[map_index],
+            tagdata.count, tagdata.offset, tagdata.offset_as_data);
+        break;
       default:
         GST_WARNING ("Unhandled tag type: %u", tagdata.tag_type);
         break;
@@ -2049,9 +2090,9 @@
 {
   gboolean latitude;
   gdouble value;
-  gint degrees;
-  gint minutes;
-  gint seconds;
+  guint32 degrees;
+  guint32 minutes;
+  guint32 seconds_numerator, seconds_denominator;
   guint32 offset;
 
   latitude = exiftag->exif_tag == EXIF_TAG_GPS_LATITUDE;        /* exif tag for latitude */
@@ -2079,21 +2120,24 @@
   }
 
   /* now write the degrees stuff */
-  GST_LOG ("Converting geo location %lf to degrees", value);
-  degrees = (gint) value;
+  GST_DEBUG ("Converting %lf degrees geo location to HMS", value);
+  degrees = (guint32) value;
   value -= degrees;
-  minutes = (gint) (value * 60);
+  minutes = (guint32) (value * 60);
   value = (value * 60) - minutes;
-  seconds = (gint) (value * 60);
-  GST_LOG ("Converted geo location to %d.%d'%d'' degrees", degrees,
-      minutes, seconds);
+  seconds_denominator = 10000000UL;
+  seconds_numerator = (guint32) (value * 60 * seconds_denominator);
+
+  GST_DEBUG ("Converted rational geo location to %u/%u %u/%u %u/%u degrees ",
+      degrees, 1U, minutes, 1U, seconds_numerator, seconds_denominator);
 
   offset = gst_byte_writer_get_size (&writer->datawriter);
   gst_exif_writer_write_tag_header (writer, exiftag->exif_tag,
       EXIF_TYPE_RATIONAL, 3, offset, NULL);
   gst_exif_writer_write_rational_data (writer, degrees, 1);
   gst_exif_writer_write_rational_data (writer, minutes, 1);
-  gst_exif_writer_write_rational_data (writer, seconds, 1);
+  gst_exif_writer_write_rational_data (writer, seconds_numerator,
+      seconds_denominator);
 }
 
 static gint
@@ -2210,12 +2254,11 @@
   gst_util_fraction_to_double (degrees_n, degrees_d, &degrees);
   gst_util_fraction_to_double (minutes_n, minutes_d, &minutes);
   gst_util_fraction_to_double (seconds_n, seconds_d, &seconds);
-
   minutes += seconds / 60;
   degrees += minutes / 60;
   degrees *= multiplier;
 
-  GST_DEBUG ("Adding %s tag: %lf", exiftag->gst_tag, degrees);
+  GST_DEBUG ("Adding %s tag: %lf degrees", exiftag->gst_tag, degrees);
   gst_tag_list_add (exif_reader->taglist, GST_TAG_MERGE_REPLACE,
       exiftag->gst_tag, degrees, NULL);
 
diff --git a/gst-libs/gst/tag/gsttagdemux.c b/gst-libs/gst/tag/gsttagdemux.c
index 307e871..f0e685d 100644
--- a/gst-libs/gst/tag/gsttagdemux.c
+++ b/gst-libs/gst/tag/gsttagdemux.c
@@ -228,8 +228,7 @@
 {
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_factory));
+  gst_element_class_add_static_pad_template (element_class, &src_factory);
 
   GST_DEBUG_CATEGORY_INIT (tagdemux_debug, "tagdemux", 0,
       "tag demux base class");
@@ -467,6 +466,10 @@
           gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, trim_start,
           out_size);
       g_return_val_if_fail (sub != NULL, FALSE);
+      if (GST_BUFFER_TIMESTAMP_IS_VALID (buf))
+        GST_BUFFER_TIMESTAMP (sub) = GST_BUFFER_TIMESTAMP (buf);
+      if (GST_BUFFER_DURATION_IS_VALID (buf))
+        GST_BUFFER_DURATION (sub) = GST_BUFFER_DURATION (buf);
       gst_buffer_unref (buf);
       *buf_ref = buf = sub;
       *buf_size = out_size;
@@ -1517,8 +1520,7 @@
       }
     } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
       /* for fatal errors we post an error message */
-      GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL),
-          ("Stream stopped, reason %s", reason));
+      GST_ELEMENT_FLOW_ERROR (demux, ret);
       push_eos = TRUE;
     }
     if (push_eos) {
diff --git a/gst-libs/gst/tag/tag.h b/gst-libs/gst/tag/tag.h
index 48631d3..7ca444f 100644
--- a/gst-libs/gst/tag/tag.h
+++ b/gst-libs/gst/tag/tag.h
@@ -152,6 +152,15 @@
 #define GST_TAG_CAPTURING_FOCAL_LENGTH         "capturing-focal-length"
 
 /**
+ * GST_TAG_CAPTURING_FOCAL_LENGTH_35_MM:
+ *
+ * 35 mm equivalent focal length used when capturing an image, in mm. (double)
+ *
+ * Since: 1.10
+ */
+#define GST_TAG_CAPTURING_FOCAL_LENGTH_35_MM   "capturing-focal-length-35mm"
+
+/**
  * GST_TAG_CAPTURING_DIGITAL_ZOOM_RATIO:
  *
  * Digital zoom ratio used when capturing an image. (double)
diff --git a/gst-libs/gst/tag/tags.c b/gst-libs/gst/tag/tags.c
index 1931d18..5a0214d 100644
--- a/gst-libs/gst/tag/tags.c
+++ b/gst-libs/gst/tag/tags.c
@@ -118,6 +118,12 @@
       G_TYPE_DOUBLE, _("capturing focal length"),
       _("Focal length of the lens used capturing the image, in mm"), NULL);
 
+  gst_tag_register_static (GST_TAG_CAPTURING_FOCAL_LENGTH_35_MM,
+      GST_TAG_FLAG_META, G_TYPE_DOUBLE,
+      _("capturing 35 mm equivalent focal length"),
+      _("35 mm equivalent focal length of the lens used capturing the image, "
+          "in mm"), NULL);
+
   gst_tag_register_static (GST_TAG_CAPTURING_DIGITAL_ZOOM_RATIO,
       GST_TAG_FLAG_META, G_TYPE_DOUBLE, _("capturing digital zoom ratio"),
       _("Digital zoom ratio used when capturing an image"), NULL);
diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am
index 93bcbd4..64f4978 100644
--- a/gst-libs/gst/video/Makefile.am
+++ b/gst-libs/gst/video/Makefile.am
@@ -38,6 +38,7 @@
 	gstvideoaffinetransformationmeta.c \
 	gstvideometa.c   	\
 	gstvideopool.c		\
+	videodirection.c	\
 	videoorientation.c	\
 	videooverlay.c          \
 	gstvideodecoder.c       \
@@ -47,7 +48,8 @@
 	video-resampler.c	\
 	video-blend.c		\
 	video-overlay-composition.c \
-	video-multiview.c
+	video-multiview.c	\
+	gstvideotimecode.c
 
 nodist_libgstvideo_@GST_API_VERSION@_la_SOURCES = $(BUILT_SOURCES)
 
@@ -72,6 +74,7 @@
 	gstvideometa.h		\
 	gstvideoaffinetransformationmeta.h \
 	gstvideopool.h		\
+	videodirection.h 	\
 	videoorientation.h 	\
 	videooverlay.h          \
 	gstvideodecoder.h       \
@@ -80,7 +83,8 @@
 	video-resampler.h	\
 	video-blend.h		\
 	video-overlay-composition.h \
-	video-multiview.h
+	video-multiview.h	\
+	gstvideotimecode.h
 
 nodist_libgstvideo_@GST_API_VERSION@include_HEADERS = $(built_headers)
 noinst_HEADERS = gstvideoutilsprivate.h
diff --git a/gst-libs/gst/video/Makefile.in b/gst-libs/gst/video/Makefile.in
index 2a6d511..2ad91c5 100644
--- a/gst-libs/gst/video/Makefile.in
+++ b/gst-libs/gst/video/Makefile.in
@@ -130,6 +130,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -222,6 +223,7 @@
 	libgstvideo_@GST_API_VERSION@_la-gstvideoaffinetransformationmeta.lo \
 	libgstvideo_@GST_API_VERSION@_la-gstvideometa.lo \
 	libgstvideo_@GST_API_VERSION@_la-gstvideopool.lo \
+	libgstvideo_@GST_API_VERSION@_la-videodirection.lo \
 	libgstvideo_@GST_API_VERSION@_la-videoorientation.lo \
 	libgstvideo_@GST_API_VERSION@_la-videooverlay.lo \
 	libgstvideo_@GST_API_VERSION@_la-gstvideodecoder.lo \
@@ -231,7 +233,8 @@
 	libgstvideo_@GST_API_VERSION@_la-video-resampler.lo \
 	libgstvideo_@GST_API_VERSION@_la-video-blend.lo \
 	libgstvideo_@GST_API_VERSION@_la-video-overlay-composition.lo \
-	libgstvideo_@GST_API_VERSION@_la-video-multiview.lo
+	libgstvideo_@GST_API_VERSION@_la-video-multiview.lo \
+	libgstvideo_@GST_API_VERSION@_la-gstvideotimecode.lo
 am__objects_1 = libgstvideo_@GST_API_VERSION@_la-video-enumtypes.lo
 am__objects_2 =
 am__objects_3 = libgstvideo_@GST_API_VERSION@_la-tmp-orc.lo \
@@ -511,6 +514,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -524,6 +530,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -561,6 +570,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -656,6 +666,7 @@
 	gstvideoaffinetransformationmeta.c \
 	gstvideometa.c   	\
 	gstvideopool.c		\
+	videodirection.c	\
 	videoorientation.c	\
 	videooverlay.c          \
 	gstvideodecoder.c       \
@@ -665,7 +676,8 @@
 	video-resampler.c	\
 	video-blend.c		\
 	video-overlay-composition.c \
-	video-multiview.c
+	video-multiview.c	\
+	gstvideotimecode.c
 
 nodist_libgstvideo_@GST_API_VERSION@_la_SOURCES = $(BUILT_SOURCES)
 libgstvideo_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/video
@@ -689,6 +701,7 @@
 	gstvideometa.h		\
 	gstvideoaffinetransformationmeta.h \
 	gstvideopool.h		\
+	videodirection.h 	\
 	videoorientation.h 	\
 	videooverlay.h          \
 	gstvideodecoder.h       \
@@ -697,7 +710,8 @@
 	video-resampler.h	\
 	video-blend.h		\
 	video-overlay-composition.h \
-	video-multiview.h
+	video-multiview.h	\
+	gstvideotimecode.h
 
 nodist_libgstvideo_@GST_API_VERSION@include_HEADERS = $(built_headers)
 noinst_HEADERS = gstvideoutilsprivate.h
@@ -813,6 +827,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-gstvideometa.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-gstvideopool.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-gstvideosink.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-gstvideotimecode.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-gstvideoutils.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-gstvideoutilsprivate.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-navigation.Plo@am__quote@
@@ -833,6 +848,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-video-scaler.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-video-tile.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-video.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-videodirection.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-videoorientation.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-videooverlay.Plo@am__quote@
 
@@ -1000,6 +1016,13 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstvideo_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -c -o libgstvideo_@GST_API_VERSION@_la-gstvideopool.lo `test -f 'gstvideopool.c' || echo '$(srcdir)/'`gstvideopool.c
 
+libgstvideo_@GST_API_VERSION@_la-videodirection.lo: videodirection.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstvideo_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -MT libgstvideo_@GST_API_VERSION@_la-videodirection.lo -MD -MP -MF $(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-videodirection.Tpo -c -o libgstvideo_@GST_API_VERSION@_la-videodirection.lo `test -f 'videodirection.c' || echo '$(srcdir)/'`videodirection.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-videodirection.Tpo $(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-videodirection.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='videodirection.c' object='libgstvideo_@GST_API_VERSION@_la-videodirection.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 $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstvideo_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -c -o libgstvideo_@GST_API_VERSION@_la-videodirection.lo `test -f 'videodirection.c' || echo '$(srcdir)/'`videodirection.c
+
 libgstvideo_@GST_API_VERSION@_la-videoorientation.lo: videoorientation.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstvideo_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -MT libgstvideo_@GST_API_VERSION@_la-videoorientation.lo -MD -MP -MF $(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-videoorientation.Tpo -c -o libgstvideo_@GST_API_VERSION@_la-videoorientation.lo `test -f 'videoorientation.c' || echo '$(srcdir)/'`videoorientation.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-videoorientation.Tpo $(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-videoorientation.Plo
@@ -1070,6 +1093,13 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstvideo_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -c -o libgstvideo_@GST_API_VERSION@_la-video-multiview.lo `test -f 'video-multiview.c' || echo '$(srcdir)/'`video-multiview.c
 
+libgstvideo_@GST_API_VERSION@_la-gstvideotimecode.lo: gstvideotimecode.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstvideo_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -MT libgstvideo_@GST_API_VERSION@_la-gstvideotimecode.lo -MD -MP -MF $(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-gstvideotimecode.Tpo -c -o libgstvideo_@GST_API_VERSION@_la-gstvideotimecode.lo `test -f 'gstvideotimecode.c' || echo '$(srcdir)/'`gstvideotimecode.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-gstvideotimecode.Tpo $(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-gstvideotimecode.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gstvideotimecode.c' object='libgstvideo_@GST_API_VERSION@_la-gstvideotimecode.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 $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstvideo_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -c -o libgstvideo_@GST_API_VERSION@_la-gstvideotimecode.lo `test -f 'gstvideotimecode.c' || echo '$(srcdir)/'`gstvideotimecode.c
+
 libgstvideo_@GST_API_VERSION@_la-tmp-orc.lo: tmp-orc.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstvideo_@GST_API_VERSION@_la_CFLAGS) $(CFLAGS) -MT libgstvideo_@GST_API_VERSION@_la-tmp-orc.lo -MD -MP -MF $(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-tmp-orc.Tpo -c -o libgstvideo_@GST_API_VERSION@_la-tmp-orc.lo `test -f 'tmp-orc.c' || echo '$(srcdir)/'`tmp-orc.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-tmp-orc.Tpo $(DEPDIR)/libgstvideo_@GST_API_VERSION@_la-tmp-orc.Plo
diff --git a/gst-libs/gst/video/gstvideoaffinetransformationmeta.h b/gst-libs/gst/video/gstvideoaffinetransformationmeta.h
index 3838a01..f1ee629 100644
--- a/gst-libs/gst/video/gstvideoaffinetransformationmeta.h
+++ b/gst-libs/gst/video/gstvideoaffinetransformationmeta.h
@@ -45,6 +45,13 @@
  * matrix. The transformation matrix can be composed with
  * gst_video_affine_transformation_meta_apply_matrix().
  *
+ * The vertices operated on are all in the range 0 to 1, not in
+ * Normalized Device Coordinates (-1 to +1). Transforming points in this space
+ * are assumed to have an origin at (0.5, 0.5, 0.5) in a left-handed coordinate
+ * system with the x-axis moving horizontally (positive values to the right),
+ * the y-axis moving vertically (positive values up the screen) and the z-axis
+ * perpendicular to the screen (positive values into the screen).
+ *
  * Since: 1.8
  */
 
diff --git a/gst-libs/gst/video/gstvideodecoder.c b/gst-libs/gst/video/gstvideodecoder.c
index 068b25a..57c5728 100644
--- a/gst-libs/gst/video/gstvideodecoder.c
+++ b/gst-libs/gst/video/gstvideodecoder.c
@@ -216,7 +216,7 @@
  *   gather queue:  9  8  7
  *                        D
  *
- * Whe buffer 4 is received (with a DISCONT), we flush the gather queue like
+ * When buffer 4 is received (with a DISCONT), we flush the gather queue like
  * this:
  *
  *   while (gather)
@@ -920,6 +920,7 @@
   }
 }
 
+/* This function has to be called with the stream lock taken. */
 static GstFlowReturn
 gst_video_decoder_drain_out (GstVideoDecoder * dec, gboolean at_eos)
 {
@@ -927,8 +928,6 @@
   GstVideoDecoderPrivate *priv = dec->priv;
   GstFlowReturn ret = GST_FLOW_OK;
 
-  GST_VIDEO_DECODER_STREAM_LOCK (dec);
-
   if (dec->input_segment.rate > 0.0) {
     /* Forward mode, if unpacketized, give the child class
      * a final chance to flush out packets */
@@ -951,8 +950,6 @@
     ret = gst_video_decoder_flush_parse (dec, TRUE);
   }
 
-  GST_VIDEO_DECODER_STREAM_UNLOCK (dec);
-
   return ret;
 }
 
@@ -1104,11 +1101,11 @@
     {
       GstFlowReturn flow_ret = GST_FLOW_OK;
 
+      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
       flow_ret = gst_video_decoder_drain_out (decoder, FALSE);
       ret = (flow_ret == GST_FLOW_OK);
 
       GST_DEBUG_OBJECT (decoder, "received STREAM_START. Clearing taglist");
-      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
       /* Flush upstream tags after a STREAM_START */
       if (priv->upstream_tags) {
         gst_tag_list_unref (priv->upstream_tags);
@@ -1138,7 +1135,9 @@
     {
       GstFlowReturn flow_ret = GST_FLOW_OK;
 
+      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
       flow_ret = gst_video_decoder_drain_out (decoder, TRUE);
+      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
       ret = (flow_ret == GST_FLOW_OK);
 
       /* Forward SEGMENT_DONE immediately. This is required
@@ -1157,7 +1156,9 @@
     {
       GstFlowReturn flow_ret = GST_FLOW_OK;
 
+      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
       flow_ret = gst_video_decoder_drain_out (decoder, TRUE);
+      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
       ret = (flow_ret == GST_FLOW_OK);
 
       /* Error out even if EOS was ok when we had input, but no output */
@@ -1185,11 +1186,11 @@
       GList *events;
       GList *frame_events;
 
+      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
       flow_ret = gst_video_decoder_drain_out (decoder, FALSE);
       ret = (flow_ret == GST_FLOW_OK);
 
       /* Ensure we have caps before forwarding the event */
-      GST_VIDEO_DECODER_STREAM_LOCK (decoder);
       if (!decoder->priv->output_state) {
         if (!gst_video_decoder_negotiate_default_caps (decoder)) {
           GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
@@ -1237,7 +1238,9 @@
       if (gst_video_event_parse_still_frame (event, &in_still)) {
         if (in_still) {
           GST_DEBUG_OBJECT (decoder, "draining current data for still-frame");
+          GST_VIDEO_DECODER_STREAM_LOCK (decoder);
           flow_ret = gst_video_decoder_drain_out (decoder, FALSE);
+          GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
           ret = (flow_ret == GST_FLOW_OK);
         }
         /* Forward STILL_FRAME immediately. Everything is drained after
@@ -1883,6 +1886,7 @@
   GstClockTime pts;
   GstClockTime dts;
   GstClockTime duration;
+  guint flags;
 };
 
 static void
@@ -1909,6 +1913,7 @@
   ts->pts = GST_BUFFER_PTS (buffer);
   ts->dts = GST_BUFFER_DTS (buffer);
   ts->duration = GST_BUFFER_DURATION (buffer);
+  ts->flags = GST_BUFFER_FLAGS (buffer);
 
   priv->timestamps = g_list_append (priv->timestamps, ts);
 }
@@ -1916,7 +1921,7 @@
 static void
 gst_video_decoder_get_timestamp_at_offset (GstVideoDecoder *
     decoder, guint64 offset, GstClockTime * pts, GstClockTime * dts,
-    GstClockTime * duration)
+    GstClockTime * duration, guint * flags)
 {
 #ifndef GST_DISABLE_GST_DEBUG
   guint64 got_offset = 0;
@@ -1927,6 +1932,7 @@
   *pts = GST_CLOCK_TIME_NONE;
   *dts = GST_CLOCK_TIME_NONE;
   *duration = GST_CLOCK_TIME_NONE;
+  *flags = 0;
 
   g = decoder->priv->timestamps;
   while (g) {
@@ -1938,6 +1944,7 @@
       *pts = ts->pts;
       *dts = ts->dts;
       *duration = ts->duration;
+      *flags = ts->flags;
       g = g->next;
       decoder->priv->timestamps = g_list_remove (decoder->priv->timestamps, ts);
       timestamp_free (ts);
@@ -2089,6 +2096,12 @@
 
   g_return_val_if_fail (priv->packetized || klass->parse, GST_FLOW_ERROR);
 
+  /* Draining on DISCONT is handled in chain_reverse() for reverse playback,
+   * and this function would only be called to get everything collected GOP
+   * by GOP in the parse_gather list */
+  if (decoder->input_segment.rate > 0.0 && GST_BUFFER_IS_DISCONT (buf))
+    ret = gst_video_decoder_drain_out (decoder, FALSE);
+
   if (priv->current_frame == NULL)
     priv->current_frame = gst_video_decoder_new_frame (decoder);
 
@@ -2098,7 +2111,9 @@
   priv->input_offset += gst_buffer_get_size (buf);
 
   if (priv->packetized) {
+    gboolean was_keyframe = FALSE;
     if (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT)) {
+      was_keyframe = TRUE;
       GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (priv->current_frame);
     }
 
@@ -2111,6 +2126,16 @@
       ret = gst_video_decoder_decode_frame (decoder, priv->current_frame);
     }
     priv->current_frame = NULL;
+    /* If in trick mode and it was a keyframe, drain decoder to avoid extra
+     * latency. Only do this for forwards playback as reverse playback handles
+     * draining on keyframes in flush_parse(), and would otherwise call back
+     * from drain_out() to here causing an infinite loop.
+     * Also this function is only called for reverse playback to gather frames
+     * GOP by GOP, and does not do any actual decoding. That would be done by
+     * flush_decode() */
+    if (was_keyframe && decoder->input_segment.rate > 0.0
+        && (decoder->input_segment.flags & GST_SEEK_FLAG_TRICKMODE_KEY_UNITS))
+      gst_video_decoder_drain_out (decoder, FALSE);
   } else {
     gst_adapter_push (priv->input_adapter, buf);
 
@@ -2981,7 +3006,6 @@
 
   if (priv->discont) {
     GST_BUFFER_FLAG_SET (output_buffer, GST_BUFFER_FLAG_DISCONT);
-    priv->discont = FALSE;
   }
 
   if (decoder_class->transform_meta) {
@@ -3099,6 +3123,31 @@
     goto done;
   }
 
+  /* Is buffer too late (QoS) ? */
+  if (GST_CLOCK_TIME_IS_VALID (priv->earliest_time)
+      && GST_CLOCK_TIME_IS_VALID (cstart)) {
+    GstClockTime deadline =
+        gst_segment_to_running_time (segment, GST_FORMAT_TIME, cstart);
+    if (GST_CLOCK_TIME_IS_VALID (deadline) && deadline < priv->earliest_time) {
+      GST_DEBUG_OBJECT (decoder,
+          "Dropping frame due to QoS. start:%" GST_TIME_FORMAT " deadline:%"
+          GST_TIME_FORMAT " earliest_time:%" GST_TIME_FORMAT,
+          GST_TIME_ARGS (start), GST_TIME_ARGS (deadline),
+          GST_TIME_ARGS (priv->earliest_time));
+      gst_buffer_unref (buf);
+      priv->discont = TRUE;
+      goto done;
+    }
+  }
+
+  /* Set DISCONT flag here ! */
+
+  if (priv->discont) {
+    GST_DEBUG_OBJECT (decoder, "Setting discont on output buffer");
+    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
+    priv->discont = FALSE;
+  }
+
   /* update rate estimate */
   GST_OBJECT_LOCK (decoder);
   priv->bytes_out += gst_buffer_get_size (buf);
@@ -3225,6 +3274,7 @@
   GstBuffer *buffer;
   int n_available;
   GstClockTime pts, dts, duration;
+  guint flags;
   GstFlowReturn ret = GST_FLOW_OK;
 
   GST_LOG_OBJECT (decoder, "have_frame");
@@ -3241,11 +3291,16 @@
   priv->current_frame->input_buffer = buffer;
 
   gst_video_decoder_get_timestamp_at_offset (decoder,
-      priv->frame_offset, &pts, &dts, &duration);
+      priv->frame_offset, &pts, &dts, &duration, &flags);
 
   GST_BUFFER_PTS (buffer) = pts;
   GST_BUFFER_DTS (buffer) = dts;
   GST_BUFFER_DURATION (buffer) = duration;
+  GST_BUFFER_FLAGS (buffer) = flags;
+
+  if (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT)) {
+    GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (priv->current_frame);
+  }
 
   GST_LOG_OBJECT (decoder, "collected frame size %d, "
       "PTS %" GST_TIME_FORMAT ", DTS %" GST_TIME_FORMAT ", dur %"
@@ -3253,7 +3308,7 @@
       GST_TIME_ARGS (duration));
 
   /* In reverse playback, just capture and queue frames for later processing */
-  if (decoder->output_segment.rate < 0.0) {
+  if (decoder->input_segment.rate < 0.0) {
     priv->parse_gather =
         g_list_prepend (priv->parse_gather, priv->current_frame);
   } else {
@@ -3309,9 +3364,9 @@
   frame->abidata.ABI.ts = frame->dts;
   frame->abidata.ABI.ts2 = frame->pts;
 
-  GST_LOG_OBJECT (decoder, "PTS %" GST_TIME_FORMAT ", DTS %" GST_TIME_FORMAT,
-      GST_TIME_ARGS (frame->pts), GST_TIME_ARGS (frame->dts));
-  GST_LOG_OBJECT (decoder, "dist %d", frame->distance_from_sync);
+  GST_LOG_OBJECT (decoder, "PTS %" GST_TIME_FORMAT ", DTS %" GST_TIME_FORMAT
+      ", dist %d", GST_TIME_ARGS (frame->pts), GST_TIME_ARGS (frame->dts),
+      frame->distance_from_sync);
 
   gst_video_codec_frame_ref (frame);
   priv->frames = g_list_append (priv->frames, frame);
@@ -3709,6 +3764,8 @@
 
   if (state->caps == NULL)
     state->caps = gst_video_info_to_caps (&state->info);
+  if (state->allocation_caps == NULL)
+    state->allocation_caps = gst_caps_ref (state->caps);
 
   GST_DEBUG_OBJECT (decoder, "setting caps %" GST_PTR_FORMAT, state->caps);
 
@@ -3757,7 +3814,7 @@
     goto done;
   decoder->priv->output_state_changed = FALSE;
   /* Negotiate pool */
-  ret = gst_video_decoder_negotiate_pool (decoder, state->caps);
+  ret = gst_video_decoder_negotiate_pool (decoder, state->allocation_caps);
 
 done:
   return ret;
diff --git a/gst-libs/gst/video/gstvideodecoder.h b/gst-libs/gst/video/gstvideodecoder.h
index 34fa113..02e6753 100644
--- a/gst-libs/gst/video/gstvideodecoder.h
+++ b/gst-libs/gst/video/gstvideodecoder.h
@@ -40,7 +40,7 @@
   (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_VIDEO_DECODER,GstVideoDecoderClass))
 #define GST_IS_VIDEO_DECODER(obj) \
   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VIDEO_DECODER))
-#define GST_IS_VIDEO_DECODER_CLASS(obj) \
+#define GST_IS_VIDEO_DECODER_CLASS(klass) \
   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VIDEO_DECODER))
 #define GST_VIDEO_DECODER_CAST(obj) ((GstVideoDecoder *)(obj))
 
diff --git a/gst-libs/gst/video/gstvideoencoder.c b/gst-libs/gst/video/gstvideoencoder.c
index abbde9a..6765e28 100644
--- a/gst-libs/gst/video/gstvideoencoder.c
+++ b/gst-libs/gst/video/gstvideoencoder.c
@@ -1605,6 +1605,9 @@
     encoder->priv->output_state_changed = FALSE;
   }
 
+  if (state->allocation_caps == NULL)
+    state->allocation_caps = gst_caps_ref (state->caps);
+
   /* Push all pending pre-caps events of the oldest frame before
    * setting caps */
   frame = encoder->priv->frames ? encoder->priv->frames->data : NULL;
@@ -1643,7 +1646,7 @@
   if (!ret)
     goto done;
 
-  query = gst_query_new_allocation (state->caps, TRUE);
+  query = gst_query_new_allocation (state->allocation_caps, TRUE);
   if (!gst_pad_peer_query (encoder->srcpad, query)) {
     GST_DEBUG_OBJECT (encoder, "didn't get downstream ALLOCATION hints");
   }
diff --git a/gst-libs/gst/video/gstvideoencoder.h b/gst-libs/gst/video/gstvideoencoder.h
index 171d3c9..9282b1c 100644
--- a/gst-libs/gst/video/gstvideoencoder.h
+++ b/gst-libs/gst/video/gstvideoencoder.h
@@ -39,7 +39,7 @@
   (G_TYPE_INSTANCE_GET_CLASS((obj),GST_TYPE_VIDEO_ENCODER,GstVideoEncoderClass))
 #define GST_IS_VIDEO_ENCODER(obj) \
   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VIDEO_ENCODER))
-#define GST_IS_VIDEO_ENCODER_CLASS(obj) \
+#define GST_IS_VIDEO_ENCODER_CLASS(klass) \
   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VIDEO_ENCODER))
 #define GST_VIDEO_ENCODER_CAST(enc) ((GstVideoEncoder*)enc)
 
diff --git a/gst-libs/gst/video/gstvideometa.c b/gst-libs/gst/video/gstvideometa.c
index 30c259c..06dea5d 100644
--- a/gst-libs/gst/video/gstvideometa.c
+++ b/gst-libs/gst/video/gstvideometa.c
@@ -43,6 +43,24 @@
 #endif /* GST_DISABLE_GST_DEBUG */
 
 static gboolean
+gst_video_meta_init (GstMeta * meta, gpointer params, GstBuffer * buffer)
+{
+  GstVideoMeta *emeta = (GstVideoMeta *) meta;
+
+  emeta->buffer = NULL;
+  emeta->flags = GST_VIDEO_FRAME_FLAG_NONE;
+  emeta->format = GST_VIDEO_FORMAT_UNKNOWN;
+  emeta->id = 0;
+  emeta->width = emeta->height = emeta->n_planes = 0;
+  memset (emeta->offset, 0, sizeof (emeta->offset));
+  memset (emeta->stride, 0, sizeof (emeta->stride));
+  emeta->map = NULL;
+  emeta->unmap = NULL;
+
+  return TRUE;
+}
+
+static gboolean
 gst_video_meta_transform (GstBuffer * dest, GstMeta * meta,
     GstBuffer * buffer, GQuark type, gpointer data)
 {
@@ -113,7 +131,7 @@
   if (g_once_init_enter (&video_meta_info)) {
     const GstMetaInfo *meta =
         gst_meta_register (GST_VIDEO_META_API_TYPE, "GstVideoMeta",
-        sizeof (GstVideoMeta), (GstMetaInitFunction) NULL,
+        sizeof (GstVideoMeta), (GstMetaInitFunction) gst_video_meta_init,
         (GstMetaFreeFunction) NULL, gst_video_meta_transform);
     g_once_init_leave (&video_meta_info, meta);
   }
@@ -425,6 +443,15 @@
   return type;
 }
 
+static gboolean
+gst_video_crop_meta_init (GstMeta * meta, gpointer params, GstBuffer * buffer)
+{
+  GstVideoCropMeta *emeta = (GstVideoCropMeta *) meta;
+  emeta->x = emeta->y = emeta->width = emeta->height = 0;
+
+  return TRUE;
+}
+
 const GstMetaInfo *
 gst_video_crop_meta_get_info (void)
 {
@@ -433,7 +460,8 @@
   if (g_once_init_enter (&video_crop_meta_info)) {
     const GstMetaInfo *meta =
         gst_meta_register (GST_VIDEO_CROP_META_API_TYPE, "GstVideoCropMeta",
-        sizeof (GstVideoCropMeta), (GstMetaInitFunction) NULL,
+        sizeof (GstVideoCropMeta),
+        (GstMetaInitFunction) gst_video_crop_meta_init,
         (GstMetaFreeFunction) NULL, gst_video_crop_meta_transform);
     g_once_init_leave (&video_crop_meta_info, meta);
   }
@@ -474,6 +502,25 @@
   return type;
 }
 
+static gboolean
+gst_video_gl_texture_upload_meta_init (GstMeta * meta, gpointer params,
+    GstBuffer * buffer)
+{
+  GstVideoGLTextureUploadMeta *vmeta = (GstVideoGLTextureUploadMeta *) meta;
+
+  vmeta->texture_orientation =
+      GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL;
+  vmeta->n_textures = 0;
+  memset (vmeta->texture_type, 0, sizeof (vmeta->texture_type));
+  vmeta->buffer = NULL;
+  vmeta->upload = NULL;
+  vmeta->user_data = NULL;
+  vmeta->user_data_copy = NULL;
+  vmeta->user_data_free = NULL;
+
+  return TRUE;
+}
+
 static void
 gst_video_gl_texture_upload_meta_free (GstMeta * meta, GstBuffer * buffer)
 {
@@ -532,7 +579,7 @@
         gst_meta_register (GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE,
         "GstVideoGLTextureUploadMeta",
         sizeof (GstVideoGLTextureUploadMeta),
-        NULL,
+        gst_video_gl_texture_upload_meta_init,
         gst_video_gl_texture_upload_meta_free,
         gst_video_gl_texture_upload_meta_transform);
     g_once_init_leave (&info, meta);
@@ -682,6 +729,7 @@
     GstBuffer * buffer)
 {
   GstVideoRegionOfInterestMeta *emeta = (GstVideoRegionOfInterestMeta *) meta;
+  emeta->roi_type = 0;
   emeta->id = 0;
   emeta->parent_id = 0;
   emeta->x = emeta->y = emeta->w = emeta->h = 0;
@@ -798,3 +846,141 @@
 
   return meta;
 }
+
+/* Time Code Meta implementation *******************************************/
+
+GType
+gst_video_time_code_meta_api_get_type (void)
+{
+  static volatile GType type;
+
+  if (g_once_init_enter (&type)) {
+    static const gchar *tags[] = { NULL };
+    GType _type = gst_meta_api_type_register ("GstVideoTimeCodeMetaAPI", tags);
+    GST_INFO ("registering");
+    g_once_init_leave (&type, _type);
+  }
+  return type;
+}
+
+
+static gboolean
+gst_video_time_code_meta_transform (GstBuffer * dest, GstMeta * meta,
+    GstBuffer * buffer, GQuark type, gpointer data)
+{
+  GstVideoTimeCodeMeta *dmeta, *smeta;
+
+  if (GST_META_TRANSFORM_IS_COPY (type)) {
+    smeta = (GstVideoTimeCodeMeta *) meta;
+
+    GST_DEBUG ("copy time code metadata");
+    dmeta =
+        gst_buffer_add_video_time_code_meta_full (dest, smeta->tc.config.fps_n,
+        smeta->tc.config.fps_d, smeta->tc.config.latest_daily_jam,
+        smeta->tc.config.flags, smeta->tc.hours, smeta->tc.minutes,
+        smeta->tc.seconds, smeta->tc.frames, smeta->tc.field_count);
+    if (!dmeta)
+      return FALSE;
+  } else {
+    /* return FALSE, if transform type is not supported */
+    return FALSE;
+  }
+  return TRUE;
+}
+
+static gboolean
+gst_video_time_code_meta_init (GstMeta * meta, gpointer params,
+    GstBuffer * buffer)
+{
+  GstVideoTimeCodeMeta *emeta = (GstVideoTimeCodeMeta *) meta;
+  memset (&emeta->tc, 0, sizeof (emeta->tc));
+  gst_video_time_code_clear (&emeta->tc);
+
+  return TRUE;
+}
+
+static void
+gst_video_time_code_meta_free (GstMeta * meta, GstBuffer * buffer)
+{
+  GstVideoTimeCodeMeta *emeta = (GstVideoTimeCodeMeta *) meta;
+
+  gst_video_time_code_clear (&emeta->tc);
+}
+
+const GstMetaInfo *
+gst_video_time_code_meta_get_info (void)
+{
+  static const GstMetaInfo *meta_info = NULL;
+
+  if (g_once_init_enter (&meta_info)) {
+    const GstMetaInfo *mi =
+        gst_meta_register (GST_VIDEO_TIME_CODE_META_API_TYPE,
+        "GstVideoTimeCodeMeta",
+        sizeof (GstVideoTimeCodeMeta),
+        gst_video_time_code_meta_init,
+        gst_video_time_code_meta_free,
+        gst_video_time_code_meta_transform);
+    g_once_init_leave (&meta_info, mi);
+  }
+  return meta_info;
+}
+
+/**
+ * gst_buffer_add_video_time_code_meta:
+ * @buffer: a #GstBuffer
+ * @tc: a #GstVideoTimeCode
+ *
+ * Attaches #GstVideoTimeCodeMeta metadata to @buffer with the given
+ * parameters.
+ *
+ * Returns: (transfer none): the #GstVideoTimeCodeMeta on @buffer.
+ *
+ * Since: 1.10
+ */
+GstVideoTimeCodeMeta *
+gst_buffer_add_video_time_code_meta (GstBuffer * buffer, GstVideoTimeCode * tc)
+{
+  g_return_val_if_fail (gst_video_time_code_is_valid (tc), NULL);
+  return gst_buffer_add_video_time_code_meta_full (buffer, tc->config.fps_n,
+      tc->config.fps_d, tc->config.latest_daily_jam, tc->config.flags,
+      tc->hours, tc->minutes, tc->seconds, tc->frames, tc->field_count);
+}
+
+/**
+ * gst_buffer_add_video_time_code_meta_full:
+ * @buffer: a #GstBuffer
+ * @fps_n: framerate numerator
+ * @fps_d: framerate denominator
+ * @latest_daily_jam: a #GDateTime for the latest daily jam
+ * @flags: a #GstVideoTimeCodeFlags
+ * @hours: hours since the daily jam
+ * @minutes: minutes since the daily jam
+ * @seconds: seconds since the daily jam
+ * @frames: frames since the daily jam
+ * @field_count: fields since the daily jam
+ *
+ * Attaches #GstVideoTimeCodeMeta metadata to @buffer with the given
+ * parameters.
+ *
+ * Returns: (transfer none): the #GstVideoTimeCodeMeta on @buffer.
+ *
+ * Since: 1.10
+ */
+GstVideoTimeCodeMeta *
+gst_buffer_add_video_time_code_meta_full (GstBuffer * buffer, guint fps_n,
+    guint fps_d, GDateTime * latest_daily_jam, GstVideoTimeCodeFlags flags,
+    guint hours, guint minutes, guint seconds, guint frames, guint field_count)
+{
+  GstVideoTimeCodeMeta *meta;
+
+  g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
+
+  meta = (GstVideoTimeCodeMeta *) gst_buffer_add_meta (buffer,
+      GST_VIDEO_TIME_CODE_META_INFO, NULL);
+  gst_video_time_code_init (&meta->tc, fps_n, fps_d, latest_daily_jam, flags,
+      hours, minutes, seconds, frames, field_count);
+
+  g_return_val_if_fail (gst_video_time_code_is_valid (&meta->tc), NULL);
+
+  return meta;
+}
diff --git a/gst-libs/gst/video/gstvideometa.h b/gst-libs/gst/video/gstvideometa.h
index deb793d..d5e1562 100644
--- a/gst-libs/gst/video/gstvideometa.h
+++ b/gst-libs/gst/video/gstvideometa.h
@@ -23,6 +23,7 @@
 #include <gst/gst.h>
 
 #include <gst/video/video.h>
+#include <gst/video/gstvideotimecode.h>
 
 G_BEGIN_DECLS
 
@@ -295,6 +296,46 @@
                                                                                guint         w,
                                                                                guint         h);
 
+/**
+ * GstVideoTimeCodeMeta:
+ * @meta: parent #GstMeta
+ * @tc: the GstVideoTimeCode to attach
+ *
+ * Extra buffer metadata describing the GstVideoTimeCode of the frame.
+ *
+ * Each frame is assumed to have its own timecode, i.e. they are not
+ * automatically incremented/interpolated.
+ *
+ * Since: 1.10
+ */
+typedef struct {
+  GstMeta meta;
+
+  GstVideoTimeCode tc;
+} GstVideoTimeCodeMeta;
+
+GType              gst_video_time_code_meta_api_get_type (void);
+#define GST_VIDEO_TIME_CODE_META_API_TYPE (gst_video_time_code_meta_api_get_type())
+const GstMetaInfo *gst_video_time_code_meta_get_info (void);
+#define GST_VIDEO_TIME_CODE_META_INFO (gst_video_time_code_meta_get_info())
+
+#define gst_buffer_get_video_time_code_meta(b) \
+        ((GstVideoTimeCodeMeta*)gst_buffer_get_meta((b),GST_VIDEO_TIME_CODE_META_API_TYPE))
+GstVideoTimeCodeMeta *gst_buffer_add_video_time_code_meta    (GstBuffer             * buffer,
+                                                              GstVideoTimeCode      * tc);
+
+GstVideoTimeCodeMeta *
+gst_buffer_add_video_time_code_meta_full                     (GstBuffer             * buffer,
+                                                              guint fps_n,
+                                                              guint fps_d,
+                                                              GDateTime             * latest_daily_jam,
+                                                              GstVideoTimeCodeFlags   flags,
+                                                              guint                   hours,
+                                                              guint                   minutes,
+                                                              guint                   seconds,
+                                                              guint                   frames,
+                                                              guint                   field_count);
+
 G_END_DECLS
 
 #endif /* __GST_VIDEO_META_H__ */
diff --git a/gst-libs/gst/video/gstvideotimecode.c b/gst-libs/gst/video/gstvideotimecode.c
new file mode 100644
index 0000000..dcb9eb1
--- /dev/null
+++ b/gst-libs/gst/video/gstvideotimecode.c
@@ -0,0 +1,625 @@
+/* GStreamer
+ * Copyright (C) <2016> Vivia Nikolaidou <vivia@toolsonair.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.
+ */
+
+#include "gstvideotimecode.h"
+
+G_DEFINE_BOXED_TYPE (GstVideoTimeCode, gst_video_time_code,
+    (GBoxedCopyFunc) gst_video_time_code_copy,
+    (GBoxedFreeFunc) gst_video_time_code_free);
+
+/**
+ * gst_video_time_code_is_valid:
+ * @tc: #GstVideoTimeCode to check
+ *
+ * Returns: whether @tc is a valid timecode (supported frame rate,
+ * hours/minutes/seconds/frames not overflowing)
+ *
+ * Since: 1.10
+ */
+gboolean
+gst_video_time_code_is_valid (const GstVideoTimeCode * tc)
+{
+  g_return_val_if_fail (tc != NULL, FALSE);
+
+  if (tc->hours > 24)
+    return FALSE;
+  if (tc->minutes >= 60)
+    return FALSE;
+  if (tc->seconds >= 60)
+    return FALSE;
+  if (tc->config.fps_d == 0)
+    return FALSE;
+  if ((tc->frames > tc->config.fps_n / tc->config.fps_d)
+      && (tc->config.fps_n != 0 || tc->config.fps_d != 1))
+    return FALSE;
+  if (tc->config.fps_d == 1001) {
+    if (tc->config.fps_n != 30000 && tc->config.fps_n != 60000)
+      return FALSE;
+  } else if (tc->config.fps_n % tc->config.fps_d != 0) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+ * gst_video_time_code_to_string:
+ * @tc: #GstVideoTimeCode to convert
+ *
+ * Returns: the SMPTE ST 2059-1:2015 string representation of @tc. That will
+ * take the form hh:mm:ss:ff . The last separator (between seconds and frames)
+ * may vary:
+ *
+ * ';' for drop-frame, non-interlaced content and for drop-frame interlaced
+ * field 2
+ * ',' for drop-frame interlaced field 1
+ * ':' for non-drop-frame, non-interlaced content and for non-drop-frame
+ * interlaced field 2
+ * '.' for non-drop-frame interlaced field 1
+ *
+ * Since: 1.10
+ */
+gchar *
+gst_video_time_code_to_string (const GstVideoTimeCode * tc)
+{
+  gchar *ret;
+  gboolean top_dot_present;
+  gchar sep;
+
+  g_return_val_if_fail (gst_video_time_code_is_valid (tc), NULL);
+
+  /* Top dot is present for non-interlaced content, and for field 2 in
+   * interlaced content */
+  top_dot_present =
+      !((tc->config.flags & GST_VIDEO_TIME_CODE_FLAGS_INTERLACED) != 0
+      && tc->field_count == 1);
+
+  if (tc->config.flags & GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME)
+    sep = top_dot_present ? ';' : ',';
+  else
+    sep = top_dot_present ? ':' : '.';
+
+  ret =
+      g_strdup_printf ("%02d:%02d:%02d%c%02d", tc->hours, tc->minutes,
+      tc->seconds, sep, tc->frames);
+
+  return ret;
+}
+
+/**
+ * gst_video_time_code_to_date_time:
+ * @tc: #GstVideoTimeCode to convert
+ *
+ * The @tc.config->latest_daily_jam is required to be non-NULL.
+ *
+ * Returns: the #GDateTime representation of @tc.
+ *
+ * Since: 1.10
+ */
+GDateTime *
+gst_video_time_code_to_date_time (const GstVideoTimeCode * tc)
+{
+  GDateTime *ret;
+  GDateTime *ret2;
+  gdouble add_us;
+
+  g_return_val_if_fail (gst_video_time_code_is_valid (tc), NULL);
+  g_return_val_if_fail (tc->config.latest_daily_jam != NULL, NULL);
+
+  ret = g_date_time_ref (tc->config.latest_daily_jam);
+
+  if (ret == NULL) {
+    gchar *tc_str = gst_video_time_code_to_string (tc);
+    GST_WARNING
+        ("Asked to convert time code %s to GDateTime, but its latest daily jam is NULL",
+        tc_str);
+    g_free (tc_str);
+    return NULL;
+  }
+
+  if (tc->config.fps_n == 0 && tc->config.fps_d == 1) {
+    gchar *tc_str = gst_video_time_code_to_string (tc);
+    GST_WARNING
+        ("Asked to convert time code %s to GDateTime, but its framerate is unknown",
+        tc_str);
+    g_free (tc_str);
+    return NULL;
+  }
+
+  gst_util_fraction_to_double (tc->frames * tc->config.fps_d, tc->config.fps_n,
+      &add_us);
+  if ((tc->config.flags & GST_VIDEO_TIME_CODE_FLAGS_INTERLACED)
+      && tc->field_count == 1) {
+    gdouble sub_us;
+
+    gst_util_fraction_to_double (tc->config.fps_d, 2 * tc->config.fps_n,
+        &sub_us);
+    add_us -= sub_us;
+  }
+
+  ret2 = g_date_time_add_seconds (ret, add_us + tc->seconds);
+  g_date_time_unref (ret);
+  ret = g_date_time_add_minutes (ret2, tc->minutes);
+  g_date_time_unref (ret2);
+  ret2 = g_date_time_add_hours (ret, tc->hours);
+  g_date_time_unref (ret);
+
+  return ret2;
+}
+
+/**
+ * gst_video_time_code_nsec_since_daily_jam:
+ * @tc: a #GstVideoTimeCode
+ *
+ * Returns: how many nsec have passed since the daily jam of @tc .
+ *
+ * Since: 1.10
+ */
+guint64
+gst_video_time_code_nsec_since_daily_jam (const GstVideoTimeCode * tc)
+{
+  gdouble nsec;
+
+  g_return_val_if_fail (gst_video_time_code_is_valid (tc), -1);
+
+  if (tc->config.fps_n == 0 && tc->config.fps_d == 1) {
+    gchar *tc_str = gst_video_time_code_to_string (tc);
+    GST_WARNING
+        ("Asked to calculate nsec since daily jam of time code %s, but its framerate is unknown",
+        tc_str);
+    g_free (tc_str);
+    return -1;
+  }
+
+  if ((tc->config.flags & GST_VIDEO_TIME_CODE_FLAGS_INTERLACED)
+      && tc->field_count == 1)
+    nsec =
+        gst_util_uint64_scale (GST_SECOND * tc->frames - 500 * GST_MSECOND,
+        tc->config.fps_d, tc->config.fps_n);
+  else
+    nsec =
+        gst_util_uint64_scale (GST_SECOND * tc->frames, tc->config.fps_d,
+        tc->config.fps_n);
+
+  /* hours <= 24 (daily jam required)
+   * minutes < 60
+   * seconds < 60
+   * this can't overflow */
+  nsec += GST_SECOND * (tc->seconds + (60 * (tc->minutes + 60 * tc->hours)));
+
+  return nsec;
+}
+
+/**
+ * gst_video_time_code_frames_since_daily_jam:
+ * @tc: a #GstVideoTimeCode
+ *
+ * Returns: how many frames have passed since the daily jam of @tc .
+ *
+ * Since: 1.10
+ */
+guint64
+gst_video_time_code_frames_since_daily_jam (const GstVideoTimeCode * tc)
+{
+  guint ff_nom;
+  gdouble ff;
+
+  g_return_val_if_fail (gst_video_time_code_is_valid (tc), -1);
+  g_assert (tc->hours <= 24);
+  g_assert (tc->minutes < 60);
+  g_assert (tc->seconds < 60);
+  g_assert (tc->frames <= tc->config.fps_n / tc->config.fps_d);
+
+  gst_util_fraction_to_double (tc->config.fps_n, tc->config.fps_d, &ff);
+  if (tc->config.fps_d == 1001) {
+    ff_nom = tc->config.fps_n / 1000;
+  } else {
+    ff_nom = ff;
+  }
+  if (tc->config.flags & GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME) {
+    /* these need to be truncated to integer: side effect, code looks cleaner
+     * */
+    guint ff_minutes = 60 * ff;
+    guint ff_hours = 3600 * ff;
+    /* for 30000/1001 we drop the first 2 frames per minute, for 60000/1001 we
+     * drop the first 4 : so we use this number */
+    guint dropframe_multiplier;
+
+    if (tc->config.fps_n == 30000) {
+      dropframe_multiplier = 2;
+    } else if (tc->config.fps_n == 60000) {
+      dropframe_multiplier = 4;
+    } else {
+      GST_ERROR ("Unsupported drop frame rate %u/%u", tc->config.fps_n,
+          tc->config.fps_d);
+      return -1;
+    }
+
+    return tc->frames + (ff_nom * tc->seconds) +
+        (ff_minutes * tc->minutes) +
+        dropframe_multiplier * ((gint) (tc->minutes / 10)) +
+        (ff_hours * tc->hours);
+  } else {
+    return tc->frames + (ff_nom * (tc->seconds + (60 * (tc->minutes +
+                    (60 * tc->hours)))));
+  }
+
+}
+
+/**
+ * gst_video_time_code_increment_frame:
+ * @tc: a #GstVideoTimeCode
+ *
+ * Adds one frame to @tc .
+ *
+ * Since: 1.10
+ */
+void
+gst_video_time_code_increment_frame (GstVideoTimeCode * tc)
+{
+  return gst_video_time_code_add_frames (tc, 1);
+}
+
+/**
+ * gst_video_time_code_add_frames:
+ * @tc: a #GstVideoTimeCode
+ * @frames: How many frames to add or subtract
+ *
+ * Adds or subtracts @frames amount of frames to @tc .
+ *
+ * Since: 1.10
+ */
+void
+gst_video_time_code_add_frames (GstVideoTimeCode * tc, gint64 frames)
+{
+  guint64 framecount;
+  guint64 h_notmod24;
+  guint64 h_new, min_new, sec_new, frames_new;
+  gdouble ff;
+  guint ff_nom;
+  /* This allows for better readability than putting G_GUINT64_CONSTANT(60)
+   * into a long calculation line */
+  const guint64 sixty = 60;
+  /* formulas found in SMPTE ST 2059-1:2015 section 9.4.3
+   * and adapted for 60/1.001 as well as 30/1.001 */
+
+  g_return_if_fail (gst_video_time_code_is_valid (tc));
+  g_assert (tc->hours <= 24);
+  g_assert (tc->minutes < 60);
+  g_assert (tc->seconds < 60);
+  g_assert (tc->frames <= tc->config.fps_n / tc->config.fps_d);
+
+  gst_util_fraction_to_double (tc->config.fps_n, tc->config.fps_d, &ff);
+  if (tc->config.fps_d == 1001) {
+    ff_nom = tc->config.fps_n / 1000;
+  } else {
+    ff_nom = ff;
+    if (tc->config.fps_d != 1)
+      GST_WARNING ("Unsupported frame rate %u/%u, results may be wrong",
+          tc->config.fps_n, tc->config.fps_d);
+  }
+  if (tc->config.flags & GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME) {
+    /* these need to be truncated to integer: side effect, code looks cleaner
+     * */
+    guint ff_minutes = 60 * ff;
+    guint ff_hours = 3600 * ff;
+    /* a bunch of intermediate variables, to avoid monster code with possible
+     * integer overflows */
+    guint64 min_new_tmp1, min_new_tmp2, min_new_tmp3, min_new_denom;
+    /* for 30000/1001 we drop the first 2 frames per minute, for 60000/1001 we
+     * drop the first 4 : so we use this number */
+    guint dropframe_multiplier;
+
+    if (tc->config.fps_n == 30000)
+      dropframe_multiplier = 2;
+    else if (tc->config.fps_n == 60000)
+      dropframe_multiplier = 4;
+    else {
+      GST_ERROR ("Unsupported drop frame rate %u/%u", tc->config.fps_n,
+          tc->config.fps_d);
+      return;
+    }
+
+    framecount =
+        frames + tc->frames + (ff_nom * tc->seconds) +
+        (ff_minutes * tc->minutes) +
+        dropframe_multiplier * ((gint) (tc->minutes / 10)) +
+        (ff_hours * tc->hours);
+    h_notmod24 = gst_util_uint64_scale_int (framecount, 1, ff_hours);
+
+    min_new_denom = sixty * ff_nom;
+    min_new_tmp1 = (framecount - (h_notmod24 * ff_hours)) / min_new_denom;
+    min_new_tmp2 = framecount + dropframe_multiplier * min_new_tmp1;
+    min_new_tmp1 =
+        (framecount - (h_notmod24 * ff_hours)) / (sixty * 10 * ff_nom);
+    min_new_tmp3 =
+        dropframe_multiplier * min_new_tmp1 + (h_notmod24 * ff_hours);
+    min_new =
+        gst_util_uint64_scale_int (min_new_tmp2 - min_new_tmp3, 1,
+        min_new_denom);
+
+    sec_new =
+        (guint64) ((framecount - (ff_minutes * min_new) -
+            dropframe_multiplier * ((gint) (min_new / 10)) -
+            (ff_hours * h_notmod24)) / ff_nom);
+
+    frames_new =
+        framecount - (ff_nom * sec_new) - (ff_minutes * min_new) -
+        (dropframe_multiplier * ((gint) (min_new / 10))) -
+        (ff_hours * h_notmod24);
+  } else {
+    framecount =
+        frames + tc->frames + (ff_nom * (tc->seconds + (sixty * (tc->minutes +
+                    (sixty * tc->hours)))));
+    h_notmod24 =
+        gst_util_uint64_scale_int (framecount, 1, ff_nom * sixty * sixty);
+    min_new =
+        gst_util_uint64_scale_int ((framecount -
+            (ff_nom * sixty * sixty * h_notmod24)), 1, (ff_nom * sixty));
+    sec_new =
+        gst_util_uint64_scale_int ((framecount - (ff_nom * sixty * (min_new +
+                    (sixty * h_notmod24)))), 1, ff_nom);
+    frames_new =
+        framecount - (ff_nom * (sec_new + sixty * (min_new +
+                (sixty * h_notmod24))));
+    if (frames_new > ff_nom)
+      frames_new = 0;
+  }
+  h_new = h_notmod24 % 24;
+
+  g_assert (min_new < 60);
+  g_assert (sec_new < 60);
+  g_assert (frames_new < ff_nom);
+  tc->hours = h_new;
+  tc->minutes = min_new;
+  tc->seconds = sec_new;
+  tc->frames = frames_new;
+}
+
+/**
+ * gst_video_time_code_compare:
+ * @tc1: a #GstVideoTimeCode
+ * @tc2: another #GstVideoTimeCode
+ *
+ * Compares @tc1 and @tc2 . If both have latest daily jam information, it is
+ * taken into account. Otherwise, it is assumed that the daily jam of both
+ * @tc1 and @tc2 was at the same time.
+ *
+ * Returns: 1 if @tc1 is after @tc2, -1 if @tc1 is before @tc2, 0 otherwise.
+ *
+ * Since: 1.10
+ */
+gint
+gst_video_time_code_compare (const GstVideoTimeCode * tc1,
+    const GstVideoTimeCode * tc2)
+{
+  g_return_val_if_fail (gst_video_time_code_is_valid (tc1), -1);
+  g_return_val_if_fail (gst_video_time_code_is_valid (tc2), -1);
+
+  if (tc1->config.latest_daily_jam == NULL
+      || tc2->config.latest_daily_jam == NULL) {
+    guint64 nsec1, nsec2;
+#ifndef GST_DISABLE_GST_DEBUG
+    gchar *str1, *str2;
+
+    str1 = gst_video_time_code_to_string (tc1);
+    str2 = gst_video_time_code_to_string (tc2);
+    GST_INFO
+        ("Comparing time codes %s and %s, but at least one of them has no "
+        "latest daily jam information. Assuming they started together",
+        str1, str2);
+    g_free (str1);
+    g_free (str2);
+#endif
+    if (tc1->hours > tc2->hours) {
+      return 1;
+    } else if (tc1->hours < tc2->hours) {
+      return -1;
+    }
+    if (tc1->minutes > tc2->minutes) {
+      return 1;
+    } else if (tc1->minutes < tc2->minutes) {
+      return -1;
+    }
+    if (tc1->seconds > tc2->seconds) {
+      return 1;
+    } else if (tc1->seconds < tc2->seconds) {
+      return -1;
+    }
+
+    nsec1 =
+        gst_util_uint64_scale (GST_SECOND,
+        tc1->frames * tc1->config.fps_n, tc1->config.fps_d);
+    nsec2 =
+        gst_util_uint64_scale (GST_SECOND,
+        tc2->frames * tc2->config.fps_n, tc2->config.fps_d);
+    if (nsec1 > nsec2) {
+      return 1;
+    } else if (nsec1 < nsec2) {
+      return -1;
+    }
+    if (tc1->config.flags & GST_VIDEO_TIME_CODE_FLAGS_INTERLACED) {
+      if (tc1->field_count > tc2->field_count)
+        return 1;
+      else if (tc1->field_count < tc2->field_count)
+        return -1;
+    }
+    return 0;
+  } else {
+    GDateTime *dt1, *dt2;
+    gint ret;
+
+    dt1 = gst_video_time_code_to_date_time (tc1);
+    dt2 = gst_video_time_code_to_date_time (tc2);
+
+    ret = g_date_time_compare (dt1, dt2);
+
+    g_date_time_unref (dt1);
+    g_date_time_unref (dt2);
+
+    return ret;
+  }
+}
+
+/**
+ * gst_video_time_code_new:
+ * @fps_n: Numerator of the frame rate
+ * @fps_d: Denominator of the frame rate
+ * @latest_daily_jam: The latest daily jam of the #GstVideoTimeCode
+ * @flags: #GstVideoTimeCodeFlags
+ * @hours: the hours field of #GstVideoTimeCode
+ * @minutes: the minutes field of #GstVideoTimeCode
+ * @seconds: the seconds field of #GstVideoTimeCode
+ * @frames: the frames field of #GstVideoTimeCode
+ * @field_count: Interlaced video field count
+ *
+ * @field_count is 0 for progressive, 1 or 2 for interlaced.
+ * @latest_daiy_jam reference is stolen from caller.
+ *
+ * Returns: a new #GstVideoTimeCode with the given values.
+ *
+ * Since: 1.10
+ */
+GstVideoTimeCode *
+gst_video_time_code_new (guint fps_n, guint fps_d, GDateTime * latest_daily_jam,
+    GstVideoTimeCodeFlags flags, guint hours, guint minutes, guint seconds,
+    guint frames, guint field_count)
+{
+  GstVideoTimeCode *tc;
+
+  tc = g_new0 (GstVideoTimeCode, 1);
+  gst_video_time_code_init (tc, fps_n, fps_d, latest_daily_jam, flags, hours,
+      minutes, seconds, frames, field_count);
+  return tc;
+}
+
+/**
+ * gst_video_time_code_new_empty:
+ *
+ * Returns: a new empty #GstVideoTimeCode
+ *
+ * Since: 1.10
+ */
+GstVideoTimeCode *
+gst_video_time_code_new_empty (void)
+{
+  GstVideoTimeCode *tc;
+
+  tc = g_new0 (GstVideoTimeCode, 1);
+  gst_video_time_code_clear (tc);
+  return tc;
+}
+
+/**
+ * gst_video_time_code_init:
+ * @tc: a #GstVideoTimeCode
+ * @fps_n: Numerator of the frame rate
+ * @fps_d: Denominator of the frame rate
+ * @latest_daily_jam: The latest daily jam of the #GstVideoTimeCode
+ * @flags: #GstVideoTimeCodeFlags
+ * @hours: the hours field of #GstVideoTimeCode
+ * @minutes: the minutes field of #GstVideoTimeCode
+ * @seconds: the seconds field of #GstVideoTimeCode
+ * @frames: the frames field of #GstVideoTimeCode
+ * @field_count: Interlaced video field count
+ *
+ * @field_count is 0 for progressive, 1 or 2 for interlaced.
+ * @latest_daiy_jam reference is stolen from caller.
+ *
+ * Initializes @tc with the given values.
+ *
+ * Since: 1.10
+ */
+void
+gst_video_time_code_init (GstVideoTimeCode * tc, guint fps_n, guint fps_d,
+    GDateTime * latest_daily_jam, GstVideoTimeCodeFlags flags, guint hours,
+    guint minutes, guint seconds, guint frames, guint field_count)
+{
+  tc->hours = hours;
+  tc->minutes = minutes;
+  tc->seconds = seconds;
+  tc->frames = frames;
+  tc->field_count = field_count;
+  tc->config.fps_n = fps_n;
+  tc->config.fps_d = fps_d;
+  if (latest_daily_jam != NULL)
+    tc->config.latest_daily_jam = g_date_time_ref (latest_daily_jam);
+  else
+    tc->config.latest_daily_jam = NULL;
+  tc->config.flags = flags;
+
+  g_return_if_fail (gst_video_time_code_is_valid (tc));
+}
+
+/**
+ * gst_video_time_code_clear:
+ * @tc: a #GstVideoTimeCode
+ *
+ * Initializes @tc with empty/zero/NULL values.
+ *
+ * Since: 1.10
+ */
+void
+gst_video_time_code_clear (GstVideoTimeCode * tc)
+{
+  tc->hours = 0;
+  tc->minutes = 0;
+  tc->seconds = 0;
+  tc->frames = 0;
+  tc->field_count = 0;
+  tc->config.fps_n = 0;
+  tc->config.fps_d = 1;
+  if (tc->config.latest_daily_jam != NULL)
+    g_date_time_unref (tc->config.latest_daily_jam);
+  tc->config.latest_daily_jam = NULL;
+  tc->config.flags = 0;
+}
+
+/**
+ * gst_video_time_code_copy:
+ * @tc: a #GstVideoTimeCode
+ *
+ * Returns: a new #GstVideoTimeCode with the same values as @tc .
+ *
+ * Since: 1.10
+ */
+GstVideoTimeCode *
+gst_video_time_code_copy (const GstVideoTimeCode * tc)
+{
+  return gst_video_time_code_new (tc->config.fps_n, tc->config.fps_d,
+      tc->config.latest_daily_jam, tc->config.flags, tc->hours, tc->minutes,
+      tc->seconds, tc->frames, tc->field_count);
+}
+
+/**
+ * gst_video_time_code_free:
+ * @tc: a #GstVideoTimeCode
+ *
+ * Frees @tc .
+ *
+ * Since: 1.10
+ */
+void
+gst_video_time_code_free (GstVideoTimeCode * tc)
+{
+  if (tc->config.latest_daily_jam != NULL)
+    g_date_time_unref (tc->config.latest_daily_jam);
+
+  g_free (tc);
+}
diff --git a/gst-libs/gst/video/gstvideotimecode.h b/gst-libs/gst/video/gstvideotimecode.h
new file mode 100644
index 0000000..89c28c0
--- /dev/null
+++ b/gst-libs/gst/video/gstvideotimecode.h
@@ -0,0 +1,151 @@
+/* GStreamer
+ * Copyright (C) <2016> Vivia Nikolaidou <vivia@toolsonair.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.
+ */
+
+#ifndef __GST_VIDEO_TIME_CODE_H__
+#define __GST_VIDEO_TIME_CODE_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GstVideoTimeCodeConfig GstVideoTimeCodeConfig;
+typedef struct _GstVideoTimeCode GstVideoTimeCode;
+
+/**
+ * GstVideoTimeCodeFlags:
+ * @GST_VIDEO_TIME_CODE_FLAGS_NONE: No flags
+ * @GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME: Whether we have drop frame rate
+ * @GST_VIDEO_TIME_CODE_FLAGS_INTERLACED: Whether we have interlaced video
+ *
+ * Flags related to the time code information.
+ * For drop frame, only 30000/1001 and 60000/1001 frame rates are supported.
+ *
+ * Since: 1.10
+ */
+typedef enum
+{
+  GST_VIDEO_TIME_CODE_FLAGS_NONE = 0,
+  GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME = (1<<0),
+  GST_VIDEO_TIME_CODE_FLAGS_INTERLACED = (1<<1)
+  /* Not supported yet:
+   * GST_VIDEO_TIME_CODE_ALLOW_MORE_THAN_24H = (1<<2)
+   * GST_VIDEO_TIME_CODE_ALLOW_NEGATIVE = (1<<3)
+   */
+} GstVideoTimeCodeFlags;
+
+/**
+ * GstVideoTimeCodeConfig:
+ * @fps_n: Numerator of the frame rate
+ * @fps_d: Denominator of the frame rate
+ * @flags: the corresponding #GstVideoTimeCodeFlags
+ * @latest_daily_jam: The latest daily jam information, if present, or NULL
+ *
+ * Supported frame rates: 30000/1001, 60000/1001 (both with and without drop
+ * frame), and integer frame rates e.g. 25/1, 30/1, 50/1, 60/1.
+ *
+ * The configuration of the time code.
+ *
+ * Since: 1.10
+ */
+struct _GstVideoTimeCodeConfig {
+  guint fps_n;
+  guint fps_d;
+  GstVideoTimeCodeFlags flags;
+  GDateTime *latest_daily_jam;
+};
+
+/**
+ * GstVideoTimeCode:
+ * @hours: the hours field of #GstVideoTimeCode
+ * @minutes: the minutes field of #GstVideoTimeCode
+ * @seconds: the seconds field of #GstVideoTimeCode
+ * @frames: the frames field of #GstVideoTimeCode
+ * @field_count: Interlaced video field count
+ * @config: the corresponding #GstVideoTimeCodeConfig
+ *
+ * @field_count must be 0 for progressive video and 1 or 2 for interlaced.
+ *
+ * A representation of a SMPTE time code.
+ *
+ * @hours must be positive and less than 24. Will wrap around otherwise.
+ * @minutes and @seconds must be positive and less than 60.
+ * @frames must be less than or equal to @config.fps_n / @config.fps_d
+ * These values are *NOT* automatically normalized.
+ *
+ * Since: 1.10
+ */
+struct _GstVideoTimeCode {
+  GstVideoTimeCodeConfig config;
+
+  guint hours;
+  guint minutes;
+  guint seconds;
+  guint frames;
+  guint field_count;
+};
+
+#define GST_TYPE_VIDEO_TIME_CODE (gst_video_time_code_get_type())
+GType gst_video_time_code_get_type (void);
+
+GstVideoTimeCode * gst_video_time_code_new          (guint                    fps_n,
+                                                     guint                    fps_d,
+                                                     GDateTime              * latest_daily_jam,
+                                                     GstVideoTimeCodeFlags    flags,
+                                                     guint                    hours,
+                                                     guint                    minutes,
+                                                     guint                    seconds,
+                                                     guint                    frames,
+                                                     guint                    field_count);
+GstVideoTimeCode * gst_video_time_code_new_empty    (void);
+void gst_video_time_code_free                       (GstVideoTimeCode       * tc);
+
+GstVideoTimeCode * gst_video_time_code_copy         (const GstVideoTimeCode * tc);
+
+void gst_video_time_code_init                       (GstVideoTimeCode       * tc,
+                                                     guint                    fps_n,
+                                                     guint                    fps_d,
+                                                     GDateTime              * latest_daily_jam,
+                                                     GstVideoTimeCodeFlags    flags,
+                                                     guint                    hours,
+                                                     guint                    minutes,
+                                                     guint                    seconds,
+                                                     guint                    frames,
+                                                     guint                    field_count);
+void gst_video_time_code_clear                      (GstVideoTimeCode       * tc);
+
+gboolean gst_video_time_code_is_valid               (const GstVideoTimeCode * tc);
+
+gint gst_video_time_code_compare                    (const GstVideoTimeCode * tc1,
+                                                     const GstVideoTimeCode * tc2);
+
+void gst_video_time_code_increment_frame            (GstVideoTimeCode       * tc);
+void gst_video_time_code_add_frames                 (GstVideoTimeCode       * tc,
+                                                     gint64                   frames);
+
+gchar *gst_video_time_code_to_string                (const GstVideoTimeCode * tc);
+
+GDateTime *gst_video_time_code_to_date_time         (const GstVideoTimeCode * tc);
+
+guint64 gst_video_time_code_nsec_since_daily_jam    (const GstVideoTimeCode * tc);
+
+guint64 gst_video_time_code_frames_since_daily_jam  (const GstVideoTimeCode * tc);
+
+G_END_DECLS
+
+#endif /* __GST_VIDEO_TIME_CODE_H__ */
diff --git a/gst-libs/gst/video/gstvideoutils.c b/gst-libs/gst/video/gstvideoutils.c
index b3decaf..8a3a230 100644
--- a/gst-libs/gst/video/gstvideoutils.c
+++ b/gst-libs/gst/video/gstvideoutils.c
@@ -162,6 +162,8 @@
 
   if (state->caps)
     gst_caps_unref (state->caps);
+  if (state->allocation_caps)
+    gst_caps_unref (state->allocation_caps);
   if (state->codec_data)
     gst_buffer_unref (state->codec_data);
   g_slice_free (GstVideoCodecState, state);
diff --git a/gst-libs/gst/video/gstvideoutils.h b/gst-libs/gst/video/gstvideoutils.h
index deea0ee..f7aed89 100644
--- a/gst-libs/gst/video/gstvideoutils.h
+++ b/gst-libs/gst/video/gstvideoutils.h
@@ -41,9 +41,11 @@
 /**
  * GstVideoCodecState:
  * @info: The #GstVideoInfo describing the stream
- * @caps: The #GstCaps
+ * @caps: The #GstCaps used in the caps negotiation of the pad.
  * @codec_data: a #GstBuffer corresponding to the
  *     'codec_data' field of a stream, or NULL.
+ * @allocation_caps: The #GstCaps for allocation query and pool
+ *     negotiation. Since: 1.10
  *
  * Structure representing the state of an incoming or outgoing video
  * stream for encoders and decoders.
@@ -67,8 +69,10 @@
 
   GstBuffer *codec_data;
 
+  GstCaps *allocation_caps;
+
   /*< private >*/
-  void         *padding[GST_PADDING_LARGE];
+  void         *padding[GST_PADDING_LARGE - 1];
 };
 
 /**
diff --git a/gst-libs/gst/video/video-color.c b/gst-libs/gst/video/video-color.c
index efdb3ab..a68bced 100644
--- a/gst-libs/gst/video/video-color.c
+++ b/gst-libs/gst/video/video-color.c
@@ -300,8 +300,8 @@
 const GstVideoColorPrimariesInfo *
 gst_video_color_primaries_get_info (GstVideoColorPrimaries primaries)
 {
-  g_return_val_if_fail (primaries <
-      (GstVideoColorPrimaries) G_N_ELEMENTS (color_primaries), NULL);
+  g_return_val_if_fail ((gint) primaries <
+      G_N_ELEMENTS (color_primaries), NULL);
 
   return &color_primaries[primaries];
 }
diff --git a/gst-libs/gst/video/video-converter.c b/gst-libs/gst/video/video-converter.c
index f29278d..e67a32a 100644
--- a/gst-libs/gst/video/video-converter.c
+++ b/gst-libs/gst/video/video-converter.c
@@ -395,8 +395,6 @@
       g_ptr_array_remove_range (cache->lines, 0, to_remove);
     }
     cache->first += to_remove;
-    if (cache->first < in_line)
-      cache->first = in_line;
   } else if (in_line < cache->first) {
     gst_line_cache_clear (cache);
     cache->first = in_line;
@@ -1457,7 +1455,7 @@
         taps, convert->in_height, convert->out_height, convert->config);
 
     gst_video_scaler_get_coeff (convert->v_scaler_i, 0, NULL, &taps_i);
-    backlog = BACKLOG;
+    backlog = taps_i;
   }
   convert->v_scaler_p =
       gst_video_scaler_new (method, 0, taps, convert->in_height,
@@ -1909,8 +1907,8 @@
     if (!cache->pass_alloc) {
       /* can't pass allocator, make new temp line allocator */
       user_data =
-          converter_alloc_new (sizeof (guint16) * width * 4, n_lines + BACKLOG,
-          convert, NULL);
+          converter_alloc_new (sizeof (guint16) * width * 4,
+          n_lines + cache->backlog, convert, NULL);
       notify = (GDestroyNotify) converter_alloc_free;
       alloc_line = get_temp_line;
       alloc_writable = FALSE;
@@ -3577,6 +3575,7 @@
 
   convert_fill_border (convert, dest);
 }
+#endif
 
 static void
 convert_I420_BGRA (GstVideoConverter * convert, const GstVideoFrame * src,
@@ -3599,13 +3598,96 @@
     sv = FRAME_GET_V_LINE (src, (i + convert->in_y) >> 1);
     sv += (convert->in_x >> 1);
 
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
     video_orc_convert_I420_BGRA (d, sy, su, sv,
         data->im[0][0], data->im[0][2],
         data->im[2][1], data->im[1][1], data->im[1][2], width);
+#else
+    video_orc_convert_I420_ARGB (d, sy, su, sv,
+        data->im[0][0], data->im[0][2],
+        data->im[2][1], data->im[1][1], data->im[1][2], width);
+#endif
   }
   convert_fill_border (convert, dest);
 }
+
+static void
+convert_I420_ARGB (GstVideoConverter * convert, const GstVideoFrame * src,
+    GstVideoFrame * dest)
+{
+  int i;
+  gint width = convert->in_width;
+  gint height = convert->in_height;
+  MatrixData *data = &convert->convert_matrix;
+
+  for (i = 0; i < height; i++) {
+    guint8 *sy, *su, *sv, *d;
+
+    d = FRAME_GET_LINE (dest, i + convert->out_y);
+    d += (convert->out_x * 4);
+    sy = FRAME_GET_Y_LINE (src, i + convert->in_y);
+    sy += convert->in_x;
+    su = FRAME_GET_U_LINE (src, (i + convert->in_y) >> 1);
+    su += (convert->in_x >> 1);
+    sv = FRAME_GET_V_LINE (src, (i + convert->in_y) >> 1);
+    sv += (convert->in_x >> 1);
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+    video_orc_convert_I420_ARGB (d, sy, su, sv,
+        data->im[0][0], data->im[0][2],
+        data->im[2][1], data->im[1][1], data->im[1][2], width);
+#else
+    video_orc_convert_I420_BGRA (d, sy, su, sv,
+        data->im[0][0], data->im[0][2],
+        data->im[2][1], data->im[1][1], data->im[1][2], width);
 #endif
+  }
+  convert_fill_border (convert, dest);
+}
+
+static void
+convert_I420_pack_ARGB (GstVideoConverter * convert, const GstVideoFrame * src,
+    GstVideoFrame * dest)
+{
+  int i;
+  gint width = convert->in_width;
+  gint height = convert->in_height;
+  MatrixData *data = &convert->convert_matrix;
+  gpointer tmp = convert->tmpline;
+  gpointer d[GST_VIDEO_MAX_PLANES];
+  gint pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (dest->info.finfo, 0);
+
+  d[0] = FRAME_GET_LINE (dest, 0);
+  d[0] = (guint8 *) d[0] + convert->out_x * pstride;
+
+  for (i = 0; i < height; i++) {
+    guint8 *sy, *su, *sv;
+
+    sy = FRAME_GET_Y_LINE (src, i + convert->in_y);
+    sy += convert->in_x;
+    su = FRAME_GET_U_LINE (src, (i + convert->in_y) >> 1);
+    su += (convert->in_x >> 1);
+    sv = FRAME_GET_V_LINE (src, (i + convert->in_y) >> 1);
+    sv += (convert->in_x >> 1);
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+    video_orc_convert_I420_ARGB (tmp, sy, su, sv,
+        data->im[0][0], data->im[0][2],
+        data->im[2][1], data->im[1][1], data->im[1][2], width);
+#else
+    video_orc_convert_I420_BGRA (tmp, sy, su, sv,
+        data->im[0][0], data->im[0][2],
+        data->im[2][1], data->im[1][1], data->im[1][2], width);
+#endif
+    dest->info.finfo->pack_func (dest->info.finfo,
+        (GST_VIDEO_FRAME_IS_INTERLACED (dest) ?
+            GST_VIDEO_PACK_FLAG_INTERLACED :
+            GST_VIDEO_PACK_FLAG_NONE),
+        tmp, 0, d, dest->info.stride,
+        dest->info.chroma_site, i + convert->out_y, width);
+  }
+  convert_fill_border (convert, dest);
+}
 
 static void
 memset_u24 (guint8 * data, guint8 col[3], unsigned int n)
@@ -3968,6 +4050,7 @@
     case GST_VIDEO_FORMAT_RGB:
     case GST_VIDEO_FORMAT_BGR:
     case GST_VIDEO_FORMAT_v308:
+    case GST_VIDEO_FORMAT_IYU2:
     case GST_VIDEO_FORMAT_ARGB64:
     case GST_VIDEO_FORMAT_AYUV64:
       res = format;
@@ -4008,6 +4091,8 @@
     case GST_VIDEO_FORMAT_A422_10LE:
     case GST_VIDEO_FORMAT_A444_10BE:
     case GST_VIDEO_FORMAT_A444_10LE:
+    case GST_VIDEO_FORMAT_P010_10BE:
+    case GST_VIDEO_FORMAT_P010_10LE:
       res = format;
       g_assert_not_reached ();
       break;
@@ -4609,6 +4694,7 @@
       FALSE, FALSE, FALSE, 0, 0, convert_AYUV_ABGR},    /* alias */
   {GST_VIDEO_FORMAT_AYUV, GST_VIDEO_FORMAT_RGBx, TRUE, TRUE, TRUE, TRUE, TRUE,
       FALSE, FALSE, FALSE, 0, 0, convert_AYUV_RGBA},    /* alias */
+#endif
 
   {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_BGRA, FALSE, TRUE, TRUE, TRUE,
       TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_BGRA},
@@ -4618,7 +4704,57 @@
       TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_BGRA},
   {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_BGRx, FALSE, TRUE, TRUE, TRUE,
       TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_BGRA},
-#endif
+
+  {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_ARGB, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_ARGB},
+  {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_xRGB, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_ARGB},
+  {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_ARGB, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_ARGB},
+  {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_xRGB, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_ARGB},
+
+  {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_ABGR, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_xBGR, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_RGBA, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_RGBx, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_RGB, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_BGR, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_RGB15, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_BGR15, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_RGB16, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_BGR16, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+
+  {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_ABGR, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_xBGR, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_RGBA, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_RGBx, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_RGB, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_BGR, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_RGB15, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_BGR15, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_RGB16, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
+  {GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_BGR16, FALSE, TRUE, TRUE, TRUE,
+      TRUE, FALSE, FALSE, FALSE, 0, 0, convert_I420_pack_ARGB},
 
   /* scalers */
   {GST_VIDEO_FORMAT_GBR, GST_VIDEO_FORMAT_GBR, TRUE, FALSE, FALSE, TRUE,
@@ -4642,6 +4778,8 @@
       FALSE, FALSE, FALSE, 0, 0, convert_scale_planes},
   {GST_VIDEO_FORMAT_v308, GST_VIDEO_FORMAT_v308, TRUE, FALSE, FALSE, TRUE, TRUE,
       FALSE, FALSE, FALSE, 0, 0, convert_scale_planes},
+  {GST_VIDEO_FORMAT_IYU2, GST_VIDEO_FORMAT_IYU2, TRUE, FALSE, FALSE, TRUE, TRUE,
+      FALSE, FALSE, FALSE, 0, 0, convert_scale_planes},
 
   {GST_VIDEO_FORMAT_ARGB, GST_VIDEO_FORMAT_ARGB, TRUE, FALSE, FALSE, TRUE, TRUE,
       TRUE, FALSE, FALSE, 0, 0, convert_scale_planes},
diff --git a/gst-libs/gst/video/video-format.c b/gst-libs/gst/video/video-format.c
index cff8189..97fbc8a 100644
--- a/gst-libs/gst/video/video-format.c
+++ b/gst-libs/gst/video/video-format.c
@@ -416,6 +416,43 @@
   }
 }
 
+#define PACK_IYU2 GST_VIDEO_FORMAT_AYUV, unpack_IYU2, 1, pack_IYU2
+static void
+unpack_IYU2 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
+    gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
+    const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
+{
+  int i;
+  const guint8 *restrict s = GET_LINE (y);
+  guint8 *restrict d = dest;
+
+  s += x * 3;
+
+  for (i = 0; i < width; i++) {
+    d[i * 4 + 0] = 0xff;
+    d[i * 4 + 1] = s[i * 3 + 1];
+    d[i * 4 + 2] = s[i * 3 + 0];
+    d[i * 4 + 3] = s[i * 3 + 2];
+  }
+}
+
+static void
+pack_IYU2 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
+    const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
+    const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
+    gint y, gint width)
+{
+  int i;
+  guint8 *restrict d = GET_LINE (y);
+  const guint8 *restrict s = src;
+
+  for (i = 0; i < width; i++) {
+    d[i * 3 + 0] = s[i * 4 + 2];
+    d[i * 3 + 1] = s[i * 4 + 1];
+    d[i * 3 + 2] = s[i * 4 + 3];
+  }
+}
+
 #define PACK_AYUV GST_VIDEO_FORMAT_AYUV, unpack_copy4, 1, pack_copy4
 #define PACK_ARGB GST_VIDEO_FORMAT_ARGB, unpack_copy4, 1, pack_copy4
 static void
@@ -3306,6 +3343,252 @@
   }
 }
 
+#define PACK_P010_10BE GST_VIDEO_FORMAT_AYUV64, unpack_P010_10BE, 1, pack_P010_10BE
+static void
+unpack_P010_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
+    gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
+    const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
+{
+  int i;
+  gint uv = GET_UV_420 (y, flags);
+  const guint16 *restrict sy = GET_PLANE_LINE (0, y);
+  const guint16 *restrict suv = GET_PLANE_LINE (1, uv);
+  guint16 *restrict d = dest, Y0, Y1, U, V;
+
+  sy += x;
+  suv += (x & ~1);
+
+  if (x & 1) {
+    Y0 = GST_READ_UINT16_BE (sy);
+    U = GST_READ_UINT16_BE (suv);
+    V = GST_READ_UINT16_BE (suv + 1);
+
+    if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
+      Y0 |= (Y0 >> 10);
+      U |= (U >> 10);
+      V |= (V >> 10);
+    }
+
+    d[0] = 0xffff;
+    d[1] = Y0;
+    d[2] = U;
+    d[3] = V;
+    width--;
+    d += 4;
+    sy += 1;
+    suv += 2;
+  }
+
+  for (i = 0; i < width / 2; i++) {
+    Y0 = GST_READ_UINT16_BE (sy + 2 * i);
+    Y1 = GST_READ_UINT16_BE (sy + 2 * i + 1);
+    U = GST_READ_UINT16_BE (suv + 2 * i);
+    V = GST_READ_UINT16_BE (suv + 2 * i + 1);
+
+    if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
+      Y0 |= (Y0 >> 10);
+      Y1 |= (Y1 >> 10);
+      U |= (U >> 10);
+      V |= (V >> 10);
+    }
+
+    d[i * 8 + 0] = 0xffff;
+    d[i * 8 + 1] = Y0;
+    d[i * 8 + 2] = U;
+    d[i * 8 + 3] = V;
+    d[i * 8 + 4] = 0xffff;
+    d[i * 8 + 5] = Y1;
+    d[i * 8 + 6] = U;
+    d[i * 8 + 7] = V;
+  }
+
+  if (width & 1) {
+    gint i = width - 1;
+
+    Y0 = GST_READ_UINT16_BE (sy + i);
+    U = GST_READ_UINT16_BE (suv + i);
+    V = GST_READ_UINT16_BE (suv + i + 1);
+
+    if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
+      Y0 |= (Y0 >> 10);
+      U |= (U >> 10);
+      V |= (V >> 10);
+    }
+
+    d[i * 4 + 0] = 0xffff;
+    d[i * 4 + 1] = Y0;
+    d[i * 4 + 2] = U;
+    d[i * 4 + 3] = V;
+  }
+}
+
+static void
+pack_P010_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
+    const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
+    const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
+    gint y, gint width)
+{
+  int i;
+  gint uv = GET_UV_420 (y, flags);
+  guint16 *restrict dy = GET_PLANE_LINE (0, y);
+  guint16 *restrict duv = GET_PLANE_LINE (1, uv);
+  guint16 Y0, Y1, U, V;
+  const guint16 *restrict s = src;
+
+  if (IS_CHROMA_LINE_420 (y, flags)) {
+    for (i = 0; i < width / 2; i++) {
+      Y0 = s[i * 8 + 1] & 0xffc0;
+      Y1 = s[i * 8 + 5] & 0xffc0;
+      U = s[i * 8 + 2] & 0xffc0;
+      V = s[i * 8 + 3] & 0xffc0;
+
+      GST_WRITE_UINT16_BE (dy + i * 2 + 0, Y0);
+      GST_WRITE_UINT16_BE (dy + i * 2 + 1, Y1);
+      GST_WRITE_UINT16_BE (duv + i * 2 + 0, U);
+      GST_WRITE_UINT16_BE (duv + i * 2 + 1, V);
+    }
+    if (width & 1) {
+      gint i = width - 1;
+
+      Y0 = s[i * 4 + 1] & 0xffc0;
+      U = s[i * 4 + 2] & 0xffc0;
+      V = s[i * 4 + 3] & 0xffc0;
+
+      GST_WRITE_UINT16_BE (dy + i, Y0);
+      GST_WRITE_UINT16_BE (duv + i + 0, U);
+      GST_WRITE_UINT16_BE (duv + i + 1, V);
+    }
+  } else {
+    for (i = 0; i < width; i++) {
+      Y0 = s[i * 4 + 1] & 0xffc0;
+      GST_WRITE_UINT16_BE (dy + i, Y0);
+    }
+  }
+}
+
+#define PACK_P010_10LE GST_VIDEO_FORMAT_AYUV64, unpack_P010_10LE, 1, pack_P010_10LE
+static void
+unpack_P010_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
+    gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES],
+    const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width)
+{
+  int i;
+  gint uv = GET_UV_420 (y, flags);
+  const guint16 *restrict sy = GET_PLANE_LINE (0, y);
+  const guint16 *restrict suv = GET_PLANE_LINE (1, uv);
+  guint16 *restrict d = dest, Y0, Y1, U, V;
+
+  sy += x;
+  suv += (x & ~1);
+
+  if (x & 1) {
+    Y0 = GST_READ_UINT16_LE (sy);
+    U = GST_READ_UINT16_LE (suv);
+    V = GST_READ_UINT16_LE (suv + 1);
+
+    if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
+      Y0 |= (Y0 >> 10);
+      U |= (U >> 10);
+      V |= (V >> 10);
+    }
+
+    d[0] = 0xffff;
+    d[1] = Y0;
+    d[2] = U;
+    d[3] = V;
+    width--;
+    d += 4;
+    sy += 1;
+    suv += 2;
+  }
+
+  for (i = 0; i < width / 2; i++) {
+    Y0 = GST_READ_UINT16_LE (sy + 2 * i);
+    Y1 = GST_READ_UINT16_LE (sy + 2 * i + 1);
+    U = GST_READ_UINT16_LE (suv + 2 * i);
+    V = GST_READ_UINT16_LE (suv + 2 * i + 1);
+
+    if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
+      Y0 |= (Y0 >> 10);
+      Y1 |= (Y1 >> 10);
+      U |= (U >> 10);
+      V |= (V >> 10);
+    }
+
+    d[i * 8 + 0] = 0xffff;
+    d[i * 8 + 1] = Y0;
+    d[i * 8 + 2] = U;
+    d[i * 8 + 3] = V;
+    d[i * 8 + 4] = 0xffff;
+    d[i * 8 + 5] = Y1;
+    d[i * 8 + 6] = U;
+    d[i * 8 + 7] = V;
+  }
+
+  if (width & 1) {
+    gint i = width - 1;
+
+    Y0 = GST_READ_UINT16_LE (sy + i);
+    U = GST_READ_UINT16_LE (suv + i);
+    V = GST_READ_UINT16_LE (suv + i + 1);
+
+    if (!(flags & GST_VIDEO_PACK_FLAG_TRUNCATE_RANGE)) {
+      Y0 |= (Y0 >> 10);
+      U |= (U >> 10);
+      V |= (V >> 10);
+    }
+
+    d[i * 4 + 0] = 0xffff;
+    d[i * 4 + 1] = Y0;
+    d[i * 4 + 2] = U;
+    d[i * 4 + 3] = V;
+  }
+}
+
+static void
+pack_P010_10LE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
+    const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES],
+    const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
+    gint y, gint width)
+{
+  int i;
+  gint uv = GET_UV_420 (y, flags);
+  guint16 *restrict dy = GET_PLANE_LINE (0, y);
+  guint16 *restrict duv = GET_PLANE_LINE (1, uv);
+  guint16 Y0, Y1, U, V;
+  const guint16 *restrict s = src;
+
+  if (IS_CHROMA_LINE_420 (y, flags)) {
+    for (i = 0; i < width / 2; i++) {
+      Y0 = s[i * 8 + 1] & 0xffc0;
+      Y1 = s[i * 8 + 5] & 0xffc0;
+      U = s[i * 8 + 2] & 0xffc0;
+      V = s[i * 8 + 3] & 0xffc0;
+
+      GST_WRITE_UINT16_LE (dy + i * 2 + 0, Y0);
+      GST_WRITE_UINT16_LE (dy + i * 2 + 1, Y1);
+      GST_WRITE_UINT16_LE (duv + i * 2 + 0, U);
+      GST_WRITE_UINT16_LE (duv + i * 2 + 1, V);
+    }
+    if (width & 1) {
+      gint i = width - 1;
+
+      Y0 = s[i * 4 + 1] & 0xffc0;
+      U = s[i * 4 + 2] & 0xffc0;
+      V = s[i * 4 + 3] & 0xffc0;
+
+      GST_WRITE_UINT16_LE (dy + i, Y0);
+      GST_WRITE_UINT16_LE (duv + i + 0, U);
+      GST_WRITE_UINT16_LE (duv + i + 1, V);
+    }
+  } else {
+    for (i = 0; i < width; i++) {
+      Y0 = s[i * 4 + 1] & 0xffc0;
+      GST_WRITE_UINT16_LE (dy + i, Y0);
+    }
+  }
+}
+
 typedef struct
 {
   guint32 fourcc;
@@ -3321,6 +3604,7 @@
 #define DPTH8880         8, 4, { 0, 0, 0, 0 }, { 8, 8, 8, 0 }
 #define DPTH10_10_10     10, 3, { 0, 0, 0, 0 }, { 10, 10, 10, 0 }
 #define DPTH10_10_10_10  10, 4, { 0, 0, 0, 0 }, { 10, 10, 10, 10 }
+#define DPTH10_10_10_HI  16, 3, { 6, 6, 6, 0 }, { 10, 10, 10, 0 }
 #define DPTH16           16, 1, { 0, 0, 0, 0 }, { 16, 0, 0, 0 }
 #define DPTH16_16_16     16, 3, { 0, 0, 0, 0 }, { 16, 16, 16, 0 }
 #define DPTH16_16_16_16  16, 4, { 0, 0, 0, 0 }, { 16, 16, 16, 16 }
@@ -3574,6 +3858,12 @@
       PSTR2222, PLANE0123, OFFS0, SUB4444, PACK_A444_10LE),
   MAKE_YUV_FORMAT (NV61, "raw video", GST_MAKE_FOURCC ('N', 'V', '6', '1'),
       DPTH888, PSTR122, PLANE011, OFFS010, SUB422, PACK_NV61),
+  MAKE_YUV_FORMAT (P010_10BE, "raw video", 0x00000000, DPTH10_10_10_HI,
+      PSTR244, PLANE011, OFFS001, SUB420, PACK_P010_10BE),
+  MAKE_YUV_LE_FORMAT (P010_10LE, "raw video", 0x00000000, DPTH10_10_10_HI,
+      PSTR244, PLANE011, OFFS001, SUB420, PACK_P010_10LE),
+  MAKE_YUV_FORMAT (IYU2, "raw video", GST_MAKE_FOURCC ('I', 'Y', 'U', '2'),
+      DPTH888, PSTR333, PLANE0, OFFS102, SUB444, PACK_IYU2),
 };
 
 static GstVideoFormat
@@ -3784,6 +4074,8 @@
       return GST_VIDEO_FORMAT_NV24;
     case GST_MAKE_FOURCC ('v', '3', '0', '8'):
       return GST_VIDEO_FORMAT_v308;
+    case GST_MAKE_FOURCC ('I', 'Y', 'U', '2'):
+      return GST_VIDEO_FORMAT_IYU2;
     case GST_MAKE_FOURCC ('Y', '8', '0', '0'):
     case GST_MAKE_FOURCC ('Y', '8', ' ', ' '):
     case GST_MAKE_FOURCC ('G', 'R', 'E', 'Y'):
@@ -3846,7 +4138,7 @@
 {
   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 0);
 
-  if (format >= G_N_ELEMENTS (formats))
+  if ((gint) format >= G_N_ELEMENTS (formats))
     return 0;
 
   return formats[format].fourcc;
@@ -3866,7 +4158,7 @@
 {
   g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
 
-  if (format >= G_N_ELEMENTS (formats))
+  if ((gint) format >= G_N_ELEMENTS (formats))
     return NULL;
 
   return GST_VIDEO_FORMAT_INFO_NAME (&formats[format].info);
@@ -3883,7 +4175,7 @@
 const GstVideoFormatInfo *
 gst_video_format_get_info (GstVideoFormat format)
 {
-  g_return_val_if_fail (format < G_N_ELEMENTS (formats), NULL);
+  g_return_val_if_fail ((gint) format < G_N_ELEMENTS (formats), NULL);
 
   return &formats[format].info;
 }
@@ -3904,7 +4196,7 @@
 gconstpointer
 gst_video_format_get_palette (GstVideoFormat format, gsize * size)
 {
-  g_return_val_if_fail (format < G_N_ELEMENTS (formats), NULL);
+  g_return_val_if_fail ((gint) format < G_N_ELEMENTS (formats), NULL);
   g_return_val_if_fail (size != NULL, NULL);
 
   switch (format) {
diff --git a/gst-libs/gst/video/video-format.h b/gst-libs/gst/video/video-format.h
index 86fe297..e7f83d8 100644
--- a/gst-libs/gst/video/video-format.h
+++ b/gst-libs/gst/video/video-format.h
@@ -60,7 +60,8 @@
  * @GST_VIDEO_FORMAT_GRAY8: 8-bit grayscale
  * @GST_VIDEO_FORMAT_GRAY16_BE: 16-bit grayscale, most significant byte first
  * @GST_VIDEO_FORMAT_GRAY16_LE: 16-bit grayscale, least significant byte first
- * @GST_VIDEO_FORMAT_v308: packed 4:4:4 YUV
+ * @GST_VIDEO_FORMAT_v308: packed 4:4:4 YUV (Y-U-V ...)
+ * @GST_VIDEO_FORMAT_IYU2: packed 4:4:4 YUV (U-Y-V ...) (Since 1.10)
  * @GST_VIDEO_FORMAT_RGB16: rgb 5-6-5 bits per component
  * @GST_VIDEO_FORMAT_BGR16: reverse rgb 5-6-5 bits per component
  * @GST_VIDEO_FORMAT_RGB15: rgb 5-5-5 bits per component
@@ -93,6 +94,8 @@
  * @GST_VIDEO_FORMAT_A422_10LE: planar 4:4:2:2 YUV, 10 bits per channel
  * @GST_VIDEO_FORMAT_A444_10BE: planar 4:4:4:4 YUV, 10 bits per channel
  * @GST_VIDEO_FORMAT_A444_10LE: planar 4:4:4:4 YUV, 10 bits per channel
+ * @GST_VIDEO_FORMAT_P010_10BE: planar 4:2:0 YUV with interleaved UV plane, 10 bits per channel
+ * @GST_VIDEO_FORMAT_P010_10LE: planar 4:2:0 YUV with interleaved UV plane, 10 bits per channel
  *
  * Enum value describing the most common video formats.
  */
@@ -158,6 +161,9 @@
   GST_VIDEO_FORMAT_A444_10BE,
   GST_VIDEO_FORMAT_A444_10LE,
   GST_VIDEO_FORMAT_NV61,
+  GST_VIDEO_FORMAT_P010_10BE,
+  GST_VIDEO_FORMAT_P010_10LE,
+  GST_VIDEO_FORMAT_IYU2,
 } GstVideoFormat;
 
 #define GST_VIDEO_MAX_PLANES 4
@@ -397,7 +403,7 @@
 #define GST_VIDEO_FORMAT_INFO_DEPTH(info,c)      ((info)->depth[c])
 /**
  * GST_VIDEO_FORMAT_INFO_PSTRIDE:
- * @info: a #GstVideoInfo
+ * @info: a #GstVideoFormatInfo
  * @c: the component index
  *
  * pixel stride for the given component. This is the amount of bytes to the
@@ -412,7 +418,7 @@
 #define GST_VIDEO_FORMAT_INFO_PSTRIDE(info,c)    ((info)->pixel_stride[c])
 /**
  * GST_VIDEO_FORMAT_INFO_N_PLANES:
- * @info: a #GstVideoInfo
+ * @info: a #GstVideoFormatInfo
  *
  * Number of planes. This is the number of planes the pixel layout is
  * organized in in memory. The number of planes can be less than the
@@ -425,7 +431,7 @@
 #define GST_VIDEO_FORMAT_INFO_N_PLANES(info)     ((info)->n_planes)
 /**
  * GST_VIDEO_FORMAT_INFO_PLANE:
- * @info: a #GstVideoInfo
+ * @info: a #GstVideoFormatInfo
  * @c: the component index
  *
  * Plane number where the given component can be found. A plane may
@@ -446,7 +452,7 @@
   (((guint8*)(planes)[(info)->plane[comp]]) + (info)->poffset[comp])
 /**
  * GST_VIDEO_FORMAT_INFO_STRIDE:
- * @info: a #GstVideoInfo
+ * @info: a #GstVideoFormatInfo
  * @strides: an array of strides
  * @comp: the component index
  *
@@ -493,10 +499,10 @@
 #define GST_VIDEO_FORMATS_ALL "{ I420, YV12, YUY2, UYVY, AYUV, RGBx, "  \
     "BGRx, xRGB, xBGR, RGBA, BGRA, ARGB, ABGR, RGB, BGR, Y41B, Y42B, "  \
     "YVYU, Y444, v210, v216, NV12, NV21, NV16, NV61, NV24, GRAY8, GRAY16_BE, " \
-    "GRAY16_LE, v308, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, " \
+    "GRAY16_LE, v308, IYU2, RGB16, BGR16, RGB15, BGR15, UYVP, A420, RGB8P, YUV9, YVU9, " \
     "IYU1, ARGB64, AYUV64, r210, I420_10LE, I420_10BE, I422_10LE, I422_10BE, " \
-    " Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, "\
-    " A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE }"
+    "Y444_10LE, Y444_10BE, GBR, GBR_10LE, GBR_10BE, NV12_64Z32, A420_10LE, "\
+    "A420_10BE, A422_10LE, A422_10BE, A444_10LE, A444_10BE, P010_10LE, P010_10BE }"
 
 /**
  * GST_VIDEO_CAPS_MAKE:
diff --git a/gst-libs/gst/video/video-frame.c b/gst-libs/gst/video/video-frame.c
index 66e1fa9..30a2d85 100644
--- a/gst-libs/gst/video/video-frame.c
+++ b/gst-libs/gst/video/video-frame.c
@@ -199,10 +199,10 @@
  *   GstVideoFrame vframe;
  *   ...
  *   // set RGB pixels to black one at a time
- *   if (gst_video_frame_map (&amp;vframe, video_info, video_buffer)) {
+ *   if (gst_video_frame_map (&amp;vframe, video_info, video_buffer, GST_MAP_WRITE)) {
  *     guint8 *pixels = GST_VIDEO_FRAME_PLANE_DATA (vframe, 0);
  *     guint stride = GST_VIDEO_FRAME_PLANE_STRIDE (vframe, 0);
- *     guint pixel_stride = GST_VIDEO_FRAME_PLANE_PSTRIDE (vframe, 0);
+ *     guint pixel_stride = GST_VIDEO_FRAME_COMP_PSTRIDE (vframe, 0);
  *
  *     for (h = 0; h < height; ++h) {
  *       for (w = 0; w < width; ++w) {
@@ -211,6 +211,8 @@
  *         memset (pixel, 0, pixel_stride);
  *       }
  *     }
+ *
+ *     gst_video_frame_unmap (&amp;vframe);
  *   }
  *   ...
  * ]|
diff --git a/gst-libs/gst/video/video-frame.h b/gst-libs/gst/video/video-frame.h
index 020d6e1..ef3e03b 100644
--- a/gst-libs/gst/video/video-frame.h
+++ b/gst-libs/gst/video/video-frame.h
@@ -155,6 +155,9 @@
  *
  * Additional video buffer flags. These flags can potentially be used on any
  * buffers carrying video data - even encoded data.
+ *
+ * Note that these are only valid for #GstCaps of type: video/...
+ * They can conflict with other extended buffer flags.
  */
 typedef enum {
   GST_VIDEO_BUFFER_FLAG_INTERLACED  = (GST_BUFFER_FLAG_LAST << 0),
diff --git a/gst-libs/gst/video/video-info.c b/gst-libs/gst/video/video-info.c
index cb9c777..57b9db7 100644
--- a/gst-libs/gst/video/video-info.c
+++ b/gst-libs/gst/video/video-info.c
@@ -644,6 +644,7 @@
     case GST_VIDEO_FORMAT_RGB:
     case GST_VIDEO_FORMAT_BGR:
     case GST_VIDEO_FORMAT_v308:
+    case GST_VIDEO_FORMAT_IYU2:
       info->stride[0] = GST_ROUND_UP_4 (width * 3);
       info->offset[0] = 0;
       info->size = info->stride[0] * height;
@@ -878,6 +879,15 @@
       info->offset[3] = info->offset[1] * 3;
       info->size = info->stride[0] * height * 4;
       break;
+    case GST_VIDEO_FORMAT_P010_10LE:
+    case GST_VIDEO_FORMAT_P010_10BE:
+      info->stride[0] = GST_ROUND_UP_4 (width * 2);
+      info->stride[1] = info->stride[0];
+      info->offset[0] = 0;
+      info->offset[1] = info->stride[0] * GST_ROUND_UP_2 (height);
+      cr_h = GST_ROUND_UP_2 (height) / 2;
+      info->size = info->offset[1] + info->stride[0] * cr_h;
+      break;
 
     case GST_VIDEO_FORMAT_ENCODED:
       break;
diff --git a/gst-libs/gst/video/video-multiview.c b/gst-libs/gst/video/video-multiview.c
index 2b2a5bc..12774b0 100644
--- a/gst-libs/gst/video/video-multiview.c
+++ b/gst-libs/gst/video/video-multiview.c
@@ -418,6 +418,16 @@
   return type;
 }
 
+static gboolean
+gst_video_multiview_meta_init (GstVideoMultiviewMeta * mview_meta,
+    gpointer params, GstBuffer * buffer)
+{
+  mview_meta->n_views = 0;
+  mview_meta->view_info = NULL;
+
+  return TRUE;
+}
+
 static void
 gst_video_multiview_meta_free (GstVideoMultiviewMeta * mview_meta,
     GstBuffer * buffer)
@@ -436,7 +446,7 @@
         gst_meta_register (GST_VIDEO_MULTIVIEW_META_API_TYPE,
         "GstVideoMultiviewMeta",
         sizeof (GstVideoMultiviewMeta),
-        (GstMetaInitFunction) NULL,
+        (GstMetaInitFunction) gst_video_multiview_meta_init,
         (GstMetaFreeFunction) gst_video_multiview_meta_free,
         NULL);
     g_once_init_leave (&video_meta_info, meta);
diff --git a/gst-libs/gst/video/video-orc-dist.c b/gst-libs/gst/video/video-orc-dist.c
index 0622974..1f72291 100644
--- a/gst-libs/gst/video/video-orc-dist.c
+++ b/gst-libs/gst/video/video-orc-dist.c
@@ -333,6 +333,10 @@
     const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2,
     const guint8 * ORC_RESTRICT s3, int p1, int p2, int p3, int p4, int p5,
     int n);
+void video_orc_convert_I420_ARGB (guint8 * ORC_RESTRICT d1,
+    const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2,
+    const guint8 * ORC_RESTRICT s3, int p1, int p2, int p3, int p4, int p5,
+    int n);
 void video_orc_matrix8 (guint8 * ORC_RESTRICT d1,
     const guint8 * ORC_RESTRICT s1, orc_int64 p1, orc_int64 p2, orc_int64 p3,
     orc_int64 p4, int n);
@@ -12547,7 +12551,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 31, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 98, 105, 108, 105, 110, 101, 97, 114, 95,
-        117,
+            117,
         51, 50, 11, 4, 4, 12, 4, 4, 16, 4, 16, 4, 51, 0, 4, 24,
         25, 2, 0,
       };
@@ -21911,15 +21915,15 @@
         1, 9, 27, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 99, 111, 110,
         118, 101, 114, 116, 95, 73, 52, 50, 48, 95, 66, 71, 82, 65, 11, 4,
         4, 12, 1, 1, 12, 1, 1, 12, 1, 1, 14, 1, 128, 0, 0, 0,
-        14, 1, 127, 0, 0, 0, 16, 2, 16, 2, 16, 2, 16, 2, 16, 2,
-        20, 2, 20, 2, 20, 2, 20, 2, 20, 2, 20, 2, 20, 1, 20, 1,
-        20, 1, 20, 4, 65, 38, 4, 16, 151, 32, 38, 45, 38, 5, 65, 38,
-        38, 16, 151, 33, 38, 45, 38, 6, 65, 38, 38, 16, 151, 34, 38, 90,
-        32, 32, 24, 90, 35, 34, 25, 70, 35, 32, 35, 159, 38, 35, 196, 35,
-        38, 17, 90, 37, 33, 26, 70, 37, 32, 37, 159, 40, 37, 90, 36, 33,
-        27, 70, 36, 32, 36, 90, 32, 34, 28, 70, 36, 36, 32, 159, 39, 36,
-        196, 37, 40, 39, 195, 41, 37, 35, 21, 2, 33, 0, 41, 16, 2, 0,
-
+        14, 4, 128, 0, 0, 0, 14, 1, 127, 0, 0, 0, 16, 2, 16, 2,
+        16, 2, 16, 2, 16, 2, 20, 2, 20, 2, 20, 2, 20, 2, 20, 2,
+        20, 2, 20, 1, 20, 1, 20, 1, 20, 4, 65, 38, 4, 16, 151, 32,
+        38, 45, 38, 5, 65, 38, 38, 16, 151, 33, 38, 45, 38, 6, 65, 38,
+        38, 16, 151, 34, 38, 90, 32, 32, 24, 90, 35, 34, 25, 70, 35, 32,
+        35, 159, 38, 35, 196, 35, 38, 18, 90, 37, 33, 26, 70, 37, 32, 37,
+        159, 40, 37, 90, 36, 33, 27, 70, 36, 32, 36, 90, 32, 34, 28, 70,
+        36, 36, 32, 159, 39, 36, 196, 37, 40, 39, 195, 41, 37, 35, 21, 2,
+        33, 0, 41, 17, 2, 0,
       };
       p = orc_program_new_from_static_bytecode (bc);
       orc_program_set_backup_function (p, _backup_video_orc_convert_I420_BGRA);
@@ -21932,7 +21936,8 @@
       orc_program_add_source (p, 1, "s2");
       orc_program_add_source (p, 1, "s3");
       orc_program_add_constant (p, 1, 0x00000080, "c1");
-      orc_program_add_constant (p, 1, 0x0000007f, "c2");
+      orc_program_add_constant (p, 4, 0x00000080, "c2");
+      orc_program_add_constant (p, 1, 0x0000007f, "c3");
       orc_program_add_parameter (p, 2, "p1");
       orc_program_add_parameter (p, 2, "p2");
       orc_program_add_parameter (p, 2, "p3");
@@ -21973,7 +21978,7 @@
           ORC_VAR_D1);
       orc_program_append_2 (p, "convssswb", 0, ORC_VAR_T7, ORC_VAR_T4,
           ORC_VAR_D1, ORC_VAR_D1);
-      orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T4, ORC_VAR_T7, ORC_VAR_C2,
+      orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T4, ORC_VAR_T7, ORC_VAR_C3,
           ORC_VAR_D1);
       orc_program_append_2 (p, "mulhsw", 0, ORC_VAR_T6, ORC_VAR_T2, ORC_VAR_P3,
           ORC_VAR_D1);
@@ -21995,7 +22000,459 @@
           ORC_VAR_D1);
       orc_program_append_2 (p, "mergewl", 0, ORC_VAR_T10, ORC_VAR_T6,
           ORC_VAR_T4, ORC_VAR_D1);
-      orc_program_append_2 (p, "addb", 2, ORC_VAR_D1, ORC_VAR_T10, ORC_VAR_C1,
+      orc_program_append_2 (p, "addb", 2, ORC_VAR_D1, ORC_VAR_T10, ORC_VAR_C2,
+          ORC_VAR_D1);
+#endif
+
+      orc_program_compile (p);
+      c = orc_program_take_code (p);
+      orc_program_free (p);
+    }
+    p_inited = TRUE;
+    orc_once_mutex_unlock ();
+  }
+  ex->arrays[ORC_VAR_A2] = c;
+  ex->program = 0;
+
+  ex->n = n;
+  ex->arrays[ORC_VAR_D1] = d1;
+  ex->arrays[ORC_VAR_S1] = (void *) s1;
+  ex->arrays[ORC_VAR_S2] = (void *) s2;
+  ex->arrays[ORC_VAR_S3] = (void *) s3;
+  ex->params[ORC_VAR_P1] = p1;
+  ex->params[ORC_VAR_P2] = p2;
+  ex->params[ORC_VAR_P3] = p3;
+  ex->params[ORC_VAR_P4] = p4;
+  ex->params[ORC_VAR_P5] = p5;
+
+  func = c->exec;
+  func (ex);
+}
+#endif
+
+
+/* video_orc_convert_I420_ARGB */
+#ifdef DISABLE_ORC
+void
+video_orc_convert_I420_ARGB (guint8 * ORC_RESTRICT d1,
+    const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2,
+    const guint8 * ORC_RESTRICT s3, int p1, int p2, int p3, int p4, int p5,
+    int n)
+{
+  int i;
+  orc_union32 *ORC_RESTRICT ptr0;
+  const orc_int8 *ORC_RESTRICT ptr4;
+  const orc_int8 *ORC_RESTRICT ptr5;
+  const orc_int8 *ORC_RESTRICT ptr6;
+  orc_int8 var42;
+#if defined(__APPLE__) && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && defined (__i386__)
+  volatile orc_int8 var43;
+#else
+  orc_int8 var43;
+#endif
+  orc_union16 var44;
+  orc_union16 var45;
+#if defined(__APPLE__) && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && defined (__i386__)
+  volatile orc_int8 var46;
+#else
+  orc_int8 var46;
+#endif
+  orc_union16 var47;
+  orc_union16 var48;
+  orc_union16 var49;
+#if defined(__APPLE__) && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && defined (__i386__)
+  volatile orc_union32 var50;
+#else
+  orc_union32 var50;
+#endif
+  orc_union32 var51;
+  orc_int8 var52;
+  orc_union16 var53;
+  orc_int8 var54;
+  orc_int8 var55;
+  orc_union16 var56;
+  orc_int8 var57;
+  orc_int8 var58;
+  orc_union16 var59;
+  orc_union16 var60;
+  orc_union16 var61;
+  orc_union16 var62;
+  orc_int8 var63;
+  orc_union16 var64;
+  orc_union16 var65;
+  orc_union16 var66;
+  orc_int8 var67;
+  orc_union16 var68;
+  orc_union16 var69;
+  orc_union16 var70;
+  orc_union16 var71;
+  orc_int8 var72;
+  orc_union16 var73;
+  orc_union32 var74;
+
+  ptr0 = (orc_union32 *) d1;
+  ptr4 = (orc_int8 *) s1;
+  ptr5 = (orc_int8 *) s2;
+  ptr6 = (orc_int8 *) s3;
+
+  /* 1: loadpb */
+  var43 = (int) 0x00000080;     /* 128 or 6.32404e-322f */
+  /* 10: loadpw */
+  var44.i = p1;
+  /* 12: loadpw */
+  var45.i = p2;
+  /* 16: loadpb */
+  var46 = (int) 0x0000007f;     /* 127 or 6.27463e-322f */
+  /* 18: loadpw */
+  var47.i = p3;
+  /* 22: loadpw */
+  var48.i = p4;
+  /* 25: loadpw */
+  var49.i = p5;
+  /* 31: loadpb */
+  var50.x4[0] = (int) 0x00000080;       /* 128 or 6.32404e-322f */
+  var50.x4[1] = (int) 0x00000080;       /* 128 or 6.32404e-322f */
+  var50.x4[2] = (int) 0x00000080;       /* 128 or 6.32404e-322f */
+  var50.x4[3] = (int) 0x00000080;       /* 128 or 6.32404e-322f */
+
+  for (i = 0; i < n; i++) {
+    /* 0: loadb */
+    var42 = ptr4[i];
+    /* 2: subb */
+    var52 = var42 - var43;
+    /* 3: splatbw */
+    var53.i = ((var52 & 0xff) << 8) | (var52 & 0xff);
+    /* 4: loadupdb */
+    var54 = ptr5[i >> 1];
+    /* 5: subb */
+    var55 = var54 - var43;
+    /* 6: splatbw */
+    var56.i = ((var55 & 0xff) << 8) | (var55 & 0xff);
+    /* 7: loadupdb */
+    var57 = ptr6[i >> 1];
+    /* 8: subb */
+    var58 = var57 - var43;
+    /* 9: splatbw */
+    var59.i = ((var58 & 0xff) << 8) | (var58 & 0xff);
+    /* 11: mulhsw */
+    var60.i = (var53.i * var44.i) >> 16;
+    /* 13: mulhsw */
+    var61.i = (var59.i * var45.i) >> 16;
+    /* 14: addw */
+    var62.i = var60.i + var61.i;
+    /* 15: convssswb */
+    var63 = ORC_CLAMP_SB (var62.i);
+    /* 17: mergebw */
+    {
+      orc_union16 _dest;
+      _dest.x2[0] = var46;
+      _dest.x2[1] = var63;
+      var64.i = _dest.i;
+    }
+    /* 19: mulhsw */
+    var65.i = (var56.i * var47.i) >> 16;
+    /* 20: addw */
+    var66.i = var60.i + var65.i;
+    /* 21: convssswb */
+    var67 = ORC_CLAMP_SB (var66.i);
+    /* 23: mulhsw */
+    var68.i = (var56.i * var48.i) >> 16;
+    /* 24: addw */
+    var69.i = var60.i + var68.i;
+    /* 26: mulhsw */
+    var70.i = (var59.i * var49.i) >> 16;
+    /* 27: addw */
+    var71.i = var69.i + var70.i;
+    /* 28: convssswb */
+    var72 = ORC_CLAMP_SB (var71.i);
+    /* 29: mergebw */
+    {
+      orc_union16 _dest;
+      _dest.x2[0] = var72;
+      _dest.x2[1] = var67;
+      var73.i = _dest.i;
+    }
+    /* 30: mergewl */
+    {
+      orc_union32 _dest;
+      _dest.x2[0] = var64.i;
+      _dest.x2[1] = var73.i;
+      var74.i = _dest.i;
+    }
+    /* 32: addb */
+    var51.x4[0] = var74.x4[0] + var50.x4[0];
+    var51.x4[1] = var74.x4[1] + var50.x4[1];
+    var51.x4[2] = var74.x4[2] + var50.x4[2];
+    var51.x4[3] = var74.x4[3] + var50.x4[3];
+    /* 33: storel */
+    ptr0[i] = var51;
+  }
+
+}
+
+#else
+static void
+_backup_video_orc_convert_I420_ARGB (OrcExecutor * ORC_RESTRICT ex)
+{
+  int i;
+  int n = ex->n;
+  orc_union32 *ORC_RESTRICT ptr0;
+  const orc_int8 *ORC_RESTRICT ptr4;
+  const orc_int8 *ORC_RESTRICT ptr5;
+  const orc_int8 *ORC_RESTRICT ptr6;
+  orc_int8 var42;
+#if defined(__APPLE__) && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && defined (__i386__)
+  volatile orc_int8 var43;
+#else
+  orc_int8 var43;
+#endif
+  orc_union16 var44;
+  orc_union16 var45;
+#if defined(__APPLE__) && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && defined (__i386__)
+  volatile orc_int8 var46;
+#else
+  orc_int8 var46;
+#endif
+  orc_union16 var47;
+  orc_union16 var48;
+  orc_union16 var49;
+#if defined(__APPLE__) && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && defined (__i386__)
+  volatile orc_union32 var50;
+#else
+  orc_union32 var50;
+#endif
+  orc_union32 var51;
+  orc_int8 var52;
+  orc_union16 var53;
+  orc_int8 var54;
+  orc_int8 var55;
+  orc_union16 var56;
+  orc_int8 var57;
+  orc_int8 var58;
+  orc_union16 var59;
+  orc_union16 var60;
+  orc_union16 var61;
+  orc_union16 var62;
+  orc_int8 var63;
+  orc_union16 var64;
+  orc_union16 var65;
+  orc_union16 var66;
+  orc_int8 var67;
+  orc_union16 var68;
+  orc_union16 var69;
+  orc_union16 var70;
+  orc_union16 var71;
+  orc_int8 var72;
+  orc_union16 var73;
+  orc_union32 var74;
+
+  ptr0 = (orc_union32 *) ex->arrays[0];
+  ptr4 = (orc_int8 *) ex->arrays[4];
+  ptr5 = (orc_int8 *) ex->arrays[5];
+  ptr6 = (orc_int8 *) ex->arrays[6];
+
+  /* 1: loadpb */
+  var43 = (int) 0x00000080;     /* 128 or 6.32404e-322f */
+  /* 10: loadpw */
+  var44.i = ex->params[24];
+  /* 12: loadpw */
+  var45.i = ex->params[25];
+  /* 16: loadpb */
+  var46 = (int) 0x0000007f;     /* 127 or 6.27463e-322f */
+  /* 18: loadpw */
+  var47.i = ex->params[26];
+  /* 22: loadpw */
+  var48.i = ex->params[27];
+  /* 25: loadpw */
+  var49.i = ex->params[28];
+  /* 31: loadpb */
+  var50.x4[0] = (int) 0x00000080;       /* 128 or 6.32404e-322f */
+  var50.x4[1] = (int) 0x00000080;       /* 128 or 6.32404e-322f */
+  var50.x4[2] = (int) 0x00000080;       /* 128 or 6.32404e-322f */
+  var50.x4[3] = (int) 0x00000080;       /* 128 or 6.32404e-322f */
+
+  for (i = 0; i < n; i++) {
+    /* 0: loadb */
+    var42 = ptr4[i];
+    /* 2: subb */
+    var52 = var42 - var43;
+    /* 3: splatbw */
+    var53.i = ((var52 & 0xff) << 8) | (var52 & 0xff);
+    /* 4: loadupdb */
+    var54 = ptr5[i >> 1];
+    /* 5: subb */
+    var55 = var54 - var43;
+    /* 6: splatbw */
+    var56.i = ((var55 & 0xff) << 8) | (var55 & 0xff);
+    /* 7: loadupdb */
+    var57 = ptr6[i >> 1];
+    /* 8: subb */
+    var58 = var57 - var43;
+    /* 9: splatbw */
+    var59.i = ((var58 & 0xff) << 8) | (var58 & 0xff);
+    /* 11: mulhsw */
+    var60.i = (var53.i * var44.i) >> 16;
+    /* 13: mulhsw */
+    var61.i = (var59.i * var45.i) >> 16;
+    /* 14: addw */
+    var62.i = var60.i + var61.i;
+    /* 15: convssswb */
+    var63 = ORC_CLAMP_SB (var62.i);
+    /* 17: mergebw */
+    {
+      orc_union16 _dest;
+      _dest.x2[0] = var46;
+      _dest.x2[1] = var63;
+      var64.i = _dest.i;
+    }
+    /* 19: mulhsw */
+    var65.i = (var56.i * var47.i) >> 16;
+    /* 20: addw */
+    var66.i = var60.i + var65.i;
+    /* 21: convssswb */
+    var67 = ORC_CLAMP_SB (var66.i);
+    /* 23: mulhsw */
+    var68.i = (var56.i * var48.i) >> 16;
+    /* 24: addw */
+    var69.i = var60.i + var68.i;
+    /* 26: mulhsw */
+    var70.i = (var59.i * var49.i) >> 16;
+    /* 27: addw */
+    var71.i = var69.i + var70.i;
+    /* 28: convssswb */
+    var72 = ORC_CLAMP_SB (var71.i);
+    /* 29: mergebw */
+    {
+      orc_union16 _dest;
+      _dest.x2[0] = var72;
+      _dest.x2[1] = var67;
+      var73.i = _dest.i;
+    }
+    /* 30: mergewl */
+    {
+      orc_union32 _dest;
+      _dest.x2[0] = var64.i;
+      _dest.x2[1] = var73.i;
+      var74.i = _dest.i;
+    }
+    /* 32: addb */
+    var51.x4[0] = var74.x4[0] + var50.x4[0];
+    var51.x4[1] = var74.x4[1] + var50.x4[1];
+    var51.x4[2] = var74.x4[2] + var50.x4[2];
+    var51.x4[3] = var74.x4[3] + var50.x4[3];
+    /* 33: storel */
+    ptr0[i] = var51;
+  }
+
+}
+
+void
+video_orc_convert_I420_ARGB (guint8 * ORC_RESTRICT d1,
+    const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2,
+    const guint8 * ORC_RESTRICT s3, int p1, int p2, int p3, int p4, int p5,
+    int n)
+{
+  OrcExecutor _ex, *ex = &_ex;
+  static volatile int p_inited = 0;
+  static OrcCode *c = 0;
+  void (*func) (OrcExecutor *);
+
+  if (!p_inited) {
+    orc_once_mutex_lock ();
+    if (!p_inited) {
+      OrcProgram *p;
+
+#if 1
+      static const orc_uint8 bc[] = {
+        1, 9, 27, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 99, 111, 110,
+        118, 101, 114, 116, 95, 73, 52, 50, 48, 95, 65, 82, 71, 66, 11, 4,
+        4, 12, 1, 1, 12, 1, 1, 12, 1, 1, 14, 1, 128, 0, 0, 0,
+        14, 4, 128, 0, 0, 0, 14, 1, 127, 0, 0, 0, 16, 2, 16, 2,
+        16, 2, 16, 2, 16, 2, 20, 2, 20, 2, 20, 2, 20, 2, 20, 2,
+        20, 2, 20, 1, 20, 1, 20, 1, 20, 4, 65, 38, 4, 16, 151, 32,
+        38, 45, 38, 5, 65, 38, 38, 16, 151, 33, 38, 45, 38, 6, 65, 38,
+        38, 16, 151, 34, 38, 90, 32, 32, 24, 90, 35, 34, 25, 70, 35, 32,
+        35, 159, 38, 35, 196, 35, 18, 38, 90, 37, 33, 26, 70, 37, 32, 37,
+        159, 40, 37, 90, 36, 33, 27, 70, 36, 32, 36, 90, 32, 34, 28, 70,
+        36, 36, 32, 159, 39, 36, 196, 37, 39, 40, 195, 41, 35, 37, 21, 2,
+        33, 0, 41, 17, 2, 0,
+      };
+      p = orc_program_new_from_static_bytecode (bc);
+      orc_program_set_backup_function (p, _backup_video_orc_convert_I420_ARGB);
+#else
+      p = orc_program_new ();
+      orc_program_set_name (p, "video_orc_convert_I420_ARGB");
+      orc_program_set_backup_function (p, _backup_video_orc_convert_I420_ARGB);
+      orc_program_add_destination (p, 4, "d1");
+      orc_program_add_source (p, 1, "s1");
+      orc_program_add_source (p, 1, "s2");
+      orc_program_add_source (p, 1, "s3");
+      orc_program_add_constant (p, 1, 0x00000080, "c1");
+      orc_program_add_constant (p, 4, 0x00000080, "c2");
+      orc_program_add_constant (p, 1, 0x0000007f, "c3");
+      orc_program_add_parameter (p, 2, "p1");
+      orc_program_add_parameter (p, 2, "p2");
+      orc_program_add_parameter (p, 2, "p3");
+      orc_program_add_parameter (p, 2, "p4");
+      orc_program_add_parameter (p, 2, "p5");
+      orc_program_add_temporary (p, 2, "t1");
+      orc_program_add_temporary (p, 2, "t2");
+      orc_program_add_temporary (p, 2, "t3");
+      orc_program_add_temporary (p, 2, "t4");
+      orc_program_add_temporary (p, 2, "t5");
+      orc_program_add_temporary (p, 2, "t6");
+      orc_program_add_temporary (p, 1, "t7");
+      orc_program_add_temporary (p, 1, "t8");
+      orc_program_add_temporary (p, 1, "t9");
+      orc_program_add_temporary (p, 4, "t10");
+
+      orc_program_append_2 (p, "subb", 0, ORC_VAR_T7, ORC_VAR_S1, ORC_VAR_C1,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "splatbw", 0, ORC_VAR_T1, ORC_VAR_T7, ORC_VAR_D1,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "loadupdb", 0, ORC_VAR_T7, ORC_VAR_S2,
+          ORC_VAR_D1, ORC_VAR_D1);
+      orc_program_append_2 (p, "subb", 0, ORC_VAR_T7, ORC_VAR_T7, ORC_VAR_C1,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "splatbw", 0, ORC_VAR_T2, ORC_VAR_T7, ORC_VAR_D1,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "loadupdb", 0, ORC_VAR_T7, ORC_VAR_S3,
+          ORC_VAR_D1, ORC_VAR_D1);
+      orc_program_append_2 (p, "subb", 0, ORC_VAR_T7, ORC_VAR_T7, ORC_VAR_C1,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "splatbw", 0, ORC_VAR_T3, ORC_VAR_T7, ORC_VAR_D1,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "mulhsw", 0, ORC_VAR_T1, ORC_VAR_T1, ORC_VAR_P1,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "mulhsw", 0, ORC_VAR_T4, ORC_VAR_T3, ORC_VAR_P2,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "addw", 0, ORC_VAR_T4, ORC_VAR_T1, ORC_VAR_T4,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "convssswb", 0, ORC_VAR_T7, ORC_VAR_T4,
+          ORC_VAR_D1, ORC_VAR_D1);
+      orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T4, ORC_VAR_C3, ORC_VAR_T7,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "mulhsw", 0, ORC_VAR_T6, ORC_VAR_T2, ORC_VAR_P3,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "addw", 0, ORC_VAR_T6, ORC_VAR_T1, ORC_VAR_T6,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "convssswb", 0, ORC_VAR_T9, ORC_VAR_T6,
+          ORC_VAR_D1, ORC_VAR_D1);
+      orc_program_append_2 (p, "mulhsw", 0, ORC_VAR_T5, ORC_VAR_T2, ORC_VAR_P4,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "addw", 0, ORC_VAR_T5, ORC_VAR_T1, ORC_VAR_T5,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "mulhsw", 0, ORC_VAR_T1, ORC_VAR_T3, ORC_VAR_P5,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "addw", 0, ORC_VAR_T5, ORC_VAR_T5, ORC_VAR_T1,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "convssswb", 0, ORC_VAR_T8, ORC_VAR_T5,
+          ORC_VAR_D1, ORC_VAR_D1);
+      orc_program_append_2 (p, "mergebw", 0, ORC_VAR_T6, ORC_VAR_T8, ORC_VAR_T9,
+          ORC_VAR_D1);
+      orc_program_append_2 (p, "mergewl", 0, ORC_VAR_T10, ORC_VAR_T4,
+          ORC_VAR_T6, ORC_VAR_D1);
+      orc_program_append_2 (p, "addb", 2, ORC_VAR_D1, ORC_VAR_T10, ORC_VAR_C2,
           ORC_VAR_D1);
 #endif
 
@@ -22040,18 +22497,14 @@
 _backup_video_orc_matrix8 (OrcExecutor * ORC_RESTRICT ex)
 {
   _custom_video_orc_matrix8 (ex->arrays[ORC_VAR_D1], ex->arrays[ORC_VAR_S1],
-      (ex->
-          params[ORC_VAR_P1] & 0xffffffff) |
-      ((orc_uint64) (ex->params[ORC_VAR_T1]) << 32),
-      (ex->
-          params[ORC_VAR_P2] & 0xffffffff) |
-      ((orc_uint64) (ex->params[ORC_VAR_T2]) << 32),
-      (ex->
-          params[ORC_VAR_P3] & 0xffffffff) |
-      ((orc_uint64) (ex->params[ORC_VAR_T3]) << 32),
-      (ex->
-          params[ORC_VAR_P4] & 0xffffffff) |
-      ((orc_uint64) (ex->params[ORC_VAR_T4]) << 32), ex->n);
+      (ex->params[ORC_VAR_P1] & 0xffffffff) | ((orc_uint64) (ex->
+              params[ORC_VAR_T1]) << 32),
+      (ex->params[ORC_VAR_P2] & 0xffffffff) | ((orc_uint64) (ex->
+              params[ORC_VAR_T2]) << 32),
+      (ex->params[ORC_VAR_P3] & 0xffffffff) | ((orc_uint64) (ex->
+              params[ORC_VAR_T3]) << 32),
+      (ex->params[ORC_VAR_P4] & 0xffffffff) | ((orc_uint64) (ex->
+              params[ORC_VAR_T4]) << 32), ex->n);
 }
 
 void
@@ -24385,7 +24838,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 31, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 104, 95, 109, 117, 108, 116, 97, 112, 115,
-        95,
+            95,
         117, 56, 11, 4, 4, 12, 1, 1, 12, 2, 2, 20, 2, 150, 32, 4,
         176, 0, 32, 5, 2, 0,
       };
@@ -24537,7 +24990,7 @@
       static const orc_uint8 bc[] = {
         1, 7, 9, 34, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101,
         115, 97, 109, 112, 108, 101, 95, 104, 95, 109, 117, 108, 97, 100, 100,
-        116,
+            116,
         97, 112, 115, 95, 117, 56, 11, 4, 4, 12, 1, 1, 12, 2, 2, 20,
         2, 20, 4, 150, 32, 4, 176, 33, 32, 5, 103, 0, 0, 33, 2, 0,
 
@@ -24693,7 +25146,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 31, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 115, 99, 97, 108, 101, 116, 97, 112, 115,
-        95,
+            95,
         117, 56, 11, 1, 1, 12, 4, 4, 14, 4, 255, 15, 0, 0, 14, 4,
         12, 0, 0, 0, 20, 2, 20, 4, 103, 33, 4, 16, 125, 33, 33, 17,
         166, 32, 33, 160, 0, 32, 2, 0,
@@ -24830,7 +25283,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 34, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 104, 95, 109, 117, 108, 116, 97, 112, 115,
-        95,
+            95,
         117, 56, 95, 108, 113, 11, 2, 2, 12, 1, 1, 12, 2, 2, 20, 2,
         150, 32, 4, 89, 0, 32, 5, 2, 0,
       };
@@ -24982,7 +25435,7 @@
       static const orc_uint8 bc[] = {
         1, 7, 9, 37, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101,
         115, 97, 109, 112, 108, 101, 95, 104, 95, 109, 117, 108, 97, 100, 100,
-        116,
+            116,
         97, 112, 115, 95, 117, 56, 95, 108, 113, 11, 2, 2, 12, 1, 1, 12,
         2, 2, 20, 2, 150, 32, 4, 89, 32, 32, 5, 70, 0, 0, 32, 2,
         0,
@@ -25201,7 +25654,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 35, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 104, 95, 109, 117, 108, 116, 97, 112, 115,
-        51,
+            51,
         95, 117, 56, 95, 108, 113, 11, 2, 2, 12, 1, 1, 12, 1, 1, 12,
         1, 1, 12, 2, 2, 12, 2, 2, 12, 2, 2, 20, 2, 20, 2, 150,
         32, 4, 89, 32, 32, 7, 150, 33, 5, 89, 33, 33, 8, 70, 32, 32,
@@ -25447,7 +25900,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 38, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 104, 95, 109, 117, 108, 97, 100, 100, 116,
-        97,
+            97,
         112, 115, 51, 95, 117, 56, 95, 108, 113, 11, 2, 2, 12, 1, 1, 12,
         1, 1, 12, 1, 1, 12, 2, 2, 12, 2, 2, 12, 2, 2, 20, 2,
         20, 2, 150, 32, 4, 89, 32, 32, 7, 150, 33, 5, 89, 33, 33, 8,
@@ -25735,7 +26188,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 43, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 104, 95, 109, 117, 108, 97, 100, 100, 115,
-        99,
+            99,
         97, 108, 101, 116, 97, 112, 115, 51, 95, 117, 56, 95, 108, 113, 11, 1,
         1, 12, 1, 1, 12, 1, 1, 12, 1, 1, 12, 2, 2, 12, 2, 2,
         12, 2, 2, 12, 2, 2, 14, 2, 32, 0, 0, 0, 14, 2, 6, 0,
@@ -25914,7 +26367,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 34, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 115, 99, 97, 108, 101, 116, 97, 112, 115,
-        95,
+            95,
         117, 56, 95, 108, 113, 11, 1, 1, 12, 2, 2, 14, 2, 32, 0, 0,
         0, 14, 2, 6, 0, 0, 0, 20, 2, 70, 32, 4, 16, 94, 32, 32,
         17, 160, 0, 32, 2, 0,
@@ -26054,7 +26507,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 32, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 104, 95, 109, 117, 108, 116, 97, 112, 115,
-        95,
+            95,
         117, 49, 54, 11, 4, 4, 12, 2, 2, 12, 2, 2, 20, 4, 20, 4,
         154, 32, 4, 153, 33, 5, 120, 0, 32, 33, 2, 0,
       };
@@ -26215,7 +26668,7 @@
       static const orc_uint8 bc[] = {
         1, 7, 9, 35, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101,
         115, 97, 109, 112, 108, 101, 95, 104, 95, 109, 117, 108, 97, 100, 100,
-        116,
+            116,
         97, 112, 115, 95, 117, 49, 54, 11, 4, 4, 12, 2, 2, 12, 2, 2,
         20, 4, 20, 4, 154, 32, 4, 153, 33, 5, 120, 32, 32, 33, 103, 0,
         0, 32, 2, 0,
@@ -26367,7 +26820,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 32, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 115, 99, 97, 108, 101, 116, 97, 112, 115,
-        95,
+            95,
         117, 49, 54, 11, 2, 2, 12, 4, 4, 14, 4, 255, 15, 0, 0, 14,
         4, 12, 0, 0, 0, 20, 4, 103, 32, 4, 16, 125, 32, 32, 17, 166,
         0, 32, 2, 0,
@@ -26497,7 +26950,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 31, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 118, 95, 109, 117, 108, 116, 97, 112, 115,
-        95,
+            95,
         117, 56, 11, 4, 4, 12, 1, 1, 16, 2, 20, 2, 150, 32, 4, 176,
         0, 32, 24, 2, 0,
       };
@@ -26636,7 +27089,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 34, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 118, 95, 109, 117, 108, 97, 100, 100, 116,
-        97,
+            97,
         112, 115, 95, 117, 56, 11, 4, 4, 12, 1, 1, 16, 2, 20, 2, 20,
         4, 150, 32, 4, 176, 33, 32, 24, 103, 0, 0, 33, 2, 0,
       };
@@ -26766,7 +27219,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 32, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 118, 95, 109, 117, 108, 116, 97, 112, 115,
-        95,
+            95,
         117, 49, 54, 11, 4, 4, 12, 2, 2, 16, 2, 20, 4, 154, 32, 4,
         120, 0, 32, 24, 2, 0,
       };
@@ -26911,7 +27364,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 35, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 118, 95, 109, 117, 108, 97, 100, 100, 116,
-        97,
+            97,
         112, 115, 95, 117, 49, 54, 11, 4, 4, 12, 2, 2, 16, 2, 20, 4,
         20, 4, 154, 32, 4, 153, 33, 24, 120, 32, 32, 33, 103, 0, 0, 32,
         2, 0,
@@ -27044,7 +27497,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 34, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 118, 95, 109, 117, 108, 116, 97, 112, 115,
-        95,
+            95,
         117, 56, 95, 108, 113, 11, 2, 2, 12, 1, 1, 16, 2, 20, 2, 150,
         32, 4, 89, 0, 32, 24, 2, 0,
       };
@@ -27277,7 +27730,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 35, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 118, 95, 109, 117, 108, 116, 97, 112, 115,
-        52,
+            52,
         95, 117, 56, 95, 108, 113, 11, 2, 2, 12, 1, 1, 12, 1, 1, 12,
         1, 1, 12, 1, 1, 16, 2, 16, 2, 16, 2, 16, 2, 20, 2, 20,
         2, 150, 32, 4, 89, 32, 32, 24, 150, 33, 5, 89, 33, 33, 25, 70,
@@ -27450,7 +27903,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 37, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 118, 95, 109, 117, 108, 97, 100, 100, 116,
-        97,
+            97,
         112, 115, 95, 117, 56, 95, 108, 113, 11, 2, 2, 12, 1, 1, 16, 2,
         20, 2, 150, 32, 4, 89, 32, 32, 24, 70, 0, 0, 32, 2, 0,
       };
@@ -27697,7 +28150,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 38, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 118, 95, 109, 117, 108, 97, 100, 100, 116,
-        97,
+            97,
         112, 115, 52, 95, 117, 56, 95, 108, 113, 11, 2, 2, 12, 1, 1, 12,
         1, 1, 12, 1, 1, 12, 1, 1, 16, 2, 16, 2, 16, 2, 16, 2,
         20, 2, 20, 2, 150, 32, 4, 89, 32, 32, 24, 150, 33, 5, 89, 33,
@@ -28016,7 +28469,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 43, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 114, 101, 115,
         97, 109, 112, 108, 101, 95, 118, 95, 109, 117, 108, 97, 100, 100, 115,
-        99,
+            99,
         97, 108, 101, 116, 97, 112, 115, 52, 95, 117, 56, 95, 108, 113, 11, 1,
         1, 12, 1, 1, 12, 1, 1, 12, 1, 1, 12, 1, 1, 12, 2, 2,
         14, 2, 32, 0, 0, 0, 14, 2, 6, 0, 0, 0, 16, 2, 16, 2,
@@ -30240,7 +30693,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 30, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 100, 105, 116,
         104, 101, 114, 95, 110, 111, 110, 101, 95, 52, 117, 56, 95, 109, 97,
-        115,
+            115,
         107, 11, 4, 4, 16, 4, 20, 4, 115, 32, 24, 21, 2, 37, 0, 32,
         0, 2, 0,
       };
@@ -30550,7 +31003,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 33, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 100, 105, 116,
         104, 101, 114, 95, 118, 101, 114, 116, 101, 114, 114, 95, 52, 117, 56,
-        95,
+            95,
         109, 97, 115, 107, 11, 4, 4, 11, 8, 8, 18, 8, 20, 8, 20, 8,
         134, 32, 24, 21, 2, 150, 33, 0, 21, 2, 70, 33, 1, 33, 21, 2,
         73, 1, 32, 33, 21, 2, 74, 33, 32, 33, 21, 2, 160, 0, 33, 2,
@@ -30733,7 +31186,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 29, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 100, 105, 116,
         104, 101, 114, 95, 102, 115, 95, 109, 117, 108, 97, 100, 100, 95, 117,
-        56,
+            56,
         11, 2, 2, 14, 4, 4, 0, 0, 0, 14, 2, 5, 0, 0, 0, 14,
         4, 8, 0, 0, 0, 14, 2, 3, 0, 0, 0, 20, 2, 20, 2, 83,
         33, 0, 16, 89, 33, 33, 17, 70, 32, 33, 0, 83, 33, 0, 18, 89,
@@ -30865,7 +31318,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 27, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 100, 105, 116,
         104, 101, 114, 95, 111, 114, 100, 101, 114, 101, 100, 95, 117, 56, 11,
-        1,
+            1,
         1, 12, 1, 1, 35, 0, 0, 4, 2, 0,
       };
       p = orc_program_new_from_static_bytecode (bc);
@@ -31028,7 +31481,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 33, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 100, 105, 116,
         104, 101, 114, 95, 111, 114, 100, 101, 114, 101, 100, 95, 52, 117, 56,
-        95,
+            95,
         109, 97, 115, 107, 11, 4, 4, 12, 8, 8, 18, 8, 20, 8, 20, 8,
         134, 33, 24, 21, 2, 150, 32, 0, 21, 2, 70, 32, 32, 4, 21, 2,
         74, 32, 33, 32, 21, 2, 160, 0, 32, 2, 0,
@@ -31196,7 +31649,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 34, 118, 105, 100, 101, 111, 95, 111, 114, 99, 95, 100, 105, 116,
         104, 101, 114, 95, 111, 114, 100, 101, 114, 101, 100, 95, 52, 117, 49,
-        54,
+            54,
         95, 109, 97, 115, 107, 11, 8, 8, 12, 8, 8, 18, 8, 20, 8, 20,
         8, 134, 33, 24, 21, 2, 72, 32, 0, 4, 21, 2, 74, 0, 33, 32,
         2, 0,
diff --git a/gst-libs/gst/video/video-orc-dist.h b/gst-libs/gst/video/video-orc-dist.h
index c2fef7d..d6a2aa6 100644
--- a/gst-libs/gst/video/video-orc-dist.h
+++ b/gst-libs/gst/video/video-orc-dist.h
@@ -177,6 +177,7 @@
 void video_orc_convert_AYUV_ABGR (guint8 * ORC_RESTRICT d1, int d1_stride, const guint8 * ORC_RESTRICT s1, int s1_stride, int p1, int p2, int p3, int p4, int p5, int n, int m);
 void video_orc_convert_AYUV_RGBA (guint8 * ORC_RESTRICT d1, int d1_stride, const guint8 * ORC_RESTRICT s1, int s1_stride, int p1, int p2, int p3, int p4, int p5, int n, int m);
 void video_orc_convert_I420_BGRA (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, int p1, int p2, int p3, int p4, int p5, int n);
+void video_orc_convert_I420_ARGB (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, const guint8 * ORC_RESTRICT s2, const guint8 * ORC_RESTRICT s3, int p1, int p2, int p3, int p4, int p5, int n);
 void video_orc_matrix8 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, orc_int64 p1, orc_int64 p2, orc_int64 p3, orc_int64 p4, int n);
 void _custom_video_orc_matrix8 (guint8 * ORC_RESTRICT d1, const guint8 * ORC_RESTRICT s1, orc_int64 p1, orc_int64 p2, orc_int64 p3, orc_int64 p4, int n);
 void video_orc_resample_h_near_u32_lq (guint32 * ORC_RESTRICT d1, const guint32 * ORC_RESTRICT s1, int p1, int p2, int n);
diff --git a/gst-libs/gst/video/video-orc.orc b/gst-libs/gst/video/video-orc.orc
index 60d7c95..5af6c90 100644
--- a/gst-libs/gst/video/video-orc.orc
+++ b/gst-libs/gst/video/video-orc.orc
@@ -1663,6 +1663,7 @@
 .temp 1 b
 .temp 4 x
 .const 1 c128 128
+.const 4 c4128 128
 
 subb r, y, c128
 splatbw wy, r
@@ -1693,7 +1694,61 @@
 
 mergebw wb, b, g
 mergewl x, wb, wr
-x4 addb argb, x, c128
+x4 addb argb, x, c4128
+
+.function video_orc_convert_I420_ARGB
+.dest 4 argb guint8
+.source 1 y guint8
+.source 1 u guint8
+.source 1 v guint8
+.param 2 p1
+.param 2 p2
+.param 2 p3
+.param 2 p4
+.param 2 p5
+.temp 2 wy
+.temp 2 wu
+.temp 2 wv
+.temp 2 wr
+.temp 2 wg
+.temp 2 wb
+.temp 1 r
+.temp 1 g
+.temp 1 b
+.temp 4 x
+.const 1 c128 128
+.const 4 c4128 128
+
+subb r, y, c128
+splatbw wy, r
+loadupdb r, u
+subb r, r, c128
+splatbw wu, r
+loadupdb r, v
+subb r, r, c128
+splatbw wv, r
+
+mulhsw wy, wy, p1
+
+mulhsw wr, wv, p2
+addw wr, wy, wr
+convssswb r, wr
+mergebw wr, 127, r
+
+mulhsw wb, wu, p3
+addw wb, wy, wb
+convssswb b, wb
+
+mulhsw wg, wu, p4
+addw wg, wy, wg
+mulhsw wy, wv, p5
+addw wg, wg, wy
+
+convssswb g, wg
+
+mergebw wb, g, b
+mergewl x, wr, wb
+x4 addb argb, x, c4128
 
 .function video_orc_matrix8
 .backup _custom_video_orc_matrix8
diff --git a/gst-libs/gst/video/video-overlay-composition.c b/gst-libs/gst/video/video-overlay-composition.c
index b256b99..8e50012 100644
--- a/gst-libs/gst/video/video-overlay-composition.c
+++ b/gst-libs/gst/video/video-overlay-composition.c
@@ -186,6 +186,19 @@
   return (guint) g_atomic_int_add (&seqnum, 1);
 }
 
+static gboolean
+gst_video_overlay_composition_meta_init (GstMeta * meta, gpointer params,
+    GstBuffer * buf)
+{
+  GstVideoOverlayCompositionMeta *ometa;
+
+  ometa = (GstVideoOverlayCompositionMeta *) meta;
+
+  ometa->overlay = NULL;
+
+  return TRUE;
+}
+
 static void
 gst_video_overlay_composition_meta_free (GstMeta * meta, GstBuffer * buf)
 {
@@ -251,7 +264,8 @@
     const GstMetaInfo *meta =
         gst_meta_register (GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE,
         "GstVideoOverlayCompositionMeta",
-        sizeof (GstVideoOverlayCompositionMeta), (GstMetaInitFunction) NULL,
+        sizeof (GstVideoOverlayCompositionMeta),
+        (GstMetaInitFunction) gst_video_overlay_composition_meta_init,
         (GstMetaFreeFunction) gst_video_overlay_composition_meta_free,
         (GstMetaTransformFunction)
         gst_video_overlay_composition_meta_transform);
@@ -440,11 +454,15 @@
 /**
  * gst_video_overlay_composition_blend:
  * @comp: a #GstVideoOverlayComposition
- * @video_buf: a #GstVideoFrame containing raw video data in a supported format
+ * @video_buf: a #GstVideoFrame containing raw video data in a
+ *             supported format. It should be mapped using GST_MAP_READWRITE
  *
  * Blends the overlay rectangles in @comp on top of the raw video data
  * contained in @video_buf. The data in @video_buf must be writable and
  * mapped appropriately.
+ *
+ * Since @video_buf data is read and will be modified, it ought be
+ * mapped with flag GST_MAP_READWRITE.
  */
 /* FIXME: formats with more than 8 bit per component which get unpacked into
  * ARGB64 or AYUV64 (such as v210, v216, UYVP, GRAY16_LE and GRAY16_BE)
diff --git a/gst-libs/gst/video/video-resampler.c b/gst-libs/gst/video/video-resampler.c
index 07dddc9..0848961 100644
--- a/gst-libs/gst/video/video-resampler.c
+++ b/gst-libs/gst/video/video-resampler.c
@@ -410,6 +410,8 @@
     params.dx = ceil (2.0 * params.envelope / params.fx);
     n_taps = CLAMP (params.dx, 0, max_taps);
   }
+  if (flags & GST_VIDEO_RESAMPLER_FLAG_HALF_TAPS && n_taps > 3)
+    n_taps /= 2;
   params.fx = 2.0 * params.envelope / n_taps;
   params.ex = 2.0 / n_taps;
 
diff --git a/gst-libs/gst/video/video-resampler.h b/gst-libs/gst/video/video-resampler.h
index 699f382..3338046 100644
--- a/gst-libs/gst/video/video-resampler.h
+++ b/gst-libs/gst/video/video-resampler.h
@@ -116,6 +116,9 @@
 /**
  * GstVideoResamplerFlags:
  * @GST_VIDEO_RESAMPLER_FLAG_NONE: no flags
+ * @GST_VIDEO_RESAMPLER_FLAG_HALF_TAPS: when no taps are given, half the
+ *              number of calculated taps. This can be used when making scalers
+ *              for the different fields of an interlaced picture. Since 1.10
  *
  * Different resampler flags.
  *
@@ -123,6 +126,7 @@
  */
 typedef enum {
   GST_VIDEO_RESAMPLER_FLAG_NONE                 = (0),
+  GST_VIDEO_RESAMPLER_FLAG_HALF_TAPS            = (1 << 0),
 } GstVideoResamplerFlags;
 
 /**
diff --git a/gst-libs/gst/video/video-scaler.c b/gst-libs/gst/video/video-scaler.c
index 18bd09c..1dbae03 100644
--- a/gst-libs/gst/video/video-scaler.c
+++ b/gst-libs/gst/video/video-scaler.c
@@ -185,6 +185,8 @@
 #endif
 }
 
+#define INTERLACE_SHIFT 0.5
+
 /**
  * gst_video_scaler_new: (skip)
  * @method: a #GstVideoResamplerMethod
@@ -221,14 +223,18 @@
 
   if (flags & GST_VIDEO_SCALER_FLAG_INTERLACED) {
     GstVideoResampler tresamp, bresamp;
+    gdouble shift;
 
-    gst_video_resampler_init (&tresamp, method, 0, (out_size + 1) / 2, n_taps,
-        -0.5, (in_size + 1) / 2, (out_size + 1) / 2, options);
+    shift = (INTERLACE_SHIFT * out_size) / in_size;
+
+    gst_video_resampler_init (&tresamp, method,
+        GST_VIDEO_RESAMPLER_FLAG_HALF_TAPS, (out_size + 1) / 2, n_taps, shift,
+        (in_size + 1) / 2, (out_size + 1) / 2, options);
 
     n_taps = tresamp.max_taps;
 
     gst_video_resampler_init (&bresamp, method, 0, out_size - tresamp.out_size,
-        n_taps, 0.5, in_size - tresamp.in_size,
+        n_taps, -shift, in_size - tresamp.in_size,
         out_size - tresamp.out_size, options);
 
     resampler_zip (&scale->resampler, &tresamp, &bresamp);
@@ -1191,28 +1197,28 @@
 get_functions (GstVideoScaler * hscale, GstVideoScaler * vscale,
     GstVideoFormat format,
     GstVideoScalerHFunc * hfunc, GstVideoScalerVFunc * vfunc,
-    gint * n_elems, guint * width)
+    gint * n_elems, guint * width, gint * bits)
 {
-  gint bits;
   gboolean mono = FALSE;
 
   switch (format) {
     case GST_VIDEO_FORMAT_GRAY8:
-      bits = 8;
+      *bits = 8;
       *n_elems = 1;
       mono = TRUE;
       break;
     case GST_VIDEO_FORMAT_YUY2:
     case GST_VIDEO_FORMAT_YVYU:
     case GST_VIDEO_FORMAT_UYVY:
-      bits = 8;
+      *bits = 8;
       *n_elems = 1;
       *width = GST_ROUND_UP_4 (*width * 2);
       break;
     case GST_VIDEO_FORMAT_RGB:
     case GST_VIDEO_FORMAT_BGR:
     case GST_VIDEO_FORMAT_v308:
-      bits = 8;
+    case GST_VIDEO_FORMAT_IYU2:
+      *bits = 8;
       *n_elems = 3;
       break;
     case GST_VIDEO_FORMAT_AYUV:
@@ -1224,17 +1230,17 @@
     case GST_VIDEO_FORMAT_BGRA:
     case GST_VIDEO_FORMAT_ARGB:
     case GST_VIDEO_FORMAT_ABGR:
-      bits = 8;
+      *bits = 8;
       *n_elems = 4;
       break;
     case GST_VIDEO_FORMAT_ARGB64:
     case GST_VIDEO_FORMAT_AYUV64:
-      bits = 16;
+      *bits = 16;
       *n_elems = 4;
       break;
     case GST_VIDEO_FORMAT_GRAY16_LE:
     case GST_VIDEO_FORMAT_GRAY16_BE:
-      bits = 16;
+      *bits = 16;
       *n_elems = 1;
       mono = TRUE;
       break;
@@ -1243,13 +1249,13 @@
     case GST_VIDEO_FORMAT_NV21:
     case GST_VIDEO_FORMAT_NV24:
     case GST_VIDEO_FORMAT_NV61:
-      bits = 8;
+      *bits = 8;
       *n_elems = 2;
       break;
     default:
       return FALSE;
   }
-  if (bits == 8) {
+  if (*bits == 8) {
     switch (hscale ? hscale->resampler.max_taps : 0) {
       case 0:
         break;
@@ -1291,7 +1297,7 @@
         *vfunc = video_scale_v_ntap_u8;
         break;
     }
-  } else if (bits == 16) {
+  } else if (*bits == 16) {
     switch (hscale ? hscale->resampler.max_taps : 0) {
       case 0:
         break;
@@ -1338,7 +1344,7 @@
 gst_video_scaler_horizontal (GstVideoScaler * scale, GstVideoFormat format,
     gpointer src, gpointer dest, guint dest_offset, guint width)
 {
-  gint n_elems;
+  gint n_elems, bits;
   GstVideoScalerHFunc func = NULL;
 
   g_return_if_fail (scale != NULL);
@@ -1346,7 +1352,7 @@
   g_return_if_fail (dest != NULL);
   g_return_if_fail (dest_offset + width <= scale->resampler.out_size);
 
-  if (!get_functions (scale, NULL, format, &func, NULL, &n_elems, &width)
+  if (!get_functions (scale, NULL, format, &func, NULL, &n_elems, &width, &bits)
       || func == NULL)
     goto no_func;
 
@@ -1380,7 +1386,7 @@
 gst_video_scaler_vertical (GstVideoScaler * scale, GstVideoFormat format,
     gpointer src_lines[], gpointer dest, guint dest_offset, guint width)
 {
-  gint n_elems;
+  gint n_elems, bits;
   GstVideoScalerVFunc func = NULL;
 
   g_return_if_fail (scale != NULL);
@@ -1388,7 +1394,7 @@
   g_return_if_fail (dest != NULL);
   g_return_if_fail (dest_offset < scale->resampler.out_size);
 
-  if (!get_functions (NULL, scale, format, NULL, &func, &n_elems, &width)
+  if (!get_functions (NULL, scale, format, NULL, &func, &n_elems, &width, &bits)
       || func == NULL)
     goto no_func;
 
@@ -1435,7 +1441,7 @@
     gpointer dest, gint dest_stride, guint x, guint y,
     guint width, guint height)
 {
-  gint n_elems;
+  gint n_elems, bits;
   GstVideoScalerHFunc hfunc = NULL;
   GstVideoScalerVFunc vfunc = NULL;
   gint i;
@@ -1443,7 +1449,8 @@
   g_return_if_fail (src != NULL);
   g_return_if_fail (dest != NULL);
 
-  if (!get_functions (hscale, vscale, format, &hfunc, &vfunc, &n_elems, &width))
+  if (!get_functions (hscale, vscale, format, &hfunc, &vfunc, &n_elems, &width,
+          &bits))
     goto no_func;
 
 #define LINE(s,ss,i)  ((guint8 *)(s) + ((i) * (ss)))
@@ -1455,7 +1462,7 @@
       guint8 *s, *d;
 
       xo = x * n_elems;
-      xw = width * n_elems;
+      xw = width * n_elems * (bits / 8);
 
       s = LINE (src, src_stride, y) + xo;
       d = LINE (dest, dest_stride, y) + xo;
diff --git a/gst-libs/gst/video/video.h b/gst-libs/gst/video/video.h
index 5399182..f890eae 100644
--- a/gst-libs/gst/video/video.h
+++ b/gst-libs/gst/video/video.h
@@ -57,6 +57,36 @@
   guint stride_align[GST_VIDEO_MAX_PLANES];
 };
 
+/**
+ * GstVideoOrientationMethod:
+ * @GST_VIDEO_ORIENTATION_IDENTITY: Identity (no rotation)
+ * @GST_VIDEO_ORIENTATION_90R: Rotate clockwise 90 degrees
+ * @GST_VIDEO_ORIENTATION_180: Rotate 180 degrees
+ * @GST_VIDEO_ORIENTATION_90L: Rotate counter-clockwise 90 degrees
+ * @GST_VIDEO_ORIENTATION_HORIZ: Flip horizontally
+ * @GST_VIDEO_ORIENTATION_VERT: Flip vertically
+ * @GST_VIDEO_ORIENTATION_UL_LR: Flip across upper left/lower right diagonal
+ * @GST_VIDEO_ORIENTATION_UR_LL: Flip across upper right/lower left diagonal
+ * @GST_VIDEO_ORIENTATION_AUTO: Select flip method based on image-orientation tag
+ * @GST_VIDEO_ORIENTATION_CUSTOM: Current status depends on plugin internal setup
+ *
+ * The different video orientation methods.
+ *
+ * Since: 1.10
+ */
+typedef enum {
+  GST_VIDEO_ORIENTATION_IDENTITY,
+  GST_VIDEO_ORIENTATION_90R,
+  GST_VIDEO_ORIENTATION_180,
+  GST_VIDEO_ORIENTATION_90L,
+  GST_VIDEO_ORIENTATION_HORIZ,
+  GST_VIDEO_ORIENTATION_VERT,
+  GST_VIDEO_ORIENTATION_UL_LR,
+  GST_VIDEO_ORIENTATION_UR_LL,
+  GST_VIDEO_ORIENTATION_AUTO,
+  GST_VIDEO_ORIENTATION_CUSTOM,
+} GstVideoOrientationMethod;
+
 /* metadata macros */
 /**
  * GST_META_TAG_VIDEO_STR:
@@ -137,8 +167,10 @@
 #include <gst/video/navigation.h>
 #include <gst/video/video-blend.h>
 #include <gst/video/video-event.h>
+#include <gst/video/videodirection.h>
 #include <gst/video/videoorientation.h>
 #include <gst/video/video-overlay-composition.h>
 #include <gst/video/videooverlay.h>
+#include <gst/video/gstvideotimecode.h>
 
 #endif /* __GST_VIDEO_H__ */
diff --git a/gst-libs/gst/video/videodirection.c b/gst-libs/gst/video/videodirection.c
new file mode 100644
index 0000000..da908a9
--- /dev/null
+++ b/gst-libs/gst/video/videodirection.c
@@ -0,0 +1,52 @@
+/* GStreamer
+ * Copyright (C) 2016 Igalia <calvaris@igalia.com>
+ *
+ * videodirection.c: video rotation and flipping interface
+ *
+ * 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 "video.h"
+
+#define PROP_DIRECTION_DEFAULT GST_VIDEO_ORIENTATION_IDENTITY
+
+/**
+ * SECTION:gstvideodirection
+ * @short_description: Interface for elements providing video
+ * rotation and flipping controls
+ *
+ * The interface allows unified access to control flipping and rotation
+ * operations of video-sources or operators.
+ *
+ * Since: 1.10
+ */
+
+G_DEFINE_INTERFACE (GstVideoDirection, gst_video_direction, 0);
+
+static void
+gst_video_direction_default_init (GstVideoDirectionInterface * iface)
+{
+  g_object_interface_install_property (iface,
+      g_param_spec_enum ("video-direction", "Video direction",
+          "Video direction: rotation and flipping",
+          GST_TYPE_VIDEO_ORIENTATION_METHOD, PROP_DIRECTION_DEFAULT,
+          GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
+          G_PARAM_STATIC_STRINGS));
+}
diff --git a/gst-libs/gst/video/videodirection.h b/gst-libs/gst/video/videodirection.h
new file mode 100644
index 0000000..1428489
--- /dev/null
+++ b/gst-libs/gst/video/videodirection.h
@@ -0,0 +1,62 @@
+/* GStreamer
+ * Copyright (C) 2016 Igalia <calvaris@igalia.com>
+ *
+ * videodirection.h: video rotation and flipping interface
+ *
+ * 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_VIDEO_DIRECTION_H__
+#define __GST_VIDEO_DIRECTION_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+#define GST_TYPE_VIDEO_DIRECTION \
+  (gst_video_direction_get_type ())
+#define GST_VIDEO_DIRECTION(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VIDEO_DIRECTION, GstVideoDirection))
+#define GST_IS_VIDEO_DIRECTION(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VIDEO_DIRECTION))
+#define GST_VIDEO_DIRECTION_GET_INTERFACE(inst) \
+  (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_VIDEO_DIRECTION, GstVideoDirectionInterface))
+/**
+ * GstVideoDirection:
+ *
+ * Opaque #GstVideoDirection data structure.
+ *
+ * Since: 1.10
+ */
+typedef struct _GstVideoDirection GstVideoDirection;
+typedef struct _GstVideoDirectionInterface GstVideoDirectionInterface;
+
+/**
+ * GstVideoDirectionInterface:
+ * @iface: parent interface type.
+ *
+ * #GstVideoDirectionInterface interface.
+ *
+ * Since: 1.10
+ */
+struct _GstVideoDirectionInterface
+{
+  GTypeInterface iface;
+};
+
+GType gst_video_direction_get_type (void);
+
+G_END_DECLS
+#endif /* __GST_VIDEO_DIRECTION_H__ */
diff --git a/gst-libs/gst/video/videoorientation.c b/gst-libs/gst/video/videoorientation.c
index 2ed53f5..9e2149b 100644
--- a/gst-libs/gst/video/videoorientation.c
+++ b/gst-libs/gst/video/videoorientation.c
@@ -39,36 +39,11 @@
 /* FIXME 0.11: check if we need to add API for sometimes-supportedness
  * (aka making up for GstImplementsInterface removal) (probably yes) */
 
-static void gst_video_orientation_iface_init (GstVideoOrientationInterface *
-    iface);
-
-GType
-gst_video_orientation_get_type (void)
-{
-  static GType gst_video_orientation_type = 0;
-
-  if (!gst_video_orientation_type) {
-    static const GTypeInfo gst_video_orientation_info = {
-      sizeof (GstVideoOrientationInterface),
-      (GBaseInitFunc) gst_video_orientation_iface_init,
-      NULL,
-      NULL,
-      NULL,
-      NULL,
-      0,
-      0,
-      NULL,
-    };
-
-    gst_video_orientation_type = g_type_register_static (G_TYPE_INTERFACE,
-        "GstVideoOrientation", &gst_video_orientation_info, 0);
-  }
-
-  return gst_video_orientation_type;
-}
+G_DEFINE_INTERFACE (GstVideoOrientation, gst_video_orientation, 0)
 
 static void
-gst_video_orientation_iface_init (GstVideoOrientationInterface * iface)
+gst_video_orientation_default_init (GstVideoOrientationInterface *
+    iface)
 {
   /* default virtual functions */
 
diff --git a/gst-plugins-base.doap b/gst-plugins-base.doap
index e55f75b..16ada23 100644
--- a/gst-plugins-base.doap
+++ b/gst-plugins-base.doap
@@ -36,31 +36,31 @@
 
  <release>
   <Version>
-   <revision>1.8.3</revision>
-   <branch>1.8</branch>
+   <revision>1.9.90</revision>
+   <branch>master</branch>
    <name></name>
-   <created>2016-08-19</created>
-   <file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-plugins-base/gst-plugins-base-1.8.3.tar.xz" />
+   <created>2016-09-30</created>
+   <file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-plugins-base/gst-plugins-base-1.9.90.tar.xz" />
   </Version>
  </release>
 
  <release>
   <Version>
-   <revision>1.8.2</revision>
-   <branch>1.8</branch>
+   <revision>1.9.2</revision>
+   <branch>master</branch>
    <name></name>
-   <created>2016-06-09</created>
-   <file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-plugins-base/gst-plugins-base-1.8.2.tar.xz" />
+   <created>2016-09-01</created>
+   <file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-plugins-base/gst-plugins-base-1.9.2.tar.xz" />
   </Version>
  </release>
 
  <release>
   <Version>
-   <revision>1.8.1</revision>
-   <branch>1.8</branch>
+   <revision>1.9.1</revision>
+   <branch>master</branch>
    <name></name>
-   <created>2016-04-20</created>
-   <file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-plugins-base/gst-plugins-base-1.8.1.tar.xz" />
+   <created>2016-06-06</created>
+   <file-release rdf:resource="http://gstreamer.freedesktop.org/src/gst-plugins-base/gst-plugins-base-1.9.1.tar.xz" />
   </Version>
  </release>
 
diff --git a/gst-plugins-base.spec b/gst-plugins-base.spec
index 3f70ec7..7210a38 100644
--- a/gst-plugins-base.spec
+++ b/gst-plugins-base.spec
@@ -4,7 +4,7 @@
 %define gst_minver  0.11.0
 
 Name: 		%{gstreamer}-plugins-base
-Version: 	1.8.3
+Version: 	1.9.90
 Release: 	1.gst
 Summary: 	GStreamer streaming media framework plug-ins
 
@@ -221,6 +221,7 @@
 %{_includedir}/gstreamer-%{majorminor}/gst/audio/streamvolume.h
 %{_includedir}/gstreamer-%{majorminor}/gst/video/colorbalance.h
 %{_includedir}/gstreamer-%{majorminor}/gst/video/colorbalancechannel.h
+%{_includedir}/gstreamer-%{majorminor}/gst/video/videodirection.h
 %{_includedir}/gstreamer-%{majorminor}/gst/video/videoorientation.h
 %{_includedir}/gstreamer-%{majorminor}/gst/video/videooverlay.h
 %{_includedir}/gstreamer-%{majorminor}/gst/app/app.h
diff --git a/gst-plugins-base.spec.in b/gst-plugins-base.spec.in
index c9613f0..47e46e7 100644
--- a/gst-plugins-base.spec.in
+++ b/gst-plugins-base.spec.in
@@ -221,6 +221,7 @@
 %{_includedir}/gstreamer-%{majorminor}/gst/audio/streamvolume.h
 %{_includedir}/gstreamer-%{majorminor}/gst/video/colorbalance.h
 %{_includedir}/gstreamer-%{majorminor}/gst/video/colorbalancechannel.h
+%{_includedir}/gstreamer-%{majorminor}/gst/video/videodirection.h
 %{_includedir}/gstreamer-%{majorminor}/gst/video/videoorientation.h
 %{_includedir}/gstreamer-%{majorminor}/gst/video/videooverlay.h
 %{_includedir}/gstreamer-%{majorminor}/gst/app/app.h
diff --git a/gst/Makefile.in b/gst/Makefile.in
index b1477e0..2cf6c0d 100644
--- a/gst/Makefile.in
+++ b/gst/Makefile.in
@@ -101,6 +101,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -410,6 +411,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -423,6 +427,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -460,6 +467,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst/adder/Makefile.in b/gst/adder/Makefile.in
index b5e200f..5cc6d13 100644
--- a/gst/adder/Makefile.in
+++ b/gst/adder/Makefile.in
@@ -120,6 +120,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -458,6 +459,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -471,6 +475,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -508,6 +515,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst/adder/gstadder.c b/gst/adder/gstadder.c
index 0f297d0..fe2d21a 100644
--- a/gst/adder/gstadder.c
+++ b/gst/adder/gstadder.c
@@ -856,13 +856,12 @@
           "object.", GST_TYPE_CAPS,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_adder_src_template));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_adder_sink_template));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_adder_src_template);
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_adder_sink_template);
   gst_element_class_set_static_metadata (gstelement_class, "Adder",
-      "Generic/Audio",
-      "Add N audio channels together",
+      "Generic/Audio", "Add N audio channels together",
       "Thomas Vander Stichele <thomas at apestaart dot org>");
 
   gstelement_class->request_new_pad =
diff --git a/gst/app/Makefile.in b/gst/app/Makefile.in
index ab1fc8a..e9e1386 100644
--- a/gst/app/Makefile.in
+++ b/gst/app/Makefile.in
@@ -97,6 +97,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -428,6 +429,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -441,6 +445,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -478,6 +485,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst/audioconvert/Makefile.in b/gst/audioconvert/Makefile.in
index 5991f29..6744414 100644
--- a/gst/audioconvert/Makefile.in
+++ b/gst/audioconvert/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -434,6 +435,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -447,6 +451,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -484,6 +491,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst/audioconvert/gstaudioconvert.c b/gst/audioconvert/gstaudioconvert.c
index 606fc59..d320af4 100644
--- a/gst/audioconvert/gstaudioconvert.c
+++ b/gst/audioconvert/gstaudioconvert.c
@@ -158,13 +158,13 @@
           GST_TYPE_AUDIO_NOISE_SHAPING_METHOD, GST_AUDIO_NOISE_SHAPING_NONE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_audio_convert_src_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_audio_convert_sink_template));
-  gst_element_class_set_static_metadata (element_class,
-      "Audio converter", "Filter/Converter/Audio",
-      "Convert audio to different formats", "Benjamin Otte <otte@gnome.org>");
+  gst_element_class_add_static_pad_template (element_class,
+      &gst_audio_convert_src_template);
+  gst_element_class_add_static_pad_template (element_class,
+      &gst_audio_convert_sink_template);
+  gst_element_class_set_static_metadata (element_class, "Audio converter",
+      "Filter/Converter/Audio", "Convert audio to different formats",
+      "Benjamin Otte <otte@gnome.org>");
 
   basetransform_class->get_unit_size =
       GST_DEBUG_FUNCPTR (gst_audio_convert_get_unit_size);
diff --git a/gst/audiorate/Makefile.in b/gst/audiorate/Makefile.in
index bfc0125..7f2f918 100644
--- a/gst/audiorate/Makefile.in
+++ b/gst/audiorate/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -431,6 +432,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -444,6 +448,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -481,6 +488,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst/audiorate/gstaudiorate.c b/gst/audiorate/gstaudiorate.c
index 1927ec3..ad8720c 100644
--- a/gst/audiorate/gstaudiorate.c
+++ b/gst/audiorate/gstaudiorate.c
@@ -190,10 +190,10 @@
       "Drops/duplicates/adjusts timestamps on audio samples to make a perfect stream",
       "Wim Taymans <wim@fluendo.com>");
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_audio_rate_sink_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_audio_rate_src_template));
+  gst_element_class_add_static_pad_template (element_class,
+      &gst_audio_rate_sink_template);
+  gst_element_class_add_static_pad_template (element_class,
+      &gst_audio_rate_src_template);
 
   element_class->change_state = gst_audio_rate_change_state;
 }
diff --git a/gst/audioresample/Makefile.am b/gst/audioresample/Makefile.am
index 728700d..6d83a39 100644
--- a/gst/audioresample/Makefile.am
+++ b/gst/audioresample/Makefile.am
@@ -1,44 +1,23 @@
 plugin_LTLIBRARIES = libgstaudioresample.la
 
-# FIXME: we still link against orc if it's there, even if --disable-orc was used
-if HAVE_ORC
-ORC_TEST_LIBS = -lorc-test-0.4
-else
-ORC_TEST_LIBS = 
-endif
-
 libgstaudioresample_la_SOURCES = \
-	gstaudioresample.c \
-	speex_resampler_int.c \
-	speex_resampler_float.c \
-	speex_resampler_double.c
+	gstaudioresample.c 
+
+nodist_libgstaudioresample_la_SOURCES = $(BUILT_SOURCES)
 
 libgstaudioresample_la_CFLAGS = \
 	$(GST_PLUGINS_BASE_CFLAGS) \
 	$(GST_BASE_CFLAGS) \
-	$(GST_CFLAGS) \
-	$(ORC_CFLAGS)
+	$(GST_CFLAGS)
 
 libgstaudioresample_la_LIBADD = \
 	$(top_builddir)/gst-libs/gst/audio/libgstaudio-@GST_API_VERSION@.la \
 	$(GST_BASE_LIBS) \
 	$(GST_LIBS) \
-	$(ORC_LIBS) $(ORC_TEST_LIBS) \
 	$(LIBM)
 
 libgstaudioresample_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstaudioresample_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = \
-	arch.h \
-	fixed_arm4.h \
-	fixed_arm5e.h \
-	fixed_bfin.h \
-	fixed_debug.h \
-	fixed_generic.h \
-	gstaudioresample.h \
-	resample.c \
-	resample_sse.h \
-	resample_neon.h \
-	speex_resampler.h \
-	speex_resampler_wrapper.h
+	gstaudioresample.h
diff --git a/gst/audioresample/Makefile.in b/gst/audioresample/Makefile.in
index 2dd5ba7..b2dcdc4 100644
--- a/gst/audioresample/Makefile.in
+++ b/gst/audioresample/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -164,14 +165,12 @@
 am__DEPENDENCIES_1 =
 libgstaudioresample_la_DEPENDENCIES = $(top_builddir)/gst-libs/gst/audio/libgstaudio-@GST_API_VERSION@.la \
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_1)
 am_libgstaudioresample_la_OBJECTS =  \
-	libgstaudioresample_la-gstaudioresample.lo \
-	libgstaudioresample_la-speex_resampler_int.lo \
-	libgstaudioresample_la-speex_resampler_float.lo \
-	libgstaudioresample_la-speex_resampler_double.lo
-libgstaudioresample_la_OBJECTS = $(am_libgstaudioresample_la_OBJECTS)
+	libgstaudioresample_la-gstaudioresample.lo
+nodist_libgstaudioresample_la_OBJECTS =
+libgstaudioresample_la_OBJECTS = $(am_libgstaudioresample_la_OBJECTS) \
+	$(nodist_libgstaudioresample_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
 am__v_lt_0 = --silent
@@ -214,7 +213,8 @@
 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = $(libgstaudioresample_la_SOURCES)
+SOURCES = $(libgstaudioresample_la_SOURCES) \
+	$(nodist_libgstaudioresample_la_SOURCES)
 DIST_SOURCES = $(libgstaudioresample_la_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
@@ -241,7 +241,7 @@
   done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
-am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
@@ -437,6 +437,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -450,6 +453,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -487,6 +493,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -538,44 +545,25 @@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 plugin_LTLIBRARIES = libgstaudioresample.la
-@HAVE_ORC_FALSE@ORC_TEST_LIBS = 
-
-# FIXME: we still link against orc if it's there, even if --disable-orc was used
-@HAVE_ORC_TRUE@ORC_TEST_LIBS = -lorc-test-0.4
 libgstaudioresample_la_SOURCES = \
-	gstaudioresample.c \
-	speex_resampler_int.c \
-	speex_resampler_float.c \
-	speex_resampler_double.c
+	gstaudioresample.c 
 
+nodist_libgstaudioresample_la_SOURCES = $(BUILT_SOURCES)
 libgstaudioresample_la_CFLAGS = \
 	$(GST_PLUGINS_BASE_CFLAGS) \
 	$(GST_BASE_CFLAGS) \
-	$(GST_CFLAGS) \
-	$(ORC_CFLAGS)
+	$(GST_CFLAGS)
 
 libgstaudioresample_la_LIBADD = \
 	$(top_builddir)/gst-libs/gst/audio/libgstaudio-@GST_API_VERSION@.la \
 	$(GST_BASE_LIBS) \
 	$(GST_LIBS) \
-	$(ORC_LIBS) $(ORC_TEST_LIBS) \
 	$(LIBM)
 
 libgstaudioresample_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstaudioresample_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 noinst_HEADERS = \
-	arch.h \
-	fixed_arm4.h \
-	fixed_arm5e.h \
-	fixed_bfin.h \
-	fixed_debug.h \
-	fixed_generic.h \
-	gstaudioresample.h \
-	resample.c \
-	resample_sse.h \
-	resample_neon.h \
-	speex_resampler.h \
-	speex_resampler_wrapper.h
+	gstaudioresample.h
 
 all: all-am
 
@@ -656,9 +644,6 @@
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstaudioresample_la-gstaudioresample.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstaudioresample_la-speex_resampler_double.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstaudioresample_la-speex_resampler_float.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstaudioresample_la-speex_resampler_int.Plo@am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -691,27 +676,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 $(libgstaudioresample_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstaudioresample_la_CFLAGS) $(CFLAGS) -c -o libgstaudioresample_la-gstaudioresample.lo `test -f 'gstaudioresample.c' || echo '$(srcdir)/'`gstaudioresample.c
 
-libgstaudioresample_la-speex_resampler_int.lo: speex_resampler_int.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstaudioresample_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstaudioresample_la_CFLAGS) $(CFLAGS) -MT libgstaudioresample_la-speex_resampler_int.lo -MD -MP -MF $(DEPDIR)/libgstaudioresample_la-speex_resampler_int.Tpo -c -o libgstaudioresample_la-speex_resampler_int.lo `test -f 'speex_resampler_int.c' || echo '$(srcdir)/'`speex_resampler_int.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstaudioresample_la-speex_resampler_int.Tpo $(DEPDIR)/libgstaudioresample_la-speex_resampler_int.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='speex_resampler_int.c' object='libgstaudioresample_la-speex_resampler_int.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 $(libgstaudioresample_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstaudioresample_la_CFLAGS) $(CFLAGS) -c -o libgstaudioresample_la-speex_resampler_int.lo `test -f 'speex_resampler_int.c' || echo '$(srcdir)/'`speex_resampler_int.c
-
-libgstaudioresample_la-speex_resampler_float.lo: speex_resampler_float.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstaudioresample_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstaudioresample_la_CFLAGS) $(CFLAGS) -MT libgstaudioresample_la-speex_resampler_float.lo -MD -MP -MF $(DEPDIR)/libgstaudioresample_la-speex_resampler_float.Tpo -c -o libgstaudioresample_la-speex_resampler_float.lo `test -f 'speex_resampler_float.c' || echo '$(srcdir)/'`speex_resampler_float.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstaudioresample_la-speex_resampler_float.Tpo $(DEPDIR)/libgstaudioresample_la-speex_resampler_float.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='speex_resampler_float.c' object='libgstaudioresample_la-speex_resampler_float.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 $(libgstaudioresample_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstaudioresample_la_CFLAGS) $(CFLAGS) -c -o libgstaudioresample_la-speex_resampler_float.lo `test -f 'speex_resampler_float.c' || echo '$(srcdir)/'`speex_resampler_float.c
-
-libgstaudioresample_la-speex_resampler_double.lo: speex_resampler_double.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstaudioresample_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstaudioresample_la_CFLAGS) $(CFLAGS) -MT libgstaudioresample_la-speex_resampler_double.lo -MD -MP -MF $(DEPDIR)/libgstaudioresample_la-speex_resampler_double.Tpo -c -o libgstaudioresample_la-speex_resampler_double.lo `test -f 'speex_resampler_double.c' || echo '$(srcdir)/'`speex_resampler_double.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstaudioresample_la-speex_resampler_double.Tpo $(DEPDIR)/libgstaudioresample_la-speex_resampler_double.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='speex_resampler_double.c' object='libgstaudioresample_la-speex_resampler_double.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 $(libgstaudioresample_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstaudioresample_la_CFLAGS) $(CFLAGS) -c -o libgstaudioresample_la-speex_resampler_double.lo `test -f 'speex_resampler_double.c' || echo '$(srcdir)/'`speex_resampler_double.c
-
 mostlyclean-libtool:
 	-rm -f *.lo
 
diff --git a/gst/audioresample/README b/gst/audioresample/README
deleted file mode 100644
index faab16f..0000000
--- a/gst/audioresample/README
+++ /dev/null
@@ -1,347 +0,0 @@
- arch.h            
- fixed_arm4.h      
- fixed_arm5e.h     
- fixed_bfin.h      
- fixed_debug.h     
- fixed_generic.h   
- resample.c        
- speex_resampler.h 
-
-are taken from http://git.xiph.org/speex.git/ as of 2009-11-10.
-
-The only changes are:
-
-diff -Naur old/arch.h new/arch.h
---- old/arch.h	2009-11-10 12:18:29.000000000 +0100
-+++ new/arch.h	2009-11-10 12:19:09.000000000 +0100
-@@ -78,7 +78,10 @@
- #include "../include/speex/speex_types.h"
- #endif
- 
-+#ifndef ABS
- #define ABS(x) ((x) < 0 ? (-(x)) : (x))      /**< Absolute integer value. */
-+#endif
-+
- #define ABS16(x) ((x) < 0 ? (-(x)) : (x))    /**< Absolute 16-bit value.  */
- #define MIN16(a,b) ((a) < (b) ? (a) : (b))   /**< Maximum 16-bit value.   */
- #define MAX16(a,b) ((a) > (b) ? (a) : (b))   /**< Maximum 16-bit value.   */
-@@ -134,6 +137,28 @@
- 
- #else
- 
-+#ifdef DOUBLE_PRECISION
-+typedef double spx_mem_t;
-+typedef double spx_coef_t;
-+typedef double spx_lsp_t;
-+typedef double spx_sig_t;
-+typedef double spx_word16_t;
-+typedef double spx_word32_t;
-+
-+#define Q15ONE 1.0
-+#define LPC_SCALING  1.
-+#define SIG_SCALING  1.
-+#define LSP_SCALING  1.
-+#define GAMMA_SCALING 1.
-+#define GAIN_SCALING 1.
-+#define GAIN_SCALING_1 1.
-+
-+
-+#define VERY_SMALL 1e-20
-+#define VERY_LARGE32 1e20
-+#define VERY_LARGE16 1e20
-+#define Q15_ONE ((spx_word16_t)1.)
-+#else /* !DOUBLE_PRECISION */
- typedef float spx_mem_t;
- typedef float spx_coef_t;
- typedef float spx_lsp_t;
-@@ -154,6 +179,7 @@
- #define VERY_LARGE32 1e15f
- #define VERY_LARGE16 1e15f
- #define Q15_ONE ((spx_word16_t)1.f)
-+#endif /* DOUBLE_PRECISION */
- 
- #define QCONST16(x,bits) (x)
- #define QCONST32(x,bits) (x)
-diff -Naur old/resample.c new/resample.c
---- old/resample.c	2009-11-10 12:18:51.000000000 +0100
-+++ new/resample.c	2009-11-10 12:19:09.000000000 +0100
-@@ -63,22 +63,27 @@
- 
- #ifdef OUTSIDE_SPEEX
- #include <stdlib.h>
--static void *
-+
-+#include <glib.h>
-+
-+#define EXPORT G_GNUC_INTERNAL
-+
-+static inline void *
- speex_alloc (int size)
- {
--  return calloc (size, 1);
-+  return g_malloc0 (size);
- }
- 
--static void *
-+static inline void *
- speex_realloc (void *ptr, int size)
- {
--  return realloc (ptr, size);
-+  return g_realloc (ptr, size);
- }
- 
--static void
-+static inline void
- speex_free (void *ptr)
- {
--  free (ptr);
-+  g_free (ptr);
- }
- 
- #include "speex_resampler.h"
-@@ -90,7 +95,6 @@
- #include "os_support.h"
- #endif /* OUTSIDE_SPEEX */
- 
--#include "stack_alloc.h"
- #include <math.h>
- 
- #ifndef M_PI
-@@ -263,10 +267,17 @@
- };
- 
- /*8,24,40,56,80,104,128,160,200,256,320*/
-+#ifdef DOUBLE_PRECISION
-+static double
-+compute_func (double x, struct FuncDef *func)
-+{
-+  double y, frac;
-+#else
- static double
- compute_func (float x, struct FuncDef *func)
- {
-   float y, frac;
-+#endif
-   double interp[4];
-   int ind;
-   y = x * func->oversample;
-@@ -317,11 +328,19 @@
- }
- #else
- /* The slow way of computing a sinc for the table. Should improve that some day */
-+#ifdef DOUBLE_PRECISION
-+static spx_word16_t
-+sinc (double cutoff, double x, int N, struct FuncDef *window_func)
-+{
-+  /*fprintf (stderr, "%f ", x); */
-+  double xx = x * cutoff;
-+#else
- static spx_word16_t
- sinc (float cutoff, float x, int N, struct FuncDef *window_func)
- {
-   /*fprintf (stderr, "%f ", x); */
-   float xx = x * cutoff;
-+#endif
-   if (fabs (x) < 1e-6)
-     return cutoff;
-   else if (fabs (x) > .5 * N)
-@@ -372,6 +391,7 @@
- }
- #endif
- 
-+#ifndef DOUBLE_PRECISION
- static int
- resampler_basic_direct_single (SpeexResamplerState * st,
-     spx_uint32_t channel_index, const spx_word16_t * in, spx_uint32_t * in_len,
-@@ -428,6 +448,7 @@
-   st->samp_frac_num[channel_index] = samp_frac_num;
-   return out_sample;
- }
-+#endif
- 
- #ifdef FIXED_POINT
- #else
-@@ -483,6 +504,7 @@
- }
- #endif
- 
-+#ifndef DOUBLE_PRECISION
- static int
- resampler_basic_interpolate_single (SpeexResamplerState * st,
-     spx_uint32_t channel_index, const spx_word16_t * in, spx_uint32_t * in_len,
-@@ -562,6 +584,7 @@
-   st->samp_frac_num[channel_index] = samp_frac_num;
-   return out_sample;
- }
-+#endif
- 
- #ifdef FIXED_POINT
- #else
-@@ -592,10 +615,16 @@
-         PDIV32 (SHL32 ((samp_frac_num * st->oversample) % st->den_rate, 15),
-         st->den_rate);
- #else
-+#ifdef DOUBLE_PRECISION
-+    const spx_word16_t frac =
-+        ((double) ((samp_frac_num * st->oversample) % st->den_rate)) /
-+        st->den_rate;
-+#else
-     const spx_word16_t frac =
-         ((float) ((samp_frac_num * st->oversample) % st->den_rate)) /
-         st->den_rate;
- #endif
-+#endif
-     spx_word16_t interp[4];
- 
- 
-@@ -696,20 +725,27 @@
-       spx_int32_t j;
-       for (j = 0; j < st->filt_len; j++) {
-         st->sinc_table[i * st->filt_len + j] =
--            sinc (st->cutoff,
--            ((j - (spx_int32_t) st->filt_len / 2 + 1) -
-+            sinc (st->cutoff, ((j - (spx_int32_t) st->filt_len / 2 + 1) -
-+#ifdef DOUBLE_PRECISION
-+                ((double) i) / st->den_rate), st->filt_len,
-+#else
-                 ((float) i) / st->den_rate), st->filt_len,
-+#endif
-             quality_map[st->quality].window_func);
-       }
-     }
- #ifdef FIXED_POINT
-     st->resampler_ptr = resampler_basic_direct_single;
- #else
-+#ifdef DOUBLE_PRECISION
-+    st->resampler_ptr = resampler_basic_direct_double;
-+#else
-     if (st->quality > 8)
-       st->resampler_ptr = resampler_basic_direct_double;
-     else
-       st->resampler_ptr = resampler_basic_direct_single;
- #endif
-+#endif
-     /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff); */
-   } else {
-     spx_int32_t i;
-@@ -725,16 +761,24 @@
-     }
-     for (i = -4; i < (spx_int32_t) (st->oversample * st->filt_len + 4); i++)
-       st->sinc_table[i + 4] =
-+#ifdef DOUBLE_PRECISION
-+          sinc (st->cutoff, (i / (double) st->oversample - st->filt_len / 2),
-+#else
-           sinc (st->cutoff, (i / (float) st->oversample - st->filt_len / 2),
-+#endif
-           st->filt_len, quality_map[st->quality].window_func);
- #ifdef FIXED_POINT
-     st->resampler_ptr = resampler_basic_interpolate_single;
- #else
-+#ifdef DOUBLE_PRECISION
-+    st->resampler_ptr = resampler_basic_interpolate_double;
-+#else
-     if (st->quality > 8)
-       st->resampler_ptr = resampler_basic_interpolate_double;
-     else
-       st->resampler_ptr = resampler_basic_interpolate_single;
- #endif
-+#endif
-     /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff); */
-   }
-   st->int_advance = st->num_rate / st->den_rate;
-@@ -964,11 +1008,18 @@
-     spx_uint32_t channel_index, const spx_int16_t * in, spx_uint32_t * in_len,
-     spx_int16_t * out, spx_uint32_t * out_len)
- #else
-+#ifdef DOUBLE_PRECISION
-+EXPORT int
-+speex_resampler_process_float (SpeexResamplerState * st,
-+    spx_uint32_t channel_index, const double *in, spx_uint32_t * in_len,
-+    double *out, spx_uint32_t * out_len)
-+#else
- EXPORT int
- speex_resampler_process_float (SpeexResamplerState * st,
-     spx_uint32_t channel_index, const float *in, spx_uint32_t * in_len,
-     float *out, spx_uint32_t * out_len)
- #endif
-+#endif
- {
-   int j;
-   spx_uint32_t ilen = *in_len;
-@@ -1086,9 +1137,16 @@
-   return RESAMPLER_ERR_SUCCESS;
- }
- 
-+#ifdef DOUBLE_PRECISION
-+EXPORT int
-+speex_resampler_process_interleaved_float (SpeexResamplerState * st,
-+    const double *in, spx_uint32_t * in_len, double *out,
-+    spx_uint32_t * out_len)
-+#else
- EXPORT int
- speex_resampler_process_interleaved_float (SpeexResamplerState * st,
-     const float *in, spx_uint32_t * in_len, float *out, spx_uint32_t * out_len)
-+#endif
- {
-   spx_uint32_t i;
-   int istride_save, ostride_save;
-diff -Naur old/speex_resampler.h new/speex_resampler.h
---- old/speex_resampler.h	2009-11-10 12:18:09.000000000 +0100
-+++ new/speex_resampler.h	2009-11-10 12:19:09.000000000 +0100
-@@ -77,10 +77,10 @@
- #define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem)
- #define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror)
- 
--#define spx_int16_t short
--#define spx_int32_t int
--#define spx_uint16_t unsigned short
--#define spx_uint32_t unsigned int
-+#define spx_int16_t gint16
-+#define spx_int32_t gint32
-+#define spx_uint16_t guint16
-+#define spx_uint32_t guint32
-       
- #else /* OUTSIDE_SPEEX */
- 
-@@ -166,12 +166,21 @@
-  * @param out Output buffer
-  * @param out_len Size of the output buffer. Returns the number of samples written
-  */
-+#ifdef DOUBLE_PRECISION
-+int speex_resampler_process_float(SpeexResamplerState *st, 
-+                                   spx_uint32_t channel_index, 
-+                                   const double *in, 
-+                                   spx_uint32_t *in_len, 
-+                                   double *out, 
-+                                   spx_uint32_t *out_len);
-+#else
- int speex_resampler_process_float(SpeexResamplerState *st, 
-                                    spx_uint32_t channel_index, 
-                                    const float *in, 
-                                    spx_uint32_t *in_len, 
-                                    float *out, 
-                                    spx_uint32_t *out_len);
-+#endif
- 
- /** Resample an int array. The input and output buffers must *not* overlap.
-  * @param st Resampler state
-@@ -199,11 +208,19 @@
-  * @param out_len Size of the output buffer. Returns the number of samples written.
-  * This is all per-channel.
-  */
-+#ifdef DOUBLE_PRECISION
-+int speex_resampler_process_interleaved_float(SpeexResamplerState *st, 
-+                                               const double *in, 
-+                                               spx_uint32_t *in_len, 
-+                                               double *out, 
-+                                               spx_uint32_t *out_len);
-+#else
- int speex_resampler_process_interleaved_float(SpeexResamplerState *st, 
-                                                const float *in, 
-                                                spx_uint32_t *in_len, 
-                                                float *out, 
-                                                spx_uint32_t *out_len);
-+#endif
- 
- /** Resample an interleaved int array. The input and output buffers must *not* overlap.
-  * @param st Resampler state
diff --git a/gst/audioresample/arch.h b/gst/audioresample/arch.h
deleted file mode 100644
index 4e77e6e..0000000
--- a/gst/audioresample/arch.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/* Copyright (C) 2003 Jean-Marc Valin */
-/**
-   @file arch.h
-   @brief Various architecture definitions Speex
-*/
-/*
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-   
-   - Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-   
-   - Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-   
-   - Neither the name of the Xiph.org Foundation nor the names of its
-   contributors may be used to endorse or promote products derived from
-   this software without specific prior written permission.
-   
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
-   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef ARCH_H
-#define ARCH_H
-
-#ifndef SPEEX_VERSION
-#define SPEEX_MAJOR_VERSION 1         /**< Major Speex version. */
-#define SPEEX_MINOR_VERSION 1         /**< Minor Speex version. */
-#define SPEEX_MICRO_VERSION 15        /**< Micro Speex version. */
-#define SPEEX_EXTRA_VERSION ""        /**< Extra Speex version. */
-#define SPEEX_VERSION "speex-1.2beta3"  /**< Speex version string. */
-#endif
-
-/* A couple test to catch stupid option combinations */
-#ifdef FIXED_POINT
-
-#ifdef FLOATING_POINT
-#error You cannot compile as floating point and fixed point at the same time
-#endif
-#ifdef _USE_SSE
-#error SSE is only for floating-point
-#endif
-#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM))
-#error Make up your mind. What CPU do you have?
-#endif
-#ifdef VORBIS_PSYCHO
-#error Vorbis-psy model currently not implemented in fixed-point
-#endif
-
-#else
-
-#ifndef FLOATING_POINT
-#error You now need to define either FIXED_POINT or FLOATING_POINT
-#endif
-#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM)
-#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions?
-#endif
-#ifdef FIXED_POINT_DEBUG
-#error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?"
-#endif
-
-
-#endif
-
-#ifndef OUTSIDE_SPEEX
-#include "../include/speex/speex_types.h"
-#endif
-
-#ifndef ABS
-#define ABS(x) ((x) < 0 ? (-(x)) : (x))      /**< Absolute integer value. */
-#endif
-
-#define ABS16(x) ((x) < 0 ? (-(x)) : (x))    /**< Absolute 16-bit value.  */
-#define MIN16(a,b) ((a) < (b) ? (a) : (b))   /**< Maximum 16-bit value.   */
-#define MAX16(a,b) ((a) > (b) ? (a) : (b))   /**< Maximum 16-bit value.   */
-#define ABS32(x) ((x) < 0 ? (-(x)) : (x))    /**< Absolute 32-bit value.  */
-#define MIN32(a,b) ((a) < (b) ? (a) : (b))   /**< Maximum 32-bit value.   */
-#define MAX32(a,b) ((a) > (b) ? (a) : (b))   /**< Maximum 32-bit value.   */
-
-#ifdef FIXED_POINT
-
-typedef spx_int16_t spx_word16_t;
-typedef spx_int32_t spx_word32_t;
-typedef spx_word32_t spx_mem_t;
-typedef spx_word16_t spx_coef_t;
-typedef spx_word16_t spx_lsp_t;
-typedef spx_word32_t spx_sig_t;
-
-#define Q15ONE 32767
-
-#define LPC_SCALING  8192
-#define SIG_SCALING  16384
-#define LSP_SCALING  8192.
-#define GAMMA_SCALING 32768.
-#define GAIN_SCALING 64
-#define GAIN_SCALING_1 0.015625
-
-#define LPC_SHIFT    13
-#define LSP_SHIFT    13
-#define SIG_SHIFT    14
-#define GAIN_SHIFT   6
-
-#define VERY_SMALL 0
-#define VERY_LARGE32 ((spx_word32_t)2147483647)
-#define VERY_LARGE16 ((spx_word16_t)32767)
-#define Q15_ONE ((spx_word16_t)32767)
-
-
-#ifdef FIXED_DEBUG
-#include "fixed_debug.h"
-#else
-
-#include "fixed_generic.h"
-
-#ifdef ARM5E_ASM
-#include "fixed_arm5e.h"
-#elif defined (ARM4_ASM)
-#include "fixed_arm4.h"
-#elif defined (BFIN_ASM)
-#include "fixed_bfin.h"
-#endif
-
-#endif
-
-
-#else
-
-#ifdef DOUBLE_PRECISION
-typedef double spx_mem_t;
-typedef double spx_coef_t;
-typedef double spx_lsp_t;
-typedef double spx_sig_t;
-typedef double spx_word16_t;
-typedef double spx_word32_t;
-
-#define Q15ONE 1.0
-#define LPC_SCALING  1.
-#define SIG_SCALING  1.
-#define LSP_SCALING  1.
-#define GAMMA_SCALING 1.
-#define GAIN_SCALING 1.
-#define GAIN_SCALING_1 1.
-
-
-#define VERY_SMALL 1e-20
-#define VERY_LARGE32 1e20
-#define VERY_LARGE16 1e20
-#define Q15_ONE ((spx_word16_t)1.)
-#else /* !DOUBLE_PRECISION */
-typedef float spx_mem_t;
-typedef float spx_coef_t;
-typedef float spx_lsp_t;
-typedef float spx_sig_t;
-typedef float spx_word16_t;
-typedef float spx_word32_t;
-
-#define Q15ONE 1.0f
-#define LPC_SCALING  1.f
-#define SIG_SCALING  1.f
-#define LSP_SCALING  1.f
-#define GAMMA_SCALING 1.f
-#define GAIN_SCALING 1.f
-#define GAIN_SCALING_1 1.f
-
-
-#define VERY_SMALL 1e-15f
-#define VERY_LARGE32 1e15f
-#define VERY_LARGE16 1e15f
-#define Q15_ONE ((spx_word16_t)1.f)
-#endif /* DOUBLE_PRECISION */
-
-#define QCONST16(x,bits) (x)
-#define QCONST32(x,bits) (x)
-
-#define NEG16(x) (-(x))
-#define NEG32(x) (-(x))
-#define EXTRACT16(x) (x)
-#define EXTEND32(x) (x)
-#define SHR16(a,shift) (a)
-#define SHL16(a,shift) (a)
-#define SHR32(a,shift) (a)
-#define SHL32(a,shift) (a)
-#define PSHR16(a,shift) (a)
-#define PSHR32(a,shift) (a)
-#define VSHR32(a,shift) (a)
-#define SATURATE16(x,a) (x)
-#define SATURATE32(x,a) (x)
-#define SATURATE32PSHR(x,shift,a) (x)
-
-#define PSHR(a,shift)       (a)
-#define SHR(a,shift)       (a)
-#define SHL(a,shift)       (a)
-#define SATURATE(x,a) (x)
-
-#define ADD16(a,b) ((a)+(b))
-#define SUB16(a,b) ((a)-(b))
-#define ADD32(a,b) ((a)+(b))
-#define SUB32(a,b) ((a)-(b))
-#define MULT16_16_16(a,b)     ((a)*(b))
-#define MULT16_16(a,b)     ((spx_word32_t)(a)*(spx_word32_t)(b))
-#define MAC16_16(c,a,b)     ((c)+(spx_word32_t)(a)*(spx_word32_t)(b))
-
-#define MULT16_32_Q11(a,b)     ((a)*(b))
-#define MULT16_32_Q13(a,b)     ((a)*(b))
-#define MULT16_32_Q14(a,b)     ((a)*(b))
-#define MULT16_32_Q15(a,b)     ((a)*(b))
-#define MULT16_32_P15(a,b)     ((a)*(b))
-
-#define MAC16_32_Q11(c,a,b)     ((c)+(a)*(b))
-#define MAC16_32_Q15(c,a,b)     ((c)+(a)*(b))
-
-#define MAC16_16_Q11(c,a,b)     ((c)+(a)*(b))
-#define MAC16_16_Q13(c,a,b)     ((c)+(a)*(b))
-#define MAC16_16_P13(c,a,b)     ((c)+(a)*(b))
-#define MULT16_16_Q11_32(a,b)     ((a)*(b))
-#define MULT16_16_Q13(a,b)     ((a)*(b))
-#define MULT16_16_Q14(a,b)     ((a)*(b))
-#define MULT16_16_Q15(a,b)     ((a)*(b))
-#define MULT16_16_P15(a,b)     ((a)*(b))
-#define MULT16_16_P13(a,b)     ((a)*(b))
-#define MULT16_16_P14(a,b)     ((a)*(b))
-
-#define DIV32_16(a,b)     (((spx_word32_t)(a))/(spx_word16_t)(b))
-#define PDIV32_16(a,b)     (((spx_word32_t)(a))/(spx_word16_t)(b))
-#define DIV32(a,b)     (((spx_word32_t)(a))/(spx_word32_t)(b))
-#define PDIV32(a,b)     (((spx_word32_t)(a))/(spx_word32_t)(b))
-
-
-#endif
-
-
-#if defined (CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
-
-/* 2 on TI C5x DSP */
-#define BYTES_PER_CHAR 2 
-#define BITS_PER_CHAR 16
-#define LOG2_BITS_PER_CHAR 4
-
-#else 
-
-#define BYTES_PER_CHAR 1
-#define BITS_PER_CHAR 8
-#define LOG2_BITS_PER_CHAR 3
-
-#endif
-
-
-
-#ifdef FIXED_DEBUG
-extern long long spx_mips;
-#endif
-
-
-#endif
diff --git a/gst/audioresample/fixed_arm4.h b/gst/audioresample/fixed_arm4.h
deleted file mode 100644
index b6981ca..0000000
--- a/gst/audioresample/fixed_arm4.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/* Copyright (C) 2004 Jean-Marc Valin */
-/**
-   @file fixed_arm4.h
-   @brief ARM4 fixed-point operations
-*/
-/*
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-   
-   - Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-   
-   - Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-   
-   - Neither the name of the Xiph.org Foundation nor the names of its
-   contributors may be used to endorse or promote products derived from
-   this software without specific prior written permission.
-   
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
-   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef FIXED_ARM4_H
-#define FIXED_ARM4_H
-
-#undef MULT16_32_Q14
-static inline spx_word32_t MULT16_32_Q14(spx_word16_t x, spx_word32_t y) {
-  int res;
-  int dummy;
-  asm (
-        "smull  %0,%1,%2,%3 \n\t"
-        "mov %0, %0, lsr #14 \n\t"
-        "add %0, %0, %1, lsl #18 \n\t"
-   : "=&r"(res), "=&r" (dummy)
-   : "r"(y),"r"((int)x));
-  return(res);
-}
-
-#undef MULT16_32_Q15
-static inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) {
-  int res;
-  int dummy;
-  asm (
-        "smull  %0,%1,%2,%3 \n\t"
-        "mov %0, %0, lsr #15 \n\t"
-        "add %0, %0, %1, lsl #17 \n\t"
-   : "=&r"(res), "=&r" (dummy)
-   : "r"(y),"r"((int)x));
-  return(res);
-}
-
-#undef DIV32_16
-static inline short DIV32_16(int a, int b)
-{
-   int res=0;
-   int dead1, dead2, dead3, dead4, dead5;
-   __asm__ __volatile__ (
-         "\teor %5, %0, %1\n"
-         "\tmovs %4, %0\n"
-         "\trsbmi %0, %0, #0 \n"
-         "\tmovs %4, %1\n"
-         "\trsbmi %1, %1, #0 \n"
-         "\tmov %4, #1\n"
-
-         "\tsubs %3, %0, %1, asl #14 \n"
-         "\tmovpl %0, %3 \n"
-         "\torrpl %2, %2, %4, asl #14 \n"
-
-         "\tsubs %3, %0, %1, asl #13 \n"
-         "\tmovpl %0, %3 \n"
-         "\torrpl %2, %2, %4, asl #13 \n"
-
-         "\tsubs %3, %0, %1, asl #12 \n"
-         "\tmovpl %0, %3 \n"
-         "\torrpl %2, %2, %4, asl #12 \n"
-
-         "\tsubs %3, %0, %1, asl #11 \n"
-         "\tmovpl %0, %3 \n"
-         "\torrpl %2, %2, %4, asl #11 \n"
-
-         "\tsubs %3, %0, %1, asl #10 \n"
-         "\tmovpl %0, %3 \n"
-         "\torrpl %2, %2, %4, asl #10 \n"
-
-         "\tsubs %3, %0, %1, asl #9 \n"
-         "\tmovpl %0, %3 \n"
-         "\torrpl %2, %2, %4, asl #9 \n"
-
-         "\tsubs %3, %0, %1, asl #8 \n"
-         "\tmovpl %0, %3 \n"
-         "\torrpl %2, %2, %4, asl #8 \n"
-
-         "\tsubs %3, %0, %1, asl #7 \n"
-         "\tmovpl %0, %3 \n"
-         "\torrpl %2, %2, %4, asl #7 \n"
-
-         "\tsubs %3, %0, %1, asl #6 \n"
-         "\tmovpl %0, %3 \n"
-         "\torrpl %2, %2, %4, asl #6 \n"
-         
-         "\tsubs %3, %0, %1, asl #5 \n"
-         "\tmovpl %0, %3 \n"
-         "\torrpl %2, %2, %4, asl #5 \n"
-
-         "\tsubs %3, %0, %1, asl #4 \n"
-         "\tmovpl %0, %3 \n"
-         "\torrpl %2, %2, %4, asl #4 \n"
-
-         "\tsubs %3, %0, %1, asl #3 \n"
-         "\tmovpl %0, %3 \n"
-         "\torrpl %2, %2, %4, asl #3 \n"
-
-         "\tsubs %3, %0, %1, asl #2 \n"
-         "\tmovpl %0, %3 \n"
-         "\torrpl %2, %2, %4, asl #2 \n"
-
-         "\tsubs %3, %0, %1, asl #1 \n"
-         "\tmovpl %0, %3 \n"
-         "\torrpl %2, %2, %4, asl #1 \n"
-
-         "\tsubs %3, %0, %1 \n"
-         "\tmovpl %0, %3 \n"
-         "\torrpl %2, %2, %4 \n"
-
-         "\tmovs %5, %5, lsr #31 \n"
-         "\trsbne %2, %2, #0 \n"
-   : "=r" (dead1), "=r" (dead2), "=r" (res),
-   "=r" (dead3), "=r" (dead4), "=r" (dead5)
-   : "0" (a), "1" (b), "2" (res)
-   : "cc"
-                        );
-   return res;
-}
-
-
-#endif
diff --git a/gst/audioresample/fixed_arm5e.h b/gst/audioresample/fixed_arm5e.h
deleted file mode 100644
index 9b4861c..0000000
--- a/gst/audioresample/fixed_arm5e.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/* Copyright (C) 2003 Jean-Marc Valin */
-/**
-   @file fixed_arm5e.h
-   @brief ARM-tuned fixed-point operations
-*/
-/*
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-   
-   - Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-   
-   - Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-   
-   - Neither the name of the Xiph.org Foundation nor the names of its
-   contributors may be used to endorse or promote products derived from
-   this software without specific prior written permission.
-   
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
-   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef FIXED_ARM5E_H
-#define FIXED_ARM5E_H
-
-#undef MULT16_16
-static inline spx_word32_t MULT16_16(spx_word16_t x, spx_word16_t y) {
-  int res;
-  asm ("smulbb  %0,%1,%2;\n"
-              : "=&r"(res)
-              : "%r"(x),"r"(y));
-  return(res);
-}
-
-#undef MAC16_16
-static inline spx_word32_t MAC16_16(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
-  int res;
-  asm ("smlabb  %0,%1,%2,%3;\n"
-              : "=&r"(res)
-               : "%r"(x),"r"(y),"r"(a));
-  return(res);
-}
-
-#undef MULT16_32_Q15
-static inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) {
-  int res;
-  asm ("smulwb  %0,%1,%2;\n"
-              : "=&r"(res)
-               : "%r"(y<<1),"r"(x));
-  return(res);
-}
-
-#undef MAC16_32_Q15
-static inline spx_word32_t MAC16_32_Q15(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
-  int res;
-  asm ("smlawb  %0,%1,%2,%3;\n"
-              : "=&r"(res)
-               : "%r"(y<<1),"r"(x),"r"(a));
-  return(res);
-}
-
-#undef MULT16_32_Q11
-static inline spx_word32_t MULT16_32_Q11(spx_word16_t x, spx_word32_t y) {
-  int res;
-  asm ("smulwb  %0,%1,%2;\n"
-              : "=&r"(res)
-               : "%r"(y<<5),"r"(x));
-  return(res);
-}
-
-#undef MAC16_32_Q11
-static inline spx_word32_t MAC16_32_Q11(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
-  int res;
-  asm ("smlawb  %0,%1,%2,%3;\n"
-              : "=&r"(res)
-               : "%r"(y<<5),"r"(x),"r"(a));
-  return(res);
-}
-
-#undef DIV32_16
-static inline short DIV32_16(int a, int b)
-{
-   int res=0;
-   int dead1, dead2, dead3, dead4, dead5;
-   __asm__ __volatile__ (
-         "\teor %5, %0, %1\n"
-         "\tmovs %4, %0\n"
-         "\trsbmi %0, %0, #0 \n"
-         "\tmovs %4, %1\n"
-         "\trsbmi %1, %1, #0 \n"
-         "\tmov %4, #1\n"
-
-         "\tsubs %3, %0, %1, asl #14 \n"
-         "\torrpl %2, %2, %4, asl #14 \n"
-         "\tmovpl %0, %3 \n"
-
-         "\tsubs %3, %0, %1, asl #13 \n"
-         "\torrpl %2, %2, %4, asl #13 \n"
-         "\tmovpl %0, %3 \n"
-
-         "\tsubs %3, %0, %1, asl #12 \n"
-         "\torrpl %2, %2, %4, asl #12 \n"
-         "\tmovpl %0, %3 \n"
-
-         "\tsubs %3, %0, %1, asl #11 \n"
-         "\torrpl %2, %2, %4, asl #11 \n"
-         "\tmovpl %0, %3 \n"
-
-         "\tsubs %3, %0, %1, asl #10 \n"
-         "\torrpl %2, %2, %4, asl #10 \n"
-         "\tmovpl %0, %3 \n"
-
-         "\tsubs %3, %0, %1, asl #9 \n"
-         "\torrpl %2, %2, %4, asl #9 \n"
-         "\tmovpl %0, %3 \n"
-
-         "\tsubs %3, %0, %1, asl #8 \n"
-         "\torrpl %2, %2, %4, asl #8 \n"
-         "\tmovpl %0, %3 \n"
-
-         "\tsubs %3, %0, %1, asl #7 \n"
-         "\torrpl %2, %2, %4, asl #7 \n"
-         "\tmovpl %0, %3 \n"
-
-         "\tsubs %3, %0, %1, asl #6 \n"
-         "\torrpl %2, %2, %4, asl #6 \n"
-         "\tmovpl %0, %3 \n"
-
-         "\tsubs %3, %0, %1, asl #5 \n"
-         "\torrpl %2, %2, %4, asl #5 \n"
-         "\tmovpl %0, %3 \n"
-
-         "\tsubs %3, %0, %1, asl #4 \n"
-         "\torrpl %2, %2, %4, asl #4 \n"
-         "\tmovpl %0, %3 \n"
-
-         "\tsubs %3, %0, %1, asl #3 \n"
-         "\torrpl %2, %2, %4, asl #3 \n"
-         "\tmovpl %0, %3 \n"
-
-         "\tsubs %3, %0, %1, asl #2 \n"
-         "\torrpl %2, %2, %4, asl #2 \n"
-         "\tmovpl %0, %3 \n"
-
-         "\tsubs %3, %0, %1, asl #1 \n"
-         "\torrpl %2, %2, %4, asl #1 \n"
-         "\tmovpl %0, %3 \n"
-
-         "\tsubs %3, %0, %1 \n"
-         "\torrpl %2, %2, %4 \n"
-         "\tmovpl %0, %3 \n"
-         
-         "\tmovs %5, %5, lsr #31 \n"
-         "\trsbne %2, %2, #0 \n"
-   : "=r" (dead1), "=r" (dead2), "=r" (res),
-   "=r" (dead3), "=r" (dead4), "=r" (dead5)
-   : "0" (a), "1" (b), "2" (res)
-   : "memory", "cc"
-                        );
-   return res;
-}
-
-
-
-
-#endif
diff --git a/gst/audioresample/fixed_bfin.h b/gst/audioresample/fixed_bfin.h
deleted file mode 100644
index 9eb21e3..0000000
--- a/gst/audioresample/fixed_bfin.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/* Copyright (C) 2005 Analog Devices
-   Author: Jean-Marc Valin */
-/**
-   @file fixed_bfin.h
-   @brief Blackfin fixed-point operations
-*/
-/*
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-   
-   - Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-   
-   - Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-   
-   - Neither the name of the Xiph.org Foundation nor the names of its
-   contributors may be used to endorse or promote products derived from
-   this software without specific prior written permission.
-   
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
-   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef FIXED_BFIN_H
-#define FIXED_BFIN_H
-
-#include "bfin.h"
-
-#undef PDIV32_16
-static inline spx_word16_t PDIV32_16(spx_word32_t a, spx_word16_t b)
-{
-   spx_word32_t res, bb;
-   bb = b;
-   a += b>>1;
-   __asm__  (
-         "P0 = 15;\n\t"
-         "R0 = %1;\n\t"
-         "R1 = %2;\n\t"
-         //"R0 = R0 + R1;\n\t"
-         "R0 <<= 1;\n\t"
-         "DIVS (R0, R1);\n\t"
-         "LOOP divide%= LC0 = P0;\n\t"
-         "LOOP_BEGIN divide%=;\n\t"
-            "DIVQ (R0, R1);\n\t"
-         "LOOP_END divide%=;\n\t"
-         "R0 = R0.L;\n\t"
-         "%0 = R0;\n\t"
-   : "=m" (res)
-   : "m" (a), "m" (bb)
-   : "P0", "R0", "R1", "ASTAT" BFIN_HWLOOP0_REGS);
-   return res;
-}
-
-#undef DIV32_16
-static inline spx_word16_t DIV32_16(spx_word32_t a, spx_word16_t b)
-{
-   spx_word32_t res, bb;
-   bb = b;
-   /* Make the roundinf consistent with the C version 
-      (do we need to do that?)*/
-   if (a<0) 
-      a += (b-1);
-   __asm__  (
-         "P0 = 15;\n\t"
-         "R0 = %1;\n\t"
-         "R1 = %2;\n\t"
-         "R0 <<= 1;\n\t"
-         "DIVS (R0, R1);\n\t"
-         "LOOP divide%= LC0 = P0;\n\t"
-         "LOOP_BEGIN divide%=;\n\t"
-            "DIVQ (R0, R1);\n\t"
-         "LOOP_END divide%=;\n\t"
-         "R0 = R0.L;\n\t"
-         "%0 = R0;\n\t"
-   : "=m" (res)
-   : "m" (a), "m" (bb)
-   : "P0", "R0", "R1", "ASTAT" BFIN_HWLOOP0_REGS);
-   return res;
-}
-
-#undef MAX16
-static inline spx_word16_t MAX16(spx_word16_t a, spx_word16_t b)
-{
-   spx_word32_t res;
-   __asm__  (
-         "%1 = %1.L (X);\n\t"
-         "%2 = %2.L (X);\n\t"
-         "%0 = MAX(%1,%2);"
-   : "=d" (res)
-   : "%d" (a), "d" (b)
-   : "ASTAT"
-   );
-   return res;
-}
-
-#undef MULT16_32_Q15
-static inline spx_word32_t MULT16_32_Q15(spx_word16_t a, spx_word32_t b)
-{
-   spx_word32_t res;
-   __asm__
-   (
-         "A1 = %2.L*%1.L (M);\n\t"
-         "A1 = A1 >>> 15;\n\t"
-         "%0 = (A1 += %2.L*%1.H) ;\n\t"
-   : "=&W" (res), "=&d" (b)
-   : "d" (a), "1" (b)
-   : "A1", "ASTAT"
-   );
-   return res;
-}
-
-#undef MAC16_32_Q15
-static inline spx_word32_t MAC16_32_Q15(spx_word32_t c, spx_word16_t a, spx_word32_t b)
-{
-   spx_word32_t res;
-   __asm__
-         (
-         "A1 = %2.L*%1.L (M);\n\t"
-         "A1 = A1 >>> 15;\n\t"
-         "%0 = (A1 += %2.L*%1.H);\n\t"
-         "%0 = %0 + %4;\n\t"
-   : "=&W" (res), "=&d" (b)
-   : "d" (a), "1" (b), "d" (c)
-   : "A1", "ASTAT"
-         );
-   return res;
-}
-
-#undef MULT16_32_Q14
-static inline spx_word32_t MULT16_32_Q14(spx_word16_t a, spx_word32_t b)
-{
-   spx_word32_t res;
-   __asm__
-         (
-         "%2 <<= 1;\n\t"
-         "A1 = %1.L*%2.L (M);\n\t"
-         "A1 = A1 >>> 15;\n\t"
-         "%0 = (A1 += %1.L*%2.H);\n\t"
-   : "=W" (res), "=d" (a), "=d" (b)
-   : "1" (a), "2" (b)
-   : "A1", "ASTAT"
-         );
-   return res;
-}
-
-#undef MAC16_32_Q14
-static inline spx_word32_t MAC16_32_Q14(spx_word32_t c, spx_word16_t a, spx_word32_t b)
-{
-   spx_word32_t res;
-   __asm__
-         (
-         "%1 <<= 1;\n\t"
-         "A1 = %2.L*%1.L (M);\n\t"
-         "A1 = A1 >>> 15;\n\t"
-         "%0 = (A1 += %2.L*%1.H);\n\t"
-         "%0 = %0 + %4;\n\t"
-   : "=&W" (res), "=&d" (b)
-   : "d" (a), "1" (b), "d" (c)
-   : "A1", "ASTAT"
-         );
-   return res;
-}
-
-#endif
diff --git a/gst/audioresample/fixed_debug.h b/gst/audioresample/fixed_debug.h
deleted file mode 100644
index 54f3866..0000000
--- a/gst/audioresample/fixed_debug.h
+++ /dev/null
@@ -1,487 +0,0 @@
-/* Copyright (C) 2003 Jean-Marc Valin */
-/**
-   @file fixed_debug.h
-   @brief Fixed-point operations with debugging
-*/
-/*
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-   
-   - Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-   
-   - Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-   
-   - Neither the name of the Xiph.org Foundation nor the names of its
-   contributors may be used to endorse or promote products derived from
-   this software without specific prior written permission.
-   
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
-   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef FIXED_DEBUG_H
-#define FIXED_DEBUG_H
-
-#include <stdio.h>
-
-extern long long spx_mips;
-#define MIPS_INC spx_mips++,
-
-#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
-#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
-
-
-#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
-#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
-
-static inline short NEG16(int x)
-{
-   int res;
-   if (!VERIFY_SHORT(x))
-   {
-      fprintf (stderr, "NEG16: input is not short: %d\n", (int)x);
-   }
-   res = -x;
-   if (!VERIFY_SHORT(res))
-      fprintf (stderr, "NEG16: output is not short: %d\n", (int)res);
-   spx_mips++;
-   return res;
-}
-static inline int NEG32(long long x)
-{
-   long long res;
-   if (!VERIFY_INT(x))
-   {
-      fprintf (stderr, "NEG16: input is not int: %d\n", (int)x);
-   }
-   res = -x;
-   if (!VERIFY_INT(res))
-      fprintf (stderr, "NEG16: output is not int: %d\n", (int)res);
-   spx_mips++;
-   return res;
-}
-
-#define EXTRACT16(x) _EXTRACT16(x, __FILE__, __LINE__)
-static inline short _EXTRACT16(int x, char *file, int line)
-{
-   int res;
-   if (!VERIFY_SHORT(x))
-   {
-      fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line);
-   }
-   res = x;
-   spx_mips++;
-   return res;
-}
-
-#define EXTEND32(x) _EXTEND32(x, __FILE__, __LINE__)
-static inline int _EXTEND32(int x, char *file, int line)
-{
-   int res;
-   if (!VERIFY_SHORT(x))
-   {
-      fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line);
-   }
-   res = x;
-   spx_mips++;
-   return res;
-}
-
-#define SHR16(a, shift) _SHR16(a, shift, __FILE__, __LINE__)
-static inline short _SHR16(int a, int shift, char *file, int line) 
-{
-   int res;
-   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
-   {
-      fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line);
-   }
-   res = a>>shift;
-   if (!VERIFY_SHORT(res))
-      fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line);
-   spx_mips++;
-   return res;
-}
-#define SHL16(a, shift) _SHL16(a, shift, __FILE__, __LINE__)
-static inline short _SHL16(int a, int shift, char *file, int line) 
-{
-   int res;
-   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
-   {
-      fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line);
-   }
-   res = a<<shift;
-   if (!VERIFY_SHORT(res))
-      fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line);
-   spx_mips++;
-   return res;
-}
-
-static inline int SHR32(long long a, int shift) 
-{
-   long long  res;
-   if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
-   {
-      fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift);
-   }
-   res = a>>shift;
-   if (!VERIFY_INT(res))
-   {
-      fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
-   }
-   spx_mips++;
-   return res;
-}
-static inline int SHL32(long long a, int shift) 
-{
-   long long  res;
-   if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
-   {
-      fprintf (stderr, "SHL32: inputs are not int: %d %d\n", (int)a, shift);
-   }
-   res = a<<shift;
-   if (!VERIFY_INT(res))
-   {
-      fprintf (stderr, "SHL32: output is not int: %d\n", (int)res);
-   }
-   spx_mips++;
-   return res;
-}
-
-#define PSHR16(a,shift) (SHR16(ADD16((a),((1<<((shift))>>1))),shift))
-#define PSHR32(a,shift) (SHR32(ADD32((a),((EXTEND32(1)<<((shift))>>1))),shift))
-#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
-
-#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
-#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
-
-//#define SHR(a,shift) ((a) >> (shift))
-//#define SHL(a,shift) ((a) << (shift))
-
-#define ADD16(a, b) _ADD16(a, b, __FILE__, __LINE__)
-static inline short _ADD16(int a, int b, char *file, int line) 
-{
-   int res;
-   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
-   {
-      fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
-   }
-   res = a+b;
-   if (!VERIFY_SHORT(res))
-   {
-      fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line);
-   }
-   spx_mips++;
-   return res;
-}
-
-#define SUB16(a, b) _SUB16(a, b, __FILE__, __LINE__)
-static inline short _SUB16(int a, int b, char *file, int line) 
-{
-   int res;
-   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
-   {
-      fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
-   }
-   res = a-b;
-   if (!VERIFY_SHORT(res))
-      fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line);
-   spx_mips++;
-   return res;
-}
-
-#define ADD32(a, b) _ADD32(a, b, __FILE__, __LINE__)
-static inline int _ADD32(long long a, long long b, char *file, int line) 
-{
-   long long res;
-   if (!VERIFY_INT(a) || !VERIFY_INT(b))
-   {
-      fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
-   }
-   res = a+b;
-   if (!VERIFY_INT(res))
-   {
-      fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line);
-   }
-   spx_mips++;
-   return res;
-}
-
-static inline int SUB32(long long a, long long b) 
-{
-   long long res;
-   if (!VERIFY_INT(a) || !VERIFY_INT(b))
-   {
-      fprintf (stderr, "SUB32: inputs are not int: %d %d\n", (int)a, (int)b);
-   }
-   res = a-b;
-   if (!VERIFY_INT(res))
-      fprintf (stderr, "SUB32: output is not int: %d\n", (int)res);
-   spx_mips++;
-   return res;
-}
-
-#define ADD64(a,b) (MIPS_INC(a)+(b))
-
-/* result fits in 16 bits */
-static inline short MULT16_16_16(int a, int b) 
-{
-   int res;
-   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
-   {
-      fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
-   }
-   res = a*b;
-   if (!VERIFY_SHORT(res))
-      fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
-   spx_mips++;
-   return res;
-}
-
-#define MULT16_16(a, b) _MULT16_16(a, b, __FILE__, __LINE__)
-static inline int _MULT16_16(int a, int b, char *file, int line) 
-{
-   long long res;
-   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
-   {
-      fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
-   }
-   res = ((long long)a)*b;
-   if (!VERIFY_INT(res))
-      fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line);
-   spx_mips++;
-   return res;
-}
-
-#define MAC16_16(c,a,b)     (spx_mips--,ADD32((c),MULT16_16((a),(b))))
-#define MAC16_16_Q11(c,a,b)     (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),11)))))
-#define MAC16_16_Q13(c,a,b)     (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),13)))))
-#define MAC16_16_P13(c,a,b)     (EXTRACT16(ADD32((c),SHR32(ADD32(4096,MULT16_16((a),(b))),13))))
-
-
-#define MULT16_32_QX(a, b, Q) _MULT16_32_QX(a, b, Q, __FILE__, __LINE__)
-static inline int _MULT16_32_QX(int a, long long b, int Q, char *file, int line)
-{
-   long long res;
-   if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
-   {
-      fprintf (stderr, "MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
-   }
-   if (ABS32(b)>=(EXTEND32(1)<<(15+Q)))
-      fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);      
-   res = (((long long)a)*(long long)b) >> Q;
-   if (!VERIFY_INT(res))
-      fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q, (int)a, (int)b,(int)res, file, line);
-   spx_mips+=5;
-   return res;
-}
-
-static inline int MULT16_32_PX(int a, long long b, int Q)
-{
-   long long res;
-   if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
-   {
-      fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d\n", Q, (int)a, (int)b);
-   }
-   if (ABS32(b)>=(EXTEND32(1)<<(15+Q)))
-      fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d\n", Q, (int)a, (int)b);      
-   res = ((((long long)a)*(long long)b) + ((EXTEND32(1)<<Q)>>1))>> Q;
-   if (!VERIFY_INT(res))
-      fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d\n", Q, (int)a, (int)b,(int)res);
-   spx_mips+=5;
-   return res;
-}
-
-
-#define MULT16_32_Q11(a,b) MULT16_32_QX(a,b,11)
-#define MAC16_32_Q11(c,a,b) ADD32((c),MULT16_32_Q11((a),(b)))
-#define MULT16_32_Q12(a,b) MULT16_32_QX(a,b,12)
-#define MULT16_32_Q13(a,b) MULT16_32_QX(a,b,13)
-#define MULT16_32_Q14(a,b) MULT16_32_QX(a,b,14)
-#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
-#define MULT16_32_P15(a,b) MULT16_32_PX(a,b,15)
-#define MAC16_32_Q15(c,a,b) ADD32((c),MULT16_32_Q15((a),(b)))
-
-static inline int SATURATE(int a, int b)
-{
-   if (a>b)
-      a=b;
-   if (a<-b)
-      a = -b;
-   return a;
-}
-
-static inline int MULT16_16_Q11_32(int a, int b) 
-{
-   long long res;
-   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
-   {
-      fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
-   }
-   res = ((long long)a)*b;
-   res >>= 11;
-   if (!VERIFY_INT(res))
-      fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
-   spx_mips+=3;
-   return res;
-}
-static inline short MULT16_16_Q13(int a, int b) 
-{
-   long long res;
-   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
-   {
-      fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
-   }
-   res = ((long long)a)*b;
-   res >>= 13;
-   if (!VERIFY_SHORT(res))
-      fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
-   spx_mips+=3;
-   return res;
-}
-static inline short MULT16_16_Q14(int a, int b) 
-{
-   long long res;
-   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
-   {
-      fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
-   }
-   res = ((long long)a)*b;
-   res >>= 14;
-   if (!VERIFY_SHORT(res))
-      fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
-   spx_mips+=3;
-   return res;
-}
-static inline short MULT16_16_Q15(int a, int b) 
-{
-   long long res;
-   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
-   {
-      fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d\n", a, b);
-   }
-   res = ((long long)a)*b;
-   res >>= 15;
-   if (!VERIFY_SHORT(res))
-   {
-      fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int)res);
-   }
-   spx_mips+=3;
-   return res;
-}
-
-static inline short MULT16_16_P13(int a, int b) 
-{
-   long long res;
-   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
-   {
-      fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
-   }
-   res = ((long long)a)*b;
-   res += 4096;
-   if (!VERIFY_INT(res))
-      fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
-   res >>= 13;
-   if (!VERIFY_SHORT(res))
-      fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
-   spx_mips+=4;
-   return res;
-}
-static inline short MULT16_16_P14(int a, int b) 
-{
-   long long res;
-   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
-   {
-      fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
-   }
-   res = ((long long)a)*b;
-   res += 8192;
-   if (!VERIFY_INT(res))
-      fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
-   res >>= 14;
-   if (!VERIFY_SHORT(res))
-      fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
-   spx_mips+=4;
-   return res;
-}
-static inline short MULT16_16_P15(int a, int b) 
-{
-   long long res;
-   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
-   {
-      fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
-   }
-   res = ((long long)a)*b;
-   res += 16384;
-   if (!VERIFY_INT(res))
-      fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
-   res >>= 15;
-   if (!VERIFY_SHORT(res))
-      fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
-   spx_mips+=4;
-   return res;
-}
-
-#define DIV32_16(a, b) _DIV32_16(a, b, __FILE__, __LINE__)
-
-static inline int _DIV32_16(long long a, long long b, char *file, int line) 
-{
-   long long res;
-   if (b==0)
-   {
-      fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
-      return 0;
-   }
-   if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
-   {
-      fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
-   }
-   res = a/b;
-   if (!VERIFY_SHORT(res))
-   {
-      fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line);
-      if (res>32767)
-         res = 32767;
-      if (res<-32768)
-         res = -32768;
-   }
-   spx_mips+=20;
-   return res;
-}
-
-#define DIV32(a, b) _DIV32(a, b, __FILE__, __LINE__)
-static inline int _DIV32(long long a, long long b, char *file, int line) 
-{
-   long long res;
-   if (b==0)
-   {
-      fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
-      return 0;
-   }
-
-   if (!VERIFY_INT(a) || !VERIFY_INT(b))
-   {
-      fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
-   }
-   res = a/b;
-   if (!VERIFY_INT(res))
-      fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line);
-   spx_mips+=36;
-   return res;
-}
-#define PDIV32(a,b) DIV32(ADD32((a),(b)>>1),b)
-#define PDIV32_16(a,b) DIV32_16(ADD32((a),(b)>>1),b)
-
-#endif
diff --git a/gst/audioresample/fixed_generic.h b/gst/audioresample/fixed_generic.h
deleted file mode 100644
index 6991352..0000000
--- a/gst/audioresample/fixed_generic.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Copyright (C) 2003 Jean-Marc Valin */
-/**
-   @file fixed_generic.h
-   @brief Generic fixed-point operations
-*/
-/*
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-   
-   - Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-   
-   - Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-   
-   - Neither the name of the Xiph.org Foundation nor the names of its
-   contributors may be used to endorse or promote products derived from
-   this software without specific prior written permission.
-   
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
-   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef FIXED_GENERIC_H
-#define FIXED_GENERIC_H
-
-#define QCONST16(x,bits) ((spx_word16_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
-#define QCONST32(x,bits) ((spx_word32_t)(.5+(x)*(((spx_word32_t)1)<<(bits))))
-
-#define NEG16(x) (-(x))
-#define NEG32(x) (-(x))
-#define EXTRACT16(x) ((spx_word16_t)(x))
-#define EXTEND32(x) ((spx_word32_t)(x))
-#define SHR16(a,shift) ((a) >> (shift))
-#define SHL16(a,shift) ((a) << (shift))
-#define SHR32(a,shift) ((a) >> (shift))
-#define SHL32(a,shift) ((a) << (shift))
-#define PSHR16(a,shift) (SHR16((a)+((1<<((shift))>>1)),shift))
-#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift))
-#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
-#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
-#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
- 
-#define SATURATE32PSHR(x,shift,a) (((x)>=(SHL32(a,shift))) ? (a) : \
-                                   (x)<=-(SHL32(a,shift)) ? -(a) : \
-                                   (PSHR32(x, shift)))
-
-#define SHR(a,shift) ((a) >> (shift))
-#define SHL(a,shift) ((spx_word32_t)(a) << (shift))
-#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift))
-#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
-
-
-#define ADD16(a,b) ((spx_word16_t)((spx_word16_t)(a)+(spx_word16_t)(b)))
-#define SUB16(a,b) ((spx_word16_t)(a)-(spx_word16_t)(b))
-#define ADD32(a,b) ((spx_word32_t)(a)+(spx_word32_t)(b))
-#define SUB32(a,b) ((spx_word32_t)(a)-(spx_word32_t)(b))
-
-
-/* result fits in 16 bits */
-#define MULT16_16_16(a,b)     ((((spx_word16_t)(a))*((spx_word16_t)(b))))
-
-/* (spx_word32_t)(spx_word16_t) gives TI compiler a hint that it's 16x16->32 multiply */
-#define MULT16_16(a,b)     (((spx_word32_t)(spx_word16_t)(a))*((spx_word32_t)(spx_word16_t)(b)))
-
-#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))
-#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12))
-#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13))
-#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14))
-
-#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))
-#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)))
-
-#define MULT16_32_P15(a,b) ADD32(MULT16_16((a),SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15))
-#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))
-#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
-
-
-#define MAC16_16_Q11(c,a,b)     (ADD32((c),SHR(MULT16_16((a),(b)),11)))
-#define MAC16_16_Q13(c,a,b)     (ADD32((c),SHR(MULT16_16((a),(b)),13)))
-#define MAC16_16_P13(c,a,b)     (ADD32((c),SHR(ADD32(4096,MULT16_16((a),(b))),13)))
-
-#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11))
-#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13))
-#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14))
-#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15))
-
-#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13))
-#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14))
-#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15))
-
-#define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15))
-
-#define DIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a))/((spx_word16_t)(b))))
-#define PDIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word16_t)(b))))
-#define DIV32(a,b) (((spx_word32_t)(a))/((spx_word32_t)(b)))
-#define PDIV32(a,b) (((spx_word32_t)(a)+((spx_word16_t)(b)>>1))/((spx_word32_t)(b)))
-
-#endif
diff --git a/gst/audioresample/gstaudioresample.c b/gst/audioresample/gstaudioresample.c
index 7155c3c..df6782b 100644
--- a/gst/audioresample/gstaudioresample.c
+++ b/gst/audioresample/gstaudioresample.c
@@ -59,46 +59,33 @@
 #include <gst/audio/audio.h>
 #include <gst/base/gstbasetransform.h>
 
-#ifndef DISABLE_ORC
-#include <orc/orc.h>
-#include <orc-test/orctest.h>
-#include <orc-test/orcprofile.h>
-#endif
-
 GST_DEBUG_CATEGORY (audio_resample_debug);
 #define GST_CAT_DEFAULT audio_resample_debug
-#if !defined(AUDIORESAMPLE_FORMAT_AUTO) || defined(DISABLE_ORC)
+#if !defined(AUDIORESAMPLE_FORMAT_AUTO)
 GST_DEBUG_CATEGORY_STATIC (GST_CAT_PERFORMANCE);
 #endif
 
-#define GST_TYPE_SPEEX_RESAMPLER_SINC_FILTER_MODE (speex_resampler_sinc_filter_mode_get_type ())
+#undef USE_SPEEX
+
+#define DEFAULT_QUALITY GST_AUDIO_RESAMPLER_QUALITY_DEFAULT
+#define DEFAULT_RESAMPLE_METHOD GST_AUDIO_RESAMPLER_METHOD_KAISER
+#define DEFAULT_SINC_FILTER_MODE GST_AUDIO_RESAMPLER_FILTER_MODE_AUTO
+#define DEFAULT_SINC_FILTER_AUTO_THRESHOLD (1*1048576)
+#define DEFAULT_SINC_FILTER_INTERPOLATION GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_CUBIC
 
 enum
 {
   PROP_0,
   PROP_QUALITY,
+  PROP_RESAMPLE_METHOD,
   PROP_SINC_FILTER_MODE,
-  PROP_SINC_FILTER_AUTO_THRESHOLD
+  PROP_SINC_FILTER_AUTO_THRESHOLD,
+  PROP_SINC_FILTER_INTERPOLATION
 };
 
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
 #define SUPPORTED_CAPS \
-  GST_AUDIO_CAPS_MAKE ("{ F32LE, F64LE, S32LE, S24LE, S16LE, S8 }") \
+  GST_AUDIO_CAPS_MAKE (GST_AUDIO_FORMATS_ALL) \
   ", layout = (string) { interleaved, non-interleaved }"
-#else
-#define SUPPORTED_CAPS \
-  GST_AUDIO_CAPS_MAKE ("{ F32BE, F64BE, S32BE, S24BE, S16BE, S8 }") \
-  ", layout = (string) { interleaved, non-interleaved }"
-#endif
-
-/* If TRUE integer arithmetic resampling is faster and will be used if appropriate */
-#if defined AUDIORESAMPLE_FORMAT_INT
-static gboolean gst_audio_resample_use_int = TRUE;
-#elif defined AUDIORESAMPLE_FORMAT_FLOAT
-static gboolean gst_audio_resample_use_int = FALSE;
-#else
-static gboolean gst_audio_resample_use_int = FALSE;
-#endif
 
 static GstStaticPadTemplate gst_audio_resample_sink_template =
 GST_STATIC_PAD_TEMPLATE ("sink",
@@ -117,8 +104,6 @@
 static void gst_audio_resample_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 
-static GType speex_resampler_sinc_filter_mode_get_type (void);
-
 /* vmethods */
 static gboolean gst_audio_resample_get_unit_size (GstBaseTransform * base,
     GstCaps * caps, gsize * size);
@@ -159,15 +144,20 @@
   g_object_class_install_property (gobject_class, PROP_QUALITY,
       g_param_spec_int ("quality", "Quality", "Resample quality with 0 being "
           "the lowest and 10 being the best",
-          SPEEX_RESAMPLER_QUALITY_MIN, SPEEX_RESAMPLER_QUALITY_MAX,
-          SPEEX_RESAMPLER_QUALITY_DEFAULT,
+          GST_AUDIO_RESAMPLER_QUALITY_MIN, GST_AUDIO_RESAMPLER_QUALITY_MAX,
+          DEFAULT_QUALITY,
           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_RESAMPLE_METHOD,
+      g_param_spec_enum ("resample-method", "Resample method to use",
+          "What resample method to use",
+          GST_TYPE_AUDIO_RESAMPLER_METHOD,
+          DEFAULT_RESAMPLE_METHOD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (gobject_class, PROP_SINC_FILTER_MODE,
       g_param_spec_enum ("sinc-filter-mode", "Sinc filter table mode",
           "What sinc filter table mode to use",
-          GST_TYPE_SPEEX_RESAMPLER_SINC_FILTER_MODE,
-          SPEEX_RESAMPLER_SINC_FILTER_DEFAULT,
+          GST_TYPE_AUDIO_RESAMPLER_FILTER_MODE,
+          DEFAULT_SINC_FILTER_MODE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   g_object_class_install_property (gobject_class,
@@ -175,13 +165,21 @@
       g_param_spec_uint ("sinc-filter-auto-threshold",
           "Sinc filter auto mode threshold",
           "Memory usage threshold to use if sinc filter mode is AUTO, given in bytes",
-          0, G_MAXUINT, SPEEX_RESAMPLER_SINC_FILTER_AUTO_THRESHOLD_DEFAULT,
+          0, G_MAXUINT, DEFAULT_SINC_FILTER_AUTO_THRESHOLD,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class,
+      PROP_SINC_FILTER_INTERPOLATION,
+      g_param_spec_enum ("sinc-filter-interpolation",
+          "Sinc filter interpolation",
+          "How to interpolate the sinc filter table",
+          GST_TYPE_AUDIO_RESAMPLER_FILTER_INTERPOLATION,
+          DEFAULT_SINC_FILTER_INTERPOLATION,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_audio_resample_src_template));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_audio_resample_sink_template));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_audio_resample_src_template);
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_audio_resample_sink_template);
 
   gst_element_class_set_static_metadata (gstelement_class, "Audio resampler",
       "Filter/Converter/Audio", "Resamples audio",
@@ -218,10 +216,11 @@
 {
   GstBaseTransform *trans = GST_BASE_TRANSFORM (resample);
 
-  resample->quality = SPEEX_RESAMPLER_QUALITY_DEFAULT;
-  resample->sinc_filter_mode = SPEEX_RESAMPLER_SINC_FILTER_DEFAULT;
-  resample->sinc_filter_auto_threshold =
-      SPEEX_RESAMPLER_SINC_FILTER_AUTO_THRESHOLD_DEFAULT;
+  resample->method = DEFAULT_RESAMPLE_METHOD;
+  resample->quality = DEFAULT_QUALITY;
+  resample->sinc_filter_mode = DEFAULT_SINC_FILTER_MODE;
+  resample->sinc_filter_auto_threshold = DEFAULT_SINC_FILTER_AUTO_THRESHOLD;
+  resample->sinc_filter_interpolation = DEFAULT_SINC_FILTER_INTERPOLATION;
 
   gst_base_transform_set_gap_aware (trans, TRUE);
   gst_pad_set_query_function (trans->srcpad, gst_audio_resample_query);
@@ -243,11 +242,6 @@
   resample->samples_in = 0;
   resample->samples_out = 0;
 
-  resample->tmp_in = NULL;
-  resample->tmp_in_size = 0;
-  resample->tmp_out = NULL;
-  resample->tmp_out_size = 0;
-
   return TRUE;
 }
 
@@ -256,21 +250,10 @@
 {
   GstAudioResample *resample = GST_AUDIO_RESAMPLE (base);
 
-  if (resample->state) {
-    resample->funcs->destroy (resample->state);
-    resample->state = NULL;
+  if (resample->converter) {
+    gst_audio_converter_free (resample->converter);
+    resample->converter = NULL;
   }
-
-  resample->funcs = NULL;
-
-  g_free (resample->tmp_in);
-  resample->tmp_in = NULL;
-  resample->tmp_in_size = 0;
-
-  g_free (resample->tmp_out);
-  resample->tmp_out = NULL;
-  resample->tmp_out_size = 0;
-
   return TRUE;
 }
 
@@ -370,134 +353,99 @@
   return othercaps;
 }
 
-static const SpeexResampleFuncs *
-gst_audio_resample_get_funcs (gint width, gboolean fp)
+static GstStructure *
+make_options (GstAudioResample * resample, GstAudioInfo * in,
+    GstAudioInfo * out)
 {
-  const SpeexResampleFuncs *funcs = NULL;
+  GstStructure *options;
 
-  if (gst_audio_resample_use_int && (width == 8 || width == 16) && !fp)
-    funcs = &int_funcs;
-  else if ((!gst_audio_resample_use_int && (width == 8 || width == 16) && !fp)
-      || (width == 32 && fp))
-    funcs = &float_funcs;
-  else if ((width == 64 && fp) || ((width == 32 || width == 24) && !fp))
-    funcs = &double_funcs;
-  else
-    g_assert_not_reached ();
+  options = gst_structure_new_empty ("resampler-options");
+  if (in != NULL && out != NULL)
+    gst_audio_resampler_options_set_quality (resample->method,
+        resample->quality, in->rate, out->rate, options);
 
-  return funcs;
-}
+  gst_structure_set (options,
+      GST_AUDIO_CONVERTER_OPT_RESAMPLER_METHOD, GST_TYPE_AUDIO_RESAMPLER_METHOD,
+      resample->method,
+      GST_AUDIO_RESAMPLER_OPT_FILTER_MODE, GST_TYPE_AUDIO_RESAMPLER_FILTER_MODE,
+      resample->sinc_filter_mode, GST_AUDIO_RESAMPLER_OPT_FILTER_MODE_THRESHOLD,
+      G_TYPE_UINT, resample->sinc_filter_auto_threshold,
+      GST_AUDIO_RESAMPLER_OPT_FILTER_INTERPOLATION,
+      GST_TYPE_AUDIO_RESAMPLER_FILTER_INTERPOLATION,
+      resample->sinc_filter_interpolation, NULL);
 
-static SpeexResamplerState *
-gst_audio_resample_init_state (GstAudioResample * resample, gint width,
-    gint channels, gint inrate, gint outrate, gint quality, gboolean fp,
-    SpeexResamplerSincFilterMode sinc_filter_mode,
-    guint32 sinc_filter_auto_threshold)
-{
-  SpeexResamplerState *ret = NULL;
-  gint err = RESAMPLER_ERR_SUCCESS;
-  const SpeexResampleFuncs *funcs = gst_audio_resample_get_funcs (width, fp);
-
-  ret = funcs->init (channels, inrate, outrate, quality,
-      sinc_filter_mode, sinc_filter_auto_threshold, &err);
-
-  if (G_UNLIKELY (err != RESAMPLER_ERR_SUCCESS)) {
-    GST_ERROR_OBJECT (resample, "Failed to create resampler state: %s",
-        funcs->strerror (err));
-    return NULL;
-  }
-
-  if (sinc_filter_mode == SPEEX_RESAMPLER_SINC_FILTER_AUTO) {
-    GST_INFO_OBJECT (resample, "Using the %s sinc filter table",
-        funcs->get_sinc_filter_mode (ret) ? "full" : "interpolated");
-  }
-
-  funcs->skip_zeros (ret);
-
-  return ret;
+  return options;
 }
 
 static gboolean
-gst_audio_resample_update_state (GstAudioResample * resample, gint width,
-    gint channels, gint inrate, gint outrate, gint quality, gboolean fp,
-    SpeexResamplerSincFilterMode sinc_filter_mode,
-    guint32 sinc_filter_auto_threshold)
+gst_audio_resample_update_state (GstAudioResample * resample, GstAudioInfo * in,
+    GstAudioInfo * out)
 {
-  gboolean ret = TRUE;
   gboolean updated_latency = FALSE;
+  gsize old_latency = -1;
+  GstStructure *options;
 
-  updated_latency = (resample->inrate != inrate
-      || quality != resample->quality) && resample->state != NULL;
+  if (resample->converter == NULL && in == NULL && out == NULL)
+    return TRUE;
 
-  if (resample->state == NULL) {
-    ret = TRUE;
-  } else if (resample->channels != channels || fp != resample->fp
-      || width != resample->width
-      || sinc_filter_mode != resample->sinc_filter_mode
-      || sinc_filter_auto_threshold != resample->sinc_filter_auto_threshold) {
-    resample->funcs->destroy (resample->state);
-    resample->state =
-        gst_audio_resample_init_state (resample, width, channels, inrate,
-        outrate, quality, fp, sinc_filter_mode, sinc_filter_auto_threshold);
+  options = make_options (resample, in, out);
 
-    resample->funcs = gst_audio_resample_get_funcs (width, fp);
-    ret = (resample->state != NULL);
-  } else if (resample->inrate != inrate || resample->outrate != outrate) {
-    gint err = RESAMPLER_ERR_SUCCESS;
+  if (resample->converter)
+    old_latency = gst_audio_converter_get_max_latency (resample->converter);
 
-    err = resample->funcs->set_rate (resample->state, inrate, outrate);
-
-    if (G_UNLIKELY (err != RESAMPLER_ERR_SUCCESS))
-      GST_ERROR_OBJECT (resample, "Failed to update rate: %s",
-          resample->funcs->strerror (err));
-
-    ret = (err == RESAMPLER_ERR_SUCCESS);
-  } else if (quality != resample->quality) {
-    gint err = RESAMPLER_ERR_SUCCESS;
-
-    err = resample->funcs->set_quality (resample->state, quality);
-
-    if (G_UNLIKELY (err != RESAMPLER_ERR_SUCCESS))
-      GST_ERROR_OBJECT (resample, "Failed to update quality: %s",
-          resample->funcs->strerror (err));
-
-    ret = (err == RESAMPLER_ERR_SUCCESS);
+  /* if channels and layout changed, destroy existing resampler */
+  if (in != NULL && (in->finfo != resample->in.finfo ||
+          in->channels != resample->in.channels ||
+          in->layout != resample->in.layout) && resample->converter) {
+    gst_audio_converter_free (resample->converter);
+    resample->converter = NULL;
   }
+  if (resample->converter == NULL) {
+    resample->converter =
+        gst_audio_converter_new (GST_AUDIO_CONVERTER_FLAG_VARIABLE_RATE, in,
+        out, options);
+    if (resample->converter == NULL)
+      goto resampler_failed;
+  } else if (in && out) {
+    gboolean ret;
 
-  resample->width = width;
-  resample->channels = channels;
-  resample->fp = fp;
-  resample->quality = quality;
-  resample->inrate = inrate;
-  resample->outrate = outrate;
-  resample->sinc_filter_mode = sinc_filter_mode;
-  resample->sinc_filter_auto_threshold = sinc_filter_auto_threshold;
+    ret =
+        gst_audio_converter_update_config (resample->converter, in->rate,
+        out->rate, options);
+    if (!ret)
+      goto update_failed;
+  } else {
+    gst_structure_free (options);
+  }
+  if (old_latency != -1)
+    updated_latency =
+        old_latency !=
+        gst_audio_converter_get_max_latency (resample->converter);
 
   if (updated_latency)
     gst_element_post_message (GST_ELEMENT (resample),
         gst_message_new_latency (GST_OBJECT (resample)));
 
-  return ret;
+  return TRUE;
+
+  /* ERRORS */
+resampler_failed:
+  {
+    GST_ERROR_OBJECT (resample, "failed to create resampler");
+    return FALSE;
+  }
+update_failed:
+  {
+    GST_ERROR_OBJECT (resample, "failed to update resampler");
+    return FALSE;
+  }
 }
 
 static void
 gst_audio_resample_reset_state (GstAudioResample * resample)
 {
-  if (resample->state)
-    resample->funcs->reset_mem (resample->state);
-}
-
-static gint
-_gcd (gint a, gint b)
-{
-  while (b != 0) {
-    int temp = a;
-
-    a = b;
-    b = temp % b;
-  }
-
-  return ABS (a);
+  if (resample->converter)
+    gst_audio_converter_reset (resample->converter);
 }
 
 static gboolean
@@ -505,43 +453,27 @@
     GstPadDirection direction, GstCaps * caps, gsize size, GstCaps * othercaps,
     gsize * othersize)
 {
+  GstAudioResample *resample = GST_AUDIO_RESAMPLE (base);
   gboolean ret = TRUE;
-  GstAudioInfo in, out;
-  guint32 ratio_den, ratio_num;
-  gint inrate, outrate, gcd;
   gint bpf;
 
   GST_LOG_OBJECT (base, "asked to transform size %" G_GSIZE_FORMAT
       " in direction %s", size, direction == GST_PAD_SINK ? "SINK" : "SRC");
 
-  /* Get sample width -> bytes_per_samp, channels, inrate, outrate */
-  ret = gst_audio_info_from_caps (&in, caps);
-  ret &= gst_audio_info_from_caps (&out, othercaps);
-  if (G_UNLIKELY (!ret)) {
-    GST_ERROR_OBJECT (base, "Wrong caps");
-    return FALSE;
-  }
   /* Number of samples in either buffer is size / (width*channels) ->
    * calculate the factor */
-  bpf = GST_AUDIO_INFO_BPF (&in);
-  inrate = GST_AUDIO_INFO_RATE (&in);
-  outrate = GST_AUDIO_INFO_RATE (&out);
+  bpf = GST_AUDIO_INFO_BPF (&resample->in);
 
   /* Convert source buffer size to samples */
   size /= bpf;
 
-  /* Simplify the conversion ratio factors */
-  gcd = _gcd (inrate, outrate);
-  ratio_num = inrate / gcd;
-  ratio_den = outrate / gcd;
-
   if (direction == GST_PAD_SINK) {
-    /* asked to convert size of an incoming buffer. Round up the output size */
-    *othersize = gst_util_uint64_scale_int_ceil (size, ratio_den, ratio_num);
+    /* asked to convert size of an incoming buffer */
+    *othersize = gst_audio_converter_get_out_frames (resample->converter, size);
     *othersize *= bpf;
   } else {
-    /* asked to convert size of an outgoing buffer. Round down the input size */
-    *othersize = gst_util_uint64_scale_int (size, ratio_num, ratio_den);
+    /* asked to convert size of an outgoing buffer */
+    *othersize = gst_audio_converter_get_in_frames (resample->converter, size);
     *othersize *= bpf;
   }
 
@@ -556,9 +488,6 @@
 gst_audio_resample_set_caps (GstBaseTransform * base, GstCaps * incaps,
     GstCaps * outcaps)
 {
-  gboolean ret;
-  gint width, inrate, outrate, channels;
-  gboolean fp;
   GstAudioResample *resample = GST_AUDIO_RESAMPLE (base);
   GstAudioInfo in, out;
 
@@ -571,21 +500,10 @@
     goto invalid_outcaps;
 
   /* FIXME do some checks */
+  gst_audio_resample_update_state (resample, &in, &out);
 
-  /* take new values */
-  width = GST_AUDIO_FORMAT_INFO_WIDTH (in.finfo);
-  channels = GST_AUDIO_INFO_CHANNELS (&in);
-  inrate = GST_AUDIO_INFO_RATE (&in);
-  outrate = GST_AUDIO_INFO_RATE (&out);
-  fp = GST_AUDIO_FORMAT_INFO_IS_FLOAT (in.finfo);
-
-  ret =
-      gst_audio_resample_update_state (resample, width, channels, inrate,
-      outrate, resample->quality, fp, resample->sinc_filter_mode,
-      resample->sinc_filter_auto_threshold);
-
-  if (G_UNLIKELY (!ret))
-    return FALSE;
+  resample->in = in;
+  resample->out = out;
 
   return TRUE;
 
@@ -602,209 +520,24 @@
   }
 }
 
-#define GST_MAXINT24 (8388607)
-#define GST_MININT24 (-8388608)
-
-#if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
-#define GST_READ_UINT24 GST_READ_UINT24_LE
-#define GST_WRITE_UINT24 GST_WRITE_UINT24_LE
-#else
-#define GST_READ_UINT24 GST_READ_UINT24_BE
-#define GST_WRITE_UINT24 GST_WRITE_UINT24_BE
-#endif
-
-static void
-gst_audio_resample_convert_buffer (GstAudioResample * resample,
-    const guint8 * in, guint8 * out, guint len, gboolean inverse)
-{
-  len *= resample->channels;
-
-  if (inverse) {
-    if (gst_audio_resample_use_int && resample->width == 8 && !resample->fp) {
-      gint8 *o = (gint8 *) out;
-      gint16 *i = (gint16 *) in;
-      gint32 tmp;
-
-      while (len) {
-        tmp = *i + (G_MAXINT8 >> 1);
-        *o = CLAMP (tmp >> 8, G_MININT8, G_MAXINT8);
-        o++;
-        i++;
-        len--;
-      }
-    } else if (!gst_audio_resample_use_int && resample->width == 8
-        && !resample->fp) {
-      gint8 *o = (gint8 *) out;
-      gfloat *i = (gfloat *) in;
-      gfloat tmp;
-
-      while (len) {
-        tmp = *i;
-        *o = (gint8) CLAMP (tmp * G_MAXINT8 + 0.5, G_MININT8, G_MAXINT8);
-        o++;
-        i++;
-        len--;
-      }
-    } else if (!gst_audio_resample_use_int && resample->width == 16
-        && !resample->fp) {
-      gint16 *o = (gint16 *) out;
-      gfloat *i = (gfloat *) in;
-      gfloat tmp;
-
-      while (len) {
-        tmp = *i;
-        *o = (gint16) CLAMP (tmp * G_MAXINT16 + 0.5, G_MININT16, G_MAXINT16);
-        o++;
-        i++;
-        len--;
-      }
-    } else if (resample->width == 24 && !resample->fp) {
-      guint8 *o = (guint8 *) out;
-      gdouble *i = (gdouble *) in;
-      gdouble tmp;
-
-      while (len) {
-        tmp = *i;
-        GST_WRITE_UINT24 (o, (gint32) CLAMP (tmp * GST_MAXINT24 + 0.5,
-                GST_MININT24, GST_MAXINT24));
-        o += 3;
-        i++;
-        len--;
-      }
-    } else if (resample->width == 32 && !resample->fp) {
-      gint32 *o = (gint32 *) out;
-      gdouble *i = (gdouble *) in;
-      gdouble tmp;
-
-      while (len) {
-        tmp = *i;
-        *o = (gint32) CLAMP (tmp * G_MAXINT32 + 0.5, G_MININT32, G_MAXINT32);
-        o++;
-        i++;
-        len--;
-      }
-    } else {
-      g_assert_not_reached ();
-    }
-  } else {
-    if (gst_audio_resample_use_int && resample->width == 8 && !resample->fp) {
-      gint8 *i = (gint8 *) in;
-      gint16 *o = (gint16 *) out;
-      gint32 tmp;
-
-      while (len) {
-        tmp = *i;
-        *o = tmp << 8;
-        o++;
-        i++;
-        len--;
-      }
-    } else if (!gst_audio_resample_use_int && resample->width == 8
-        && !resample->fp) {
-      gint8 *i = (gint8 *) in;
-      gfloat *o = (gfloat *) out;
-      gfloat tmp;
-
-      while (len) {
-        tmp = *i;
-        *o = tmp / G_MAXINT8;
-        o++;
-        i++;
-        len--;
-      }
-    } else if (!gst_audio_resample_use_int && resample->width == 16
-        && !resample->fp) {
-      gint16 *i = (gint16 *) in;
-      gfloat *o = (gfloat *) out;
-      gfloat tmp;
-
-      while (len) {
-        tmp = *i;
-        *o = tmp / G_MAXINT16;
-        o++;
-        i++;
-        len--;
-      }
-    } else if (resample->width == 24 && !resample->fp) {
-      guint8 *i = (guint8 *) in;
-      gdouble *o = (gdouble *) out;
-      gdouble tmp;
-      guint32 tmp2;
-
-      while (len) {
-        tmp2 = GST_READ_UINT24 (i);
-        if (tmp2 & 0x00800000)
-          tmp2 |= 0xff000000;
-        tmp = (gint32) tmp2;
-        *o = tmp / GST_MAXINT24;
-        o++;
-        i += 3;
-        len--;
-      }
-    } else if (resample->width == 32 && !resample->fp) {
-      gint32 *i = (gint32 *) in;
-      gdouble *o = (gdouble *) out;
-      gdouble tmp;
-
-      while (len) {
-        tmp = *i;
-        *o = tmp / G_MAXINT32;
-        o++;
-        i++;
-        len--;
-      }
-    } else {
-      g_assert_not_reached ();
-    }
-  }
-}
-
-static guint8 *
-gst_audio_resample_workspace_realloc (guint8 ** workspace, guint * size,
-    guint new_size)
-{
-  guint8 *new;
-  if (new_size <= *size)
-    /* no need to resize */
-    return *workspace;
-  new = g_realloc (*workspace, new_size);
-  if (!new)
-    /* failure (re)allocating memeory */
-    return NULL;
-  /* success */
-  *workspace = new;
-  *size = new_size;
-  return *workspace;
-}
-
 /* Push history_len zeros into the filter, but discard the output. */
 static void
 gst_audio_resample_dump_drain (GstAudioResample * resample, guint history_len)
 {
-  gint outsize;
-  guint in_len G_GNUC_UNUSED, in_processed;
-  guint out_len, out_processed;
-  guint num, den;
-  gpointer buf;
+  gsize out_len, outsize;
+  gpointer out[1];
 
-  g_assert (resample->state != NULL);
-
-  resample->funcs->get_ratio (resample->state, &num, &den);
-
-  in_len = in_processed = history_len;
-  out_processed = out_len =
-      gst_util_uint64_scale_int_ceil (history_len, den, num);
-  outsize = out_len * resample->channels * (resample->funcs->width / 8);
-
+  out_len =
+      gst_audio_converter_get_out_frames (resample->converter, history_len);
   if (out_len == 0)
     return;
 
-  buf = g_malloc (outsize);
-  resample->funcs->process (resample->state, NULL, &in_processed, buf,
-      &out_processed);
-  g_free (buf);
+  outsize = out_len * resample->out.bpf;
 
-  g_assert (in_len == in_processed);
+  out[0] = g_malloc (outsize);
+  gst_audio_converter_samples (resample->converter, 0, NULL, history_len,
+      out, out_len);
+  g_free (out[0]);
 }
 
 static void
@@ -813,77 +546,40 @@
   GstBuffer *outbuf;
   GstFlowReturn res;
   gint outsize;
-  guint in_len, in_processed;
-  guint out_len, out_processed;
-  gint err;
-  guint num, den;
+  gsize out_len;
   GstMapInfo map;
+  gpointer out[1];
 
-  g_assert (resample->state != NULL);
+  g_assert (resample->converter != NULL);
 
   /* Don't drain samples if we were reset. */
   if (!GST_CLOCK_TIME_IS_VALID (resample->t0))
     return;
 
-  resample->funcs->get_ratio (resample->state, &num, &den);
-
-  in_len = in_processed = history_len;
-  out_len = out_processed =
-      gst_util_uint64_scale_int_ceil (history_len, den, num);
-  outsize = out_len * resample->channels * (resample->width / 8);
-
+  out_len =
+      gst_audio_converter_get_out_frames (resample->converter, history_len);
   if (out_len == 0)
     return;
 
+  outsize = out_len * resample->in.bpf;
   outbuf = gst_buffer_new_and_alloc (outsize);
 
   gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
 
-  if (resample->funcs->width != resample->width) {
-    /* need to convert data format;  allocate workspace */
-    if (!gst_audio_resample_workspace_realloc (&resample->tmp_out,
-            &resample->tmp_out_size, (resample->funcs->width / 8) * out_len *
-            resample->channels)) {
-      GST_ERROR_OBJECT (resample, "failed to allocate workspace");
-      return;
-    }
+  out[0] = map.data;
+  gst_audio_converter_samples (resample->converter, 0, NULL, history_len,
+      out, out_len);
 
-    /* process */
-    err = resample->funcs->process (resample->state, NULL, &in_processed,
-        resample->tmp_out, &out_processed);
-
-    /* convert output format */
-    gst_audio_resample_convert_buffer (resample, resample->tmp_out,
-        map.data, out_processed, TRUE);
-  } else {
-    /* don't need to convert data format;  process */
-    err = resample->funcs->process (resample->state, NULL, &in_processed,
-        map.data, &out_processed);
-  }
-
-  /* If we wrote more than allocated something is really wrong now
-   * and we should better abort immediately */
-  g_assert (out_len >= out_processed);
-
-  outsize = out_processed * resample->channels * (resample->width / 8);
   gst_buffer_unmap (outbuf, &map);
-  gst_buffer_resize (outbuf, 0, outsize);
-
-  if (G_UNLIKELY (err != RESAMPLER_ERR_SUCCESS)) {
-    GST_WARNING_OBJECT (resample, "Failed to process drain: %s",
-        resample->funcs->strerror (err));
-    gst_buffer_unref (outbuf);
-    return;
-  }
 
   /* time */
   if (GST_CLOCK_TIME_IS_VALID (resample->t0)) {
     GST_BUFFER_TIMESTAMP (outbuf) = resample->t0 +
         gst_util_uint64_scale_int_round (resample->samples_out, GST_SECOND,
-        resample->outrate);
+        resample->out.rate);
     GST_BUFFER_DURATION (outbuf) = resample->t0 +
-        gst_util_uint64_scale_int_round (resample->samples_out + out_processed,
-        GST_SECOND, resample->outrate) - GST_BUFFER_TIMESTAMP (outbuf);
+        gst_util_uint64_scale_int_round (resample->samples_out + out_len,
+        GST_SECOND, resample->out.rate) - GST_BUFFER_TIMESTAMP (outbuf);
   } else {
     GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
     GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
@@ -891,21 +587,15 @@
   /* offset */
   if (resample->out_offset0 != GST_BUFFER_OFFSET_NONE) {
     GST_BUFFER_OFFSET (outbuf) = resample->out_offset0 + resample->samples_out;
-    GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET (outbuf) + out_processed;
+    GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET (outbuf) + out_len;
   } else {
     GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE;
     GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE;
   }
   /* move along */
-  resample->samples_out += out_processed;
+  resample->samples_out += out_len;
   resample->samples_in += history_len;
 
-  if (G_UNLIKELY (out_processed == 0 && in_len * den > num)) {
-    GST_WARNING_OBJECT (resample, "Failed to get drain, dropping buffer");
-    gst_buffer_unref (outbuf);
-    return;
-  }
-
   GST_LOG_OBJECT (resample,
       "Pushing drain buffer of %u bytes with timestamp %" GST_TIME_FORMAT
       " duration %" GST_TIME_FORMAT " offset %" G_GUINT64_FORMAT " offset_end %"
@@ -931,8 +621,6 @@
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_FLUSH_STOP:
       gst_audio_resample_reset_state (resample);
-      if (resample->state)
-        resample->funcs->skip_zeros (resample->state);
       resample->num_gap_samples = 0;
       resample->num_nongap_samples = 0;
       resample->t0 = GST_CLOCK_TIME_NONE;
@@ -943,13 +631,12 @@
       resample->need_discont = TRUE;
       break;
     case GST_EVENT_SEGMENT:
-      if (resample->state) {
-        guint latency = resample->funcs->get_input_latency (resample->state);
+      if (resample->converter) {
+        gsize latency =
+            gst_audio_converter_get_max_latency (resample->converter);
         gst_audio_resample_push_drain (resample, latency);
       }
       gst_audio_resample_reset_state (resample);
-      if (resample->state)
-        resample->funcs->skip_zeros (resample->state);
       resample->num_gap_samples = 0;
       resample->num_nongap_samples = 0;
       resample->t0 = GST_CLOCK_TIME_NONE;
@@ -960,8 +647,9 @@
       resample->need_discont = TRUE;
       break;
     case GST_EVENT_EOS:
-      if (resample->state) {
-        guint latency = resample->funcs->get_input_latency (resample->state);
+      if (resample->converter) {
+        gsize latency =
+            gst_audio_converter_get_max_latency (resample->converter);
         gst_audio_resample_push_drain (resample, latency);
       }
       gst_audio_resample_reset_state (resample);
@@ -991,7 +679,7 @@
   /* convert the inbound timestamp to an offset. */
   offset =
       gst_util_uint64_scale_int_round (GST_BUFFER_TIMESTAMP (buf) -
-      resample->t0, resample->inrate, GST_SECOND);
+      resample->t0, resample->in.rate, GST_SECOND);
 
   /* many elements generate imperfect streams due to rounding errors, so we
    * permit a small error (up to one sample) without triggering a filter
@@ -999,14 +687,14 @@
   /* allow even up to more samples, since sink is not so strict anyway,
    * so give that one a chance to handle this as configured */
   delta = ABS ((gint64) (offset - resample->samples_in));
-  if (delta <= (resample->inrate >> 5))
+  if (delta <= (resample->in.rate >> 5))
     return FALSE;
 
   GST_WARNING_OBJECT (resample,
       "encountered timestamp discontinuity of %" G_GUINT64_FORMAT " samples = %"
       GST_TIME_FORMAT, delta,
       GST_TIME_ARGS (gst_util_uint64_scale_int_round (delta, GST_SECOND,
-              resample->inrate)));
+              resample->in.rate)));
   return TRUE;
 }
 
@@ -1016,21 +704,22 @@
 {
   GstMapInfo in_map, out_map;
   gsize outsize;
-  guint32 in_len, in_processed;
-  guint32 out_len, out_processed;
-  guint filt_len = resample->funcs->get_filt_len (resample->state);
+  guint32 in_len;
+  guint32 out_len;
+  guint filt_len =
+      gst_audio_converter_get_max_latency (resample->converter) * 2;
+  gboolean inbuf_writable;
 
-  gst_buffer_map (inbuf, &in_map, GST_MAP_READ);
+  inbuf_writable = gst_buffer_is_writable (inbuf)
+      && gst_buffer_n_memory (inbuf) == 1
+      && gst_memory_is_writable (gst_buffer_peek_memory (inbuf, 0));
+
+  gst_buffer_map (inbuf, &in_map,
+      inbuf_writable ? GST_MAP_READWRITE : GST_MAP_READ);
   gst_buffer_map (outbuf, &out_map, GST_MAP_WRITE);
 
-  in_len = in_map.size / resample->channels;
-  out_len = out_map.size / resample->channels;
-
-  in_len /= (resample->width / 8);
-  out_len /= (resample->width / 8);
-
-  in_processed = in_len;
-  out_processed = out_len;
+  in_len = in_map.size / resample->in.bpf;
+  out_len = out_map.size / resample->out.bpf;
 
   if (GST_BUFFER_FLAG_IS_SET (inbuf, GST_BUFFER_FLAG_GAP)) {
     resample->num_nongap_samples = 0;
@@ -1048,27 +737,28 @@
 
     {
       guint num, den;
-      resample->funcs->get_ratio (resample->state, &num, &den);
+
+      num = resample->in.rate;
+      den = resample->out.rate;
+
       if (resample->samples_in + in_len >= filt_len / 2)
-        out_processed =
+        out_len =
             gst_util_uint64_scale_int_ceil (resample->samples_in + in_len -
             filt_len / 2, den, num) - resample->samples_out;
       else
-        out_processed = 0;
+        out_len = 0;
 
       memset (out_map.data, 0, out_map.size);
       GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
       resample->num_gap_samples += in_len;
-      in_processed = in_len;
     }
   } else {                      /* not a gap */
-
-    gint err;
-
     if (resample->num_gap_samples > filt_len) {
       /* push in enough zeros to restore the filter to the right offset */
-      guint num, den;
-      resample->funcs->get_ratio (resample->state, &num, &den);
+      guint num;
+
+      num = resample->in.rate;
+
       gst_audio_resample_dump_drain (resample,
           (resample->num_gap_samples - filt_len) % num);
     }
@@ -1078,65 +768,30 @@
       if (resample->num_nongap_samples > filt_len)
         resample->num_nongap_samples = filt_len;
     }
-
-    if (resample->funcs->width != resample->width) {
-      /* need to convert data format for processing;  ensure we have enough
-       * workspace available */
-      if (!gst_audio_resample_workspace_realloc (&resample->tmp_in,
-              &resample->tmp_in_size, in_len * resample->channels *
-              (resample->funcs->width / 8)) ||
-          !gst_audio_resample_workspace_realloc (&resample->tmp_out,
-              &resample->tmp_out_size, out_len * resample->channels *
-              (resample->funcs->width / 8))) {
-        GST_ERROR_OBJECT (resample, "failed to allocate workspace");
-        gst_buffer_unmap (inbuf, &in_map);
-        gst_buffer_unmap (outbuf, &out_map);
-        return GST_FLOW_ERROR;
-      }
-
-      /* convert input */
-      gst_audio_resample_convert_buffer (resample, in_map.data,
-          resample->tmp_in, in_len, FALSE);
-
+    {
       /* process */
-      err = resample->funcs->process (resample->state,
-          resample->tmp_in, &in_processed, resample->tmp_out, &out_processed);
+      gpointer in[1], out[1];
+      GstAudioConverterFlags flags;
 
-      /* convert output */
-      gst_audio_resample_convert_buffer (resample, resample->tmp_out,
-          out_map.data, out_processed, TRUE);
-    } else {
-      /* no format conversion required;  process */
-      err = resample->funcs->process (resample->state,
-          in_map.data, &in_processed, out_map.data, &out_processed);
+      flags = 0;
+      if (inbuf_writable)
+        flags |= GST_AUDIO_CONVERTER_FLAG_IN_WRITABLE;
+
+      in[0] = in_map.data;
+      out[0] = out_map.data;
+      gst_audio_converter_samples (resample->converter, flags, in, in_len,
+          out, out_len);
     }
-
-    if (G_UNLIKELY (err != RESAMPLER_ERR_SUCCESS)) {
-      GST_ERROR_OBJECT (resample, "Failed to convert data: %s",
-          resample->funcs->strerror (err));
-      gst_buffer_unmap (inbuf, &in_map);
-      gst_buffer_unmap (outbuf, &out_map);
-      return GST_FLOW_ERROR;
-    }
-  }
-
-  /* If we wrote more than allocated something is really wrong now and we
-   * should better abort immediately */
-  g_assert (out_len >= out_processed);
-
-  if (G_UNLIKELY (in_len != in_processed)) {
-    GST_WARNING_OBJECT (resample, "converted %d of %d input samples",
-        in_processed, in_len);
   }
 
   /* time */
   if (GST_CLOCK_TIME_IS_VALID (resample->t0)) {
     GST_BUFFER_TIMESTAMP (outbuf) = resample->t0 +
         gst_util_uint64_scale_int_round (resample->samples_out, GST_SECOND,
-        resample->outrate);
+        resample->out.rate);
     GST_BUFFER_DURATION (outbuf) = resample->t0 +
-        gst_util_uint64_scale_int_round (resample->samples_out + out_processed,
-        GST_SECOND, resample->outrate) - GST_BUFFER_TIMESTAMP (outbuf);
+        gst_util_uint64_scale_int_round (resample->samples_out + out_len,
+        GST_SECOND, resample->out.rate) - GST_BUFFER_TIMESTAMP (outbuf);
   } else {
     GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
     GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
@@ -1144,31 +799,33 @@
   /* offset */
   if (resample->out_offset0 != GST_BUFFER_OFFSET_NONE) {
     GST_BUFFER_OFFSET (outbuf) = resample->out_offset0 + resample->samples_out;
-    GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET (outbuf) + out_processed;
+    GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET (outbuf) + out_len;
   } else {
     GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET_NONE;
     GST_BUFFER_OFFSET_END (outbuf) = GST_BUFFER_OFFSET_NONE;
   }
   /* move along */
-  resample->samples_out += out_processed;
+  resample->samples_out += out_len;
   resample->samples_in += in_len;
 
   gst_buffer_unmap (inbuf, &in_map);
   gst_buffer_unmap (outbuf, &out_map);
 
-  outsize = out_processed * resample->channels * (resample->width / 8);
-  gst_buffer_resize (outbuf, 0, outsize);
+  outsize = out_len * resample->in.bpf;
 
   GST_LOG_OBJECT (resample,
       "Converted to buffer of %" G_GUINT32_FORMAT
       " samples (%" G_GSIZE_FORMAT " bytes) with timestamp %" GST_TIME_FORMAT
       ", duration %" GST_TIME_FORMAT ", offset %" G_GUINT64_FORMAT
-      ", offset_end %" G_GUINT64_FORMAT, out_processed, outsize,
+      ", offset_end %" G_GUINT64_FORMAT, out_len, outsize,
       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
       GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)),
       GST_BUFFER_OFFSET (outbuf), GST_BUFFER_OFFSET_END (outbuf));
 
-  return GST_FLOW_OK;
+  if (outsize == 0)
+    return GST_BASE_TRANSFORM_FLOW_DROPPED;
+  else
+    return GST_FLOW_OK;
 }
 
 static GstFlowReturn
@@ -1178,18 +835,6 @@
   GstAudioResample *resample = GST_AUDIO_RESAMPLE (base);
   GstFlowReturn ret;
 
-  if (resample->state == NULL) {
-    if (G_UNLIKELY (!(resample->state =
-                gst_audio_resample_init_state (resample, resample->width,
-                    resample->channels, resample->inrate, resample->outrate,
-                    resample->quality, resample->fp, resample->sinc_filter_mode,
-                    resample->sinc_filter_auto_threshold))))
-      return GST_FLOW_ERROR;
-
-    resample->funcs =
-        gst_audio_resample_get_funcs (resample->width, resample->fp);
-  }
-
   GST_LOG_OBJECT (resample, "transforming buffer of %" G_GSIZE_FORMAT " bytes,"
       " ts %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT ", offset %"
       G_GINT64_FORMAT ", offset_end %" G_GINT64_FORMAT,
@@ -1201,13 +846,20 @@
    * flag to resync timestamp and offset counters and send event
    * downstream */
   if (G_UNLIKELY (gst_audio_resample_check_discont (resample, inbuf))) {
+    gsize size;
+    gint bpf = GST_AUDIO_INFO_BPF (&resample->in);
+
     gst_audio_resample_reset_state (resample);
     resample->need_discont = TRUE;
+
+    /* need to recalculate the output size */
+    size = gst_buffer_get_size (inbuf) / bpf;
+    size = gst_audio_converter_get_out_frames (resample->converter, size);
+    gst_buffer_set_size (outbuf, size * bpf);
   }
 
   /* handle discontinuity */
   if (G_UNLIKELY (resample->need_discont)) {
-    resample->funcs->skip_zeros (resample->state);
     resample->num_gap_samples = 0;
     resample->num_nongap_samples = 0;
     /* reset */
@@ -1225,7 +877,7 @@
       resample->in_offset0 = GST_BUFFER_OFFSET (inbuf);
       resample->out_offset0 =
           gst_util_uint64_scale_int_round (resample->in_offset0,
-          resample->outrate, resample->inrate);
+          resample->out.rate, resample->in.rate);
     } else {
       GST_DEBUG_OBJECT (resample, "... but new offset is invalid");
       resample->in_offset0 = GST_BUFFER_OFFSET_NONE;
@@ -1279,8 +931,8 @@
 
   if (base->segment.format == GST_FORMAT_TIME) {
     input =
-        gst_audio_buffer_clip (input, &base->segment, resample->inrate,
-        resample->channels * resample->width);
+        gst_audio_buffer_clip (input, &base->segment, resample->in.rate,
+        resample->in.bpf);
 
     if (!input)
       return GST_FLOW_OK;
@@ -1305,12 +957,12 @@
       GstClockTime min, max;
       gboolean live;
       guint64 latency;
-      gint rate = resample->inrate;
+      gint rate = resample->in.rate;
       gint resampler_latency;
 
-      if (resample->state)
+      if (resample->converter)
         resampler_latency =
-            resample->funcs->get_input_latency (resample->state);
+            gst_audio_converter_get_max_latency (resample->converter);
       else
         resampler_latency = 0;
 
@@ -1360,43 +1012,35 @@
     const GValue * value, GParamSpec * pspec)
 {
   GstAudioResample *resample;
-  gint quality;
 
   resample = GST_AUDIO_RESAMPLE (object);
 
   switch (prop_id) {
     case PROP_QUALITY:
       /* FIXME locking! */
-      quality = g_value_get_int (value);
-      GST_DEBUG_OBJECT (resample, "new quality %d", quality);
-
-      gst_audio_resample_update_state (resample, resample->width,
-          resample->channels, resample->inrate, resample->outrate,
-          quality, resample->fp, resample->sinc_filter_mode,
-          resample->sinc_filter_auto_threshold);
+      resample->quality = g_value_get_int (value);
+      GST_DEBUG_OBJECT (resample, "new quality %d", resample->quality);
+      gst_audio_resample_update_state (resample, NULL, NULL);
       break;
-    case PROP_SINC_FILTER_MODE:{
+    case PROP_RESAMPLE_METHOD:
+      resample->method = g_value_get_enum (value);
+      gst_audio_resample_update_state (resample, NULL, NULL);
+      break;
+    case PROP_SINC_FILTER_MODE:
       /* FIXME locking! */
-      SpeexResamplerSincFilterMode sinc_filter_mode = g_value_get_enum (value);
-
-      gst_audio_resample_update_state (resample, resample->width,
-          resample->channels, resample->inrate, resample->outrate,
-          resample->quality, resample->fp, sinc_filter_mode,
-          resample->sinc_filter_auto_threshold);
-
+      resample->sinc_filter_mode = g_value_get_enum (value);
+      gst_audio_resample_update_state (resample, NULL, NULL);
       break;
-    }
-    case PROP_SINC_FILTER_AUTO_THRESHOLD:{
+    case PROP_SINC_FILTER_AUTO_THRESHOLD:
       /* FIXME locking! */
-      guint32 sinc_filter_auto_threshold = g_value_get_uint (value);
-
-      gst_audio_resample_update_state (resample, resample->width,
-          resample->channels, resample->inrate, resample->outrate,
-          resample->quality, resample->fp, resample->sinc_filter_mode,
-          sinc_filter_auto_threshold);
-
+      resample->sinc_filter_auto_threshold = g_value_get_uint (value);
+      gst_audio_resample_update_state (resample, NULL, NULL);
       break;
-    }
+    case PROP_SINC_FILTER_INTERPOLATION:
+      /* FIXME locking! */
+      resample->sinc_filter_interpolation = g_value_get_enum (value);
+      gst_audio_resample_update_state (resample, NULL, NULL);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1415,177 +1059,30 @@
     case PROP_QUALITY:
       g_value_set_int (value, resample->quality);
       break;
+    case PROP_RESAMPLE_METHOD:
+      g_value_set_enum (value, resample->method);
+      break;
     case PROP_SINC_FILTER_MODE:
       g_value_set_enum (value, resample->sinc_filter_mode);
       break;
     case PROP_SINC_FILTER_AUTO_THRESHOLD:
       g_value_set_uint (value, resample->sinc_filter_auto_threshold);
       break;
+    case PROP_SINC_FILTER_INTERPOLATION:
+      g_value_set_enum (value, resample->sinc_filter_interpolation);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
 }
 
-static GType
-speex_resampler_sinc_filter_mode_get_type (void)
-{
-  static GType speex_resampler_sinc_filter_mode_type = 0;
-
-  if (!speex_resampler_sinc_filter_mode_type) {
-    static const GEnumValue sinc_filter_modes[] = {
-      {SPEEX_RESAMPLER_SINC_FILTER_INTERPOLATED, "Use interpolated sinc table",
-          "interpolated"},
-      {SPEEX_RESAMPLER_SINC_FILTER_FULL, "Use full sinc table", "full"},
-      {SPEEX_RESAMPLER_SINC_FILTER_AUTO,
-          "Use full table if table size below threshold", "auto"},
-      {0, NULL, NULL},
-    };
-
-    speex_resampler_sinc_filter_mode_type =
-        g_enum_register_static ("SpeexResamplerSincFilterMode",
-        sinc_filter_modes);
-  }
-
-  return speex_resampler_sinc_filter_mode_type;
-}
-
-/* FIXME: should have a benchmark fallback for the case where orc is disabled */
-#if defined(AUDIORESAMPLE_FORMAT_AUTO) && !defined(DISABLE_ORC)
-
-#define BENCHMARK_SIZE 512
-
-static gboolean
-_benchmark_int_float (SpeexResamplerState * st)
-{
-  gint16 in[BENCHMARK_SIZE] = { 0, }, G_GNUC_UNUSED out[BENCHMARK_SIZE / 2];
-  gfloat in_tmp[BENCHMARK_SIZE], out_tmp[BENCHMARK_SIZE / 2];
-  gint i;
-  guint32 inlen = BENCHMARK_SIZE, outlen = BENCHMARK_SIZE / 2;
-
-  for (i = 0; i < BENCHMARK_SIZE; i++) {
-    gfloat tmp = in[i];
-    in_tmp[i] = tmp / G_MAXINT16;
-  }
-
-  resample_float_resampler_process_interleaved_float (st,
-      (const guint8 *) in_tmp, &inlen, (guint8 *) out_tmp, &outlen);
-
-  if (outlen == 0) {
-    GST_ERROR ("Failed to use float resampler");
-    return FALSE;
-  }
-
-  for (i = 0; i < outlen; i++) {
-    gfloat tmp = out_tmp[i];
-    out[i] = CLAMP (tmp * G_MAXINT16 + 0.5, G_MININT16, G_MAXINT16);
-  }
-
-  return TRUE;
-}
-
-static gboolean
-_benchmark_int_int (SpeexResamplerState * st)
-{
-  gint16 in[BENCHMARK_SIZE] = { 0, }, out[BENCHMARK_SIZE / 2];
-  guint32 inlen = BENCHMARK_SIZE, outlen = BENCHMARK_SIZE / 2;
-
-  resample_int_resampler_process_interleaved_int (st, (const guint8 *) in,
-      &inlen, (guint8 *) out, &outlen);
-
-  if (outlen == 0) {
-    GST_ERROR ("Failed to use int resampler");
-    return FALSE;
-  }
-
-  return TRUE;
-}
-
-static gboolean
-_benchmark_integer_resampling (void)
-{
-  OrcProfile a, b;
-  gdouble av, bv;
-  SpeexResamplerState *sta, *stb;
-  int i;
-
-  orc_profile_init (&a);
-  orc_profile_init (&b);
-
-  sta = resample_float_resampler_init (1, 48000, 24000, 4,
-      SPEEX_RESAMPLER_SINC_FILTER_INTERPOLATED,
-      SPEEX_RESAMPLER_SINC_FILTER_AUTO_THRESHOLD_DEFAULT, NULL);
-  if (sta == NULL) {
-    GST_ERROR ("Failed to create float resampler state");
-    return FALSE;
-  }
-
-  stb = resample_int_resampler_init (1, 48000, 24000, 4,
-      SPEEX_RESAMPLER_SINC_FILTER_INTERPOLATED,
-      SPEEX_RESAMPLER_SINC_FILTER_AUTO_THRESHOLD_DEFAULT, NULL);
-  if (stb == NULL) {
-    resample_float_resampler_destroy (sta);
-    GST_ERROR ("Failed to create int resampler state");
-    return FALSE;
-  }
-
-  /* Benchmark */
-  for (i = 0; i < 10; i++) {
-    orc_profile_start (&a);
-    if (!_benchmark_int_float (sta))
-      goto error;
-    orc_profile_stop (&a);
-  }
-
-  /* Benchmark */
-  for (i = 0; i < 10; i++) {
-    orc_profile_start (&b);
-    if (!_benchmark_int_int (stb))
-      goto error;
-    orc_profile_stop (&b);
-  }
-
-  /* Handle results */
-  orc_profile_get_ave_std (&a, &av, NULL);
-  orc_profile_get_ave_std (&b, &bv, NULL);
-
-  /* Remember benchmark result in global variable */
-  gst_audio_resample_use_int = (av > bv);
-  resample_float_resampler_destroy (sta);
-  resample_int_resampler_destroy (stb);
-
-  if (av > bv)
-    GST_INFO ("Using integer resampler if appropriate: %lf < %lf", bv, av);
-  else
-    GST_INFO ("Using float resampler for everything: %lf <= %lf", av, bv);
-
-  return TRUE;
-
-error:
-  resample_float_resampler_destroy (sta);
-  resample_int_resampler_destroy (stb);
-
-  return FALSE;
-}
-#endif /* defined(AUDIORESAMPLE_FORMAT_AUTO) && !defined(DISABLE_ORC) */
-
 static gboolean
 plugin_init (GstPlugin * plugin)
 {
   GST_DEBUG_CATEGORY_INIT (audio_resample_debug, "audioresample", 0,
       "audio resampling element");
 
-#if defined(AUDIORESAMPLE_FORMAT_AUTO) && !defined(DISABLE_ORC)
-  if (!_benchmark_integer_resampling ())
-    return FALSE;
-#else
-  GST_WARNING ("Orc disabled, can't benchmark int vs. float resampler");
-  {
-    GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
-    GST_CAT_WARNING (GST_CAT_PERFORMANCE, "orc disabled, no benchmarking done");
-  }
-#endif
-
   if (!gst_element_register (plugin, "audioresample", GST_RANK_PRIMARY,
           GST_TYPE_AUDIO_RESAMPLE)) {
     return FALSE;
diff --git a/gst/audioresample/gstaudioresample.h b/gst/audioresample/gstaudioresample.h
index 726236a..6092493 100644
--- a/gst/audioresample/gstaudioresample.h
+++ b/gst/audioresample/gstaudioresample.h
@@ -26,8 +26,6 @@
 #include <gst/base/gstbasetransform.h>
 #include <gst/audio/audio.h>
 
-#include "speex_resampler_wrapper.h"
-
 G_BEGIN_DECLS
 
 #define GST_TYPE_AUDIO_RESAMPLE \
@@ -60,31 +58,21 @@
   guint64 out_offset0;
   guint64 samples_in;
   guint64 samples_out;
-  
+
   guint64 num_gap_samples;
   guint64 num_nongap_samples;
 
   /* properties */
+  GstAudioResamplerMethod method;
   gint quality;
+  GstAudioResamplerFilterMode sinc_filter_mode;
+  guint32 sinc_filter_auto_threshold;
+  GstAudioResamplerFilterInterpolation sinc_filter_interpolation;
 
   /* state */
-  gboolean fp;
-  gint width;
-  gint channels;
-  gint inrate;
-  gint outrate;
-
-  SpeexResamplerSincFilterMode sinc_filter_mode;
-  guint32 sinc_filter_auto_threshold;
-
-  guint8 *tmp_in;
-  guint tmp_in_size;
-
-  guint8 *tmp_out;
-  guint tmp_out_size;
-
-  SpeexResamplerState *state;
-  const SpeexResampleFuncs *funcs;
+  GstAudioInfo in;
+  GstAudioInfo out;
+  GstAudioConverter *converter;
 };
 
 struct _GstAudioResampleClass {
diff --git a/gst/audioresample/resample.c b/gst/audioresample/resample.c
deleted file mode 100644
index c375535..0000000
--- a/gst/audioresample/resample.c
+++ /dev/null
@@ -1,1516 +0,0 @@
-/* Copyright (C) 2007-2008 Jean-Marc Valin
-   Copyright (C) 2008      Thorvald Natvig
-      
-   File: resample.c
-   Arbitrary resampling code
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are
-   met:
-
-   1. Redistributions of source code must retain the above copyright notice,
-   this list of conditions and the following disclaimer.
-
-   2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-
-   3. The name of the author may not be used to endorse or promote products
-   derived from this software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-   POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*
-   The design goals of this code are:
-      - Very fast algorithm
-      - SIMD-friendly algorithm
-      - Low memory requirement
-      - Good *perceptual* quality (and not best SNR)
-
-   Warning: This resampler is relatively new. Although I think I got rid of 
-   all the major bugs and I don't expect the API to change anymore, there
-   may be something I've missed. So use with caution.
-
-   This algorithm is based on this original resampling algorithm:
-   Smith, Julius O. Digital Audio Resampling Home Page
-   Center for Computer Research in Music and Acoustics (CCRMA), 
-   Stanford University, 2007.
-   Web published at http://www-ccrma.stanford.edu/~jos/resample/.
-
-   There is one main difference, though. This resampler uses cubic 
-   interpolation instead of linear interpolation in the above paper. This
-   makes the table much smaller and makes it possible to compute that table
-   on a per-stream basis. In turn, being able to tweak the table for each 
-   stream makes it possible to both reduce complexity on simple ratios 
-   (e.g. 2/3), and get rid of the rounding operations in the inner loop. 
-   The latter both reduces CPU time and makes the algorithm more SIMD-friendly.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef OUTSIDE_SPEEX
-#include <stdlib.h>
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include <glib.h>
-
-#ifdef HAVE_ORC
-#include <orc/orc.h>
-#endif
-
-#define EXPORT G_GNUC_INTERNAL
-
-#ifdef _USE_SSE
-#if !defined(__SSE__) || !defined(HAVE_XMMINTRIN_H)
-#undef _USE_SSE
-#endif
-#endif
-
-#ifdef _USE_SSE2
-#if !defined(__SSE2__) || !defined(HAVE_EMMINTRIN_H)
-#undef _USE_SSE2
-#endif
-#endif
-
-#ifdef _USE_NEON
-#ifndef HAVE_ARM_NEON
-#undef _USE_NEON
-#endif
-#endif
-
-static inline void *
-speex_alloc (int size)
-{
-  return g_malloc0 (size);
-}
-
-static inline void *
-speex_realloc (void *ptr, int size)
-{
-  return g_realloc (ptr, size);
-}
-
-static inline void
-speex_free (void *ptr)
-{
-  g_free (ptr);
-}
-
-#include "speex_resampler.h"
-#include "arch.h"
-#else /* OUTSIDE_SPEEX */
-
-#include "../include/speex/speex_resampler.h"
-#include "arch.h"
-#include "os_support.h"
-#endif /* OUTSIDE_SPEEX */
-
-#include <math.h>
-
-#ifdef FIXED_POINT
-#define WORD2INT(x) ((x) < -32767 ? -32768 : ((x) > 32766 ? 32767 : (x)))
-#else
-#define WORD2INT(x) ((x) < -32767.5f ? -32768 : ((x) > 32766.5f ? 32767 : floor(.5+(x))))
-#endif
-
-#define IMAX(a,b) ((a) > (b) ? (a) : (b))
-#define IMIN(a,b) ((a) < (b) ? (a) : (b))
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#if defined _USE_SSE || defined _USE_SSE2
-#include "resample_sse.h"
-#endif
-
-#ifdef _USE_NEON
-#include "resample_neon.h"
-#endif
-
-/* Numer of elements to allocate on the stack */
-#ifdef VAR_ARRAYS
-#define FIXED_STACK_ALLOC 8192
-#else
-#define FIXED_STACK_ALLOC 1024
-#endif
-
-/* Allow selecting SSE or not when compiled with SSE support */
-#ifdef _USE_SSE
-#define SSE_FALLBACK(macro) \
-  if (st->use_sse) goto sse_##macro##_sse; {
-#define SSE_IMPLEMENTATION(macro) \
-  goto sse_##macro##_end; } sse_##macro##_sse: {
-#define SSE_END(macro) sse_##macro##_end:; }
-#else
-#define SSE_FALLBACK(macro)
-#endif
-
-#ifdef _USE_SSE2
-#define SSE2_FALLBACK(macro) \
-  if (st->use_sse2) goto sse2_##macro##_sse2; {
-#define SSE2_IMPLEMENTATION(macro) \
-  goto sse2_##macro##_end; } sse2_##macro##_sse2: {
-#define SSE2_END(macro) sse2_##macro##_end:; }
-#else
-#define SSE2_FALLBACK(macro)
-#endif
-
-#ifdef _USE_NEON
-#define NEON_FALLBACK(macro) \
-  if (st->use_neon) goto neon_##macro##_neon; {
-#define NEON_IMPLEMENTATION(macro) \
-  goto neon_##macro##_end; } neon_##macro##_neon: {
-#define NEON_END(macro) neon_##macro##_end:; }
-#else
-#define NEON_FALLBACK(macro)
-#endif
-
-
-typedef int (*resampler_basic_func) (SpeexResamplerState *, spx_uint32_t,
-    const spx_word16_t *, spx_uint32_t *, spx_word16_t *, spx_uint32_t *);
-
-struct SpeexResamplerState_
-{
-  spx_uint32_t in_rate;
-  spx_uint32_t out_rate;
-  spx_uint32_t num_rate;
-  spx_uint32_t den_rate;
-
-  int quality;
-  spx_uint32_t nb_channels;
-  spx_uint32_t filt_len;
-  spx_uint32_t mem_alloc_size;
-  spx_uint32_t buffer_size;
-  int int_advance;
-  int frac_advance;
-  float cutoff;
-  spx_uint32_t oversample;
-  int initialised;
-  int started;
-  int use_full_sinc_table;
-
-  /* These are per-channel */
-  spx_int32_t *last_sample;
-  spx_uint32_t *samp_frac_num;
-  spx_uint32_t *magic_samples;
-
-  spx_word16_t *mem;
-  spx_word16_t *sinc_table;
-  spx_uint32_t sinc_table_length;
-  resampler_basic_func resampler_ptr;
-
-  int in_stride;
-  int out_stride;
-
-  int use_sse:1;
-  int use_sse2:1;
-  int use_neon:1;
-};
-
-static const double kaiser12_table[68] = {
-  0.99859849, 1.00000000, 0.99859849, 0.99440475, 0.98745105, 0.97779076,
-  0.96549770, 0.95066529, 0.93340547, 0.91384741, 0.89213598, 0.86843014,
-  0.84290116, 0.81573067, 0.78710866, 0.75723148, 0.72629970, 0.69451601,
-  0.66208321, 0.62920216, 0.59606986, 0.56287762, 0.52980938, 0.49704014,
-  0.46473455, 0.43304576, 0.40211431, 0.37206735, 0.34301800, 0.31506490,
-  0.28829195, 0.26276832, 0.23854851, 0.21567274, 0.19416736, 0.17404546,
-  0.15530766, 0.13794294, 0.12192957, 0.10723616, 0.09382272, 0.08164178,
-  0.07063950, 0.06075685, 0.05193064, 0.04409466, 0.03718069, 0.03111947,
-  0.02584161, 0.02127838, 0.01736250, 0.01402878, 0.01121463, 0.00886058,
-  0.00691064, 0.00531256, 0.00401805, 0.00298291, 0.00216702, 0.00153438,
-  0.00105297, 0.00069463, 0.00043489, 0.00025272, 0.00013031, 0.0000527734,
-  0.00001000, 0.00000000
-};
-
-/*
-static const double kaiser12_table[36] = {
-   0.99440475, 1.00000000, 0.99440475, 0.97779076, 0.95066529, 0.91384741,
-   0.86843014, 0.81573067, 0.75723148, 0.69451601, 0.62920216, 0.56287762,
-   0.49704014, 0.43304576, 0.37206735, 0.31506490, 0.26276832, 0.21567274,
-   0.17404546, 0.13794294, 0.10723616, 0.08164178, 0.06075685, 0.04409466,
-   0.03111947, 0.02127838, 0.01402878, 0.00886058, 0.00531256, 0.00298291,
-   0.00153438, 0.00069463, 0.00025272, 0.0000527734, 0.00000500, 0.00000000};
-*/
-static const double kaiser10_table[36] = {
-  0.99537781, 1.00000000, 0.99537781, 0.98162644, 0.95908712, 0.92831446,
-  0.89005583, 0.84522401, 0.79486424, 0.74011713, 0.68217934, 0.62226347,
-  0.56155915, 0.50119680, 0.44221549, 0.38553619, 0.33194107, 0.28205962,
-  0.23636152, 0.19515633, 0.15859932, 0.12670280, 0.09935205, 0.07632451,
-  0.05731132, 0.04193980, 0.02979584, 0.02044510, 0.01345224, 0.00839739,
-  0.00488951, 0.00257636, 0.00115101, 0.00035515, 0.00000000, 0.00000000
-};
-
-static const double kaiser8_table[36] = {
-  0.99635258, 1.00000000, 0.99635258, 0.98548012, 0.96759014, 0.94302200,
-  0.91223751, 0.87580811, 0.83439927, 0.78875245, 0.73966538, 0.68797126,
-  0.63451750, 0.58014482, 0.52566725, 0.47185369, 0.41941150, 0.36897272,
-  0.32108304, 0.27619388, 0.23465776, 0.19672670, 0.16255380, 0.13219758,
-  0.10562887, 0.08273982, 0.06335451, 0.04724088, 0.03412321, 0.02369490,
-  0.01563093, 0.00959968, 0.00527363, 0.00233883, 0.00050000, 0.00000000
-};
-
-static const double kaiser6_table[36] = {
-  0.99733006, 1.00000000, 0.99733006, 0.98935595, 0.97618418, 0.95799003,
-  0.93501423, 0.90755855, 0.87598009, 0.84068475, 0.80211977, 0.76076565,
-  0.71712752, 0.67172623, 0.62508937, 0.57774224, 0.53019925, 0.48295561,
-  0.43647969, 0.39120616, 0.34752997, 0.30580127, 0.26632152, 0.22934058,
-  0.19505503, 0.16360756, 0.13508755, 0.10953262, 0.08693120, 0.06722600,
-  0.05031820, 0.03607231, 0.02432151, 0.01487334, 0.00752000, 0.00000000
-};
-
-struct FuncDef
-{
-  const double *table;
-  int oversample;
-};
-
-static struct FuncDef _KAISER12 = { kaiser12_table, 64 };
-
-#define KAISER12 (&_KAISER12)
-/*static struct FuncDef _KAISER12 = {kaiser12_table, 32};
-#define KAISER12 (&_KAISER12)*/
-static struct FuncDef _KAISER10 = { kaiser10_table, 32 };
-
-#define KAISER10 (&_KAISER10)
-static struct FuncDef _KAISER8 = { kaiser8_table, 32 };
-
-#define KAISER8 (&_KAISER8)
-static struct FuncDef _KAISER6 = { kaiser6_table, 32 };
-
-#define KAISER6 (&_KAISER6)
-
-struct QualityMapping
-{
-  int base_length;
-  int oversample;
-  float downsample_bandwidth;
-  float upsample_bandwidth;
-  struct FuncDef *window_func;
-};
-
-
-/* This table maps conversion quality to internal parameters. There are two
-   reasons that explain why the up-sampling bandwidth is larger than the 
-   down-sampling bandwidth:
-   1) When up-sampling, we can assume that the spectrum is already attenuated
-      close to the Nyquist rate (from an A/D or a previous resampling filter)
-   2) Any aliasing that occurs very close to the Nyquist rate will be masked
-      by the sinusoids/noise just below the Nyquist rate (guaranteed only for
-      up-sampling).
-*/
-static const struct QualityMapping quality_map[11] = {
-  {8, 4, 0.830f, 0.860f, KAISER6},      /* Q0 */
-  {16, 4, 0.850f, 0.880f, KAISER6},     /* Q1 */
-  {32, 4, 0.882f, 0.910f, KAISER6},     /* Q2 *//* 82.3% cutoff ( ~60 dB stop) 6  */
-  {48, 8, 0.895f, 0.917f, KAISER8},     /* Q3 *//* 84.9% cutoff ( ~80 dB stop) 8  */
-  {64, 8, 0.921f, 0.940f, KAISER8},     /* Q4 *//* 88.7% cutoff ( ~80 dB stop) 8  */
-  {80, 16, 0.922f, 0.940f, KAISER10},   /* Q5 *//* 89.1% cutoff (~100 dB stop) 10 */
-  {96, 16, 0.940f, 0.945f, KAISER10},   /* Q6 *//* 91.5% cutoff (~100 dB stop) 10 */
-  {128, 16, 0.950f, 0.950f, KAISER10},  /* Q7 *//* 93.1% cutoff (~100 dB stop) 10 */
-  {160, 16, 0.960f, 0.960f, KAISER10},  /* Q8 *//* 94.5% cutoff (~100 dB stop) 10 */
-  {192, 32, 0.968f, 0.968f, KAISER12},  /* Q9 *//* 95.5% cutoff (~100 dB stop) 10 */
-  {256, 32, 0.975f, 0.975f, KAISER12},  /* Q10 *//* 96.6% cutoff (~100 dB stop) 10 */
-};
-
-/*8,24,40,56,80,104,128,160,200,256,320*/
-#ifdef DOUBLE_PRECISION
-static double
-compute_func (double x, struct FuncDef *func)
-{
-  double y, frac;
-#else
-static double
-compute_func (float x, struct FuncDef *func)
-{
-  float y, frac;
-#endif
-  double interp[4];
-  int ind;
-  y = x * func->oversample;
-  ind = (int) floor (y);
-  frac = (y - ind);
-  /* CSE with handle the repeated powers */
-  interp[3] = -0.1666666667 * frac + 0.1666666667 * (frac * frac * frac);
-  interp[2] = frac + 0.5 * (frac * frac) - 0.5 * (frac * frac * frac);
-  /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac; */
-  interp[0] =
-      -0.3333333333 * frac + 0.5 * (frac * frac) -
-      0.1666666667 * (frac * frac * frac);
-  /* Just to make sure we don't have rounding problems */
-  interp[1] = 1.f - interp[3] - interp[2] - interp[0];
-
-  /*sum = frac*accum[1] + (1-frac)*accum[2]; */
-  return interp[0] * func->table[ind] + interp[1] * func->table[ind + 1] +
-      interp[2] * func->table[ind + 2] + interp[3] * func->table[ind + 3];
-}
-
-#if 0
-#include <stdio.h>
-int
-main (int argc, char **argv)
-{
-  int i;
-  for (i = 0; i < 256; i++) {
-    printf ("%f\n", compute_func (i / 256., KAISER12));
-  }
-  return 0;
-}
-#endif
-
-#ifdef FIXED_POINT
-/* The slow way of computing a sinc for the table. Should improve that some day */
-static spx_word16_t
-sinc (float cutoff, float x, int N, struct FuncDef *window_func)
-{
-  /*fprintf (stderr, "%f ", x); */
-  float xx = x * cutoff;
-  if (fabs (x) < 1e-6f)
-    return WORD2INT (32768. * cutoff);
-  else if (fabs (x) > .5f * N)
-    return 0;
-  /*FIXME: Can it really be any slower than this? */
-  return WORD2INT (32768. * cutoff * sin (G_PI * xx) / (G_PI * xx) *
-      compute_func (fabs (2. * x / N), window_func));
-}
-#else
-/* The slow way of computing a sinc for the table. Should improve that some day */
-#ifdef DOUBLE_PRECISION
-static spx_word16_t
-sinc (double cutoff, double x, int N, struct FuncDef *window_func)
-{
-  /*fprintf (stderr, "%f ", x); */
-  double xx = x * cutoff;
-#else
-static spx_word16_t
-sinc (float cutoff, float x, int N, struct FuncDef *window_func)
-{
-  /*fprintf (stderr, "%f ", x); */
-  float xx = x * cutoff;
-#endif
-  if (fabs (x) < 1e-6)
-    return cutoff;
-  else if (fabs (x) > .5 * N)
-    return 0;
-  /*FIXME: Can it really be any slower than this? */
-  return cutoff * sin (G_PI * xx) / (G_PI * xx) * compute_func (fabs (2. * x /
-          N), window_func);
-}
-#endif
-
-#ifdef FIXED_POINT
-static void
-cubic_coef (spx_word16_t x, spx_word16_t interp[4])
-{
-  /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation
-     but I know it's MMSE-optimal on a sinc */
-  spx_word16_t x2, x3;
-  x2 = MULT16_16_P15 (x, x);
-  x3 = MULT16_16_P15 (x, x2);
-  interp[0] =
-      PSHR32 (MULT16_16 (QCONST16 (-0.16667f, 15),
-          x) + MULT16_16 (QCONST16 (0.16667f, 15), x3), 15);
-  interp[1] =
-      EXTRACT16 (EXTEND32 (x) + SHR32 (SUB32 (EXTEND32 (x2), EXTEND32 (x3)),
-          1));
-  interp[3] =
-      PSHR32 (MULT16_16 (QCONST16 (-0.33333f, 15),
-          x) + MULT16_16 (QCONST16 (.5f, 15),
-          x2) - MULT16_16 (QCONST16 (0.16667f, 15), x3), 15);
-  /* Just to make sure we don't have rounding problems */
-  interp[2] = Q15_ONE - interp[0] - interp[1] - interp[3];
-  if (interp[2] < 32767)
-    interp[2] += 1;
-}
-#else
-static void
-cubic_coef (spx_word16_t frac, spx_word16_t interp[4])
-{
-  /* Compute interpolation coefficients. I'm not sure whether this corresponds to cubic interpolation
-     but I know it's MMSE-optimal on a sinc */
-  interp[0] = -0.16667f * frac + 0.16667f * frac * frac * frac;
-  interp[1] = frac + 0.5f * frac * frac - 0.5f * frac * frac * frac;
-  /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac; */
-  interp[3] =
-      -0.33333f * frac + 0.5f * frac * frac - 0.16667f * frac * frac * frac;
-  /* Just to make sure we don't have rounding problems */
-  interp[2] = 1. - interp[0] - interp[1] - interp[3];
-}
-#endif
-
-#ifndef DOUBLE_PRECISION
-static int
-resampler_basic_direct_single (SpeexResamplerState * st,
-    spx_uint32_t channel_index, const spx_word16_t * in, spx_uint32_t * in_len,
-    spx_word16_t * out, spx_uint32_t * out_len)
-{
-  const int N = st->filt_len;
-  int out_sample = 0;
-  int last_sample = st->last_sample[channel_index];
-  spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
-  const spx_word16_t *sinc_table = st->sinc_table;
-  const int out_stride = st->out_stride;
-  const int int_advance = st->int_advance;
-  const int frac_advance = st->frac_advance;
-  const spx_uint32_t den_rate = st->den_rate;
-  spx_word32_t sum;
-  int j;
-
-  while (!(last_sample >= (spx_int32_t) * in_len
-          || out_sample >= (spx_int32_t) * out_len)) {
-    const spx_word16_t *sinc = &sinc_table[samp_frac_num * N];
-    const spx_word16_t *iptr = &in[last_sample];
-
-    SSE_FALLBACK (INNER_PRODUCT_SINGLE)
-        NEON_FALLBACK (INNER_PRODUCT_SINGLE)
-        sum = 0;
-    for (j = 0; j < N; j++)
-      sum += MULT16_16 (sinc[j], iptr[j]);
-
-/*    This code is slower on most DSPs which have only 2 accumulators.
-      Plus this forces truncation to 32 bits and you lose the HW guard bits.
-      I think we can trust the compiler and let it vectorize and/or unroll itself.
-      spx_word32_t accum[4] = {0,0,0,0};
-      for(j=0;j<N;j+=4) {
-        accum[0] += MULT16_16(sinc[j], iptr[j]);
-        accum[1] += MULT16_16(sinc[j+1], iptr[j+1]);
-        accum[2] += MULT16_16(sinc[j+2], iptr[j+2]);
-        accum[3] += MULT16_16(sinc[j+3], iptr[j+3]);
-      }
-      sum = accum[0] + accum[1] + accum[2] + accum[3];
-*/
-#if defined(OVERRIDE_INNER_PRODUCT_SINGLE) && defined(_USE_NEON)
-    NEON_IMPLEMENTATION (INNER_PRODUCT_SINGLE)
-        sum = inner_product_single (sinc, iptr, N);
-    NEON_END (INNER_PRODUCT_SINGLE)
-#elif defined(OVERRIDE_INNER_PRODUCT_SINGLE) && defined(_USE_SSE)
-    SSE_IMPLEMENTATION (INNER_PRODUCT_SINGLE)
-        sum = inner_product_single (sinc, iptr, N);
-    SSE_END (INNER_PRODUCT_SINGLE)
-#endif
-        out[out_stride * out_sample++] = SATURATE32PSHR (sum, 15, 32767);
-    last_sample += int_advance;
-    samp_frac_num += frac_advance;
-    if (samp_frac_num >= den_rate) {
-      samp_frac_num -= den_rate;
-      last_sample++;
-    }
-  }
-
-  st->last_sample[channel_index] = last_sample;
-  st->samp_frac_num[channel_index] = samp_frac_num;
-  return out_sample;
-}
-#endif
-
-#ifdef FIXED_POINT
-#else
-/* This is the same as the previous function, except with a double-precision accumulator */
-static int
-resampler_basic_direct_double (SpeexResamplerState * st,
-    spx_uint32_t channel_index, const spx_word16_t * in, spx_uint32_t * in_len,
-    spx_word16_t * out, spx_uint32_t * out_len)
-{
-  const int N = st->filt_len;
-  int out_sample = 0;
-  int last_sample = st->last_sample[channel_index];
-  spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
-  const spx_word16_t *sinc_table = st->sinc_table;
-  const int out_stride = st->out_stride;
-  const int int_advance = st->int_advance;
-  const int frac_advance = st->frac_advance;
-  const spx_uint32_t den_rate = st->den_rate;
-  double sum;
-  int j;
-
-  while (!(last_sample >= (spx_int32_t) * in_len
-          || out_sample >= (spx_int32_t) * out_len)) {
-    const spx_word16_t *sinc = &sinc_table[samp_frac_num * N];
-    const spx_word16_t *iptr = &in[last_sample];
-
-    SSE2_FALLBACK (INNER_PRODUCT_DOUBLE)
-    double accum[4] = { 0, 0, 0, 0 };
-
-    for (j = 0; j < N; j += 4) {
-      accum[0] += sinc[j] * iptr[j];
-      accum[1] += sinc[j + 1] * iptr[j + 1];
-      accum[2] += sinc[j + 2] * iptr[j + 2];
-      accum[3] += sinc[j + 3] * iptr[j + 3];
-    }
-    sum = accum[0] + accum[1] + accum[2] + accum[3];
-#if defined(OVERRIDE_INNER_PRODUCT_DOUBLE) && defined(_USE_SSE2)
-    SSE2_IMPLEMENTATION (INNER_PRODUCT_DOUBLE)
-        sum = inner_product_double (sinc, iptr, N);
-    SSE2_END (INNER_PRODUCT_DOUBLE)
-#endif
-        out[out_stride * out_sample++] = PSHR32 (sum, 15);
-    last_sample += int_advance;
-    samp_frac_num += frac_advance;
-    if (samp_frac_num >= den_rate) {
-      samp_frac_num -= den_rate;
-      last_sample++;
-    }
-  }
-
-  st->last_sample[channel_index] = last_sample;
-  st->samp_frac_num[channel_index] = samp_frac_num;
-  return out_sample;
-}
-#endif
-
-#ifndef DOUBLE_PRECISION
-static int
-resampler_basic_interpolate_single (SpeexResamplerState * st,
-    spx_uint32_t channel_index, const spx_word16_t * in, spx_uint32_t * in_len,
-    spx_word16_t * out, spx_uint32_t * out_len)
-{
-  const int N = st->filt_len;
-  int out_sample = 0;
-  int last_sample = st->last_sample[channel_index];
-  spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
-  const int out_stride = st->out_stride;
-  const int int_advance = st->int_advance;
-  const int frac_advance = st->frac_advance;
-  const spx_uint32_t den_rate = st->den_rate;
-  int j;
-  spx_word32_t sum;
-
-  while (!(last_sample >= (spx_int32_t) * in_len
-          || out_sample >= (spx_int32_t) * out_len)) {
-    const spx_word16_t *iptr = &in[last_sample];
-
-    const int offset = samp_frac_num * st->oversample / st->den_rate;
-#ifdef FIXED_POINT
-    const spx_word16_t frac =
-        ((((gint64) samp_frac_num * (gint64) st->oversample) % st->den_rate)
-        << 15) / st->den_rate;
-#else
-    const spx_word16_t frac =
-        ((float) ((samp_frac_num * st->oversample) % st->den_rate)) /
-        st->den_rate;
-#endif
-    spx_word16_t interp[4];
-
-
-    SSE_FALLBACK (INTERPOLATE_PRODUCT_SINGLE)
-    spx_word32_t accum[4] = { 0, 0, 0, 0 };
-
-    for (j = 0; j < N; j++) {
-      const spx_word16_t curr_in = iptr[j];
-      accum[0] +=
-          MULT16_16 (curr_in,
-          st->sinc_table[4 + (j + 1) * st->oversample - offset - 2]);
-      accum[1] +=
-          MULT16_16 (curr_in,
-          st->sinc_table[4 + (j + 1) * st->oversample - offset - 1]);
-      accum[2] +=
-          MULT16_16 (curr_in,
-          st->sinc_table[4 + (j + 1) * st->oversample - offset]);
-      accum[3] +=
-          MULT16_16 (curr_in,
-          st->sinc_table[4 + (j + 1) * st->oversample - offset + 1]);
-    }
-
-    cubic_coef (frac, interp);
-    sum =
-        MULT16_32_Q15 (interp[0], SHR32 (accum[0],
-            1)) + MULT16_32_Q15 (interp[1], SHR32 (accum[1],
-            1)) + MULT16_32_Q15 (interp[2], SHR32 (accum[2],
-            1)) + MULT16_32_Q15 (interp[3], SHR32 (accum[3], 1));
-#if defined(OVERRIDE_INTERPOLATE_PRODUCT_SINGLE) && defined(_USE_SSE)
-    SSE_IMPLEMENTATION (INTERPOLATE_PRODUCT_SINGLE)
-        cubic_coef (frac, interp);
-    sum =
-        interpolate_product_single (iptr,
-        st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample,
-        interp);
-    SSE_END (INTERPOLATE_PRODUCT_SINGLE)
-#endif
-        out[out_stride * out_sample++] = SATURATE32PSHR (sum, 14, 32767);
-    last_sample += int_advance;
-    samp_frac_num += frac_advance;
-    if (samp_frac_num >= den_rate) {
-      samp_frac_num -= den_rate;
-      last_sample++;
-    }
-  }
-
-  st->last_sample[channel_index] = last_sample;
-  st->samp_frac_num[channel_index] = samp_frac_num;
-  return out_sample;
-}
-#endif
-
-#ifdef FIXED_POINT
-#else
-/* This is the same as the previous function, except with a double-precision accumulator */
-static int
-resampler_basic_interpolate_double (SpeexResamplerState * st,
-    spx_uint32_t channel_index, const spx_word16_t * in, spx_uint32_t * in_len,
-    spx_word16_t * out, spx_uint32_t * out_len)
-{
-  const int N = st->filt_len;
-  int out_sample = 0;
-  int last_sample = st->last_sample[channel_index];
-  spx_uint32_t samp_frac_num = st->samp_frac_num[channel_index];
-  const int out_stride = st->out_stride;
-  const int int_advance = st->int_advance;
-  const int frac_advance = st->frac_advance;
-  const spx_uint32_t den_rate = st->den_rate;
-  int j;
-  spx_word32_t sum;
-
-  while (!(last_sample >= (spx_int32_t) * in_len
-          || out_sample >= (spx_int32_t) * out_len)) {
-    const spx_word16_t *iptr = &in[last_sample];
-
-    const int offset = samp_frac_num * st->oversample / st->den_rate;
-#ifdef FIXED_POINT
-    const spx_word16_t frac =
-        PDIV32 (SHL32 ((samp_frac_num * st->oversample) % st->den_rate, 15),
-        st->den_rate);
-#else
-#ifdef DOUBLE_PRECISION
-    const spx_word16_t frac =
-        ((double) ((samp_frac_num * st->oversample) % st->den_rate)) /
-        st->den_rate;
-#else
-    const spx_word16_t frac =
-        ((float) ((samp_frac_num * st->oversample) % st->den_rate)) /
-        st->den_rate;
-#endif
-#endif
-    spx_word16_t interp[4];
-
-
-    SSE2_FALLBACK (INTERPOLATE_PRODUCT_DOUBLE)
-    double accum[4] = { 0, 0, 0, 0 };
-
-    for (j = 0; j < N; j++) {
-      const double curr_in = iptr[j];
-      accum[0] +=
-          MULT16_16 (curr_in,
-          st->sinc_table[4 + (j + 1) * st->oversample - offset - 2]);
-      accum[1] +=
-          MULT16_16 (curr_in,
-          st->sinc_table[4 + (j + 1) * st->oversample - offset - 1]);
-      accum[2] +=
-          MULT16_16 (curr_in,
-          st->sinc_table[4 + (j + 1) * st->oversample - offset]);
-      accum[3] +=
-          MULT16_16 (curr_in,
-          st->sinc_table[4 + (j + 1) * st->oversample - offset + 1]);
-    }
-
-    cubic_coef (frac, interp);
-    sum =
-        MULT16_32_Q15 (interp[0], accum[0]) + MULT16_32_Q15 (interp[1],
-        accum[1]) + MULT16_32_Q15 (interp[2],
-        accum[2]) + MULT16_32_Q15 (interp[3], accum[3]);
-#if defined(OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE) && defined(_USE_SSE2)
-    SSE2_IMPLEMENTATION (INTERPOLATE_PRODUCT_DOUBLE)
-        cubic_coef (frac, interp);
-    sum =
-        interpolate_product_double (iptr,
-        st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample,
-        interp);
-    SSE2_END (INTERPOLATE_PRODUCT_DOUBLE)
-#endif
-        out[out_stride * out_sample++] = PSHR32 (sum, 15);
-    last_sample += int_advance;
-    samp_frac_num += frac_advance;
-    if (samp_frac_num >= den_rate) {
-      samp_frac_num -= den_rate;
-      last_sample++;
-    }
-  }
-
-  st->last_sample[channel_index] = last_sample;
-  st->samp_frac_num[channel_index] = samp_frac_num;
-  return out_sample;
-}
-#endif
-
-static void
-update_filter (SpeexResamplerState * st)
-{
-  spx_uint32_t old_length;
-
-  old_length = st->filt_len;
-  st->oversample = quality_map[st->quality].oversample;
-  st->filt_len = quality_map[st->quality].base_length;
-
-  if (st->num_rate > st->den_rate) {
-    /* down-sampling */
-    st->cutoff =
-        quality_map[st->quality].downsample_bandwidth * st->den_rate /
-        st->num_rate;
-    /* FIXME: divide the numerator and denominator by a certain amount if they're too large */
-    st->filt_len = st->filt_len * st->num_rate / st->den_rate;
-    /* Round down to make sure we have a multiple of 4 */
-    st->filt_len &= (~0x3);
-    if (2 * st->den_rate < st->num_rate)
-      st->oversample >>= 1;
-    if (4 * st->den_rate < st->num_rate)
-      st->oversample >>= 1;
-    if (8 * st->den_rate < st->num_rate)
-      st->oversample >>= 1;
-    if (16 * st->den_rate < st->num_rate)
-      st->oversample >>= 1;
-    if (st->oversample < 1)
-      st->oversample = 1;
-  } else {
-    /* up-sampling */
-    st->cutoff = quality_map[st->quality].upsample_bandwidth;
-  }
-
-  /* Choose the resampling type that requires the least amount of memory */
-  /* Or if the full sinc table is explicitely requested, use that */
-  if (st->use_full_sinc_table || (st->den_rate <= st->oversample)) {
-    spx_uint32_t i;
-    if (!st->sinc_table)
-      st->sinc_table =
-          (spx_word16_t *) speex_alloc (st->filt_len * st->den_rate *
-          sizeof (spx_word16_t));
-    else if (st->sinc_table_length < st->filt_len * st->den_rate) {
-      st->sinc_table =
-          (spx_word16_t *) speex_realloc (st->sinc_table,
-          st->filt_len * st->den_rate * sizeof (spx_word16_t));
-      st->sinc_table_length = st->filt_len * st->den_rate;
-    }
-    for (i = 0; i < st->den_rate; i++) {
-      spx_int32_t j;
-      for (j = 0; j < st->filt_len; j++) {
-        st->sinc_table[i * st->filt_len + j] =
-            sinc (st->cutoff, ((j - (spx_int32_t) st->filt_len / 2 + 1) -
-#ifdef DOUBLE_PRECISION
-                ((double) i) / st->den_rate), st->filt_len,
-#else
-                ((float) i) / st->den_rate), st->filt_len,
-#endif
-            quality_map[st->quality].window_func);
-      }
-    }
-#ifdef FIXED_POINT
-    st->resampler_ptr = resampler_basic_direct_single;
-#else
-#ifdef DOUBLE_PRECISION
-    st->resampler_ptr = resampler_basic_direct_double;
-#else
-    if (st->quality > 8)
-      st->resampler_ptr = resampler_basic_direct_double;
-    else
-      st->resampler_ptr = resampler_basic_direct_single;
-#endif
-#endif
-    /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff); */
-  } else {
-    spx_int32_t i;
-    if (!st->sinc_table)
-      st->sinc_table =
-          (spx_word16_t *) speex_alloc ((st->filt_len * st->oversample +
-              8) * sizeof (spx_word16_t));
-    else if (st->sinc_table_length < st->filt_len * st->oversample + 8) {
-      st->sinc_table =
-          (spx_word16_t *) speex_realloc (st->sinc_table,
-          (st->filt_len * st->oversample + 8) * sizeof (spx_word16_t));
-      st->sinc_table_length = st->filt_len * st->oversample + 8;
-    }
-    for (i = -4; i < (spx_int32_t) (st->oversample * st->filt_len + 4); i++)
-      st->sinc_table[i + 4] =
-#ifdef DOUBLE_PRECISION
-          sinc (st->cutoff, (i / (double) st->oversample - st->filt_len / 2),
-#else
-          sinc (st->cutoff, (i / (float) st->oversample - st->filt_len / 2),
-#endif
-          st->filt_len, quality_map[st->quality].window_func);
-#ifdef FIXED_POINT
-    st->resampler_ptr = resampler_basic_interpolate_single;
-#else
-#ifdef DOUBLE_PRECISION
-    st->resampler_ptr = resampler_basic_interpolate_double;
-#else
-    if (st->quality > 8)
-      st->resampler_ptr = resampler_basic_interpolate_double;
-    else
-      st->resampler_ptr = resampler_basic_interpolate_single;
-#endif
-#endif
-    /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff); */
-  }
-  st->int_advance = st->num_rate / st->den_rate;
-  st->frac_advance = st->num_rate % st->den_rate;
-
-
-  /* Here's the place where we update the filter memory to take into account
-     the change in filter length. It's probably the messiest part of the code
-     due to handling of lots of corner cases. */
-  if (!st->mem) {
-    spx_uint32_t i;
-    st->mem_alloc_size = st->filt_len - 1 + st->buffer_size;
-    st->mem =
-        (spx_word16_t *) speex_alloc (st->nb_channels * st->mem_alloc_size *
-        sizeof (spx_word16_t));
-    for (i = 0; i < st->nb_channels * st->mem_alloc_size; i++)
-      st->mem[i] = 0;
-    /*speex_warning("init filter"); */
-  } else if (!st->started) {
-    spx_uint32_t i;
-    st->mem_alloc_size = st->filt_len - 1 + st->buffer_size;
-    st->mem =
-        (spx_word16_t *) speex_realloc (st->mem,
-        st->nb_channels * st->mem_alloc_size * sizeof (spx_word16_t));
-    for (i = 0; i < st->nb_channels * st->mem_alloc_size; i++)
-      st->mem[i] = 0;
-    /*speex_warning("reinit filter"); */
-  } else if (st->filt_len > old_length) {
-    spx_int32_t i;
-    /* Increase the filter length */
-    /*speex_warning("increase filter size"); */
-    int old_alloc_size = st->mem_alloc_size;
-    if ((st->filt_len - 1 + st->buffer_size) > st->mem_alloc_size) {
-      st->mem_alloc_size = st->filt_len - 1 + st->buffer_size;
-      st->mem =
-          (spx_word16_t *) speex_realloc (st->mem,
-          st->nb_channels * st->mem_alloc_size * sizeof (spx_word16_t));
-    }
-    for (i = st->nb_channels - 1; i >= 0; i--) {
-      spx_int32_t j;
-      spx_uint32_t olen = old_length;
-      /*if (st->magic_samples[i]) */
-      {
-        /* Try and remove the magic samples as if nothing had happened */
-
-        /* FIXME: This is wrong but for now we need it to avoid going over the array bounds */
-        olen = old_length + 2 * st->magic_samples[i];
-        for (j = old_length - 2 + st->magic_samples[i]; j >= 0; j--)
-          st->mem[i * st->mem_alloc_size + j + st->magic_samples[i]] =
-              st->mem[i * old_alloc_size + j];
-        for (j = 0; j < st->magic_samples[i]; j++)
-          st->mem[i * st->mem_alloc_size + j] = 0;
-        st->magic_samples[i] = 0;
-      }
-      if (st->filt_len > olen) {
-        /* If the new filter length is still bigger than the "augmented" length */
-        /* Copy data going backward */
-        for (j = 0; j < olen - 1; j++)
-          st->mem[i * st->mem_alloc_size + (st->filt_len - 2 - j)] =
-              st->mem[i * st->mem_alloc_size + (olen - 2 - j)];
-        /* Then put zeros for lack of anything better */
-        for (; j < st->filt_len - 1; j++)
-          st->mem[i * st->mem_alloc_size + (st->filt_len - 2 - j)] = 0;
-        /* Adjust last_sample */
-        st->last_sample[i] += (st->filt_len - olen) / 2;
-      } else {
-        /* Put back some of the magic! */
-        st->magic_samples[i] = (olen - st->filt_len) / 2;
-        for (j = 0; j < st->filt_len - 1 + st->magic_samples[i]; j++)
-          st->mem[i * st->mem_alloc_size + j] =
-              st->mem[i * st->mem_alloc_size + j + st->magic_samples[i]];
-      }
-    }
-  } else if (st->filt_len < old_length) {
-    spx_uint32_t i;
-    /* Reduce filter length, this a bit tricky. We need to store some of the memory as "magic"
-       samples so they can be used directly as input the next time(s) */
-    for (i = 0; i < st->nb_channels; i++) {
-      spx_uint32_t j;
-      spx_uint32_t old_magic = st->magic_samples[i];
-      st->magic_samples[i] = (old_length - st->filt_len) / 2;
-      /* We must copy some of the memory that's no longer used */
-      /* Copy data going backward */
-      for (j = 0; j < st->filt_len - 1 + st->magic_samples[i] + old_magic; j++)
-        st->mem[i * st->mem_alloc_size + j] =
-            st->mem[i * st->mem_alloc_size + j + st->magic_samples[i]];
-      st->magic_samples[i] += old_magic;
-    }
-  }
-
-}
-
-EXPORT SpeexResamplerState *
-speex_resampler_init (spx_uint32_t nb_channels, spx_uint32_t in_rate,
-    spx_uint32_t out_rate, int quality,
-    SpeexResamplerSincFilterMode sinc_filter_mode,
-    spx_uint32_t sinc_filter_auto_threshold, int *err)
-{
-  return speex_resampler_init_frac (nb_channels, in_rate, out_rate, in_rate,
-      out_rate, quality, sinc_filter_mode, sinc_filter_auto_threshold, err);
-}
-
-#if defined HAVE_ORC && !defined DISABLE_ORC
-static void
-check_insn_set (SpeexResamplerState * st, const char *name)
-{
-  if (!name)
-    return;
-#ifdef _USE_SSE
-  if (!strcmp (name, "sse"))
-    st->use_sse = 1;
-#endif
-#ifdef _USE_SSE2
-  if (!strcmp (name, "sse2"))
-    st->use_sse = st->use_sse2 = 1;
-#endif
-#ifdef _USE_NEON
-  if (!strcmp (name, "neon"))
-    st->use_neon = 1;
-#endif
-}
-#endif
-
-EXPORT SpeexResamplerState *
-speex_resampler_init_frac (spx_uint32_t nb_channels, spx_uint32_t ratio_num,
-    spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate,
-    int quality, SpeexResamplerSincFilterMode sinc_filter_mode,
-    spx_uint32_t sinc_filter_auto_threshold, int *err)
-{
-  spx_uint32_t i;
-  SpeexResamplerState *st;
-  int use_full_sinc_table = 0;
-  if (quality > 10 || quality < 0) {
-    if (err)
-      *err = RESAMPLER_ERR_INVALID_ARG;
-    return NULL;
-  }
-  if (ratio_den == 0) {
-    if (err)
-      *err = RESAMPLER_ERR_INVALID_ARG;
-    return NULL;
-  }
-  switch (sinc_filter_mode) {
-    case RESAMPLER_SINC_FILTER_INTERPOLATED:
-      use_full_sinc_table = 0;
-      break;
-    case RESAMPLER_SINC_FILTER_FULL:
-      use_full_sinc_table = 1;
-      break;
-    case RESAMPLER_SINC_FILTER_AUTO:
-      /* Handled below */
-      break;
-    default:
-      if (err)
-        *err = RESAMPLER_ERR_INVALID_ARG;
-      return NULL;
-  }
-
-  st = (SpeexResamplerState *) speex_alloc (sizeof (SpeexResamplerState));
-  st->initialised = 0;
-  st->started = 0;
-  st->in_rate = 0;
-  st->out_rate = 0;
-  st->num_rate = 0;
-  st->den_rate = 0;
-  st->quality = -1;
-  st->sinc_table_length = 0;
-  st->mem_alloc_size = 0;
-  st->filt_len = 0;
-  st->mem = 0;
-  st->resampler_ptr = 0;
-  st->use_full_sinc_table = use_full_sinc_table;
-
-  st->cutoff = 1.f;
-  st->nb_channels = nb_channels;
-  st->in_stride = 1;
-  st->out_stride = 1;
-
-#ifdef FIXED_POINT
-  st->buffer_size = 160;
-#else
-  st->buffer_size = 160;
-#endif
-
-  st->use_sse = st->use_sse2 = 0;
-  st->use_neon = 0;
-#if defined HAVE_ORC && !defined DISABLE_ORC
-  orc_init ();
-  {
-    OrcTarget *target = orc_target_get_default ();
-    if (target) {
-      unsigned int flags = orc_target_get_default_flags (target);
-      check_insn_set (st, orc_target_get_name (target));
-      for (i = 0; i < 32; ++i) {
-        if (flags & (1U << i)) {
-          check_insn_set (st, orc_target_get_flag_name (target, i));
-        }
-      }
-    }
-  }
-#endif
-
-  /* Per channel data */
-  st->last_sample = (spx_int32_t *) speex_alloc (nb_channels * sizeof (int));
-  st->magic_samples = (spx_uint32_t *) speex_alloc (nb_channels * sizeof (int));
-  st->samp_frac_num = (spx_uint32_t *) speex_alloc (nb_channels * sizeof (int));
-  for (i = 0; i < nb_channels; i++) {
-    st->last_sample[i] = 0;
-    st->magic_samples[i] = 0;
-    st->samp_frac_num[i] = 0;
-  }
-
-  speex_resampler_set_quality (st, quality);
-  speex_resampler_set_rate_frac (st, ratio_num, ratio_den, in_rate, out_rate);
-
-  if (sinc_filter_mode == RESAMPLER_SINC_FILTER_AUTO) {
-    /*
-       Estimate how big the filter table would become if the full mode were to be used
-       calculations used correspond to the ones in update_filter()
-       if the size is bigger than the threshold, use interpolated sinc instead
-     */
-    spx_uint32_t base_filter_length = st->filt_len =
-        quality_map[st->quality].base_length;
-    spx_uint32_t filter_table_size =
-        base_filter_length * st->den_rate * sizeof (spx_uint16_t);
-    st->use_full_sinc_table =
-        (filter_table_size > sinc_filter_auto_threshold) ? 0 : 1;
-  }
-
-  update_filter (st);
-
-  st->initialised = 1;
-  if (err)
-    *err = RESAMPLER_ERR_SUCCESS;
-
-  return st;
-}
-
-EXPORT void
-speex_resampler_destroy (SpeexResamplerState * st)
-{
-  speex_free (st->mem);
-  speex_free (st->sinc_table);
-  speex_free (st->last_sample);
-  speex_free (st->magic_samples);
-  speex_free (st->samp_frac_num);
-  speex_free (st);
-}
-
-static int
-speex_resampler_process_native (SpeexResamplerState * st,
-    spx_uint32_t channel_index, spx_uint32_t * in_len, spx_word16_t * out,
-    spx_uint32_t * out_len)
-{
-  int j = 0;
-  const int N = st->filt_len;
-  int out_sample = 0;
-  spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size;
-  spx_uint32_t ilen;
-
-  st->started = 1;
-
-  /* Call the right resampler through the function ptr */
-  out_sample = st->resampler_ptr (st, channel_index, mem, in_len, out, out_len);
-
-  if (st->last_sample[channel_index] < (spx_int32_t) * in_len)
-    *in_len = st->last_sample[channel_index];
-  *out_len = out_sample;
-  st->last_sample[channel_index] -= *in_len;
-
-  ilen = *in_len;
-
-  for (j = 0; j < N - 1; ++j)
-    mem[j] = mem[j + ilen];
-
-  return RESAMPLER_ERR_SUCCESS;
-}
-
-static int
-speex_resampler_magic (SpeexResamplerState * st, spx_uint32_t channel_index,
-    spx_word16_t ** out, spx_uint32_t out_len)
-{
-  spx_uint32_t tmp_in_len = st->magic_samples[channel_index];
-  spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size;
-  const int N = st->filt_len;
-
-  speex_resampler_process_native (st, channel_index, &tmp_in_len, *out,
-      &out_len);
-
-  st->magic_samples[channel_index] -= tmp_in_len;
-
-  /* If we couldn't process all "magic" input samples, save the rest for next time */
-  if (st->magic_samples[channel_index]) {
-    spx_uint32_t i;
-    for (i = 0; i < st->magic_samples[channel_index]; i++)
-      mem[N - 1 + i] = mem[N - 1 + i + tmp_in_len];
-  }
-  *out += out_len * st->out_stride;
-  return out_len;
-}
-
-#ifdef FIXED_POINT
-EXPORT int
-speex_resampler_process_int (SpeexResamplerState * st,
-    spx_uint32_t channel_index, const spx_int16_t * in, spx_uint32_t * in_len,
-    spx_int16_t * out, spx_uint32_t * out_len)
-#else
-#ifdef DOUBLE_PRECISION
-EXPORT int
-speex_resampler_process_float (SpeexResamplerState * st,
-    spx_uint32_t channel_index, const double *in, spx_uint32_t * in_len,
-    double *out, spx_uint32_t * out_len)
-#else
-EXPORT int
-speex_resampler_process_float (SpeexResamplerState * st,
-    spx_uint32_t channel_index, const float *in, spx_uint32_t * in_len,
-    float *out, spx_uint32_t * out_len)
-#endif
-#endif
-{
-  int j;
-  spx_uint32_t ilen = *in_len;
-  spx_uint32_t olen = *out_len;
-  spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size;
-  const int filt_offs = st->filt_len - 1;
-  const spx_uint32_t xlen = st->mem_alloc_size - filt_offs;
-  const int istride = st->in_stride;
-
-  if (st->magic_samples[channel_index])
-    olen -= speex_resampler_magic (st, channel_index, &out, olen);
-  if (!st->magic_samples[channel_index]) {
-    while (ilen) {
-      spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen;
-      spx_uint32_t ochunk = olen;
-
-      if (in) {
-        for (j = 0; j < ichunk; ++j)
-          x[j + filt_offs] = in[j * istride];
-      } else {
-        for (j = 0; j < ichunk; ++j)
-          x[j + filt_offs] = 0;
-      }
-      speex_resampler_process_native (st, channel_index, &ichunk, out, &ochunk);
-      ilen -= ichunk;
-      olen -= ochunk;
-      out += ochunk * st->out_stride;
-      if (in)
-        in += ichunk * istride;
-      if (olen == 0 && ichunk == 0)
-        break;
-    }
-  }
-  *in_len -= ilen;
-  *out_len -= olen;
-  return RESAMPLER_ERR_SUCCESS;
-}
-
-#ifdef FIXED_POINT
-EXPORT int
-speex_resampler_process_float (SpeexResamplerState * st,
-    spx_uint32_t channel_index, const float *in, spx_uint32_t * in_len,
-    float *out, spx_uint32_t * out_len)
-#else
-EXPORT int
-speex_resampler_process_int (SpeexResamplerState * st,
-    spx_uint32_t channel_index, const spx_int16_t * in, spx_uint32_t * in_len,
-    spx_int16_t * out, spx_uint32_t * out_len)
-#endif
-{
-  int j;
-  const int istride_save = st->in_stride;
-  const int ostride_save = st->out_stride;
-  spx_uint32_t ilen = *in_len;
-  spx_uint32_t olen = *out_len;
-  spx_word16_t *x = st->mem + channel_index * st->mem_alloc_size;
-  const spx_uint32_t xlen = st->mem_alloc_size - (st->filt_len - 1);
-#ifdef VAR_ARRAYS
-  const unsigned int ylen =
-      (olen < FIXED_STACK_ALLOC) ? olen : FIXED_STACK_ALLOC;
-  VARDECL (spx_word16_t * ystack);
-  ALLOC (ystack, ylen, spx_word16_t);
-#else
-  const unsigned int ylen = FIXED_STACK_ALLOC;
-  spx_word16_t ystack[FIXED_STACK_ALLOC];
-#endif
-
-  st->out_stride = 1;
-
-  while (ilen) {
-    spx_word16_t *y = ystack;
-    spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen;
-    spx_uint32_t ochunk = (olen > ylen) ? ylen : olen;
-    spx_uint32_t omagic = 0;
-
-    if (st->magic_samples[channel_index]) {
-      omagic = speex_resampler_magic (st, channel_index, &y, ochunk);
-      ochunk -= omagic;
-      olen -= omagic;
-    }
-    if (!st->magic_samples[channel_index]) {
-      if (in) {
-        for (j = 0; j < ichunk; ++j)
-#ifdef FIXED_POINT
-          x[j + st->filt_len - 1] = WORD2INT (in[j * istride_save]);
-#else
-          x[j + st->filt_len - 1] = in[j * istride_save];
-#endif
-      } else {
-        for (j = 0; j < ichunk; ++j)
-          x[j + st->filt_len - 1] = 0;
-      }
-
-      speex_resampler_process_native (st, channel_index, &ichunk, y, &ochunk);
-    } else {
-      ichunk = 0;
-      ochunk = 0;
-    }
-
-    for (j = 0; j < ochunk + omagic; ++j)
-#ifdef FIXED_POINT
-      out[j * ostride_save] = ystack[j];
-#else
-      out[j * ostride_save] = WORD2INT (ystack[j]);
-#endif
-
-    ilen -= ichunk;
-    olen -= ochunk;
-    out += (ochunk + omagic) * ostride_save;
-    if (in)
-      in += ichunk * istride_save;
-    if (olen == 0 && ichunk == 0)
-      break;
-  }
-  st->out_stride = ostride_save;
-  *in_len -= ilen;
-  *out_len -= olen;
-
-  return RESAMPLER_ERR_SUCCESS;
-}
-
-#ifdef DOUBLE_PRECISION
-EXPORT int
-speex_resampler_process_interleaved_float (SpeexResamplerState * st,
-    const double *in, spx_uint32_t * in_len, double *out,
-    spx_uint32_t * out_len)
-#else
-EXPORT int
-speex_resampler_process_interleaved_float (SpeexResamplerState * st,
-    const float *in, spx_uint32_t * in_len, float *out, spx_uint32_t * out_len)
-#endif
-{
-  spx_uint32_t i;
-  int istride_save, ostride_save;
-  spx_uint32_t bak_len = *out_len;
-  istride_save = st->in_stride;
-  ostride_save = st->out_stride;
-  st->in_stride = st->out_stride = st->nb_channels;
-  for (i = 0; i < st->nb_channels; i++) {
-    *out_len = bak_len;
-    if (in != NULL)
-      speex_resampler_process_float (st, i, in + i, in_len, out + i, out_len);
-    else
-      speex_resampler_process_float (st, i, NULL, in_len, out + i, out_len);
-  }
-  st->in_stride = istride_save;
-  st->out_stride = ostride_save;
-  return RESAMPLER_ERR_SUCCESS;
-}
-
-EXPORT int
-speex_resampler_process_interleaved_int (SpeexResamplerState * st,
-    const spx_int16_t * in, spx_uint32_t * in_len, spx_int16_t * out,
-    spx_uint32_t * out_len)
-{
-  spx_uint32_t i;
-  int istride_save, ostride_save;
-  spx_uint32_t bak_len = *out_len;
-  istride_save = st->in_stride;
-  ostride_save = st->out_stride;
-  st->in_stride = st->out_stride = st->nb_channels;
-  for (i = 0; i < st->nb_channels; i++) {
-    *out_len = bak_len;
-    if (in != NULL)
-      speex_resampler_process_int (st, i, in + i, in_len, out + i, out_len);
-    else
-      speex_resampler_process_int (st, i, NULL, in_len, out + i, out_len);
-  }
-  st->in_stride = istride_save;
-  st->out_stride = ostride_save;
-  return RESAMPLER_ERR_SUCCESS;
-}
-
-EXPORT int
-speex_resampler_set_rate (SpeexResamplerState * st, spx_uint32_t in_rate,
-    spx_uint32_t out_rate)
-{
-  return speex_resampler_set_rate_frac (st, in_rate, out_rate, in_rate,
-      out_rate);
-}
-
-EXPORT void
-speex_resampler_get_rate (SpeexResamplerState * st, spx_uint32_t * in_rate,
-    spx_uint32_t * out_rate)
-{
-  *in_rate = st->in_rate;
-  *out_rate = st->out_rate;
-}
-
-EXPORT int
-speex_resampler_set_rate_frac (SpeexResamplerState * st, spx_uint32_t ratio_num,
-    spx_uint32_t ratio_den, spx_uint32_t in_rate, spx_uint32_t out_rate)
-{
-  spx_uint32_t fact;
-  spx_uint32_t old_den;
-  spx_uint32_t i;
-  if (st->in_rate == in_rate && st->out_rate == out_rate
-      && st->num_rate == ratio_num && st->den_rate == ratio_den)
-    return RESAMPLER_ERR_SUCCESS;
-
-  old_den = st->den_rate;
-  st->in_rate = in_rate;
-  st->out_rate = out_rate;
-  st->num_rate = ratio_num;
-  st->den_rate = ratio_den;
-  /* FIXME: This is terribly inefficient, but who cares (at least for now)? */
-  for (fact = 2; fact <= IMIN (st->num_rate, st->den_rate); fact++) {
-    while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0)) {
-      st->num_rate /= fact;
-      st->den_rate /= fact;
-    }
-  }
-
-  if (old_den > 0) {
-    for (i = 0; i < st->nb_channels; i++) {
-      st->samp_frac_num[i] =
-          (gint64) st->samp_frac_num[i] * (gint64) st->den_rate / old_den;
-      /* Safety net */
-      if (st->samp_frac_num[i] >= st->den_rate)
-        st->samp_frac_num[i] = st->den_rate - 1;
-    }
-  }
-
-  if (st->initialised)
-    update_filter (st);
-  return RESAMPLER_ERR_SUCCESS;
-}
-
-EXPORT void
-speex_resampler_get_ratio (SpeexResamplerState * st, spx_uint32_t * ratio_num,
-    spx_uint32_t * ratio_den)
-{
-  *ratio_num = st->num_rate;
-  *ratio_den = st->den_rate;
-}
-
-EXPORT int
-speex_resampler_set_quality (SpeexResamplerState * st, int quality)
-{
-  if (quality > 10 || quality < 0)
-    return RESAMPLER_ERR_INVALID_ARG;
-  if (st->quality == quality)
-    return RESAMPLER_ERR_SUCCESS;
-  st->quality = quality;
-  if (st->initialised)
-    update_filter (st);
-  return RESAMPLER_ERR_SUCCESS;
-}
-
-EXPORT void
-speex_resampler_get_quality (SpeexResamplerState * st, int *quality)
-{
-  *quality = st->quality;
-}
-
-EXPORT void
-speex_resampler_set_input_stride (SpeexResamplerState * st, spx_uint32_t stride)
-{
-  st->in_stride = stride;
-}
-
-EXPORT void
-speex_resampler_get_input_stride (SpeexResamplerState * st,
-    spx_uint32_t * stride)
-{
-  *stride = st->in_stride;
-}
-
-EXPORT void
-speex_resampler_set_output_stride (SpeexResamplerState * st,
-    spx_uint32_t stride)
-{
-  st->out_stride = stride;
-}
-
-EXPORT void
-speex_resampler_get_output_stride (SpeexResamplerState * st,
-    spx_uint32_t * stride)
-{
-  *stride = st->out_stride;
-}
-
-EXPORT int
-speex_resampler_get_input_latency (SpeexResamplerState * st)
-{
-  return st->filt_len / 2;
-}
-
-EXPORT int
-speex_resampler_get_output_latency (SpeexResamplerState * st)
-{
-  return ((st->filt_len / 2) * st->den_rate +
-      (st->num_rate >> 1)) / st->num_rate;
-}
-
-EXPORT int
-speex_resampler_get_filt_len (SpeexResamplerState * st)
-{
-  return st->filt_len;
-}
-
-EXPORT int
-speex_resampler_get_sinc_filter_mode (SpeexResamplerState * st)
-{
-  return st->use_full_sinc_table;
-}
-
-EXPORT int
-speex_resampler_skip_zeros (SpeexResamplerState * st)
-{
-  spx_uint32_t i;
-  for (i = 0; i < st->nb_channels; i++)
-    st->last_sample[i] = st->filt_len / 2;
-  return RESAMPLER_ERR_SUCCESS;
-}
-
-EXPORT int
-speex_resampler_reset_mem (SpeexResamplerState * st)
-{
-  spx_uint32_t i;
-  for (i = 0; i < st->nb_channels * (st->filt_len - 1); i++)
-    st->mem[i] = 0;
-  return RESAMPLER_ERR_SUCCESS;
-}
-
-EXPORT const char *
-speex_resampler_strerror (int err)
-{
-  switch (err) {
-    case RESAMPLER_ERR_SUCCESS:
-      return "Success.";
-    case RESAMPLER_ERR_ALLOC_FAILED:
-      return "Memory allocation failed.";
-    case RESAMPLER_ERR_BAD_STATE:
-      return "Bad resampler state.";
-    case RESAMPLER_ERR_INVALID_ARG:
-      return "Invalid argument.";
-    case RESAMPLER_ERR_PTR_OVERLAP:
-      return "Input and output buffers overlap.";
-    default:
-      return "Unknown error. Bad error code or strange version mismatch.";
-  }
-}
diff --git a/gst/audioresample/resample_neon.h b/gst/audioresample/resample_neon.h
deleted file mode 100644
index 478488f..0000000
--- a/gst/audioresample/resample_neon.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/* Copyright (C) 2007-2008 Jean-Marc Valin
- * Copyright (C) 2008 Thorvald Natvig
- * Copyright (C) 2011 Texas Instruments
- *               author Jyri Sarha
- */
-/**
-   @file resample_neon.h
-   @brief Resampler functions (NEON version)
-*/
-/*
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-
-   - Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-
-   - Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-
-   - Neither the name of the Xiph.org Foundation nor the names of its
-   contributors may be used to endorse or promote products derived from
-   this software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
-   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <arm_neon.h>
-
-#ifdef FIXED_POINT
-#ifdef __thumb2__ 
-static inline int32_t saturate_32bit_to_16bit(int32_t a) {
-    int32_t ret;
-    asm ("ssat %[ret], #16, %[a]"
-         : [ret] "=&r" (ret)
-         : [a] "r" (a)
-         : );
-    return ret;
-}
-#else
-static inline int32_t saturate_32bit_to_16bit(int32_t a) {
-    int32_t ret;
-    asm ("vmov.s32 d0[0], %[a]\n"
-         "vqmovn.s32 d0, q0\n"
-         "vmov.s16 %[ret], d0[0]\n"
-         : [ret] "=&r" (ret)
-         : [a] "r" (a)
-         : "q0");
-    return ret;
-}
-#endif
-#undef WORD2INT
-#define WORD2INT(x) (saturate_32bit_to_16bit(x))
-
-#define OVERRIDE_INNER_PRODUCT_SINGLE
-/* Only works when len % 4 == 0 */
-static inline int32_t inner_product_single(const int16_t *a, const int16_t *b, unsigned int len)
-{
-    int32_t ret;
-    uint32_t remainder = len % 16;
-    len = len - remainder;
-
-    asm volatile ("	 cmp %[len], #0\n"
-		  "	 bne 1f\n"
-		  "	 vld1.16 {d16}, [%[b]]!\n"
-		  "	 vld1.16 {d20}, [%[a]]!\n"
-		  "	 subs %[remainder], %[remainder], #4\n"
-		  "	 vmull.s16 q0, d16, d20\n"
-		  "      beq 5f\n" 
-		  "	 b 4f\n"
-		  "1:"
-		  "	 vld1.16 {d16, d17, d18, d19}, [%[b]]!\n"
-		  "	 vld1.16 {d20, d21, d22, d23}, [%[a]]!\n"
-		  "	 subs %[len], %[len], #16\n"
-		  "	 vmull.s16 q0, d16, d20\n"
-		  "	 vmlal.s16 q0, d17, d21\n"
-		  "	 vmlal.s16 q0, d18, d22\n"
-		  "	 vmlal.s16 q0, d19, d23\n"
-		  "	 beq 3f\n"
-		  "2:"
-		  "	 vld1.16 {d16, d17, d18, d19}, [%[b]]!\n"
-		  "	 vld1.16 {d20, d21, d22, d23}, [%[a]]!\n"
-		  "	 subs %[len], %[len], #16\n"
-		  "	 vmlal.s16 q0, d16, d20\n"
-		  "	 vmlal.s16 q0, d17, d21\n"
-		  "	 vmlal.s16 q0, d18, d22\n"
-		  "	 vmlal.s16 q0, d19, d23\n"
-		  "	 bne 2b\n"
-		  "3:"
-		  "	 cmp %[remainder], #0\n"
-		  "	 beq 5f\n"
-		  "4:"
-		  "	 vld1.16 {d16}, [%[b]]!\n"
-		  "	 vld1.16 {d20}, [%[a]]!\n"
-		  "	 subs %[remainder], %[remainder], #4\n"
-		  "	 vmlal.s16 q0, d16, d20\n"
-		  "	 bne 4b\n"
-		  "5:"
-		  "	 vaddl.s32 q0, d0, d1\n"
-		  "	 vadd.s64 d0, d0, d1\n"
-		  "	 vqmovn.s64 d0, q0\n"
-		  "	 vqrshrn.s32 d0, q0, #15\n"
-		  "	 vmov.s16 %[ret], d0[0]\n"
-		  : [ret] "=&r" (ret), [a] "+r" (a), [b] "+r" (b),
-		    [len] "+r" (len), [remainder] "+r" (remainder)
-		  :
-		  : "cc", "q0",
-		    "d16", "d17", "d18", "d19",
-		    "d20", "d21", "d22", "d23");
-
-    return ret;
-}
-#elif defined(FLOATING_POINT)
-
-static inline int32_t saturate_float_to_16bit(float a) {
-    int32_t ret;
-    asm ("vmov.f32 d0[0], %[a]\n"
-         "vcvt.s32.f32 d0, d0, #15\n"
-         "vqrshrn.s32 d0, q0, #15\n"
-         "vmov.s16 %[ret], d0[0]\n"
-         : [ret] "=&r" (ret)
-         : [a] "r" (a)
-         : "q0");
-    return ret;
-}
-#undef WORD2INT
-#define WORD2INT(x) (saturate_float_to_16bit(x))
-
-#define OVERRIDE_INNER_PRODUCT_SINGLE
-/* Only works when len % 4 == 0 */
-static inline float inner_product_single(const float *a, const float *b, unsigned int len)
-{
-    float ret;
-    uint32_t remainder = len % 16;
-    len = len - remainder;
-
-    asm volatile ("	 cmp %[len], #0\n"
-		  "	 bne 1f\n"
-		  "	 vld1.32 {q4}, [%[b]]!\n"
-		  "	 vld1.32 {q8}, [%[a]]!\n"
-		  "	 subs %[remainder], %[remainder], #4\n"
-		  "	 vmul.f32 q0, q4, q8\n"
-		  "      bne 4f\n" 
-		  "	 b 5f\n"
-		  "1:"
-		  "	 vld1.32 {q4, q5}, [%[b]]!\n"
-		  "	 vld1.32 {q8, q9}, [%[a]]!\n"
-		  "	 vld1.32 {q6, q7}, [%[b]]!\n"
-		  "	 vld1.32 {q10, q11}, [%[a]]!\n"
-		  "	 subs %[len], %[len], #16\n"
-		  "	 vmul.f32 q0, q4, q8\n"
-		  "	 vmul.f32 q1, q5, q9\n"
-		  "	 vmul.f32 q2, q6, q10\n"
-		  "	 vmul.f32 q3, q7, q11\n"
-		  "	 beq 3f\n"
-		  "2:"
-		  "	 vld1.32 {q4, q5}, [%[b]]!\n"
-		  "	 vld1.32 {q8, q9}, [%[a]]!\n"
-		  "	 vld1.32 {q6, q7}, [%[b]]!\n"
-		  "	 vld1.32 {q10, q11}, [%[a]]!\n"
-		  "	 subs %[len], %[len], #16\n"
-		  "	 vmla.f32 q0, q4, q8\n"
-		  "	 vmla.f32 q1, q5, q9\n"
-		  "	 vmla.f32 q2, q6, q10\n"
-		  "	 vmla.f32 q3, q7, q11\n"
-		  "	 bne 2b\n"
-		  "3:"
-		  "	 vadd.f32 q4, q0, q1\n"
-		  "	 vadd.f32 q5, q2, q3\n"
-		  "	 cmp %[remainder], #0\n"
-		  "	 vadd.f32 q0, q4, q5\n"
-		  "	 beq 5f\n"
-		  "4:"
-		  "	 vld1.32 {q6}, [%[b]]!\n"
-		  "	 vld1.32 {q10}, [%[a]]!\n"
-		  "	 subs %[remainder], %[remainder], #4\n"
-		  "	 vmla.f32 q0, q6, q10\n"
-		  "	 bne 4b\n"
-		  "5:"
-		  "	 vadd.f32 d0, d0, d1\n"
-		  "	 vpadd.f32 d0, d0, d0\n"
-		  "	 vmov.f32 %[ret], d0[0]\n"
-		  : [ret] "=&r" (ret), [a] "+r" (a), [b] "+r" (b),
-		    [len] "+l" (len), [remainder] "+l" (remainder)
-		  :
-		  : "cc", "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8",
-                    "q9", "q10", "q11");
-    return ret;
-}
-#endif
-
diff --git a/gst/audioresample/resample_sse.h b/gst/audioresample/resample_sse.h
deleted file mode 100644
index 55d1f40..0000000
--- a/gst/audioresample/resample_sse.h
+++ /dev/null
@@ -1,229 +0,0 @@
-/* Copyright (C) 2007-2008 Jean-Marc Valin
- * Copyright (C) 2008 Thorvald Natvig
- */
-/**
-   @file resample_sse.h
-   @brief Resampler functions (SSE version)
-*/
-/*
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-   
-   - Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-   
-   - Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-   
-   - Neither the name of the Xiph.org Foundation nor the names of its
-   contributors may be used to endorse or promote products derived from
-   this software without specific prior written permission.
-   
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
-   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifdef HAVE_XMMINTRIN_H
-#include <xmmintrin.h>
-#endif
-
-#define OVERRIDE_INNER_PRODUCT_SINGLE
-static inline float inner_product_single(const float *a, const float *b, unsigned int len)
-{
-   int i = 0;
-   float ret = 0;
-   __m128 sum = _mm_setzero_ps();
-
-   if (len > 7)
-   {
-      for (;i<len-7;i+=8)
-      {
-         sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i)));
-         sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4)));
-      }
-      sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
-      sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
-      _mm_store_ss(&ret, sum);
-   }
-
-   for (; i < len; i++)
-     ret += a[i] * b[i];
-
-   return ret;
-}
-
-#define OVERRIDE_INTERPOLATE_PRODUCT_SINGLE
-static inline float interpolate_product_single(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {
-  int i = 0;
-  float ret = 0;
-  __m128 sum = _mm_setzero_ps();
-  __m128 f = _mm_loadu_ps(frac);
-
-  if (len > 1)
-  {
-     for(;i<len-1;i+=2)
-     {
-        sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample)));
-        sum = _mm_add_ps(sum, _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample)));
-     }
-
-     sum = _mm_mul_ps(f, sum);
-     sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
-     sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
-     _mm_store_ss(&ret, sum);
-  }
-
-  if (i == len-1)
-    ret += a[i] * (frac[0]*b[i*oversample] + frac[1]*b[i*oversample + 1] + frac[2]*b[i*oversample + 2] + frac[3]*b[i*oversample + 3]);
-
-  return ret;
-}
-
-#ifdef _USE_SSE2
-#ifdef HAVE_EMMINTRIN_H
-#include <emmintrin.h>
-#endif
-#define OVERRIDE_INNER_PRODUCT_DOUBLE
-
-#ifdef DOUBLE_PRECISION
-static inline double inner_product_double(const double *a, const double *b, unsigned int len)
-{
-   int i = 0;
-   double ret = 0;
-   __m128d sum = _mm_setzero_pd();
-
-   if (len > 3)
-   {
-      for (;i<len-3;i+=4)
-      {
-         sum = _mm_add_pd(sum, _mm_mul_pd(_mm_loadu_pd(a+i), _mm_loadu_pd(b+i)));
-         sum = _mm_add_pd(sum, _mm_mul_pd(_mm_loadu_pd(a+i+2), _mm_loadu_pd(b+i+2)));
-      }
-      sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
-      _mm_store_sd(&ret, sum);
-   }
-
-   for (; i < len; i++)
-     ret += a[i] * b[i];
-
-   return ret;
-}
-#else
-static inline double inner_product_double(const float *a, const float *b, unsigned int len)
-{
-   int i = 0;
-   double ret = 0;
-   __m128d sum = _mm_setzero_pd();
-   __m128 t;
-
-   if (len > 7)
-   {
-      for (;i<len-7;i+=8)
-      {
-         t = _mm_mul_ps(_mm_loadu_ps(a+i), _mm_loadu_ps(b+i));
-         sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
-         sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
-
-         t = _mm_mul_ps(_mm_loadu_ps(a+i+4), _mm_loadu_ps(b+i+4));
-         sum = _mm_add_pd(sum, _mm_cvtps_pd(t));
-         sum = _mm_add_pd(sum, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
-      }
-      sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
-      _mm_store_sd(&ret, sum);
-   }
-
-   for (; i < len; i++)
-     ret += a[i] * b[i];
-
-   return ret;
-}
-#endif
-
-
-#define OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE
-
-#ifdef DOUBLE_PRECISION
-static inline double interpolate_product_double(const double *a, const double *b, unsigned int len, const spx_uint32_t oversample, double *frac) {
-  int i = 0;
-  double ret = 0;
-  __m128d sum;
-  __m128d sum1 = _mm_setzero_pd();
-  __m128d sum2 = _mm_setzero_pd();
-  __m128d f1 = _mm_loadu_pd(frac);
-  __m128d f2 = _mm_loadu_pd(frac+2);
-  __m128d t;
-  
-  if (len > 1)
-  {
-     for(;i<len-1;i+=2)
-     {
-       t = _mm_load1_pd(a+i);
-       sum1 = _mm_add_pd(sum1, _mm_mul_pd(t, _mm_loadu_pd(b+i*oversample)));
-       sum2 = _mm_add_pd(sum2, _mm_mul_pd(t, _mm_loadu_pd(b+i*oversample+2)));
-
-       t = _mm_load1_pd(a+i+1);
-       sum1 = _mm_add_pd(sum1, _mm_mul_pd(t, _mm_loadu_pd(b+(i+1)*oversample)));
-       sum2 = _mm_add_pd(sum2, _mm_mul_pd(t, _mm_loadu_pd(b+(i+1)*oversample+2)));
-     }
-     sum1 = _mm_mul_pd(f1, sum1);
-     sum2 = _mm_mul_pd(f2, sum2);
-     sum = _mm_add_pd(sum1, sum2);
-     sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
-     _mm_store_sd(&ret, sum);
-  }
-
-  if (i == len-1)
-    ret += a[i] * (frac[0]*b[i*oversample] + frac[1]*b[i*oversample + 1] + frac[2]*b[i*oversample + 2] + frac[3]*b[i*oversample + 3]);
-
-  return ret;
-}
-#else
-static inline double interpolate_product_double(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac) {
-  int i = 0;
-  double ret = 0;
-  __m128d sum;
-  __m128d sum1 = _mm_setzero_pd();
-  __m128d sum2 = _mm_setzero_pd();
-  __m128 f = _mm_loadu_ps(frac);
-  __m128d f1 = _mm_cvtps_pd(f);
-  __m128d f2 = _mm_cvtps_pd(_mm_movehl_ps(f,f));
-  __m128 t;
-
-  if (len > 1)
-  {
-     for(;i<len-1;i+=2)
-     {
-        t = _mm_mul_ps(_mm_load1_ps(a+i), _mm_loadu_ps(b+i*oversample));
-        sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
-        sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
-
-        t = _mm_mul_ps(_mm_load1_ps(a+i+1), _mm_loadu_ps(b+(i+1)*oversample));
-        sum1 = _mm_add_pd(sum1, _mm_cvtps_pd(t));
-        sum2 = _mm_add_pd(sum2, _mm_cvtps_pd(_mm_movehl_ps(t, t)));
-     }
-     sum1 = _mm_mul_pd(f1, sum1);
-     sum2 = _mm_mul_pd(f2, sum2);
-     sum = _mm_add_pd(sum1, sum2);
-     sum = _mm_add_sd(sum, _mm_unpackhi_pd(sum, sum));
-     _mm_store_sd(&ret, sum);
-  }
-
-  if (i == len-1)
-    ret += a[i] * (frac[0]*b[i*oversample] + frac[1]*b[i*oversample + 1] + frac[2]*b[i*oversample + 2] + frac[3]*b[i*oversample + 3]);
-
-  return ret;
-}
-#endif
-
-#endif
diff --git a/gst/audioresample/speex_resampler.h b/gst/audioresample/speex_resampler.h
deleted file mode 100644
index b9aaa2c..0000000
--- a/gst/audioresample/speex_resampler.h
+++ /dev/null
@@ -1,403 +0,0 @@
-/* Copyright (C) 2007 Jean-Marc Valin
-      
-   File: speex_resampler.h
-   Resampling code
-      
-   The design goals of this code are:
-      - Very fast algorithm
-      - Low memory requirement
-      - Good *perceptual* quality (and not best SNR)
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are
-   met:
-
-   1. Redistributions of source code must retain the above copyright notice,
-   this list of conditions and the following disclaimer.
-
-   2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-
-   3. The name of the author may not be used to endorse or promote products
-   derived from this software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-   DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-   POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-#ifndef SPEEX_RESAMPLER_H
-#define SPEEX_RESAMPLER_H
-
-#ifdef OUTSIDE_SPEEX
-
-/********* WARNING: MENTAL SANITY ENDS HERE *************/
-
-/* If the resampler is defined outside of Speex, we change the symbol names so that 
-   there won't be any clash if linking with Speex later on. */
-
-/* #define RANDOM_PREFIX your software name here */
-#ifndef RANDOM_PREFIX
-#error "Please define RANDOM_PREFIX (above) to something specific to your project to prevent symbol name clashes"
-#endif
-
-#define CAT_PREFIX2(a,b) a ## b
-#define CAT_PREFIX(a,b) CAT_PREFIX2(a, b)
-      
-#define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init)
-#define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac)
-#define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy)
-#define speex_resampler_process_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_float)
-#define speex_resampler_process_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_int)
-#define speex_resampler_process_interleaved_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_float)
-#define speex_resampler_process_interleaved_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_int)
-#define speex_resampler_set_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate)
-#define speex_resampler_get_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_get_rate)
-#define speex_resampler_set_rate_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate_frac)
-#define speex_resampler_get_ratio CAT_PREFIX(RANDOM_PREFIX,_resampler_get_ratio)
-#define speex_resampler_set_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_set_quality)
-#define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality)
-#define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride)
-#define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride)
-#define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride)
-#define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride)
-#define speex_resampler_get_input_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_latency)
-#define speex_resampler_get_output_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_latency)
-#define speex_resampler_get_filt_len CAT_PREFIX(RANDOM_PREFIX,_resampler_get_filt_len)
-#define speex_resampler_get_sinc_filter_mode CAT_PREFIX(RANDOM_PREFIX,_resampler_get_sinc_filter_mode)
-#define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros)
-#define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem)
-#define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror)
-
-#define spx_int16_t gint16
-#define spx_int32_t gint32
-#define spx_uint16_t guint16
-#define spx_uint32_t guint32
-      
-#else /* OUTSIDE_SPEEX */
-
-#ifdef _BUILD_SPEEX
-# include "speex_types.h"
-#else
-# include <speex/speex_types.h>
-#endif
-
-#endif /* OUTSIDE_SPEEX */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define SPEEX_RESAMPLER_QUALITY_MAX 10
-#define SPEEX_RESAMPLER_QUALITY_MIN 0
-#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4
-#define SPEEX_RESAMPLER_QUALITY_VOIP 3
-#define SPEEX_RESAMPLER_QUALITY_DESKTOP 5
-
-enum {
-   RESAMPLER_ERR_SUCCESS         = 0,
-   RESAMPLER_ERR_ALLOC_FAILED    = 1,
-   RESAMPLER_ERR_BAD_STATE       = 2,
-   RESAMPLER_ERR_INVALID_ARG     = 3,
-   RESAMPLER_ERR_PTR_OVERLAP     = 4,
-   
-   RESAMPLER_ERR_MAX_ERROR
-};
-
-typedef enum {
-   RESAMPLER_SINC_FILTER_INTERPOLATED   = 0,
-   RESAMPLER_SINC_FILTER_FULL           = 1,
-   RESAMPLER_SINC_FILTER_AUTO           = 2
-} SpeexResamplerSincFilterMode;
-
-#define RESAMPLER_SINC_FILTER_DEFAULT RESAMPLER_SINC_FILTER_INTERPOLATED
-#define RESAMPLER_SINC_FILTER_AUTO_THRESHOLD_DEFAULT (1 * 1048576)
-
-struct SpeexResamplerState_;
-typedef struct SpeexResamplerState_ SpeexResamplerState;
-
-/** Create a new resampler with integer input and output rates.
- * @param nb_channels Number of channels to be processed
- * @param in_rate Input sampling rate (integer number of Hz).
- * @param out_rate Output sampling rate (integer number of Hz).
- * @param quality Resampling quality between 0 and 10, where 0 has poor quality
- * and 10 has very high quality.
- * @param sinc_filter_mode Sinc filter table mode to use
- * @param sinc_filter_auto_threshold Threshold to use if sinc filter mode is auto, in bytes
- * @return Newly created resampler state
- * @retval NULL Error: not enough memory
- *
- * If a full filter table would be larger than the auto threshold, and sinc_filter_mode is AUTO,
- * the resample uses the interpolated mode instead
- *
- * @note A full sinc table can significantly improve the resampler's performance, but calculating the table
- * takes longer, as opposed to the interpolated variant
- */
-SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, 
-                                          spx_uint32_t in_rate, 
-                                          spx_uint32_t out_rate, 
-                                          int quality,
-                                          SpeexResamplerSincFilterMode sinc_filter_mode,
-                                          spx_uint32_t sinc_filter_auto_threshold,
-                                          int *err);
-
-/** Create a new resampler with fractional input/output rates. The sampling 
- * rate ratio is an arbitrary rational number with both the numerator and 
- * denominator being 32-bit integers.
- * @param nb_channels Number of channels to be processed
- * @param ratio_num Numerator of the sampling rate ratio
- * @param ratio_den Denominator of the sampling rate ratio
- * @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
- * @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
- * @param quality Resampling quality between 0 and 10, where 0 has poor quality
- * and 10 has very high quality.
- * @param sinc_filter_mode Sinc filter table mode to use
- * @param sinc_filter_auto_threshold Threshold to use if sinc filter mode is auto, in bytes
- * @return Newly created resampler state
- * @retval NULL Error: not enough memory
- *
- * If a full filter table would be larger than the auto threshold, and sinc_filter_mode is AUTO,
- * the resample uses the interpolated mode instead
- *
- * @note A full sinc table can significantly improve the resampler's performance, but calculating the table
- * takes longer, as opposed to the interpolated variant
- */
-SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, 
-                                               spx_uint32_t ratio_num, 
-                                               spx_uint32_t ratio_den, 
-                                               spx_uint32_t in_rate, 
-                                               spx_uint32_t out_rate, 
-                                               int quality,
-                                               SpeexResamplerSincFilterMode sinc_filter_mode,
-                                               spx_uint32_t sinc_filter_auto_threshold,
-                                               int *err);
-
-/** Destroy a resampler state.
- * @param st Resampler state
- */
-void speex_resampler_destroy(SpeexResamplerState *st);
-
-/** Resample a float array. The input and output buffers must *not* overlap.
- * @param st Resampler state
- * @param channel_index Index of the channel to process for the multi-channel 
- * base (0 otherwise)
- * @param in Input buffer
- * @param in_len Number of input samples in the input buffer. Returns the 
- * number of samples processed
- * @param out Output buffer
- * @param out_len Size of the output buffer. Returns the number of samples written
- */
-#ifdef DOUBLE_PRECISION
-int speex_resampler_process_float(SpeexResamplerState *st, 
-                                   spx_uint32_t channel_index, 
-                                   const double *in, 
-                                   spx_uint32_t *in_len, 
-                                   double *out, 
-                                   spx_uint32_t *out_len);
-#else
-int speex_resampler_process_float(SpeexResamplerState *st, 
-                                   spx_uint32_t channel_index, 
-                                   const float *in, 
-                                   spx_uint32_t *in_len, 
-                                   float *out, 
-                                   spx_uint32_t *out_len);
-#endif
-
-/** Resample an int array. The input and output buffers must *not* overlap.
- * @param st Resampler state
- * @param channel_index Index of the channel to process for the multi-channel 
- * base (0 otherwise)
- * @param in Input buffer
- * @param in_len Number of input samples in the input buffer. Returns the number
- * of samples processed
- * @param out Output buffer
- * @param out_len Size of the output buffer. Returns the number of samples written
- */
-int speex_resampler_process_int(SpeexResamplerState *st, 
-                                 spx_uint32_t channel_index, 
-                                 const spx_int16_t *in, 
-                                 spx_uint32_t *in_len, 
-                                 spx_int16_t *out, 
-                                 spx_uint32_t *out_len);
-
-/** Resample an interleaved float array. The input and output buffers must *not* overlap.
- * @param st Resampler state
- * @param in Input buffer
- * @param in_len Number of input samples in the input buffer. Returns the number
- * of samples processed. This is all per-channel.
- * @param out Output buffer
- * @param out_len Size of the output buffer. Returns the number of samples written.
- * This is all per-channel.
- */
-#ifdef DOUBLE_PRECISION
-int speex_resampler_process_interleaved_float(SpeexResamplerState *st, 
-                                               const double *in, 
-                                               spx_uint32_t *in_len, 
-                                               double *out, 
-                                               spx_uint32_t *out_len);
-#else
-int speex_resampler_process_interleaved_float(SpeexResamplerState *st, 
-                                               const float *in, 
-                                               spx_uint32_t *in_len, 
-                                               float *out, 
-                                               spx_uint32_t *out_len);
-#endif
-
-/** Resample an interleaved int array. The input and output buffers must *not* overlap.
- * @param st Resampler state
- * @param in Input buffer
- * @param in_len Number of input samples in the input buffer. Returns the number
- * of samples processed. This is all per-channel.
- * @param out Output buffer
- * @param out_len Size of the output buffer. Returns the number of samples written.
- * This is all per-channel.
- */
-int speex_resampler_process_interleaved_int(SpeexResamplerState *st, 
-                                             const spx_int16_t *in, 
-                                             spx_uint32_t *in_len, 
-                                             spx_int16_t *out, 
-                                             spx_uint32_t *out_len);
-
-/** Set (change) the input/output sampling rates (integer value).
- * @param st Resampler state
- * @param in_rate Input sampling rate (integer number of Hz).
- * @param out_rate Output sampling rate (integer number of Hz).
- */
-int speex_resampler_set_rate(SpeexResamplerState *st, 
-                              spx_uint32_t in_rate, 
-                              spx_uint32_t out_rate);
-
-/** Get the current input/output sampling rates (integer value).
- * @param st Resampler state
- * @param in_rate Input sampling rate (integer number of Hz) copied.
- * @param out_rate Output sampling rate (integer number of Hz) copied.
- */
-void speex_resampler_get_rate(SpeexResamplerState *st, 
-                              spx_uint32_t *in_rate, 
-                              spx_uint32_t *out_rate);
-
-/** Set (change) the input/output sampling rates and resampling ratio 
- * (fractional values in Hz supported).
- * @param st Resampler state
- * @param ratio_num Numerator of the sampling rate ratio
- * @param ratio_den Denominator of the sampling rate ratio
- * @param in_rate Input sampling rate rounded to the nearest integer (in Hz).
- * @param out_rate Output sampling rate rounded to the nearest integer (in Hz).
- */
-int speex_resampler_set_rate_frac(SpeexResamplerState *st, 
-                                   spx_uint32_t ratio_num, 
-                                   spx_uint32_t ratio_den, 
-                                   spx_uint32_t in_rate, 
-                                   spx_uint32_t out_rate);
-
-/** Get the current resampling ratio. This will be reduced to the least
- * common denominator.
- * @param st Resampler state
- * @param ratio_num Numerator of the sampling rate ratio copied
- * @param ratio_den Denominator of the sampling rate ratio copied
- */
-void speex_resampler_get_ratio(SpeexResamplerState *st, 
-                               spx_uint32_t *ratio_num, 
-                               spx_uint32_t *ratio_den);
-
-/** Set (change) the conversion quality.
- * @param st Resampler state
- * @param quality Resampling quality between 0 and 10, where 0 has poor 
- * quality and 10 has very high quality.
- */
-int speex_resampler_set_quality(SpeexResamplerState *st, 
-                                 int quality);
-
-/** Get the conversion quality.
- * @param st Resampler state
- * @param quality Resampling quality between 0 and 10, where 0 has poor 
- * quality and 10 has very high quality.
- */
-void speex_resampler_get_quality(SpeexResamplerState *st, 
-                                 int *quality);
-
-/** Set (change) the input stride.
- * @param st Resampler state
- * @param stride Input stride
- */
-void speex_resampler_set_input_stride(SpeexResamplerState *st, 
-                                      spx_uint32_t stride);
-
-/** Get the input stride.
- * @param st Resampler state
- * @param stride Input stride copied
- */
-void speex_resampler_get_input_stride(SpeexResamplerState *st, 
-                                      spx_uint32_t *stride);
-
-/** Set (change) the output stride.
- * @param st Resampler state
- * @param stride Output stride
- */
-void speex_resampler_set_output_stride(SpeexResamplerState *st, 
-                                      spx_uint32_t stride);
-
-/** Get the output stride.
- * @param st Resampler state copied
- * @param stride Output stride
- */
-void speex_resampler_get_output_stride(SpeexResamplerState *st, 
-                                      spx_uint32_t *stride);
-
-/** Get the latency introduced by the resampler measured in input samples.
- * @param st Resampler state
- */
-int speex_resampler_get_input_latency(SpeexResamplerState *st);
-
-/** Get the latency introduced by the resampler measured in output samples.
- * @param st Resampler state
- */
-int speex_resampler_get_output_latency(SpeexResamplerState *st);
-
-/** Get the length of the filter in input samples.
- * @param st Resampler state
- */
-int speex_resampler_get_filt_len(SpeexResamplerState *st);
-
-/** Returns 1 if the full sinc filter table is used, 0 if the interpolated one is used
- * @param st Resampler state
- * @return Sinc filter mode
- */
-int speex_resampler_get_sinc_filter_mode(SpeexResamplerState *st);
-
-/** Make sure that the first samples to go out of the resamplers don't have 
- * leading zeros. This is only useful before starting to use a newly created 
- * resampler. It is recommended to use that when resampling an audio file, as
- * it will generate a file with the same length. For real-time processing,
- * it is probably easier not to use this call (so that the output duration
- * is the same for the first frame).
- * @param st Resampler state
- */
-int speex_resampler_skip_zeros(SpeexResamplerState *st);
-
-/** Reset a resampler so a new (unrelated) stream can be processed.
- * @param st Resampler state
- */
-int speex_resampler_reset_mem(SpeexResamplerState *st);
-
-/** Returns the English meaning for an error code
- * @param err Error code
- * @return English string
- */
-const char *speex_resampler_strerror(int err);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/gst/audioresample/speex_resampler_double.c b/gst/audioresample/speex_resampler_double.c
deleted file mode 100644
index 6c5d63c..0000000
--- a/gst/audioresample/speex_resampler_double.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* GStreamer
- * Copyright (C) 2007-2008 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.
- */
-
-#define _USE_SSE2
-#define FLOATING_POINT
-#define DOUBLE_PRECISION
-#define OUTSIDE_SPEEX
-#define RANDOM_PREFIX resample_double
-
-#include "resample.c"
diff --git a/gst/audioresample/speex_resampler_int.c b/gst/audioresample/speex_resampler_int.c
deleted file mode 100644
index beeb045..0000000
--- a/gst/audioresample/speex_resampler_int.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* GStreamer
- * Copyright (C) 2007-2008 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.
- */
-
-#define FIXED_POINT 1
-#define OUTSIDE_SPEEX 1
-/* disabled, 16-bit integer NEON support seems broken */
-/* #define _USE_NEON */
-#define RANDOM_PREFIX resample_int
-
-#include "resample.c"
diff --git a/gst/audioresample/speex_resampler_wrapper.h b/gst/audioresample/speex_resampler_wrapper.h
deleted file mode 100644
index cd13a88..0000000
--- a/gst/audioresample/speex_resampler_wrapper.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/* GStreamer
- * Copyright (C) 2007-2008 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 __SPEEX_RESAMPLER_WRAPPER_H__
-#define __SPEEX_RESAMPLER_WRAPPER_H__
-
-#define SPEEX_RESAMPLER_QUALITY_MAX 10
-#define SPEEX_RESAMPLER_QUALITY_MIN 0
-#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4
-#define SPEEX_RESAMPLER_QUALITY_VOIP 3
-#define SPEEX_RESAMPLER_QUALITY_DESKTOP 5
-
-#define SPEEX_RESAMPLER_SINC_FILTER_DEFAULT SPEEX_RESAMPLER_SINC_FILTER_AUTO
-#define SPEEX_RESAMPLER_SINC_FILTER_AUTO_THRESHOLD_DEFAULT (1 * 1048576)
-
-enum
-{
-  RESAMPLER_ERR_SUCCESS = 0,
-  RESAMPLER_ERR_ALLOC_FAILED = 1,
-  RESAMPLER_ERR_BAD_STATE = 2,
-  RESAMPLER_ERR_INVALID_ARG = 3,
-  RESAMPLER_ERR_PTR_OVERLAP = 4,
-
-  RESAMPLER_ERR_MAX_ERROR
-};
-
-typedef enum {
-  SPEEX_RESAMPLER_SINC_FILTER_INTERPOLATED   = 0,
-  SPEEX_RESAMPLER_SINC_FILTER_FULL           = 1,
-  SPEEX_RESAMPLER_SINC_FILTER_AUTO           = 2
-} SpeexResamplerSincFilterMode;
-
-typedef struct SpeexResamplerState_ SpeexResamplerState;
-
-typedef struct {
-  SpeexResamplerState *(*init) (guint32 nb_channels,
-    guint32 in_rate, guint32 out_rate, gint quality,
-    SpeexResamplerSincFilterMode sinc_filter_mode,
-    guint32 sinc_filter_auto_threshold, gint * err);
-  void (*destroy) (SpeexResamplerState * st);
-  int (*process) (SpeexResamplerState *
-    st, const guint8 * in, guint32 * in_len, guint8 * out, guint32 * out_len);
-  int (*set_rate) (SpeexResamplerState * st,
-    guint32 in_rate, guint32 out_rate);
-  void (*get_rate) (SpeexResamplerState * st,
-    guint32 * in_rate, guint32 * out_rate);
-  void (*get_ratio) (SpeexResamplerState * st,
-    guint32 * ratio_num, guint32 * ratio_den);
-  int (*get_input_latency) (SpeexResamplerState * st);
-  int (*get_filt_len) (SpeexResamplerState * st);
-  int (*get_sinc_filter_mode) (SpeexResamplerState * st);
-  int (*set_quality) (SpeexResamplerState * st, gint quality);
-  int (*reset_mem) (SpeexResamplerState * st);
-  int (*skip_zeros) (SpeexResamplerState * st);
-  const char * (*strerror) (gint err);
-  unsigned int width;
-} SpeexResampleFuncs;
-
-SpeexResamplerState *resample_float_resampler_init (guint32 nb_channels,
-    guint32 in_rate, guint32 out_rate, gint quality,
-    SpeexResamplerSincFilterMode sinc_filter_mode,
-    guint32 sinc_filter_auto_threshold, gint * err);
-void resample_float_resampler_destroy (SpeexResamplerState * st);
-int resample_float_resampler_process_interleaved_float (SpeexResamplerState *
-    st, const guint8 * in, guint32 * in_len, guint8 * out, guint32 * out_len);
-int resample_float_resampler_set_rate (SpeexResamplerState * st,
-    guint32 in_rate, guint32 out_rate);
-void resample_float_resampler_get_rate (SpeexResamplerState * st,
-    guint32 * in_rate, guint32 * out_rate);
-void resample_float_resampler_get_ratio (SpeexResamplerState * st,
-    guint32 * ratio_num, guint32 * ratio_den);
-int resample_float_resampler_get_input_latency (SpeexResamplerState * st);
-int resample_float_resampler_get_filt_len (SpeexResamplerState * st);
-int resample_float_resampler_get_sinc_filter_mode (SpeexResamplerState * st);
-int resample_float_resampler_set_quality (SpeexResamplerState * st, gint quality);
-int resample_float_resampler_reset_mem (SpeexResamplerState * st);
-int resample_float_resampler_skip_zeros (SpeexResamplerState * st);
-const char * resample_float_resampler_strerror (gint err);
-
-static const SpeexResampleFuncs float_funcs =
-{
-  resample_float_resampler_init,
-  resample_float_resampler_destroy,
-  resample_float_resampler_process_interleaved_float,
-  resample_float_resampler_set_rate,
-  resample_float_resampler_get_rate,
-  resample_float_resampler_get_ratio,
-  resample_float_resampler_get_input_latency,
-  resample_float_resampler_get_filt_len,
-  resample_float_resampler_get_sinc_filter_mode,
-  resample_float_resampler_set_quality,
-  resample_float_resampler_reset_mem,
-  resample_float_resampler_skip_zeros,
-  resample_float_resampler_strerror,
-  32
-};
-
-SpeexResamplerState *resample_double_resampler_init (guint32 nb_channels,
-    guint32 in_rate, guint32 out_rate, gint quality,
-    SpeexResamplerSincFilterMode sinc_filter_mode,
-    guint32 sinc_filter_auto_threshold, gint * err);
-void resample_double_resampler_destroy (SpeexResamplerState * st);
-int resample_double_resampler_process_interleaved_float (SpeexResamplerState *
-    st, const guint8 * in, guint32 * in_len, guint8 * out, guint32 * out_len);
-int resample_double_resampler_set_rate (SpeexResamplerState * st,
-    guint32 in_rate, guint32 out_rate);
-void resample_double_resampler_get_rate (SpeexResamplerState * st,
-    guint32 * in_rate, guint32 * out_rate);
-void resample_double_resampler_get_ratio (SpeexResamplerState * st,
-    guint32 * ratio_num, guint32 * ratio_den);
-int resample_double_resampler_get_input_latency (SpeexResamplerState * st);
-int resample_double_resampler_get_filt_len (SpeexResamplerState * st);
-int resample_double_resampler_get_sinc_filter_mode (SpeexResamplerState * st);
-int resample_double_resampler_set_quality (SpeexResamplerState * st, gint quality);
-int resample_double_resampler_reset_mem (SpeexResamplerState * st);
-int resample_double_resampler_skip_zeros (SpeexResamplerState * st);
-const char * resample_double_resampler_strerror (gint err);
-
-static const SpeexResampleFuncs double_funcs =
-{
-  resample_double_resampler_init,
-  resample_double_resampler_destroy,
-  resample_double_resampler_process_interleaved_float,
-  resample_double_resampler_set_rate,
-  resample_double_resampler_get_rate,
-  resample_double_resampler_get_ratio,
-  resample_double_resampler_get_input_latency,
-  resample_double_resampler_get_filt_len,
-  resample_double_resampler_get_sinc_filter_mode,
-  resample_double_resampler_set_quality,
-  resample_double_resampler_reset_mem,
-  resample_double_resampler_skip_zeros,
-  resample_double_resampler_strerror,
-  64
-};
-
-SpeexResamplerState *resample_int_resampler_init (guint32 nb_channels,
-    guint32 in_rate, guint32 out_rate, gint quality,
-    SpeexResamplerSincFilterMode sinc_filter_mode,
-    guint32 sinc_filter_auto_threshold, gint * err);
-void resample_int_resampler_destroy (SpeexResamplerState * st);
-int resample_int_resampler_process_interleaved_int (SpeexResamplerState *
-    st, const guint8 * in, guint32 * in_len, guint8 * out, guint32 * out_len);
-int resample_int_resampler_set_rate (SpeexResamplerState * st,
-    guint32 in_rate, guint32 out_rate);
-void resample_int_resampler_get_rate (SpeexResamplerState * st,
-    guint32 * in_rate, guint32 * out_rate);
-void resample_int_resampler_get_ratio (SpeexResamplerState * st,
-    guint32 * ratio_num, guint32 * ratio_den);
-int resample_int_resampler_get_input_latency (SpeexResamplerState * st);
-int resample_int_resampler_get_filt_len (SpeexResamplerState * st);
-int resample_int_resampler_get_sinc_filter_mode (SpeexResamplerState * st);
-int resample_int_resampler_set_quality (SpeexResamplerState * st, gint quality);
-int resample_int_resampler_reset_mem (SpeexResamplerState * st);
-int resample_int_resampler_skip_zeros (SpeexResamplerState * st);
-const char * resample_int_resampler_strerror (gint err);
-
-static const SpeexResampleFuncs int_funcs =
-{
-  resample_int_resampler_init,
-  resample_int_resampler_destroy,
-  resample_int_resampler_process_interleaved_int,
-  resample_int_resampler_set_rate,
-  resample_int_resampler_get_rate,
-  resample_int_resampler_get_ratio,
-  resample_int_resampler_get_input_latency,
-  resample_int_resampler_get_filt_len,
-  resample_int_resampler_get_sinc_filter_mode,
-  resample_int_resampler_set_quality,
-  resample_int_resampler_reset_mem,
-  resample_int_resampler_skip_zeros,
-  resample_int_resampler_strerror,
-  16
-};
-
-#endif /* __SPEEX_RESAMPLER_WRAPPER_H__ */
diff --git a/gst/audiotestsrc/Makefile.in b/gst/audiotestsrc/Makefile.in
index 905723f..802291c 100644
--- a/gst/audiotestsrc/Makefile.in
+++ b/gst/audiotestsrc/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -433,6 +434,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -446,6 +450,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -483,6 +490,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst/audiotestsrc/gstaudiotestsrc.c b/gst/audiotestsrc/gstaudiotestsrc.c
index 15cb4a3..d00c1c6 100644
--- a/gst/audiotestsrc/gstaudiotestsrc.c
+++ b/gst/audiotestsrc/gstaudiotestsrc.c
@@ -207,10 +207,10 @@
           "Can activate in pull mode", DEFAULT_CAN_ACTIVATE_PULL,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_audio_test_src_src_template));
-  gst_element_class_set_static_metadata (gstelement_class,
-      "Audio test source", "Source/Audio",
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_audio_test_src_src_template);
+  gst_element_class_set_static_metadata (gstelement_class, "Audio test source",
+      "Source/Audio",
       "Creates audio test signals of given frequency and volume",
       "Stefan Kost <ensonic@users.sf.net>");
 
@@ -1123,21 +1123,16 @@
 
   src->next_sample = next_sample;
 
-  if (!src->reverse) {
-    if (GST_CLOCK_TIME_IS_VALID (segment->start)) {
-      segment->time = segment->start;
-    }
-  } else {
-    if (GST_CLOCK_TIME_IS_VALID (segment->stop)) {
-      segment->time = segment->stop;
-    }
-  }
-
-  if (GST_CLOCK_TIME_IS_VALID (segment->stop)) {
+  if (segment->rate > 0 && GST_CLOCK_TIME_IS_VALID (segment->stop)) {
     time = segment->stop;
     src->sample_stop =
         gst_util_uint64_scale_round (time, samplerate, GST_SECOND);
     src->check_seek_stop = TRUE;
+  } else if (segment->rate < 0) {
+    time = segment->start;
+    src->sample_stop =
+        gst_util_uint64_scale_round (time, samplerate, GST_SECOND);
+    src->check_seek_stop = TRUE;
   } else {
     src->check_seek_stop = FALSE;
   }
@@ -1212,7 +1207,7 @@
   }
 
   /* check for eos */
-  if (src->check_seek_stop &&
+  if (src->check_seek_stop && !src->reverse &&
       (src->sample_stop > src->next_sample) &&
       (src->sample_stop < src->next_sample + samples)
       ) {
@@ -1220,6 +1215,13 @@
     src->generate_samples_per_buffer = src->sample_stop - src->next_sample;
     next_sample = src->sample_stop;
     src->eos_reached = TRUE;
+  } else if (src->check_seek_stop && src->reverse &&
+      (src->sample_stop > src->next_sample)
+      ) {
+    /* calculate only partial buffer */
+    src->generate_samples_per_buffer = src->sample_stop - src->next_sample;
+    next_sample = src->sample_stop;
+    src->eos_reached = TRUE;
   } else {
     /* calculate full buffer */
     src->generate_samples_per_buffer = samples;
diff --git a/gst/encoding/Makefile.in b/gst/encoding/Makefile.in
index 6def3e5..9d116d1 100644
--- a/gst/encoding/Makefile.in
+++ b/gst/encoding/Makefile.in
@@ -106,6 +106,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -443,6 +444,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -456,6 +460,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -493,6 +500,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst/encoding/gstencodebin.c b/gst/encoding/gstencodebin.c
index 55dab2f..1f5de54 100644
--- a/gst/encoding/gstencodebin.c
+++ b/gst/encoding/gstencodebin.c
@@ -431,16 +431,15 @@
   klass->request_pad = gst_encode_bin_request_pad_signal;
   klass->request_profile_pad = gst_encode_bin_request_profile_pad_signal;
 
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&muxer_src_template));
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&video_sink_template));
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&audio_sink_template));
-  /* gst_element_class_add_pad_template (gstelement_klass, */
-  /*     gst_static_pad_template_get (&text_sink_template)); */
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&private_sink_template));
+  gst_element_class_add_static_pad_template (gstelement_klass,
+      &muxer_src_template);
+  gst_element_class_add_static_pad_template (gstelement_klass,
+      &video_sink_template);
+  gst_element_class_add_static_pad_template (gstelement_klass,
+      &audio_sink_template);
+  /* gst_element_class_add_static_pad_template (gstelement_klass, &text_sink_template); */
+  gst_element_class_add_static_pad_template (gstelement_klass,
+      &private_sink_template);
 
   gstelement_klass->change_state =
       GST_DEBUG_FUNCPTR (gst_encode_bin_change_state);
diff --git a/gst/encoding/gstsmartencoder.c b/gst/encoding/gstsmartencoder.c
index 69ab7d6..a950edf 100644
--- a/gst/encoding/gstsmartencoder.c
+++ b/gst/encoding/gstsmartencoder.c
@@ -100,10 +100,8 @@
 
   gst_smart_encoder_parent_class = g_type_class_peek_parent (klass);
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_template));
+  gst_element_class_add_static_pad_template (element_class, &src_template);
+  gst_element_class_add_static_pad_template (element_class, &sink_template);
 
   gst_element_class_set_static_metadata (element_class, "Smart Video Encoder",
       "Codec/Recoder/Video",
diff --git a/gst/encoding/gststreamcombiner.c b/gst/encoding/gststreamcombiner.c
index 42c959d..008b08d 100644
--- a/gst/encoding/gststreamcombiner.c
+++ b/gst/encoding/gststreamcombiner.c
@@ -77,10 +77,8 @@
   GST_DEBUG_CATEGORY_INIT (gst_stream_combiner_debug, "streamcombiner", 0,
       "Stream Combiner");
 
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&src_template));
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&sink_template));
+  gst_element_class_add_static_pad_template (gstelement_klass, &src_template);
+  gst_element_class_add_static_pad_template (gstelement_klass, &sink_template);
 
   gstelement_klass->request_new_pad =
       GST_DEBUG_FUNCPTR (gst_stream_combiner_request_new_pad);
diff --git a/gst/encoding/gststreamsplitter.c b/gst/encoding/gststreamsplitter.c
index 6bf3894..f8ad794 100644
--- a/gst/encoding/gststreamsplitter.c
+++ b/gst/encoding/gststreamsplitter.c
@@ -66,10 +66,8 @@
   GST_DEBUG_CATEGORY_INIT (gst_stream_splitter_debug, "streamsplitter", 0,
       "Stream Splitter");
 
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&src_template));
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&sink_template));
+  gst_element_class_add_static_pad_template (gstelement_klass, &src_template);
+  gst_element_class_add_static_pad_template (gstelement_klass, &sink_template);
 
   gstelement_klass->request_new_pad =
       GST_DEBUG_FUNCPTR (gst_stream_splitter_request_new_pad);
@@ -157,8 +155,7 @@
   for (tmp = events; tmp; tmp = tmp->next) {
     if (GST_EVENT_TYPE (tmp->data) != GST_EVENT_EOS &&
         GST_EVENT_TYPE (tmp->data) != GST_EVENT_SEGMENT &&
-        GST_EVENT_IS_STICKY (tmp->data) &&
-        pad != NULL) {
+        GST_EVENT_IS_STICKY (tmp->data) && pad != NULL) {
       gst_pad_store_sticky_event (pad, GST_EVENT_CAST (tmp->data));
     }
     gst_event_unref (tmp->data);
diff --git a/gst/gio/Makefile.in b/gst/gio/Makefile.in
index 6c9d6cb..c7a6f5c 100644
--- a/gst/gio/Makefile.in
+++ b/gst/gio/Makefile.in
@@ -100,6 +100,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -437,6 +438,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -450,6 +454,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -487,6 +494,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst/gio/gstgiobasesink.c b/gst/gio/gstgiobasesink.c
index 3dbec56..caacba5 100644
--- a/gst/gio/gstgiobasesink.c
+++ b/gst/gio/gstgiobasesink.c
@@ -59,8 +59,7 @@
 
   gobject_class->finalize = gst_gio_base_sink_finalize;
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sink_factory));
+  gst_element_class_add_static_pad_template (gstelement_class, &sink_factory);
 
   gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_gio_base_sink_start);
   gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_gio_base_sink_stop);
diff --git a/gst/gio/gstgiobasesrc.c b/gst/gio/gstgiobasesrc.c
index 213ede6..b4fddc1 100644
--- a/gst/gio/gstgiobasesrc.c
+++ b/gst/gio/gstgiobasesrc.c
@@ -64,8 +64,7 @@
 
   gobject_class->finalize = gst_gio_base_src_finalize;
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&src_factory));
+  gst_element_class_add_static_pad_template (gstelement_class, &src_factory);
 
   gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_gio_base_src_start);
   gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_gio_base_src_stop);
diff --git a/gst/playback/Makefile.am b/gst/playback/Makefile.am
index 081b224..9603dab 100644
--- a/gst/playback/Makefile.am
+++ b/gst/playback/Makefile.am
@@ -4,9 +4,13 @@
 
 libgstplayback_la_SOURCES = \
 	gstdecodebin2.c \
+	gstdecodebin3.c \
 	gsturidecodebin.c \
+	gsturisourcebin.c \
+	gstparsebin.c \
 	gstplayback.c \
 	gstplaybin2.c \
+	gstplaybin3.c \
 	gstplaysink.c \
 	gstplay-enum.c \
 	gstsubtitleoverlay.c \
@@ -26,7 +30,10 @@
 	$(GST_LIBS)
 libgstplayback_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
+# FIXME: gstdecodebin3-parse.c isn't really a header,
+# but for now it's included into gstdecodebin3.c directly
 noinst_HEADERS = \
+        gstdecodebin3-parse.c \
 	gstplayback.h \
 	gstplaysink.h \
 	gstplay-enum.h \
diff --git a/gst/playback/Makefile.in b/gst/playback/Makefile.in
index f5bd2a0..92a0657 100644
--- a/gst/playback/Makefile.in
+++ b/gst/playback/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -167,9 +168,13 @@
 	$(top_builddir)/gst-libs/gst/video/libgstvideo-@GST_API_VERSION@.la \
 	$(am__DEPENDENCIES_1)
 am_libgstplayback_la_OBJECTS = libgstplayback_la-gstdecodebin2.lo \
+	libgstplayback_la-gstdecodebin3.lo \
 	libgstplayback_la-gsturidecodebin.lo \
+	libgstplayback_la-gsturisourcebin.lo \
+	libgstplayback_la-gstparsebin.lo \
 	libgstplayback_la-gstplayback.lo \
 	libgstplayback_la-gstplaybin2.lo \
+	libgstplayback_la-gstplaybin3.lo \
 	libgstplayback_la-gstplaysink.lo \
 	libgstplayback_la-gstplay-enum.lo \
 	libgstplayback_la-gstsubtitleoverlay.lo \
@@ -447,6 +452,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -460,6 +468,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -497,6 +508,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -551,9 +563,13 @@
 csp_cflags = -DCOLORSPACE=\"videoconvert\"
 libgstplayback_la_SOURCES = \
 	gstdecodebin2.c \
+	gstdecodebin3.c \
 	gsturidecodebin.c \
+	gsturisourcebin.c \
+	gstparsebin.c \
 	gstplayback.c \
 	gstplaybin2.c \
+	gstplaybin3.c \
 	gstplaysink.c \
 	gstplay-enum.c \
 	gstsubtitleoverlay.c \
@@ -573,7 +589,11 @@
 	$(GST_LIBS)
 
 libgstplayback_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
+
+# FIXME: gstdecodebin3-parse.c isn't really a header,
+# but for now it's included into gstdecodebin3.c directly
 noinst_HEADERS = \
+        gstdecodebin3-parse.c \
 	gstplayback.h \
 	gstplaysink.h \
 	gstplay-enum.h \
@@ -667,10 +687,13 @@
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstplayback_la-gstdecodebin2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstplayback_la-gstdecodebin3.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstplayback_la-gstparsebin.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstplayback_la-gstplay-enum.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstplayback_la-gstplayback.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstplayback_la-gstplaybackutils.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstplayback_la-gstplaybin2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstplayback_la-gstplaybin3.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstplayback_la-gstplaysink.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstplayback_la-gstplaysinkaudioconvert.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstplayback_la-gstplaysinkconvertbin.Plo@am__quote@
@@ -678,6 +701,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstplayback_la-gststreamsynchronizer.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstplayback_la-gstsubtitleoverlay.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstplayback_la-gsturidecodebin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstplayback_la-gsturisourcebin.Plo@am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -710,6 +734,13 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstplayback_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstplayback_la_CFLAGS) $(CFLAGS) -c -o libgstplayback_la-gstdecodebin2.lo `test -f 'gstdecodebin2.c' || echo '$(srcdir)/'`gstdecodebin2.c
 
+libgstplayback_la-gstdecodebin3.lo: gstdecodebin3.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstplayback_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstplayback_la_CFLAGS) $(CFLAGS) -MT libgstplayback_la-gstdecodebin3.lo -MD -MP -MF $(DEPDIR)/libgstplayback_la-gstdecodebin3.Tpo -c -o libgstplayback_la-gstdecodebin3.lo `test -f 'gstdecodebin3.c' || echo '$(srcdir)/'`gstdecodebin3.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstplayback_la-gstdecodebin3.Tpo $(DEPDIR)/libgstplayback_la-gstdecodebin3.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gstdecodebin3.c' object='libgstplayback_la-gstdecodebin3.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 $(libgstplayback_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstplayback_la_CFLAGS) $(CFLAGS) -c -o libgstplayback_la-gstdecodebin3.lo `test -f 'gstdecodebin3.c' || echo '$(srcdir)/'`gstdecodebin3.c
+
 libgstplayback_la-gsturidecodebin.lo: gsturidecodebin.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstplayback_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstplayback_la_CFLAGS) $(CFLAGS) -MT libgstplayback_la-gsturidecodebin.lo -MD -MP -MF $(DEPDIR)/libgstplayback_la-gsturidecodebin.Tpo -c -o libgstplayback_la-gsturidecodebin.lo `test -f 'gsturidecodebin.c' || echo '$(srcdir)/'`gsturidecodebin.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstplayback_la-gsturidecodebin.Tpo $(DEPDIR)/libgstplayback_la-gsturidecodebin.Plo
@@ -717,6 +748,20 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstplayback_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstplayback_la_CFLAGS) $(CFLAGS) -c -o libgstplayback_la-gsturidecodebin.lo `test -f 'gsturidecodebin.c' || echo '$(srcdir)/'`gsturidecodebin.c
 
+libgstplayback_la-gsturisourcebin.lo: gsturisourcebin.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstplayback_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstplayback_la_CFLAGS) $(CFLAGS) -MT libgstplayback_la-gsturisourcebin.lo -MD -MP -MF $(DEPDIR)/libgstplayback_la-gsturisourcebin.Tpo -c -o libgstplayback_la-gsturisourcebin.lo `test -f 'gsturisourcebin.c' || echo '$(srcdir)/'`gsturisourcebin.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstplayback_la-gsturisourcebin.Tpo $(DEPDIR)/libgstplayback_la-gsturisourcebin.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gsturisourcebin.c' object='libgstplayback_la-gsturisourcebin.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 $(libgstplayback_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstplayback_la_CFLAGS) $(CFLAGS) -c -o libgstplayback_la-gsturisourcebin.lo `test -f 'gsturisourcebin.c' || echo '$(srcdir)/'`gsturisourcebin.c
+
+libgstplayback_la-gstparsebin.lo: gstparsebin.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstplayback_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstplayback_la_CFLAGS) $(CFLAGS) -MT libgstplayback_la-gstparsebin.lo -MD -MP -MF $(DEPDIR)/libgstplayback_la-gstparsebin.Tpo -c -o libgstplayback_la-gstparsebin.lo `test -f 'gstparsebin.c' || echo '$(srcdir)/'`gstparsebin.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstplayback_la-gstparsebin.Tpo $(DEPDIR)/libgstplayback_la-gstparsebin.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gstparsebin.c' object='libgstplayback_la-gstparsebin.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 $(libgstplayback_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstplayback_la_CFLAGS) $(CFLAGS) -c -o libgstplayback_la-gstparsebin.lo `test -f 'gstparsebin.c' || echo '$(srcdir)/'`gstparsebin.c
+
 libgstplayback_la-gstplayback.lo: gstplayback.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstplayback_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstplayback_la_CFLAGS) $(CFLAGS) -MT libgstplayback_la-gstplayback.lo -MD -MP -MF $(DEPDIR)/libgstplayback_la-gstplayback.Tpo -c -o libgstplayback_la-gstplayback.lo `test -f 'gstplayback.c' || echo '$(srcdir)/'`gstplayback.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstplayback_la-gstplayback.Tpo $(DEPDIR)/libgstplayback_la-gstplayback.Plo
@@ -731,6 +776,13 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstplayback_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstplayback_la_CFLAGS) $(CFLAGS) -c -o libgstplayback_la-gstplaybin2.lo `test -f 'gstplaybin2.c' || echo '$(srcdir)/'`gstplaybin2.c
 
+libgstplayback_la-gstplaybin3.lo: gstplaybin3.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstplayback_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstplayback_la_CFLAGS) $(CFLAGS) -MT libgstplayback_la-gstplaybin3.lo -MD -MP -MF $(DEPDIR)/libgstplayback_la-gstplaybin3.Tpo -c -o libgstplayback_la-gstplaybin3.lo `test -f 'gstplaybin3.c' || echo '$(srcdir)/'`gstplaybin3.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstplayback_la-gstplaybin3.Tpo $(DEPDIR)/libgstplayback_la-gstplaybin3.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gstplaybin3.c' object='libgstplayback_la-gstplaybin3.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 $(libgstplayback_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstplayback_la_CFLAGS) $(CFLAGS) -c -o libgstplayback_la-gstplaybin3.lo `test -f 'gstplaybin3.c' || echo '$(srcdir)/'`gstplaybin3.c
+
 libgstplayback_la-gstplaysink.lo: gstplaysink.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstplayback_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstplayback_la_CFLAGS) $(CFLAGS) -MT libgstplayback_la-gstplaysink.lo -MD -MP -MF $(DEPDIR)/libgstplayback_la-gstplaysink.Tpo -c -o libgstplayback_la-gstplaysink.lo `test -f 'gstplaysink.c' || echo '$(srcdir)/'`gstplaysink.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstplayback_la-gstplaysink.Tpo $(DEPDIR)/libgstplayback_la-gstplaysink.Plo
diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c
index 7eb89da..d6872ad 100644
--- a/gst/playback/gstdecodebin2.c
+++ b/gst/playback/gstdecodebin2.c
@@ -100,9 +100,7 @@
 #include "gstplay-enum.h"
 #include "gstplayback.h"
 #include "gstrawcaps.h"
-
-/* Also used by gsturidecodebin.c */
-gint _decode_bin_compare_factories_func (gconstpointer p1, gconstpointer p2);
+#include "gstplaybackutils.h"
 
 /* generic templates */
 static GstStaticPadTemplate decoder_bin_sink_template =
@@ -553,6 +551,7 @@
 static void gst_decode_pad_set_blocked (GstDecodePad * dpad, gboolean blocked);
 static gboolean gst_decode_pad_query (GstPad * pad, GstObject * parent,
     GstQuery * query);
+static gboolean gst_decode_pad_is_exposable (GstDecodePad * endpad);
 
 static void gst_pending_pad_free (GstPendingPad * ppad);
 static GstPadProbeReturn pad_event_cb (GstPad * pad, GstPadProbeInfo * info,
@@ -999,10 +998,10 @@
   klass->autoplug_select = GST_DEBUG_FUNCPTR (gst_decode_bin_autoplug_select);
   klass->autoplug_query = GST_DEBUG_FUNCPTR (gst_decode_bin_autoplug_query);
 
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&decoder_bin_sink_template));
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&decoder_bin_src_template));
+  gst_element_class_add_static_pad_template (gstelement_klass,
+      &decoder_bin_sink_template);
+  gst_element_class_add_static_pad_template (gstelement_klass,
+      &decoder_bin_src_template);
 
   gst_element_class_set_static_metadata (gstelement_klass,
       "Decoder Bin", "Generic/Bin/Decoder",
@@ -1022,33 +1021,6 @@
   g_type_class_ref (GST_TYPE_DECODE_PAD);
 }
 
-gint
-_decode_bin_compare_factories_func (gconstpointer p1, gconstpointer p2)
-{
-  GstPluginFeature *f1, *f2;
-  gboolean is_parser1, is_parser2;
-
-  f1 = (GstPluginFeature *) p1;
-  f2 = (GstPluginFeature *) p2;
-
-  is_parser1 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f1),
-      GST_ELEMENT_FACTORY_TYPE_PARSER);
-  is_parser2 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f2),
-      GST_ELEMENT_FACTORY_TYPE_PARSER);
-
-
-  /* We want all parsers first as we always want to plug parsers
-   * before decoders */
-  if (is_parser1 && !is_parser2)
-    return -1;
-  else if (!is_parser1 && is_parser2)
-    return 1;
-
-  /* And if it's a both a parser we first sort by rank
-   * and then by factory name */
-  return gst_plugin_feature_rank_compare_func (p1, p2);
-}
-
 /* Must be called with factories lock! */
 static void
 gst_decode_bin_update_factories_list (GstDecodeBin * dbin)
@@ -1063,7 +1035,8 @@
         gst_element_factory_list_get_elements
         (GST_ELEMENT_FACTORY_TYPE_DECODABLE, GST_RANK_MARGINAL);
     dbin->factories =
-        g_list_sort (dbin->factories, _decode_bin_compare_factories_func);
+        g_list_sort (dbin->factories,
+        gst_playback_utils_compare_factories_func);
     dbin->factories_cookie = cookie;
   }
 }
@@ -1739,12 +1712,10 @@
   if (is_parser_converter) {
     GstCaps *filter_caps;
     gint i;
+    GstElement *capsfilter;
     GstPad *p;
     GstDecodeElement *delem;
 
-    g_assert (chain->elements != NULL);
-    delem = (GstDecodeElement *) chain->elements->data;
-
     filter_caps = gst_caps_new_empty ();
     for (i = 0; i < factories->n_values; i++) {
       GstElementFactory *factory =
@@ -1778,17 +1749,28 @@
     /* Append the parser caps to prevent any not-negotiated errors */
     filter_caps = gst_caps_merge (filter_caps, gst_caps_ref (caps));
 
-    delem->capsfilter = gst_element_factory_make ("capsfilter", NULL);
-    g_object_set (G_OBJECT (delem->capsfilter), "caps", filter_caps, NULL);
+    if (chain->elements) {
+      delem = (GstDecodeElement *) chain->elements->data;
+      capsfilter = delem->capsfilter =
+          gst_element_factory_make ("capsfilter", NULL);
+    } else {
+      delem = g_slice_new0 (GstDecodeElement);
+      capsfilter = delem->element =
+          gst_element_factory_make ("capsfilter", NULL);
+      delem->capsfilter = NULL;
+      chain->elements = g_list_prepend (chain->elements, delem);
+    }
+
+    g_object_set (G_OBJECT (capsfilter), "caps", filter_caps, NULL);
     gst_caps_unref (filter_caps);
-    gst_element_set_state (delem->capsfilter, GST_STATE_PAUSED);
-    gst_bin_add (GST_BIN_CAST (dbin), gst_object_ref (delem->capsfilter));
+    gst_element_set_state (capsfilter, GST_STATE_PAUSED);
+    gst_bin_add (GST_BIN_CAST (dbin), gst_object_ref (capsfilter));
 
     decode_pad_set_target (dpad, NULL);
-    p = gst_element_get_static_pad (delem->capsfilter, "sink");
+    p = gst_element_get_static_pad (capsfilter, "sink");
     gst_pad_link_full (pad, p, GST_PAD_LINK_CHECK_NOTHING);
     gst_object_unref (p);
-    p = gst_element_get_static_pad (delem->capsfilter, "src");
+    p = gst_element_get_static_pad (capsfilter, "src");
     decode_pad_set_target (dpad, p);
     pad = p;
 
@@ -2115,6 +2097,8 @@
     if (!(mqpad = gst_decode_group_control_demuxer_pad (chain->parent, pad)))
       goto beach;
     src = chain->parent->multiqueue;
+    /* Forward sticky events to mq src pad to allow factory initialization */
+    gst_pad_sticky_events_foreach (pad, copy_sticky_events, mqpad);
     pad = mqpad;
     decode_pad_set_target (dpad, pad);
   }
@@ -2132,7 +2116,8 @@
     gboolean subtitle;
     GList *to_connect = NULL;
     GList *to_expose = NULL;
-    gboolean is_parser_converter = FALSE;
+    gboolean is_parser = FALSE;
+    gboolean is_decoder = FALSE;
 
     /* Set dpad target to pad again, it might've been unset
      * below but we came back here because something failed
@@ -2198,10 +2183,10 @@
      * parser is the only one that does not change the data. A
      * valid example for this would be multiple id3demux in a row.
      */
-    is_parser_converter = strstr (gst_element_factory_get_metadata (factory,
+    is_parser = strstr (gst_element_factory_get_metadata (factory,
             GST_ELEMENT_METADATA_KLASS), "Parser") != NULL;
 
-    if (is_parser_converter) {
+    if (is_parser) {
       gboolean skip = FALSE;
       GList *l;
 
@@ -2394,6 +2379,23 @@
         chain->demuxer = TRUE;
     }
 
+    /* If we are configured to use buffering and there is no demuxer in the
+     * chain, we still want a multiqueue, otherwise we will ignore the
+     * use-buffering property. In that case, we will insert a multiqueue after
+     * the parser or decoder - not elsewhere, otherwise we won't have
+     * timestamps.
+     */
+    is_decoder = strstr (gst_element_factory_get_metadata (factory,
+            GST_ELEMENT_METADATA_KLASS), "Decoder") != NULL;
+
+    if (!chain->parent && (is_parser || is_decoder) && dbin->use_buffering) {
+      chain->demuxer = TRUE;
+      if (is_decoder) {
+        GST_WARNING_OBJECT (dbin,
+            "Buffering messages used for decoded and non-parsed data");
+      }
+    }
+
     CHAIN_MUTEX_UNLOCK (chain);
 
     /* Set connection-speed property if needed */
@@ -2797,14 +2799,11 @@
   query = gst_query_new_seeking (GST_FORMAT_BYTES);
   if (!gst_pad_peer_query (pad, query)) {
     GST_DEBUG_OBJECT (dbin, "seeking query failed");
-    gst_query_unref (query);
-    return FALSE;
+    goto done;
   }
 
   gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
 
-  gst_query_unref (query);
-
   /* try harder to query upstream size if we didn't get it the first time */
   if (seekable && stop == -1) {
     GST_DEBUG_OBJECT (dbin, "doing duration query to fix up unset stop");
@@ -2815,10 +2814,13 @@
    * practice even if it technically may be seekable */
   if (seekable && (start != 0 || stop <= start)) {
     GST_DEBUG_OBJECT (dbin, "seekable but unknown start/stop -> disable");
-    return FALSE;
+    seekable = FALSE;
+  } else {
+    GST_DEBUG_OBJECT (dbin, "upstream seekable: %d", seekable);
   }
 
-  GST_DEBUG_OBJECT (dbin, "upstream seekable: %d", seekable);
+done:
+  gst_query_unref (query);
   return seekable;
 }
 
@@ -3922,7 +3924,7 @@
     goto out;
   }
 
-  if (chain->endpad && (chain->endpad->blocked || chain->endpad->exposed)) {
+  if (chain->endpad && gst_decode_pad_is_exposable (chain->endpad)) {
     complete = TRUE;
     goto out;
   }
@@ -4149,8 +4151,32 @@
   gboolean drained = FALSE;
   GstDecodeChain *chain = pad->chain;
   GstDecodeBin *dbin = chain->dbin;
+  GstEvent *tmp;
 
   GST_LOG_OBJECT (dbin, "pad %p", pad);
+
+  /* Send a stream-group-done event in case downstream needs
+   * to unblock before we can drain */
+  tmp = gst_pad_get_sticky_event (GST_PAD (pad), GST_EVENT_STREAM_START, 0);
+  if (tmp) {
+    guint group_id;
+    if (gst_event_parse_group_id (tmp, &group_id)) {
+      GstPad *peer = gst_pad_get_peer (GST_PAD (pad));
+
+      if (peer) {
+        GST_DEBUG_OBJECT (dbin,
+            "Sending stream-group-done for group %u to pad %"
+            GST_PTR_FORMAT, group_id, pad);
+        gst_pad_send_event (peer, gst_event_new_stream_group_done (group_id));
+        gst_object_unref (peer);
+      }
+    } else {
+      GST_DEBUG_OBJECT (dbin,
+          "No group ID to send stream-group-done on pad %" GST_PTR_FORMAT, pad);
+    }
+    gst_event_unref (tmp);
+  }
+
   EXPOSE_LOCK (dbin);
   if (dbin->decode_chain) {
     drain_and_switch_chains (dbin->decode_chain, pad, &last_group, &drained,
@@ -4728,7 +4754,7 @@
   }
 
   if (chain->endpad) {
-    if (!chain->endpad->blocked && !chain->endpad->exposed)
+    if (!gst_decode_pad_is_exposable (chain->endpad) && !chain->endpad->exposed)
       return FALSE;
     *endpads = g_list_prepend (*endpads, gst_object_ref (chain->endpad));
     return TRUE;
@@ -5034,6 +5060,15 @@
   return ret;
 }
 
+static gboolean
+gst_decode_pad_is_exposable (GstDecodePad * endpad)
+{
+  if (endpad->blocked || endpad->exposed)
+    return TRUE;
+
+  return gst_pad_has_current_caps (GST_PAD_CAST (endpad));
+}
+
 /*gst_decode_pad_new:
  *
  * Creates a new GstDecodePad for the given pad.
diff --git a/gst/playback/gstdecodebin3-parse.c b/gst/playback/gstdecodebin3-parse.c
new file mode 100644
index 0000000..a54cf82
--- /dev/null
+++ b/gst/playback/gstdecodebin3-parse.c
@@ -0,0 +1,556 @@
+/* GStreamer
+ *
+ * Copyright (C) <2015> Centricular Ltd
+ *  @author: Edward Hervey <edward@centricular.com>
+ *  @author: Jan Schmidt <jan@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.
+ */
+
+#if 0
+/* Not needed for now - we're including gstdecodebin3-parse.c into gstdecodebin3.c */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gprintf.h>
+#include <gst/gst.h>
+#include <gst/pbutils/pbutils.h>
+
+#include "gstplayback.h"
+#endif
+
+/* Streams that come from demuxers (input/upstream) */
+/* FIXME : All this is hardcoded. Switch to tree of chains */
+struct _DecodebinInputStream
+{
+  GstDecodebin3 *dbin;
+  GstStream *pending_stream;    /* Extra ref */
+  GstStream *active_stream;
+
+  DecodebinInput *input;
+
+  GstPad *srcpad;               /* From demuxer */
+
+  /* id of the pad event probe */
+  gulong output_event_probe_id;
+
+  /* id of the buffer blocking probe on the input (demuxer src) pad */
+  gulong input_buffer_probe_id;
+
+  /* Whether we saw an EOS on input. This should be treated accordingly
+   * when the stream is no longer used */
+  gboolean saw_eos;
+  /* TRUE if the EOS being pushed is only for draining and does not represent
+   * the full media EOS */
+  gboolean drain_eos;
+};
+
+static void parsebin_pad_added_cb (GstElement * demux, GstPad * pad,
+    DecodebinInput * input);
+static void parsebin_pad_removed_cb (GstElement * demux, GstPad * pad,
+    DecodebinInput * input);
+
+static gboolean
+pending_pads_are_eos (DecodebinInput * input)
+{
+  GList *tmp;
+
+  for (tmp = input->pending_pads; tmp; tmp = tmp->next) {
+    PendingPad *ppad = (PendingPad *) tmp->data;
+    if (ppad->saw_eos == FALSE)
+      return FALSE;
+  }
+
+  return TRUE;
+}
+
+static gboolean
+all_inputs_are_eos (GstDecodebin3 * dbin)
+{
+  GList *tmp;
+  /* First check input streams */
+  for (tmp = dbin->input_streams; tmp; tmp = tmp->next) {
+    DecodebinInputStream *input = (DecodebinInputStream *) tmp->data;
+    if (input->saw_eos == FALSE)
+      return FALSE;
+  }
+
+  /* Check pending pads */
+  if (!pending_pads_are_eos (dbin->main_input))
+    return FALSE;
+  for (tmp = dbin->other_inputs; tmp; tmp = tmp->next)
+    if (!pending_pads_are_eos ((DecodebinInput *) tmp->data))
+      return FALSE;
+
+  GST_DEBUG_OBJECT (dbin, "All streams are EOS");
+  return TRUE;
+}
+
+static void
+check_all_streams_for_eos (GstDecodebin3 * dbin)
+{
+  GList *tmp;
+
+  if (!all_inputs_are_eos (dbin))
+    return;
+
+  /* We know all streams are EOS, properly clean up everything */
+  for (tmp = dbin->input_streams; tmp; tmp = tmp->next) {
+    DecodebinInputStream *input = (DecodebinInputStream *) tmp->data;
+    GstPad *peer = gst_pad_get_peer (input->srcpad);
+
+    /* Send EOS and then remove elements */
+    if (peer) {
+      gst_pad_send_event (peer, gst_event_new_eos ());
+      gst_object_unref (peer);
+    }
+    GST_FIXME_OBJECT (input->srcpad, "Remove input stream");
+  }
+}
+
+/* Get the intersection of parser caps and available (sorted) decoders */
+static GstCaps *
+get_parser_caps_filter (GstDecodebin3 * dbin, GstCaps * caps)
+{
+  GList *tmp;
+  GstCaps *filter_caps = gst_caps_new_empty ();
+
+  g_mutex_lock (&dbin->factories_lock);
+  gst_decode_bin_update_factories_list (dbin);
+  for (tmp = dbin->decoder_factories; tmp; tmp = tmp->next) {
+    GstElementFactory *factory = (GstElementFactory *) tmp->data;
+    GstCaps *tcaps, *intersection;
+    const GList *tmps;
+
+    GST_LOG ("Trying factory %s",
+        gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
+    for (tmps = gst_element_factory_get_static_pad_templates (factory); tmps;
+        tmps = tmps->next) {
+      GstStaticPadTemplate *st = (GstStaticPadTemplate *) tmps->data;
+      if (st->direction != GST_PAD_SINK || st->presence != GST_PAD_ALWAYS)
+        continue;
+      tcaps = gst_static_pad_template_get_caps (st);
+      intersection =
+          gst_caps_intersect_full (tcaps, caps, GST_CAPS_INTERSECT_FIRST);
+      filter_caps = gst_caps_merge (filter_caps, intersection);
+      gst_caps_unref (tcaps);
+    }
+  }
+  g_mutex_unlock (&dbin->factories_lock);
+  GST_DEBUG_OBJECT (dbin, "Got filter caps %" GST_PTR_FORMAT, filter_caps);
+  return filter_caps;
+}
+
+static gboolean
+check_parser_caps_filter (GstDecodebin3 * dbin, GstCaps * caps)
+{
+  GList *tmp;
+  gboolean res = FALSE;
+
+  g_mutex_lock (&dbin->factories_lock);
+  gst_decode_bin_update_factories_list (dbin);
+  for (tmp = dbin->decoder_factories; tmp; tmp = tmp->next) {
+    GstElementFactory *factory = (GstElementFactory *) tmp->data;
+    GstCaps *tcaps;
+    const GList *tmps;
+
+    GST_LOG ("Trying factory %s",
+        gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
+    for (tmps = gst_element_factory_get_static_pad_templates (factory); tmps;
+        tmps = tmps->next) {
+      GstStaticPadTemplate *st = (GstStaticPadTemplate *) tmps->data;
+      if (st->direction != GST_PAD_SINK || st->presence != GST_PAD_ALWAYS)
+        continue;
+      tcaps = gst_static_pad_template_get_caps (st);
+      if (gst_caps_can_intersect (tcaps, caps)) {
+        res = TRUE;
+        gst_caps_unref (tcaps);
+        goto beach;
+      }
+      gst_caps_unref (tcaps);
+    }
+  }
+beach:
+  g_mutex_unlock (&dbin->factories_lock);
+  GST_DEBUG_OBJECT (dbin, "Can intersect : %d", res);
+  return res;
+}
+
+/* Probe on the output of a parser chain (the last
+ * src pad) */
+static GstPadProbeReturn
+parse_chain_output_probe (GstPad * pad, GstPadProbeInfo * info,
+    DecodebinInputStream * input)
+{
+  GstPadProbeReturn ret = GST_PAD_PROBE_OK;
+
+  if (GST_IS_EVENT (GST_PAD_PROBE_INFO_DATA (info))) {
+    GstEvent *ev = GST_PAD_PROBE_INFO_EVENT (info);
+
+    GST_DEBUG_OBJECT (pad, "Got event %s", GST_EVENT_TYPE_NAME (ev));
+    switch (GST_EVENT_TYPE (ev)) {
+      case GST_EVENT_STREAM_START:
+      {
+        GstStream *stream = NULL;
+        guint group_id = G_MAXUINT32;
+        gst_event_parse_group_id (ev, &group_id);
+        GST_DEBUG_OBJECT (pad, "Got stream-start, group_id:%d, input %p",
+            group_id, input->input);
+        if (set_input_group_id (input->input, &group_id)) {
+          ev = gst_event_make_writable (ev);
+          gst_event_set_group_id (ev, group_id);
+          GST_PAD_PROBE_INFO_DATA (info) = ev;
+        }
+        input->saw_eos = FALSE;
+
+        gst_event_parse_stream (ev, &stream);
+        /* FIXME : Would we ever end up with a stream already set on the input ?? */
+        if (stream) {
+          if (input->active_stream != stream) {
+            MultiQueueSlot *slot;
+            if (input->active_stream)
+              gst_object_unref (input->active_stream);
+            input->active_stream = stream;
+            /* We have the beginning of a stream, get a multiqueue slot and link to it */
+            slot = get_slot_for_input (input->dbin, input);
+            link_input_to_slot (input, slot);
+          } else
+            gst_object_unref (stream);
+        }
+      }
+        break;
+      case GST_EVENT_CAPS:
+      {
+        GstCaps *caps = NULL;
+        gst_event_parse_caps (ev, &caps);
+        GST_DEBUG_OBJECT (pad, "caps %" GST_PTR_FORMAT, caps);
+        if (caps && input->active_stream)
+          gst_stream_set_caps (input->active_stream, caps);
+      }
+        break;
+      case GST_EVENT_EOS:
+        /* FIXME : Make sure this makes sense ... */
+        if (TRUE) {
+          GST_DEBUG_OBJECT (pad, "real input pad, marking as EOS");
+          input->saw_eos = TRUE;
+          check_all_streams_for_eos (input->dbin);
+          ret = GST_PAD_PROBE_DROP;
+        } else {
+          MultiQueueSlot *slot = get_slot_for_input (input->dbin, input);
+
+          slot->drain_eos = input->drain_eos;
+
+          if (input->drain_eos) {
+            GST_DEBUG_OBJECT (pad,
+                "Got EOS at end of input stream (drain_eos:%d) Dropping.",
+                input->drain_eos);
+            ret = GST_PAD_PROBE_DROP;
+          } else {
+            GST_DEBUG_OBJECT (pad,
+                "Got EOS at end of input stream (drain_eos:%d) Passing.",
+                input->drain_eos);
+          }
+        }
+        break;
+      default:
+        break;
+    }
+  } else if (GST_IS_QUERY (GST_PAD_PROBE_INFO_DATA (info))) {
+    GstQuery *q = GST_PAD_PROBE_INFO_QUERY (info);
+    GST_DEBUG_OBJECT (pad, "Seeing query %s", GST_QUERY_TYPE_NAME (q));
+    /* If we have a parser, we want to reply to the caps query */
+    /* FIXME: Set a flag when the input stream is created for
+     * streams where we shouldn't reply to these queries */
+    if (GST_QUERY_TYPE (q) == GST_QUERY_CAPS
+        && (info->type & GST_PAD_PROBE_TYPE_PULL)) {
+      GstCaps *filter = NULL;
+      GstCaps *allowed;
+      gst_query_parse_caps (q, &filter);
+      allowed = get_parser_caps_filter (input->dbin, filter);
+      GST_DEBUG_OBJECT (pad,
+          "Intercepting caps query, setting %" GST_PTR_FORMAT, allowed);
+      gst_query_set_caps_result (q, allowed);
+      gst_caps_unref (allowed);
+      ret = GST_PAD_PROBE_HANDLED;
+    } else if (GST_QUERY_TYPE (q) == GST_QUERY_ACCEPT_CAPS) {
+      GstCaps *prop = NULL;
+      gst_query_parse_accept_caps (q, &prop);
+      /* Fast check against target caps */
+      if (gst_caps_can_intersect (prop, input->dbin->caps))
+        gst_query_set_accept_caps_result (q, TRUE);
+      else {
+        gboolean accepted = check_parser_caps_filter (input->dbin, prop);
+        /* check against caps filter */
+        gst_query_set_accept_caps_result (q, accepted);
+        GST_DEBUG_OBJECT (pad, "ACCEPT_CAPS query, returning %d", accepted);
+      }
+      ret = GST_PAD_PROBE_HANDLED;
+    }
+  }
+
+  return ret;
+}
+
+static DecodebinInputStream *
+create_input_stream (GstDecodebin3 * dbin, GstStream * stream, GstPad * pad,
+    DecodebinInput * input)
+{
+  DecodebinInputStream *res = g_new0 (DecodebinInputStream, 1);
+
+  GST_DEBUG_OBJECT (pad, "Creating input stream for stream %p %s (input:%p)",
+      stream, gst_stream_get_stream_id (stream), input);
+
+  res->dbin = dbin;
+  res->input = input;
+  res->pending_stream = gst_object_ref (stream);
+  res->srcpad = pad;
+
+  /* Put probe on output source pad (for detecting EOS/STREAM_START) */
+  res->output_event_probe_id =
+      gst_pad_add_probe (pad,
+      GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM,
+      (GstPadProbeCallback) parse_chain_output_probe, res, NULL);
+
+  /* Add to list of current input streams */
+  dbin->input_streams = g_list_append (dbin->input_streams, res);
+  GST_DEBUG_OBJECT (pad, "Done creating input stream");
+
+  return res;
+}
+
+static void
+remove_input_stream (GstDecodebin3 * dbin, DecodebinInputStream * stream)
+{
+  MultiQueueSlot *slot;
+
+  GST_DEBUG_OBJECT (dbin, "Removing input stream %p (%s)", stream,
+      stream->active_stream ? gst_stream_get_stream_id (stream->active_stream) :
+      "<NONE>");
+
+  /* Unlink from slot */
+  if (stream->srcpad) {
+    GstPad *peer;
+    peer = gst_pad_get_peer (stream->srcpad);
+    if (peer) {
+      gst_pad_unlink (stream->srcpad, peer);
+      gst_object_unref (peer);
+    }
+  }
+
+  slot = get_slot_for_input (dbin, stream);
+  if (slot) {
+    slot->pending_stream = NULL;
+    slot->input = NULL;
+    GST_DEBUG_OBJECT (dbin, "slot %p cleared", slot);
+  }
+
+  if (stream->active_stream)
+    gst_object_unref (stream->active_stream);
+  if (stream->pending_stream)
+    gst_object_unref (stream->pending_stream);
+
+  dbin->input_streams = g_list_remove (dbin->input_streams, stream);
+
+  g_free (stream);
+}
+
+
+/* FIXME : HACK, REMOVE, USE INPUT CHAINS */
+static GstPadProbeReturn
+parsebin_buffer_probe (GstPad * pad, GstPadProbeInfo * info,
+    DecodebinInput * input)
+{
+  GstDecodebin3 *dbin = input->dbin;
+  GList *tmp;
+
+  GST_FIXME_OBJECT (dbin, "Need a lock !");
+
+  GST_DEBUG_OBJECT (pad, "Got a buffer ! UNBLOCK !");
+
+  /* Any data out the demuxer means it's not creating pads
+   * any more right now */
+
+  /* 1. Re-use existing streams if/when possible */
+  GST_FIXME_OBJECT (dbin, "Re-use existing input streams if/when possible");
+
+  /* 2. Remove unused streams (push EOS) */
+  GST_DEBUG_OBJECT (dbin, "Removing unused streams");
+  tmp = dbin->input_streams;
+  while (tmp != NULL) {
+    DecodebinInputStream *input_stream = (DecodebinInputStream *) tmp->data;
+    GList *next = tmp->next;
+
+    GST_DEBUG_OBJECT (dbin, "Checking input stream %p", input_stream);
+    if (input_stream->input_buffer_probe_id) {
+      GST_DEBUG_OBJECT (dbin,
+          "Removing pad block on input %p pad %" GST_PTR_FORMAT, input_stream,
+          input_stream->srcpad);
+      gst_pad_remove_probe (input_stream->srcpad,
+          input_stream->input_buffer_probe_id);
+    }
+    input_stream->input_buffer_probe_id = 0;
+
+    if (input_stream->saw_eos) {
+      remove_input_stream (dbin, input_stream);
+      tmp = dbin->input_streams;
+    } else
+      tmp = next;
+  }
+
+  GST_DEBUG_OBJECT (dbin, "Creating new streams (if needed)");
+  /* 3. Create new streams */
+  for (tmp = input->pending_pads; tmp; tmp = tmp->next) {
+    GstStream *stream;
+    PendingPad *ppad = (PendingPad *) tmp->data;
+
+    stream = gst_pad_get_stream (ppad->pad);
+    if (stream == NULL) {
+      GST_ERROR_OBJECT (dbin, "No stream for pad ????");
+    } else {
+      MultiQueueSlot *slot;
+      DecodebinInputStream *input_stream;
+      /* The remaining pads in pending_pads are the ones that require a new
+       * input stream */
+      input_stream = create_input_stream (dbin, stream, ppad->pad, ppad->input);
+      /* See if we can link it straight away */
+      input_stream->active_stream = stream;
+      slot = get_slot_for_input (dbin, input_stream);
+      link_input_to_slot (input_stream, slot);
+      /* Remove the buffer and event probe */
+      gst_pad_remove_probe (ppad->pad, ppad->buffer_probe);
+      gst_pad_remove_probe (ppad->pad, ppad->event_probe);
+      g_free (ppad);
+    }
+  }
+
+  g_list_free (input->pending_pads);
+  input->pending_pads = NULL;
+
+  /* Weed out unused multiqueue slots */
+  for (tmp = dbin->slots; tmp; tmp = tmp->next) {
+    MultiQueueSlot *slot = (MultiQueueSlot *) tmp->data;
+    GST_LOG_OBJECT (dbin, "Slot %d input:%p drain_eos:%d",
+        slot->id, slot->input, slot->drain_eos);
+    if (slot->input == NULL) {
+      GST_DEBUG_OBJECT (slot->sink_pad, "Sending EOS to unused slot");
+      gst_pad_send_event (slot->sink_pad, gst_event_new_eos ());
+    }
+  }
+
+  return GST_PAD_PROBE_OK;
+}
+
+static GstPadProbeReturn
+parsebin_pending_event_probe (GstPad * pad, GstPadProbeInfo * info,
+    PendingPad * ppad)
+{
+  GstDecodebin3 *dbin = ppad->dbin;
+  /* We drop all events by default */
+  GstPadProbeReturn ret = GST_PAD_PROBE_DROP;
+  GstEvent *ev = GST_PAD_PROBE_INFO_EVENT (info);
+
+  GST_DEBUG_OBJECT (pad, "Got event %p %s", ev, GST_EVENT_TYPE_NAME (ev));
+  switch (GST_EVENT_TYPE (ev)) {
+    case GST_EVENT_EOS:
+    {
+      GST_DEBUG_OBJECT (pad, "Pending pad marked as EOS, removing");
+      ppad->input->pending_pads =
+          g_list_remove (ppad->input->pending_pads, ppad);
+      gst_pad_remove_probe (ppad->pad, ppad->buffer_probe);
+      gst_pad_remove_probe (ppad->pad, ppad->event_probe);
+      g_free (ppad);
+
+      check_all_streams_for_eos (dbin);
+    }
+      break;
+    default:
+      break;
+  }
+
+  return ret;
+}
+
+static void
+parsebin_pad_added_cb (GstElement * demux, GstPad * pad, DecodebinInput * input)
+{
+  GstDecodebin3 *dbin = input->dbin;
+  PendingPad *ppad;
+  GList *tmp;
+
+  GST_DEBUG_OBJECT (dbin, "New pad %s:%s (input:%p)", GST_DEBUG_PAD_NAME (pad),
+      input);
+
+  ppad = g_new0 (PendingPad, 1);
+  ppad->dbin = dbin;
+  ppad->input = input;
+  ppad->pad = pad;
+
+  ppad->event_probe =
+      gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
+      (GstPadProbeCallback) parsebin_pending_event_probe, ppad, NULL);
+  ppad->buffer_probe =
+      gst_pad_add_probe (pad,
+      GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
+      (GstPadProbeCallback) parsebin_buffer_probe, input, NULL);
+
+  input->pending_pads = g_list_append (input->pending_pads, ppad);
+
+  /* FIXME : ONLY DO FOR THIS PARSEBIN/INPUT ! */
+  /* Check if all existing input streams have a buffer probe set */
+  for (tmp = dbin->input_streams; tmp; tmp = tmp->next) {
+    DecodebinInputStream *input_stream = (DecodebinInputStream *) tmp->data;
+    if (input_stream->input_buffer_probe_id == 0) {
+      GST_DEBUG_OBJECT (input_stream->srcpad, "Adding blocking buffer probe");
+      input_stream->input_buffer_probe_id =
+          gst_pad_add_probe (input_stream->srcpad,
+          GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER,
+          (GstPadProbeCallback) parsebin_buffer_probe, input_stream->input,
+          NULL);
+    }
+  }
+}
+
+static void
+parsebin_pad_removed_cb (GstElement * demux, GstPad * pad, DecodebinInput * inp)
+{
+  GstDecodebin3 *dbin = inp->dbin;
+  DecodebinInputStream *input = NULL;
+  GList *tmp;
+  GST_DEBUG_OBJECT (pad, "removed");
+
+  for (tmp = dbin->input_streams; tmp; tmp = tmp->next) {
+    DecodebinInputStream *cand = (DecodebinInputStream *) tmp->data;
+    if (cand->srcpad == pad)
+      input = cand;
+  }
+  /* If there are no pending pads, this means we will definitely not need this
+   * stream anymore */
+  if (input) {
+    GST_DEBUG_OBJECT (pad, "stream %p", input);
+    if (inp->pending_pads == NULL) {
+      GST_DEBUG_OBJECT (pad, "Remove input stream %p", input);
+      remove_input_stream (dbin, input);
+    } else {
+      input->srcpad = NULL;
+      if (input->input_buffer_probe_id)
+        gst_pad_remove_probe (pad, input->input_buffer_probe_id);
+      input->input_buffer_probe_id = 0;
+    }
+  }
+}
diff --git a/gst/playback/gstdecodebin3.c b/gst/playback/gstdecodebin3.c
new file mode 100644
index 0000000..6e45acf
--- /dev/null
+++ b/gst/playback/gstdecodebin3.c
@@ -0,0 +1,2514 @@
+/* GStreamer
+ *
+ * Copyright (C) <2015> Centricular Ltd
+ *  @author: Edward Hervey <edward@centricular.com>
+ *  @author: Jan Schmidt <jan@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 <glib.h>
+#include <glib-object.h>
+#include <glib/gprintf.h>
+#include <gst/gst.h>
+#include <gst/pbutils/pbutils.h>
+
+#include "gstplayback.h"
+#include "gstplay-enum.h"
+#include "gstrawcaps.h"
+
+/**
+ * SECTION:element-decodebin3
+ *
+ * #GstBin that auto-magically constructs a decoding pipeline using available
+ * decoders and demuxers via auto-plugging. The output is raw audio, video
+ * or subtitle streams.
+ *
+ * decodebin3 differs from the previous decodebin (decodebin2) in important ways:
+ *
+ * <itemizedlist>
+ * <listitem>
+ * supports publication and selection of stream information via
+ * GstStreamCollection messages and #GST_EVENT_SELECT_STREAM events.
+ * </listitem>
+ * <listitem>
+ * dynamically switches stream connections internally, and
+ * reuses decoder elements when stream selections change, so that in
+ * the normal case it maintains 1 decoder of each type (video/audio/subtitle)
+ * and only creates new elements when streams change and an existing decoder
+ * is not capable of handling the new format.
+ * </listitem>
+ * <listitem>
+ * supports multiple input pads for the parallel decoding of auxilliary streams
+ * not muxed with the primary stream.
+ * </listitem>
+ * <listitem>
+ * does not handle network stream buffering. decodebin3 expects that network stream
+ * buffering is handled upstream, before data is passed to it.
+ * </listitem>
+ * </itemizedlist>
+ *
+ * <emphasis>decodebin3 is still experimental API and a technology preview.
+ * Its behaviour and exposed API is subject to change.</emphasis>
+ *
+ */
+
+/**
+ * Global design
+ *
+ * 1) From sink pad to elementary streams (GstParseBin)
+ * 
+ * The input sink pads are fed to GstParseBin. GstParseBin will feed them
+ * through typefind. When the caps are detected (or changed) we recursively
+ * figure out which demuxer, parser or depayloader is needed until we get to
+ * elementary streams.
+ *
+ * All elementary streams (whether decoded or not, whether exposed or not) are
+ * fed through multiqueue. There is only *one* multiqueue in decodebin3.
+ *
+ * => MultiQueue is the cornerstone.
+ * => No buffering before multiqueue
+ *
+ * 2) Elementary streams
+ *
+ * After GstParseBin, there are 3 main components:
+ *  1) Input Streams (provided by GstParseBin)
+ *  2) Multiqueue slots
+ *  3) Output Streams
+ *
+ * Input Streams correspond to the stream coming from GstParseBin and that gets
+ * fed into a multiqueue slot.
+ *
+ * Output Streams correspond to the combination of a (optional) decoder and an
+ * output ghostpad. Output Streams can be moved from one multiqueue slot to
+ * another, can reconfigure itself (different decoders), and can be
+ * added/removed depending on the configuration (all streams outputted, only one
+ * of each type, ...).
+ *
+ * Multiqueue slots correspond to a pair of sink/src pad from multiqueue. For
+ * each 'active' Input Stream there is a corresponding slot.
+ * Slots might have different streams on input and output (due to internal
+ * buffering).
+ *
+ * Due to internal queuing/buffering/..., all those components (might) behave
+ * asynchronously. Therefore probes will be used on each component source pad to
+ * detect various key-points:
+ *  * EOS :
+ *     the stream is done => Mark that component as done, optionally freeing/removing it
+ *  * STREAM_START :
+ *     a new stream is starting => link it further if needed
+ *
+ *
+ * 3) Gradual replacement
+ *
+ * If the caps change at any point in decodebin (input sink pad, demuxer output,
+ * multiqueue output, ..), we gradually replace (if needed) the following elements.
+ *
+ * This is handled by the probes in various locations:
+ *  a) typefind output
+ *  b) multiqueue input (source pad of Input Streams)
+ *  c) multiqueue output (source pad of Multiqueue Slots)
+ *  d) final output (target of source ghostpads)
+ *
+ * When CAPS event arrive at those points, one of three things can happen:
+ * a) There is no elements downstream yet, just create/link-to following elements
+ * b) There are downstream elements, do a ACCEPT_CAPS query
+ *  b.1) The new CAPS are accepted, keep current configuration
+ *  b.2) The new CAPS are not accepted, remove following elements then do a)
+ *
+ *
+ *
+ *    Components:
+ *
+ *                                                   MultiQ     Output
+ *                     Input(s)                      Slots      Streams
+ *  /-------------------------------------------\   /-----\  /------------- \
+ *
+ * +-------------------------------------------------------------------------+
+ * |                                                                         |
+ * | +---------------------------------------------+                         |
+ * | |   GstParseBin(s)                            |                         |
+ * | |                +--------------+             |  +-----+                |
+ * | |                |              |---[parser]-[|--| Mul |---[ decoder ]-[|
+ * |]--[ typefind ]---|  demuxer(s)  |------------[|  | ti  |                |
+ * | |                |  (if needed) |---[parser]-[|--| qu  |                |
+ * | |                |              |---[parser]-[|--| eu  |---[ decoder ]-[|
+ * | |                +--------------+             |  +------             ^  |
+ * | +---------------------------------------------+        ^             |  |
+ * |                                               ^        |             |  |
+ * +-----------------------------------------------+--------+-------------+--+
+ *                                                 |        |             |
+ *                                                 |        |             |
+ *                                       Probes  --/--------/-------------/
+ *
+ * ATOMIC SWITCHING
+ *
+ * We want to ensure we re-use decoders when switching streams. This takes place
+ * at the multiqueue output level.
+ *
+ * MAIN CONCEPTS
+ *  1) Activating a stream (i.e. linking a slot to an output) is only done within
+ *    the streaming thread in the multiqueue_src_probe() and only if the
+      stream is in the REQUESTED selection.
+ *  2) Deactivating a stream (i.e. unlinking a slot from an output) is also done
+ *    within the stream thread, but only in a purposefully called IDLE probe
+ *    that calls reassign_slot().
+ *
+ * Based on those two principles, 3 "selection" of streams (stream-id) are used:
+ * 1) requested_selection
+ *    All streams within that list should be activated
+ * 2) active_selection
+ *    List of streams that are exposed by decodebin
+ * 3) to_activate
+ *    List of streams that will be moved to requested_selection in the
+ *    reassign_slot() method (i.e. once a stream was deactivated, and the output
+ *    was retargetted)
+ */
+
+
+GST_DEBUG_CATEGORY_STATIC (decodebin3_debug);
+#define GST_CAT_DEFAULT decodebin3_debug
+
+#define GST_TYPE_DECODEBIN3	 (gst_decodebin3_get_type ())
+
+#define EXTRA_DEBUG 1
+
+typedef struct _GstDecodebin3 GstDecodebin3;
+typedef struct _GstDecodebin3Class GstDecodebin3Class;
+
+typedef struct _DecodebinInputStream DecodebinInputStream;
+typedef struct _DecodebinInput DecodebinInput;
+typedef struct _DecodebinOutputStream DecodebinOutputStream;
+
+struct _GstDecodebin3
+{
+  GstBin bin;
+
+  /* input_lock protects the following variables */
+  GMutex input_lock;
+  /* Main input (static sink pad) */
+  DecodebinInput *main_input;
+  /* Supplementary input (request sink pads) */
+  GList *other_inputs;
+  /* counter for input */
+  guint32 input_counter;
+  /* Current stream group_id (default : G_MAXUINT32) */
+  /* FIXME : Needs to be resetted appropriately (when upstream changes ?) */
+  guint32 current_group_id;
+  /* End of variables protected by input_lock */
+
+  GstElement *multiqueue;
+
+  /* FIXME : Mutex for protecting values below */
+  GstStreamCollection *collection;      /* Active collection */
+
+  GList *input_streams;         /* List of DecodebinInputStream for active collection */
+  GList *output_streams;        /* List of DecodebinOutputStream used for output */
+  GList *slots;                 /* List of MultiQueueSlot */
+  guint slot_id;
+
+  /* selection_lock protects access to following variables */
+  GMutex selection_lock;
+  /* requested selection of stream-id to activate post-multiqueue */
+  GList *requested_selection;
+  /* list of stream-id currently activated in output */
+  GList *active_selection;
+  /* List of stream-id that need to be activated (after a stream switch for ex) */
+  GList *to_activate;
+  /* Pending select streams event */
+  guint32 select_streams_seqnum;
+  /* pending list of streams to select (from downstream) */
+  GList *pending_select_streams;
+  /* TRUE if requested_selection was updated, will become FALSE once
+   * it has fully transitioned to active */
+  gboolean selection_updated;
+  /* End of variables protected by selection_lock */
+
+  /* List of pending collections.
+   * FIXME : Is this really needed ? */
+  GList *pending_collection;
+
+
+  /* Factories */
+  GMutex factories_lock;
+  guint32 factories_cookie;
+  /* All DECODABLE factories */
+  GList *factories;
+  /* Only DECODER factories */
+  GList *decoder_factories;
+  /* DECODABLE but not DECODER factories */
+  GList *decodable_factories;
+
+  /* counters for pads */
+  guint32 apadcount, vpadcount, tpadcount, opadcount;
+
+  /* Properties */
+  GstCaps *caps;
+};
+
+struct _GstDecodebin3Class
+{
+  GstBinClass class;
+
+    gint (*select_stream) (GstDecodebin3 * dbin,
+      GstStreamCollection * collection, GstStream * stream);
+};
+
+/* Input of decodebin, controls input pad and parsebin */
+struct _DecodebinInput
+{
+  GstDecodebin3 *dbin;
+
+  gboolean is_main;
+
+  GstPad *ghost_sink;
+  GstPad *parsebin_sink;
+
+  GstStreamCollection *collection;      /* Active collection */
+
+  guint group_id;
+
+  GstElement *parsebin;
+
+  gulong pad_added_sigid;
+  gulong pad_removed_sigid;
+
+  /* HACK : Remove these fields */
+  /* List of PendingPad structures */
+  GList *pending_pads;
+};
+
+/* Multiqueue Slots */
+typedef struct _MultiQueueSlot
+{
+  guint id;
+
+  GstDecodebin3 *dbin;
+  /* Type of stream handled by this slot */
+  GstStreamType type;
+
+  /* Linked input and output */
+  DecodebinInputStream *input;
+
+  /* pending => last stream received on sink pad */
+  GstStream *pending_stream;
+  /* active => last stream outputted on source pad */
+  GstStream *active_stream;
+
+  GstPad *sink_pad, *src_pad;
+
+  /* id of the MQ src_pad event probe */
+  gulong probe_id;
+
+  gboolean drain_eos;
+
+  DecodebinOutputStream *output;
+} MultiQueueSlot;
+
+/* Streams that are exposed downstream (i.e. output) */
+struct _DecodebinOutputStream
+{
+  GstDecodebin3 *dbin;
+  /* The type of stream handled by this output stream */
+  GstStreamType type;
+
+  /* The slot to which this output stream is currently connected to */
+  MultiQueueSlot *slot;
+
+  GstElement *decoder;          /* Optional */
+  GstPad *decoder_sink, *decoder_src;
+  gboolean linked;
+
+  /* ghostpad */
+  GstPad *src_pad;
+  /* Flag if ghost pad is exposed */
+  gboolean src_exposed;
+
+  /* keyframe dropping probe */
+  gulong drop_probe_id;
+};
+
+/* Pending pads from parsebin */
+typedef struct _PendingPad
+{
+  GstDecodebin3 *dbin;
+  DecodebinInput *input;
+  GstPad *pad;
+
+  gulong buffer_probe;
+  gulong event_probe;
+  gboolean saw_eos;
+} PendingPad;
+
+/* properties */
+#define DEFAULT_CAPS (gst_static_caps_get (&default_raw_caps))
+
+enum
+{
+  PROP_0,
+  PROP_CAPS
+};
+
+/* signals */
+enum
+{
+  SIGNAL_SELECT_STREAM,
+  LAST_SIGNAL
+};
+static guint gst_decodebin3_signals[LAST_SIGNAL] = { 0 };
+
+#define SELECTION_LOCK(dbin) G_STMT_START {				\
+    GST_LOG_OBJECT (dbin,						\
+		    "selection locking from thread %p",			\
+		    g_thread_self ());					\
+    g_mutex_lock (&dbin->selection_lock);				\
+    GST_LOG_OBJECT (dbin,						\
+		    "selection locked from thread %p",			\
+		    g_thread_self ());					\
+  } G_STMT_END
+
+#define SELECTION_UNLOCK(dbin) G_STMT_START {				\
+    GST_LOG_OBJECT (dbin,						\
+		    "selection unlocking from thread %p",		\
+		    g_thread_self ());					\
+    g_mutex_unlock (&dbin->selection_lock);				\
+  } G_STMT_END
+
+#define INPUT_LOCK(dbin) G_STMT_START {				\
+    GST_LOG_OBJECT (dbin,						\
+		    "input locking from thread %p",			\
+		    g_thread_self ());					\
+    g_mutex_lock (&dbin->input_lock);				\
+    GST_LOG_OBJECT (dbin,						\
+		    "input locked from thread %p",			\
+		    g_thread_self ());					\
+  } G_STMT_END
+
+#define INPUT_UNLOCK(dbin) G_STMT_START {				\
+    GST_LOG_OBJECT (dbin,						\
+		    "input unlocking from thread %p",		\
+		    g_thread_self ());					\
+    g_mutex_unlock (&dbin->input_lock);				\
+  } G_STMT_END
+
+GType gst_decodebin3_get_type (void);
+#define gst_decodebin3_parent_class parent_class
+G_DEFINE_TYPE (GstDecodebin3, gst_decodebin3, GST_TYPE_BIN);
+
+static GstStaticCaps default_raw_caps = GST_STATIC_CAPS (DEFAULT_RAW_CAPS);
+
+static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS_ANY);
+
+static GstStaticPadTemplate request_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink_%u",
+    GST_PAD_SINK,
+    GST_PAD_REQUEST,
+    GST_STATIC_CAPS_ANY);
+
+static GstStaticPadTemplate video_src_template =
+GST_STATIC_PAD_TEMPLATE ("video_%u",
+    GST_PAD_SRC,
+    GST_PAD_SOMETIMES,
+    GST_STATIC_CAPS_ANY);
+
+static GstStaticPadTemplate audio_src_template =
+GST_STATIC_PAD_TEMPLATE ("audio_%u",
+    GST_PAD_SRC,
+    GST_PAD_SOMETIMES,
+    GST_STATIC_CAPS_ANY);
+
+static GstStaticPadTemplate text_src_template =
+GST_STATIC_PAD_TEMPLATE ("text_%u",
+    GST_PAD_SRC,
+    GST_PAD_SOMETIMES,
+    GST_STATIC_CAPS_ANY);
+
+static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src_%u",
+    GST_PAD_SRC,
+    GST_PAD_SOMETIMES,
+    GST_STATIC_CAPS_ANY);
+
+
+static void gst_decodebin3_dispose (GObject * object);
+static void gst_decodebin3_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_decodebin3_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+static gboolean parsebin_autoplug_continue_cb (GstElement *
+    parsebin, GstPad * pad, GstCaps * caps, GstDecodebin3 * dbin);
+
+static gint
+gst_decodebin3_select_stream (GstDecodebin3 * dbin,
+    GstStreamCollection * collection, GstStream * stream)
+{
+  GST_LOG_OBJECT (dbin, "default select-stream, returning -1");
+
+  return -1;
+}
+
+static GstPad *gst_decodebin3_request_new_pad (GstElement * element,
+    GstPadTemplate * temp, const gchar * name, const GstCaps * caps);
+static void gst_decodebin3_handle_message (GstBin * bin, GstMessage * message);
+static GstStateChangeReturn gst_decodebin3_change_state (GstElement * element,
+    GstStateChange transition);
+static gboolean gst_decodebin3_send_event (GstElement * element,
+    GstEvent * event);
+
+static void gst_decode_bin_update_factories_list (GstDecodebin3 * dbin);
+#if 0
+static gboolean have_factory (GstDecodebin3 * dbin, GstCaps * caps,
+    GstElementFactoryListType ftype);
+#endif
+
+static void free_input (GstDecodebin3 * dbin, DecodebinInput * input);
+static DecodebinInput *create_new_input (GstDecodebin3 * dbin, gboolean main);
+static gboolean set_input_group_id (DecodebinInput * input, guint32 * group_id);
+
+static void reconfigure_output_stream (DecodebinOutputStream * output,
+    MultiQueueSlot * slot);
+static void free_output_stream (GstDecodebin3 * dbin,
+    DecodebinOutputStream * output);
+static DecodebinOutputStream *create_output_stream (GstDecodebin3 * dbin,
+    GstStreamType type);
+
+static GstPadProbeReturn slot_unassign_probe (GstPad * pad,
+    GstPadProbeInfo * info, MultiQueueSlot * slot);
+static gboolean reassign_slot (GstDecodebin3 * dbin, MultiQueueSlot * slot);
+static MultiQueueSlot *get_slot_for_input (GstDecodebin3 * dbin,
+    DecodebinInputStream * input);
+static void link_input_to_slot (DecodebinInputStream * input,
+    MultiQueueSlot * slot);
+static void free_multiqueue_slot (GstDecodebin3 * dbin, MultiQueueSlot * slot);
+
+/* FIXME: Really make all the parser stuff a self-contained helper object */
+#include "gstdecodebin3-parse.c"
+
+static gboolean
+_gst_int_accumulator (GSignalInvocationHint * ihint,
+    GValue * return_accu, const GValue * handler_return, gpointer dummy)
+{
+  gint res = g_value_get_int (handler_return);
+
+  if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
+    g_value_set_int (return_accu, res);
+
+  if (res == -1)
+    return TRUE;
+
+  return FALSE;
+}
+
+static void
+gst_decodebin3_class_init (GstDecodebin3Class * klass)
+{
+  GObjectClass *gobject_klass = (GObjectClass *) klass;
+  GstElementClass *element_class = (GstElementClass *) klass;
+  GstBinClass *bin_klass = (GstBinClass *) klass;
+
+  gobject_klass->dispose = gst_decodebin3_dispose;
+  gobject_klass->set_property = gst_decodebin3_set_property;
+  gobject_klass->get_property = gst_decodebin3_get_property;
+
+  /* FIXME : ADD PROPERTIES ! */
+  g_object_class_install_property (gobject_klass, PROP_CAPS,
+      g_param_spec_boxed ("caps", "Caps",
+          "The caps on which to stop decoding. (NULL = default)",
+          GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /* FIXME : ADD SIGNALS ! */
+  /**
+   * GstDecodebin3::select-stream
+   * @decodebin: a #GstDecodebin3
+   * @collection: a #GstStreamCollection
+   * @stream: a #GstStream
+   *
+   * This signal is emitted whenever @decodebin needs to decide whether
+   * to expose a @stream of a given @collection.
+   *
+   * Returns: 1 if the stream should be selected, 0 if it shouldn't be selected.
+   * A value of -1 (default) lets @decodebin decide what to do with the stream.
+   * */
+  gst_decodebin3_signals[SIGNAL_SELECT_STREAM] =
+      g_signal_new ("select-stream", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodebin3Class, select_stream),
+      _gst_int_accumulator, NULL, g_cclosure_marshal_generic,
+      G_TYPE_INT, 2, GST_TYPE_STREAM_COLLECTION, GST_TYPE_STREAM);
+
+
+  element_class->request_new_pad =
+      GST_DEBUG_FUNCPTR (gst_decodebin3_request_new_pad);
+  element_class->change_state = GST_DEBUG_FUNCPTR (gst_decodebin3_change_state);
+  element_class->send_event = GST_DEBUG_FUNCPTR (gst_decodebin3_send_event);
+
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&sink_template));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&request_sink_template));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&video_src_template));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&audio_src_template));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&text_src_template));
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&src_template));
+
+  gst_element_class_set_static_metadata (element_class,
+      "Decoder Bin 3", "Generic/Bin/Decoder",
+      "Autoplug and decode to raw media",
+      "Edward Hervey <edward@centricular.com>");
+
+  bin_klass->handle_message = gst_decodebin3_handle_message;
+
+  klass->select_stream = gst_decodebin3_select_stream;
+}
+
+static void
+gst_decodebin3_init (GstDecodebin3 * dbin)
+{
+  /* Create main input */
+  dbin->main_input = create_new_input (dbin, TRUE);
+
+  dbin->multiqueue = gst_element_factory_make ("multiqueue", NULL);
+  g_object_set (dbin->multiqueue, "sync-by-running-time", TRUE,
+      "max-size-buffers", 0, "use-interleave", TRUE, NULL);
+  gst_bin_add ((GstBin *) dbin, dbin->multiqueue);
+
+  dbin->current_group_id = G_MAXUINT32;
+
+  g_mutex_init (&dbin->factories_lock);
+  g_mutex_init (&dbin->selection_lock);
+  g_mutex_init (&dbin->input_lock);
+
+  dbin->caps = gst_static_caps_get (&default_raw_caps);
+}
+
+static void
+gst_decodebin3_dispose (GObject * object)
+{
+  GstDecodebin3 *dbin = (GstDecodebin3 *) object;
+  GList *walk, *next;
+
+  if (dbin->factories)
+    gst_plugin_feature_list_free (dbin->factories);
+  if (dbin->decoder_factories)
+    g_list_free (dbin->decoder_factories);
+  if (dbin->decodable_factories)
+    g_list_free (dbin->decodable_factories);
+  g_list_free (dbin->requested_selection);
+  g_list_free (dbin->active_selection);
+  g_list_free (dbin->to_activate);
+  g_list_free (dbin->pending_select_streams);
+  g_clear_object (&dbin->collection);
+
+  free_input (dbin, dbin->main_input);
+
+  for (walk = dbin->other_inputs; walk; walk = next) {
+    DecodebinInput *input = walk->data;
+
+    next = g_list_next (walk);
+
+    free_input (dbin, input);
+    dbin->other_inputs = g_list_delete_link (dbin->other_inputs, walk);
+  }
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gst_decodebin3_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstDecodebin3 *dbin = (GstDecodebin3 *) object;
+
+  /* FIXME : IMPLEMENT */
+  switch (prop_id) {
+    case PROP_CAPS:
+      GST_OBJECT_LOCK (dbin);
+      if (dbin->caps)
+        gst_caps_unref (dbin->caps);
+      dbin->caps = g_value_dup_boxed (value);
+      GST_OBJECT_UNLOCK (dbin);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_decodebin3_get_property (GObject * object, guint prop_id, GValue * value,
+    GParamSpec * pspec)
+{
+  GstDecodebin3 *dbin = (GstDecodebin3 *) object;
+
+  /* FIXME : IMPLEMENT */
+  switch (prop_id) {
+    case PROP_CAPS:
+      GST_OBJECT_LOCK (dbin);
+      g_value_set_boxed (value, dbin->caps);
+      GST_OBJECT_UNLOCK (dbin);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static gboolean
+parsebin_autoplug_continue_cb (GstElement * parsebin, GstPad * pad,
+    GstCaps * caps, GstDecodebin3 * dbin)
+{
+  GST_DEBUG_OBJECT (pad, "caps %" GST_PTR_FORMAT, caps);
+
+  /* If it matches our target caps, expose it */
+  if (gst_caps_can_intersect (caps, dbin->caps))
+    return FALSE;
+
+  return TRUE;
+}
+
+/* This method should be called whenever a STREAM_START event
+ * comes out of a given parsebin.
+ * The caller shall replace the group_id if the function returns TRUE */
+static gboolean
+set_input_group_id (DecodebinInput * input, guint32 * group_id)
+{
+  GstDecodebin3 *dbin = input->dbin;
+
+  if (input->group_id != *group_id) {
+    if (input->group_id != G_MAXUINT32)
+      GST_WARNING_OBJECT (dbin,
+          "Group id changed (%" G_GUINT32_FORMAT " -> %" G_GUINT32_FORMAT
+          ") on input %p ", input->group_id, *group_id, input);
+    input->group_id = *group_id;
+  }
+
+  if (*group_id != dbin->current_group_id) {
+    if (dbin->current_group_id == G_MAXUINT32) {
+      GST_DEBUG_OBJECT (dbin, "Setting current group id to %" G_GUINT32_FORMAT,
+          *group_id);
+      dbin->current_group_id = *group_id;
+    }
+    *group_id = dbin->current_group_id;
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/* Call with INPUT_LOCK taken */
+static gboolean
+ensure_input_parsebin (GstDecodebin3 * dbin, DecodebinInput * input)
+{
+  gboolean set_state = FALSE;
+
+  if (input->parsebin == NULL) {
+    input->parsebin = gst_element_factory_make ("parsebin", NULL);
+    if (input->parsebin == NULL)
+      goto no_parsebin;
+    input->parsebin = gst_object_ref (input->parsebin);
+    input->parsebin_sink = gst_element_get_static_pad (input->parsebin, "sink");
+    input->pad_added_sigid =
+        g_signal_connect (input->parsebin, "pad-added",
+        (GCallback) parsebin_pad_added_cb, input);
+    input->pad_removed_sigid =
+        g_signal_connect (input->parsebin, "pad-removed",
+        (GCallback) parsebin_pad_removed_cb, input);
+    g_signal_connect (input->parsebin, "autoplug-continue",
+        (GCallback) parsebin_autoplug_continue_cb, dbin);
+  }
+
+  if (GST_OBJECT_PARENT (GST_OBJECT (input->parsebin)) != GST_OBJECT (dbin)) {
+    gst_bin_add (GST_BIN (dbin), input->parsebin);
+    set_state = TRUE;
+  }
+
+  gst_ghost_pad_set_target (GST_GHOST_PAD (input->ghost_sink),
+      input->parsebin_sink);
+  if (set_state)
+    gst_element_sync_state_with_parent (input->parsebin);
+
+  return TRUE;
+
+  /* ERRORS */
+no_parsebin:
+  {
+    gst_element_post_message ((GstElement *) dbin,
+        gst_missing_element_message_new ((GstElement *) dbin, "parsebin"));
+    return FALSE;
+  }
+}
+
+static GstPadLinkReturn
+gst_decodebin3_input_pad_link (GstPad * pad, GstObject * parent, GstPad * peer)
+{
+  GstDecodebin3 *dbin = (GstDecodebin3 *) parent;
+  GstPadLinkReturn res = GST_PAD_LINK_OK;
+  DecodebinInput *input;
+
+  GST_LOG_OBJECT (parent, "Got link on input pad %" GST_PTR_FORMAT
+      ". Creating parsebin if needed", pad);
+
+  if ((input = g_object_get_data (G_OBJECT (pad), "decodebin.input")) == NULL)
+    goto fail;
+
+  INPUT_LOCK (dbin);
+  if (!ensure_input_parsebin (dbin, input))
+    res = GST_PAD_LINK_REFUSED;
+  INPUT_UNLOCK (dbin);
+
+  return res;
+fail:
+  GST_ERROR_OBJECT (parent, "Failed to retrieve input state from ghost pad");
+  return GST_PAD_LINK_REFUSED;
+}
+
+static void
+gst_decodebin3_input_pad_unlink (GstPad * pad, GstObject * parent)
+{
+  GstDecodebin3 *dbin = (GstDecodebin3 *) parent;
+  DecodebinInput *input;
+
+  GST_LOG_OBJECT (parent, "Got unlink on input pad %" GST_PTR_FORMAT
+      ". Removing parsebin.", pad);
+
+  if ((input = g_object_get_data (G_OBJECT (pad), "decodebin.input")) == NULL)
+    goto fail;
+
+  INPUT_LOCK (dbin);
+  if (input->parsebin == NULL) {
+    INPUT_UNLOCK (dbin);
+    return;
+  }
+
+  if (GST_OBJECT_PARENT (GST_OBJECT (input->parsebin)) == GST_OBJECT (dbin)) {
+    gst_bin_remove (GST_BIN (dbin), input->parsebin);
+    gst_element_set_state (input->parsebin, GST_STATE_NULL);
+  }
+  INPUT_UNLOCK (dbin);
+  return;
+
+fail:
+  GST_ERROR_OBJECT (parent, "Failed to retrieve input state from ghost pad");
+  return;
+}
+
+static void
+free_input (GstDecodebin3 * dbin, DecodebinInput * input)
+{
+  GST_DEBUG ("Freeing input %p", input);
+  gst_ghost_pad_set_target (GST_GHOST_PAD (input->ghost_sink), NULL);
+  gst_element_remove_pad (GST_ELEMENT (dbin), input->ghost_sink);
+  if (input->parsebin) {
+    g_signal_handler_disconnect (input->parsebin, input->pad_removed_sigid);
+    g_signal_handler_disconnect (input->parsebin, input->pad_added_sigid);
+    gst_element_set_state (input->parsebin, GST_STATE_NULL);
+    gst_object_unref (input->parsebin);
+    gst_object_unref (input->parsebin_sink);
+  }
+  if (input->collection)
+    gst_object_unref (input->collection);
+  g_free (input);
+}
+
+/* Call with INPUT_LOCK taken */
+static DecodebinInput *
+create_new_input (GstDecodebin3 * dbin, gboolean main)
+{
+  DecodebinInput *input;
+
+  input = g_new0 (DecodebinInput, 1);
+  input->dbin = dbin;
+  input->is_main = main;
+  input->group_id = G_MAXUINT32;
+  if (main)
+    input->ghost_sink = gst_ghost_pad_new_no_target ("sink", GST_PAD_SINK);
+  else {
+    gchar *pad_name = g_strdup_printf ("sink_%u", dbin->input_counter++);
+    input->ghost_sink = gst_ghost_pad_new_no_target (pad_name, GST_PAD_SINK);
+    g_free (pad_name);
+  }
+  g_object_set_data (G_OBJECT (input->ghost_sink), "decodebin.input", input);
+  gst_pad_set_link_function (input->ghost_sink, gst_decodebin3_input_pad_link);
+  gst_pad_set_unlink_function (input->ghost_sink,
+      gst_decodebin3_input_pad_unlink);
+
+  gst_pad_set_active (input->ghost_sink, TRUE);
+  gst_element_add_pad ((GstElement *) dbin, input->ghost_sink);
+
+  return input;
+
+}
+
+static GstPad *
+gst_decodebin3_request_new_pad (GstElement * element, GstPadTemplate * temp,
+    const gchar * name, const GstCaps * caps)
+{
+  GstDecodebin3 *dbin = (GstDecodebin3 *) element;
+  DecodebinInput *input;
+  GstPad *res = NULL;
+
+  /* We are ignoring names for the time being, not sure it makes any sense
+   * within the context of decodebin3 ... */
+  INPUT_LOCK (dbin);
+  input = create_new_input (dbin, FALSE);
+  if (input) {
+    dbin->other_inputs = g_list_append (dbin->other_inputs, input);
+    res = input->ghost_sink;
+  }
+  INPUT_UNLOCK (dbin);
+
+  return res;
+}
+
+/* Must be called with factories lock! */
+static void
+gst_decode_bin_update_factories_list (GstDecodebin3 * dbin)
+{
+  guint cookie;
+
+  cookie = gst_registry_get_feature_list_cookie (gst_registry_get ());
+  if (!dbin->factories || dbin->factories_cookie != cookie) {
+    GList *tmp;
+    if (dbin->factories)
+      gst_plugin_feature_list_free (dbin->factories);
+    if (dbin->decoder_factories)
+      g_list_free (dbin->decoder_factories);
+    if (dbin->decodable_factories)
+      g_list_free (dbin->decodable_factories);
+    dbin->factories =
+        gst_element_factory_list_get_elements
+        (GST_ELEMENT_FACTORY_TYPE_DECODABLE, GST_RANK_MARGINAL);
+    dbin->factories =
+        g_list_sort (dbin->factories, gst_plugin_feature_rank_compare_func);
+    dbin->factories_cookie = cookie;
+
+    /* Filter decoder and other decodables */
+    dbin->decoder_factories = NULL;
+    dbin->decodable_factories = NULL;
+    for (tmp = dbin->factories; tmp; tmp = tmp->next) {
+      GstElementFactory *fact = (GstElementFactory *) tmp->data;
+      if (gst_element_factory_list_is_type (fact,
+              GST_ELEMENT_FACTORY_TYPE_DECODER))
+        dbin->decoder_factories = g_list_append (dbin->decoder_factories, fact);
+      else
+        dbin->decodable_factories =
+            g_list_append (dbin->decodable_factories, fact);
+    }
+  }
+}
+
+/* Must be called with appropriate lock if list is a protected variable */
+static gboolean
+stream_in_list (GList * list, const gchar * sid)
+{
+  GList *tmp;
+
+#if EXTRA_DEBUG
+  for (tmp = list; tmp; tmp = tmp->next) {
+    gchar *osid = (gchar *) tmp->data;
+    GST_DEBUG ("Checking %s against %s", sid, osid);
+  }
+#endif
+
+  for (tmp = list; tmp; tmp = tmp->next) {
+    gchar *osid = (gchar *) tmp->data;
+    if (!g_strcmp0 (sid, osid))
+      return TRUE;
+  }
+
+  return FALSE;
+}
+
+static void
+update_requested_selection (GstDecodebin3 * dbin,
+    GstStreamCollection * collection)
+{
+  guint i, nb;
+  GList *tmp = NULL;
+  GstStreamType used_types = 0;
+
+  nb = gst_stream_collection_get_size (collection);
+
+  /* 1. Is there a pending SELECT_STREAMS we can return straight away since
+   *  the switch handler will take care of the pending selection */
+  SELECTION_LOCK (dbin);
+  if (dbin->pending_select_streams) {
+    GST_DEBUG_OBJECT (dbin,
+        "No need to create pending selection, SELECT_STREAMS underway");
+    goto beach;
+  }
+
+  /* 2. If not, are we in EXPOSE_ALL_MODE ? If so, match everything */
+  GST_FIXME_OBJECT (dbin, "Implement EXPOSE_ALL_MODE");
+
+  /* 3. If not, check if we already have some of the streams in the
+   * existing active/requested selection */
+  for (i = 0; i < nb; i++) {
+    GstStream *stream = gst_stream_collection_get_stream (collection, i);
+    const gchar *sid = gst_stream_get_stream_id (stream);
+    gint request = -1;
+    /* Fire select-stream signal to see if outside components want to
+     * hint at which streams should be selected */
+    g_signal_emit (G_OBJECT (dbin),
+        gst_decodebin3_signals[SIGNAL_SELECT_STREAM], 0, collection, stream,
+        &request);
+    GST_DEBUG_OBJECT (dbin, "stream %s , request:%d", sid, request);
+    if (request == 1 || (request == -1
+            && (stream_in_list (dbin->requested_selection, sid)
+                || stream_in_list (dbin->active_selection, sid)))) {
+      GstStreamType curtype = gst_stream_get_stream_type (stream);
+      if (request == 1)
+        GST_DEBUG_OBJECT (dbin,
+            "Using stream requested by 'select-stream' signal : %s", sid);
+      else
+        GST_DEBUG_OBJECT (dbin,
+            "Re-using stream already present in requested or active selection : %s",
+            sid);
+      tmp = g_list_append (tmp, (gchar *) sid);
+      used_types |= curtype;
+    }
+  }
+
+  /* 4. If not, match one stream of each type */
+  for (i = 0; i < nb; i++) {
+    GstStream *stream = gst_stream_collection_get_stream (collection, i);
+    GstStreamType curtype = gst_stream_get_stream_type (stream);
+    if (!(used_types & curtype)) {
+      const gchar *sid = gst_stream_get_stream_id (stream);
+      GST_DEBUG_OBJECT (dbin, "Selecting stream '%s' of type %s",
+          sid, gst_stream_type_get_name (curtype));
+      tmp = g_list_append (tmp, (gchar *) sid);
+      used_types |= curtype;
+    }
+  }
+
+beach:
+  /* Finally set the requested selection */
+  if (tmp) {
+    if (dbin->requested_selection) {
+      GST_FIXME_OBJECT (dbin,
+          "Replacing non-NULL requested_selection, what should we do ??");
+      g_list_free (dbin->requested_selection);
+    }
+    dbin->requested_selection = tmp;
+    dbin->selection_updated = TRUE;
+  }
+  SELECTION_UNLOCK (dbin);
+}
+
+/* Call with INPUT_LOCK taken */
+static GstStreamCollection *
+get_merged_collection (GstDecodebin3 * dbin)
+{
+  gboolean needs_merge = FALSE;
+  GstStreamCollection *res = NULL;
+  GList *tmp;
+  guint i, nb_stream;
+
+  /* First check if we need to do a merge or just return the only collection */
+  res = dbin->main_input->collection;
+
+  for (tmp = dbin->other_inputs; tmp; tmp = tmp->next) {
+    DecodebinInput *input = (DecodebinInput *) tmp->data;
+    if (input->collection) {
+      if (res) {
+        needs_merge = TRUE;
+        break;
+      }
+      res = input->collection;
+    }
+  }
+
+  if (!needs_merge) {
+    GST_DEBUG_OBJECT (dbin, "No need to merge, returning %p", res);
+    return gst_object_ref (res);
+  }
+
+  /* We really need to create a new collection */
+  /* FIXME : Some numbering scheme maybe ?? */
+  res = gst_stream_collection_new ("decodebin3");
+  if (dbin->main_input->collection) {
+    nb_stream = gst_stream_collection_get_size (dbin->main_input->collection);
+    GST_DEBUG_OBJECT (dbin, "main input %p %d", dbin->main_input, nb_stream);
+    for (i = 0; i < nb_stream; i++) {
+      GstStream *stream =
+          gst_stream_collection_get_stream (dbin->main_input->collection, i);
+      gst_stream_collection_add_stream (res, gst_object_ref (stream));
+    }
+  }
+
+  for (tmp = dbin->other_inputs; tmp; tmp = tmp->next) {
+    DecodebinInput *input = (DecodebinInput *) tmp->data;
+    GST_DEBUG_OBJECT (dbin, "input %p , collection %p", input,
+        input->collection);
+    if (input->collection) {
+      nb_stream = gst_stream_collection_get_size (input->collection);
+      GST_DEBUG_OBJECT (dbin, "nb_stream : %d", nb_stream);
+      for (i = 0; i < nb_stream; i++) {
+        GstStream *stream =
+            gst_stream_collection_get_stream (input->collection, i);
+        gst_stream_collection_add_stream (res, gst_object_ref (stream));
+      }
+    }
+  }
+
+  return res;
+}
+
+/* Call with INPUT_LOCK taken */
+static DecodebinInput *
+find_message_parsebin (GstDecodebin3 * dbin, GstElement * child)
+{
+  DecodebinInput *input = NULL;
+  GstElement *parent = gst_object_ref (child);
+  GList *tmp;
+
+  do {
+    GstElement *next_parent;
+
+    GST_DEBUG_OBJECT (dbin, "parent %s",
+        parent ? GST_ELEMENT_NAME (parent) : "<NONE>");
+
+    if (parent == dbin->main_input->parsebin) {
+      input = dbin->main_input;
+      break;
+    }
+    for (tmp = dbin->other_inputs; tmp; tmp = tmp->next) {
+      DecodebinInput *cur = (DecodebinInput *) tmp->data;
+      if (parent == cur->parsebin) {
+        input = cur;
+        break;
+      }
+    }
+    next_parent = (GstElement *) gst_element_get_parent (parent);
+    gst_object_unref (parent);
+    parent = next_parent;
+
+  } while (parent && parent != (GstElement *) dbin);
+
+  if (parent)
+    gst_object_unref (parent);
+
+  return input;
+}
+
+static gboolean
+stream_in_collection (GstDecodebin3 * dbin, gchar * sid)
+{
+  guint i, len;
+
+  if (dbin->collection == NULL)
+    return FALSE;
+  len = gst_stream_collection_get_size (dbin->collection);
+  for (i = 0; i < len; i++) {
+    GstStream *stream = gst_stream_collection_get_stream (dbin->collection, i);
+    const gchar *osid = gst_stream_get_stream_id (stream);
+    if (!g_strcmp0 (sid, osid))
+      return TRUE;
+  }
+
+  return FALSE;
+}
+
+/* Call with INPUT_LOCK taken */
+static void
+handle_stream_collection (GstDecodebin3 * dbin,
+    GstStreamCollection * collection, GstElement * child)
+{
+#ifndef GST_DISABLE_GST_DEBUG
+  const gchar *upstream_id;
+  guint i;
+#endif
+  DecodebinInput *input = find_message_parsebin (dbin, child);
+
+  if (!input) {
+    GST_DEBUG_OBJECT (dbin,
+        "Couldn't find corresponding input, most likely shutting down");
+    return;
+  }
+
+  /* Replace collection in input */
+  if (input->collection)
+    gst_object_unref (input->collection);
+  input->collection = gst_object_ref (collection);
+  GST_DEBUG_OBJECT (dbin, "Setting collection %p on input %p", collection,
+      input);
+
+  /* Merge collection if needed */
+  collection = get_merged_collection (dbin);
+
+#ifndef GST_DISABLE_GST_DEBUG
+  /* Just some debugging */
+  upstream_id = gst_stream_collection_get_upstream_id (collection);
+  GST_DEBUG ("Received Stream Collection. Upstream_id : %s", upstream_id);
+  GST_DEBUG ("From input %p", input);
+  GST_DEBUG ("  %d streams", gst_stream_collection_get_size (collection));
+  for (i = 0; i < gst_stream_collection_get_size (collection); i++) {
+    GstStream *stream = gst_stream_collection_get_stream (collection, i);
+    GstTagList *taglist;
+    GstCaps *caps;
+
+    GST_DEBUG ("   Stream '%s'", gst_stream_get_stream_id (stream));
+    GST_DEBUG ("     type  : %s",
+        gst_stream_type_get_name (gst_stream_get_stream_type (stream)));
+    GST_DEBUG ("     flags : 0x%x", gst_stream_get_stream_flags (stream));
+    taglist = gst_stream_get_tags (stream);
+    GST_DEBUG ("     tags  : %" GST_PTR_FORMAT, taglist);
+    caps = gst_stream_get_caps (stream);
+    GST_DEBUG ("     caps  : %" GST_PTR_FORMAT, caps);
+    if (taglist)
+      gst_tag_list_unref (taglist);
+    gst_caps_unref (caps);
+  }
+#endif
+
+  /* Store collection for later usage */
+  if (dbin->collection == NULL) {
+    dbin->collection = collection;
+  } else {
+    /* We need to check who emitted this collection (the owner).
+     * If we already had a collection from that user, this one is an update,
+     * that is to say that we need to figure out how we are going to re-use
+     * the streams/slot */
+    GST_FIXME_OBJECT (dbin, "New collection but already had one ...");
+    /* FIXME : When do we switch from pending collection to active collection ?
+     * When all streams from active collection are drained in multiqueue output ? */
+    gst_object_unref (dbin->collection);
+    dbin->collection = collection;
+    /* dbin->pending_collection = */
+    /*     g_list_append (dbin->pending_collection, collection); */
+  }
+}
+
+static void
+gst_decodebin3_handle_message (GstBin * bin, GstMessage * message)
+{
+  GstDecodebin3 *dbin = (GstDecodebin3 *) bin;
+  gboolean posting_collection = FALSE;
+
+  GST_DEBUG_OBJECT (bin, "Got Message %s", GST_MESSAGE_TYPE_NAME (message));
+
+  switch (GST_MESSAGE_TYPE (message)) {
+    case GST_MESSAGE_STREAM_COLLECTION:
+    {
+      GstStreamCollection *collection = NULL;
+      gst_message_parse_stream_collection (message, &collection);
+      if (collection) {
+        INPUT_LOCK (dbin);
+        handle_stream_collection (dbin, collection,
+            (GstElement *) GST_MESSAGE_SRC (message));
+        posting_collection = TRUE;
+        INPUT_UNLOCK (dbin);
+      }
+      if (dbin->collection && collection != dbin->collection) {
+        /* Replace collection message, we most likely aggregated it */
+        GstMessage *new_msg;
+        new_msg =
+            gst_message_new_stream_collection ((GstObject *) dbin,
+            dbin->collection);
+        gst_message_unref (message);
+        message = new_msg;
+      }
+      if (collection)
+        gst_object_unref (collection);
+      break;
+    }
+    default:
+      break;
+  }
+
+  GST_BIN_CLASS (parent_class)->handle_message (bin, message);
+
+  if (posting_collection) {
+    /* Figure out a selection for that collection */
+    update_requested_selection (dbin, dbin->collection);
+  }
+}
+
+static DecodebinOutputStream *
+find_free_compatible_output (GstDecodebin3 * dbin, GstStream * stream)
+{
+  GList *tmp;
+  GstStreamType stype = gst_stream_get_stream_type (stream);
+
+  for (tmp = dbin->output_streams; tmp; tmp = tmp->next) {
+    DecodebinOutputStream *output = (DecodebinOutputStream *) tmp->data;
+    if (output->type == stype && output->slot && output->slot->active_stream) {
+      GstStream *tstream = output->slot->active_stream;
+      if (!stream_in_list (dbin->requested_selection,
+              (gchar *) gst_stream_get_stream_id (tstream))) {
+        return output;
+      }
+    }
+  }
+
+  return NULL;
+}
+
+/* Give a certain slot, figure out if it should be linked to an
+ * output stream
+ * CALL WITH SELECTION LOCK TAKEN !*/
+static DecodebinOutputStream *
+get_output_for_slot (MultiQueueSlot * slot)
+{
+  GstDecodebin3 *dbin = slot->dbin;
+  DecodebinOutputStream *output = NULL;
+  const gchar *stream_id;
+  GstCaps *caps;
+
+  /* If we already have a configured output, just use it */
+  if (slot->output != NULL)
+    return slot->output;
+
+  /*
+   * FIXME
+   * 
+   * This method needs to be split into multiple parts
+   *
+   * 1) Figure out whether stream should be exposed or not
+   *   This is based on autoplug-continue, EXPOSE_ALL_MODE, or presence
+   *   in the default stream attribution
+   *
+   * 2) Figure out whether an output stream should be created, whether
+   *   we can re-use the output stream already linked to the slot, or
+   *   whether we need to get re-assigned another (currently used) output
+   *   stream.
+   */
+
+  stream_id = gst_stream_get_stream_id (slot->active_stream);
+  caps = gst_stream_get_caps (slot->active_stream);
+  GST_DEBUG_OBJECT (dbin, "stream %s , %" GST_PTR_FORMAT, stream_id, caps);
+  gst_caps_unref (caps);
+
+  /* 0. Emit autoplug-continue signal for pending caps ? */
+  GST_FIXME_OBJECT (dbin, "emit autoplug-continue");
+
+  /* 1. if in EXPOSE_ALL_MODE, just accept */
+  GST_FIXME_OBJECT (dbin, "Handle EXPOSE_ALL_MODE");
+
+#if 0
+  /* FIXME : The idea around this was to avoid activating a stream for
+   *     which we have no decoder. Unfortunately it is way too
+   *     expensive. Need to figure out a better solution */
+  /* 2. Is there a potential decoder (if one is required) */
+  if (!gst_caps_can_intersect (caps, dbin->caps)
+      && !have_factory (dbin, (GstCaps *) caps,
+          GST_ELEMENT_FACTORY_TYPE_DECODER)) {
+    GST_WARNING_OBJECT (dbin, "Don't have a decoder for %" GST_PTR_FORMAT,
+        caps);
+    SELECTION_UNLOCK (dbin);
+    gst_element_post_message (GST_ELEMENT_CAST (dbin),
+        gst_missing_decoder_message_new (GST_ELEMENT_CAST (dbin), caps));
+    SELECTION_LOCK (dbin);
+    return NULL;
+  }
+#endif
+
+  /* 3. In default mode check if we should expose */
+  if (stream_in_list (dbin->requested_selection, stream_id)) {
+    /* Check if we can steal an existing output stream we could re-use.
+     * that is:
+     * * an output stream whose slot->stream is not in requested
+     * * and is of the same type as this stream
+     */
+    output = find_free_compatible_output (dbin, slot->active_stream);
+    if (output) {
+      /* Move this output from its current slot to this slot */
+      dbin->to_activate =
+          g_list_append (dbin->to_activate, (gchar *) stream_id);
+      dbin->requested_selection =
+          g_list_remove (dbin->requested_selection, stream_id);
+      SELECTION_UNLOCK (dbin);
+      gst_pad_add_probe (output->slot->src_pad, GST_PAD_PROBE_TYPE_IDLE,
+          (GstPadProbeCallback) slot_unassign_probe, output->slot, NULL);
+      SELECTION_LOCK (dbin);
+      return NULL;
+    }
+
+    output = create_output_stream (dbin, slot->type);
+    output->slot = slot;
+    GST_DEBUG ("Linking slot %p to new output %p", slot, output);
+    slot->output = output;
+    dbin->active_selection =
+        g_list_append (dbin->active_selection, (gchar *) stream_id);
+  } else
+    GST_DEBUG ("Not creating any output for slot %p", slot);
+
+  return output;
+}
+
+/* Returns SELECTED_STREAMS message if active_selection is equal to
+ * requested_selection, else NULL.
+ * Must be called with LOCK taken */
+static GstMessage *
+is_selection_done (GstDecodebin3 * dbin)
+{
+  GList *tmp;
+  GstMessage *msg;
+
+  if (!dbin->selection_updated)
+    return NULL;
+
+  GST_LOG_OBJECT (dbin, "Checking");
+
+  if (dbin->to_activate != NULL) {
+    GST_DEBUG ("Still have streams to activate");
+    return NULL;
+  }
+  for (tmp = dbin->requested_selection; tmp; tmp = tmp->next) {
+    GST_DEBUG ("Checking requested stream %s", (gchar *) tmp->data);
+    if (!stream_in_list (dbin->active_selection, (gchar *) tmp->data)) {
+      GST_DEBUG ("Not in active selection, returning");
+      return NULL;
+    }
+  }
+
+  GST_DEBUG_OBJECT (dbin, "Selection active, creating message");
+
+  /* We are completely active */
+  msg = gst_message_new_streams_selected ((GstObject *) dbin, dbin->collection);
+  GST_MESSAGE_SEQNUM (msg) = dbin->select_streams_seqnum;
+  for (tmp = dbin->output_streams; tmp; tmp = tmp->next) {
+    DecodebinOutputStream *output = (DecodebinOutputStream *) tmp->data;
+    if (output->slot) {
+      GST_DEBUG_OBJECT (dbin, "Adding stream %s",
+          gst_stream_get_stream_id (output->slot->active_stream));
+
+      gst_message_streams_selected_add (msg, output->slot->active_stream);
+    } else
+      GST_WARNING_OBJECT (dbin, "No valid slot for output %p", output);
+  }
+  dbin->selection_updated = FALSE;
+  return msg;
+}
+
+static GstPadProbeReturn
+multiqueue_src_probe (GstPad * pad, GstPadProbeInfo * info,
+    MultiQueueSlot * slot)
+{
+  GstPadProbeReturn ret = GST_PAD_PROBE_OK;
+  GstDecodebin3 *dbin = slot->dbin;
+
+  if (GST_IS_EVENT (GST_PAD_PROBE_INFO_DATA (info))) {
+    GstEvent *ev = GST_PAD_PROBE_INFO_EVENT (info);
+
+    GST_DEBUG_OBJECT (pad, "Got event %p %s", ev, GST_EVENT_TYPE_NAME (ev));
+    switch (GST_EVENT_TYPE (ev)) {
+      case GST_EVENT_STREAM_START:
+      {
+        GstStream *stream = NULL;
+        const gchar *stream_id;
+
+        gst_event_parse_stream (ev, &stream);
+        if (stream == NULL) {
+          GST_ERROR_OBJECT (pad,
+              "Got a STREAM_START event without a GstStream");
+          break;
+        }
+        stream_id = gst_stream_get_stream_id (stream);
+        GST_DEBUG_OBJECT (pad, "Stream Start '%s'", stream_id);
+        if (slot->active_stream == NULL) {
+          slot->active_stream = stream;
+        } else if (slot->active_stream != stream) {
+          GST_FIXME_OBJECT (pad, "Handle stream changes (%s => %s) !",
+              gst_stream_get_stream_id (slot->active_stream),
+              gst_stream_get_stream_id (stream));
+          gst_object_unref (slot->active_stream);
+          slot->active_stream = stream;
+        } else
+          gst_object_unref (stream);
+#if 0                           /* Disabled because stream-start is pushed for every buffer on every unlinked pad */
+        {
+          gboolean is_active, is_requested;
+          /* Quick check to see if we're in the current selection */
+          /* FIXME : Re-check all slot<=>output mappings based on requested_selection */
+          SELECTION_LOCK (dbin);
+          GST_DEBUG_OBJECT (dbin, "Checking active selection");
+          is_active = stream_in_list (dbin->active_selection, stream_id);
+          GST_DEBUG_OBJECT (dbin, "Checking requested selection");
+          is_requested = stream_in_list (dbin->requested_selection, stream_id);
+          SELECTION_UNLOCK (dbin);
+          if (is_active)
+            GST_DEBUG_OBJECT (pad, "Slot in ACTIVE selection (output:%p)",
+                slot->output);
+          if (is_requested)
+            GST_DEBUG_OBJECT (pad, "Slot in REQUESTED selection (output:%p)",
+                slot->output);
+          else if (slot->output) {
+            GST_DEBUG_OBJECT (pad,
+                "Slot needs to be deactivated ? It's no longer in requested selection");
+          } else if (!is_active)
+            GST_DEBUG_OBJECT (pad,
+                "Slot in neither active nor requested selection");
+        }
+#endif
+      }
+        break;
+      case GST_EVENT_CAPS:
+      {
+        /* Configure the output slot if needed */
+        DecodebinOutputStream *output;
+        GstMessage *msg = NULL;
+        SELECTION_LOCK (dbin);
+        output = get_output_for_slot (slot);
+        if (output) {
+          reconfigure_output_stream (output, slot);
+          msg = is_selection_done (dbin);
+        }
+        SELECTION_UNLOCK (dbin);
+        if (msg)
+          gst_element_post_message ((GstElement *) slot->dbin, msg);
+      }
+        break;
+      case GST_EVENT_EOS:
+        /* FIXME : Figure out */
+        GST_FIXME_OBJECT (pad, "EOS on multiqueue source pad. input:%p",
+            slot->input);
+        if (slot->input == NULL) {
+          GstPad *peer;
+          GST_DEBUG_OBJECT (pad,
+              "last EOS for input, forwarding and removing slot");
+          peer = gst_pad_get_peer (pad);
+          if (peer) {
+            gst_pad_send_event (peer, ev);
+            gst_object_unref (peer);
+          } else {
+            gst_event_unref (ev);
+          }
+          SELECTION_LOCK (dbin);
+          /* FIXME : Shouldn't we try to re-assign the output instead of just
+           * removing it ? */
+          /* Remove the output */
+          if (slot->output) {
+            DecodebinOutputStream *output = slot->output;
+            dbin->output_streams = g_list_remove (dbin->output_streams, output);
+            free_output_stream (dbin, output);
+          }
+          SELECTION_UNLOCK (dbin);
+          ret = GST_PAD_PROBE_HANDLED;
+        }
+        break;
+      default:
+        break;
+    }
+  } else if (GST_IS_QUERY (GST_PAD_PROBE_INFO_DATA (info))) {
+    GstQuery *query = GST_PAD_PROBE_INFO_QUERY (info);
+    switch (GST_QUERY_TYPE (query)) {
+      case GST_QUERY_CAPS:
+      {
+        GST_DEBUG_OBJECT (pad, "Intercepting CAPS query");
+        gst_query_set_caps_result (query, GST_CAPS_ANY);
+        ret = GST_PAD_PROBE_HANDLED;
+      }
+        break;
+
+      case GST_QUERY_ACCEPT_CAPS:
+      {
+        GST_DEBUG_OBJECT (pad, "Intercepting Accept Caps query");
+        /* If the current decoder doesn't accept caps, we'll reconfigure
+         * on the actual caps event. So accept any caps. */
+        gst_query_set_accept_caps_result (query, TRUE);
+        ret = GST_PAD_PROBE_HANDLED;
+      }
+      default:
+        break;
+    }
+  }
+
+  return ret;
+}
+
+/* Create a new multiqueue slot for the given type
+ *
+ * It is up to the caller to know whether that slot is needed or not
+ * (and release it when no longer needed) */
+static MultiQueueSlot *
+create_new_slot (GstDecodebin3 * dbin, GstStreamType type)
+{
+  MultiQueueSlot *slot;
+  GstIterator *it = NULL;
+  GValue item = { 0, };
+
+  GST_DEBUG_OBJECT (dbin, "Creating new slot for type %s",
+      gst_stream_type_get_name (type));
+  slot = g_new0 (MultiQueueSlot, 1);
+  slot->dbin = dbin;
+  slot->id = dbin->slot_id++;
+  slot->type = type;
+  slot->sink_pad = gst_element_get_request_pad (dbin->multiqueue, "sink_%u");
+  if (slot->sink_pad == NULL)
+    goto fail;
+  it = gst_pad_iterate_internal_links (slot->sink_pad);
+  if (!it || (gst_iterator_next (it, &item)) != GST_ITERATOR_OK
+      || ((slot->src_pad = g_value_dup_object (&item)) == NULL)) {
+    GST_ERROR ("Couldn't get srcpad from multiqueue for sink pad %s:%s",
+        GST_DEBUG_PAD_NAME (slot->src_pad));
+    goto fail;
+  }
+  gst_iterator_free (it);
+  g_value_reset (&item);
+
+  g_object_set (slot->sink_pad, "group-id", (guint) type, NULL);
+
+  /* Add event probe */
+  slot->probe_id =
+      gst_pad_add_probe (slot->src_pad,
+      GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM,
+      (GstPadProbeCallback) multiqueue_src_probe, slot, NULL);
+
+  GST_DEBUG ("Created new slot %u (%p) (%s:%s)", slot->id, slot,
+      GST_DEBUG_PAD_NAME (slot->src_pad));
+  dbin->slots = g_list_append (dbin->slots, slot);
+  return slot;
+
+  /* ERRORS */
+fail:
+  {
+    if (slot->sink_pad)
+      gst_element_release_request_pad (dbin->multiqueue, slot->sink_pad);
+    g_free (slot);
+    return NULL;
+  }
+}
+
+static MultiQueueSlot *
+get_slot_for_input (GstDecodebin3 * dbin, DecodebinInputStream * input)
+{
+  GList *tmp;
+  MultiQueueSlot *empty_slot = NULL;
+  GstStreamType input_type = 0;
+  gchar *stream_id = NULL;
+
+  GST_DEBUG_OBJECT (dbin, "input %p (stream %p %s)",
+      input, input->active_stream,
+      input->
+      active_stream ? gst_stream_get_stream_id (input->active_stream) : "");
+
+  if (input->active_stream) {
+    input_type = gst_stream_get_stream_type (input->active_stream);
+    stream_id = (gchar *) gst_stream_get_stream_id (input->active_stream);
+  }
+
+  /* Go over existing slots and check if there is already one for it */
+  for (tmp = dbin->slots; tmp; tmp = tmp->next) {
+    MultiQueueSlot *slot = (MultiQueueSlot *) tmp->data;
+    /* Already used input, return that one */
+    if (slot->input == input) {
+      GST_DEBUG_OBJECT (dbin, "Returning already specified slot %d", slot->id);
+      return slot;
+    }
+  }
+
+  /* Go amongst all unused slots of the right type and try to find a candidate */
+  for (tmp = dbin->slots; tmp; tmp = tmp->next) {
+    MultiQueueSlot *slot = (MultiQueueSlot *) tmp->data;
+    if (slot->input == NULL && input_type == slot->type) {
+      /* Remember this empty slot for later */
+      empty_slot = slot;
+      /* Check if available slot is of the same stream_id */
+      GST_LOG_OBJECT (dbin, "Checking candidate slot %d (active_stream:%p)",
+          slot->id, slot->active_stream);
+      if (stream_id && slot->active_stream) {
+        gchar *ostream_id =
+            (gchar *) gst_stream_get_stream_id (slot->active_stream);
+        GST_DEBUG_OBJECT (dbin, "Checking slot %d %s against %s", slot->id,
+            ostream_id, stream_id);
+        if (!g_strcmp0 (stream_id, ostream_id))
+          break;
+      }
+    }
+  }
+
+  if (empty_slot) {
+    GST_DEBUG_OBJECT (dbin, "Re-using existing unused slot %d", empty_slot->id);
+    empty_slot->input = input;
+    return empty_slot;
+  }
+
+  if (input_type)
+    return create_new_slot (dbin, input_type);
+
+  return NULL;
+}
+
+static void
+link_input_to_slot (DecodebinInputStream * input, MultiQueueSlot * slot)
+{
+  GstEvent *event;
+  if (slot->input != NULL && slot->input != input) {
+    GST_ERROR_OBJECT (slot->dbin,
+        "Trying to link input to an already used slot");
+    return;
+  }
+  gst_pad_link_full (input->srcpad, slot->sink_pad, GST_PAD_LINK_CHECK_NOTHING);
+  slot->pending_stream = input->active_stream;
+  slot->input = input;
+  event = gst_pad_get_sticky_event (input->srcpad, GST_EVENT_STREAM_START, 0);
+  if (event)
+    gst_pad_send_event (slot->sink_pad, event);
+}
+
+#if 0
+static gboolean
+have_factory (GstDecodebin3 * dbin, GstCaps * caps,
+    GstElementFactoryListType ftype)
+{
+  gboolean ret = FALSE;
+  GList *res;
+
+  g_mutex_lock (&dbin->factories_lock);
+  gst_decode_bin_update_factories_list (dbin);
+  if (ftype == GST_ELEMENT_FACTORY_TYPE_DECODER)
+    res =
+        gst_element_factory_list_filter (dbin->decoder_factories,
+        caps, GST_PAD_SINK, TRUE);
+  else
+    res =
+        gst_element_factory_list_filter (dbin->decodable_factories,
+        caps, GST_PAD_SINK, TRUE);
+  g_mutex_unlock (&dbin->factories_lock);
+
+  if (res) {
+    ret = TRUE;
+    gst_plugin_feature_list_free (res);
+  }
+
+  return ret;
+}
+#endif
+
+static GstElement *
+create_element (GstDecodebin3 * dbin, GstStream * stream,
+    GstElementFactoryListType ftype)
+{
+  GList *res;
+  GstElement *element = NULL;
+  GstCaps *caps;
+
+  g_mutex_lock (&dbin->factories_lock);
+  gst_decode_bin_update_factories_list (dbin);
+  caps = gst_stream_get_caps (stream);
+  if (ftype == GST_ELEMENT_FACTORY_TYPE_DECODER)
+    res =
+        gst_element_factory_list_filter (dbin->decoder_factories,
+        caps, GST_PAD_SINK, TRUE);
+  else
+    res =
+        gst_element_factory_list_filter (dbin->decodable_factories,
+        caps, GST_PAD_SINK, TRUE);
+  g_mutex_unlock (&dbin->factories_lock);
+
+  if (res) {
+    element =
+        gst_element_factory_create ((GstElementFactory *) res->data, NULL);
+    GST_DEBUG ("Created element '%s'", GST_ELEMENT_NAME (element));
+    gst_plugin_feature_list_free (res);
+  } else {
+    GST_DEBUG ("Could not find an element for caps %" GST_PTR_FORMAT, caps);
+  }
+
+  gst_caps_unref (caps);
+  return element;
+}
+
+/* FIXME : VERY NAIVE. ASSUMING FIRST ONE WILL WORK */
+static GstElement *
+create_decoder (GstDecodebin3 * dbin, GstStream * stream)
+{
+  return create_element (dbin, stream, GST_ELEMENT_FACTORY_TYPE_DECODER);
+}
+
+static GstPadProbeReturn
+keyframe_waiter_probe (GstPad * pad, GstPadProbeInfo * info,
+    DecodebinOutputStream * output)
+{
+  GstBuffer *buf = GST_PAD_PROBE_INFO_BUFFER (info);
+  /* If we have a keyframe, remove the probe and let all data through */
+  /* FIXME : HANDLE HEADER BUFFER ?? */
+  if (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT) ||
+      GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_HEADER)) {
+    GST_DEBUG_OBJECT (pad,
+        "Buffer is keyframe or header, letting through and removing probe");
+    output->drop_probe_id = 0;
+    return GST_PAD_PROBE_REMOVE;
+  }
+  GST_DEBUG_OBJECT (pad, "Buffer is not a keyframe, dropping");
+  return GST_PAD_PROBE_DROP;
+}
+
+static void
+reconfigure_output_stream (DecodebinOutputStream * output,
+    MultiQueueSlot * slot)
+{
+  GstDecodebin3 *dbin = output->dbin;
+  GstCaps *new_caps = (GstCaps *) gst_stream_get_caps (slot->active_stream);
+  gboolean needs_decoder;
+
+  needs_decoder = gst_caps_can_intersect (new_caps, dbin->caps) != TRUE;
+
+  GST_DEBUG_OBJECT (dbin,
+      "Reconfiguring output %p to slot %p, needs_decoder:%d", output, slot,
+      needs_decoder);
+
+  /* FIXME : Maybe make the output un-hook itself automatically ? */
+  if (output->slot != NULL && output->slot != slot) {
+    GST_WARNING_OBJECT (dbin,
+        "Output still linked to another slot (%p)", output->slot);
+    gst_caps_unref (new_caps);
+    return;
+  }
+
+  /* Check if existing config is reusable as-is by checking if
+   * the existing decoder accepts the new caps, if not delete
+   * it and create a new one */
+  if (output->decoder) {
+    gboolean can_reuse_decoder;
+
+    if (needs_decoder) {
+      can_reuse_decoder =
+          gst_pad_query_accept_caps (output->decoder_sink, new_caps);
+    } else
+      can_reuse_decoder = FALSE;
+
+    if (can_reuse_decoder) {
+      if (output->type == GST_STREAM_TYPE_VIDEO && output->drop_probe_id == 0) {
+        GST_DEBUG_OBJECT (dbin, "Adding keyframe-waiter probe");
+        output->drop_probe_id =
+            gst_pad_add_probe (slot->src_pad, GST_PAD_PROBE_TYPE_BUFFER,
+            (GstPadProbeCallback) keyframe_waiter_probe, output, NULL);
+      }
+      GST_DEBUG_OBJECT (dbin, "Reusing existing decoder for slot %p", slot);
+      if (output->linked == FALSE) {
+        gst_pad_link_full (slot->src_pad, output->decoder_sink,
+            GST_PAD_LINK_CHECK_NOTHING);
+        output->linked = TRUE;
+      }
+      gst_caps_unref (new_caps);
+      return;
+    }
+
+    GST_DEBUG_OBJECT (dbin, "Removing old decoder for slot %p", slot);
+
+    if (output->linked)
+      gst_pad_unlink (slot->src_pad, output->decoder_sink);
+    output->linked = FALSE;
+    if (output->drop_probe_id) {
+      gst_pad_remove_probe (slot->src_pad, output->drop_probe_id);
+      output->drop_probe_id = 0;
+    }
+
+    if (!gst_ghost_pad_set_target ((GstGhostPad *) output->src_pad, NULL)) {
+      GST_ERROR_OBJECT (dbin, "Could not release decoder pad");
+      gst_caps_unref (new_caps);
+      goto cleanup;
+    }
+
+    gst_element_set_locked_state (output->decoder, TRUE);
+    gst_element_set_state (output->decoder, GST_STATE_NULL);
+
+    gst_bin_remove ((GstBin *) dbin, output->decoder);
+    output->decoder = NULL;
+  }
+
+  gst_caps_unref (new_caps);
+
+  gst_object_replace ((GstObject **) & output->decoder_sink, NULL);
+  gst_object_replace ((GstObject **) & output->decoder_src, NULL);
+
+  /* If a decoder is required, create one */
+  if (needs_decoder) {
+    /* If we don't have a decoder yet, instantiate one */
+    output->decoder = create_decoder (dbin, slot->active_stream);
+    if (output->decoder == NULL) {
+      GstCaps *caps;
+
+      SELECTION_UNLOCK (dbin);
+      /* FIXME : Should we be smarter if there's a missing decoder ?
+       * Should we deactivate that stream ? */
+      caps = gst_stream_get_caps (slot->active_stream);
+      gst_element_post_message (GST_ELEMENT_CAST (dbin),
+          gst_missing_decoder_message_new (GST_ELEMENT_CAST (dbin), caps));
+      gst_caps_unref (caps);
+      SELECTION_LOCK (dbin);
+      goto cleanup;
+    }
+    if (!gst_bin_add ((GstBin *) dbin, output->decoder)) {
+      GST_ERROR_OBJECT (dbin, "could not add decoder to pipeline");
+      goto cleanup;
+    }
+    output->decoder_sink = gst_element_get_static_pad (output->decoder, "sink");
+    output->decoder_src = gst_element_get_static_pad (output->decoder, "src");
+    if (output->type == GST_STREAM_TYPE_VIDEO) {
+      GST_DEBUG_OBJECT (dbin, "Adding keyframe-waiter probe");
+      output->drop_probe_id =
+          gst_pad_add_probe (slot->src_pad, GST_PAD_PROBE_TYPE_BUFFER,
+          (GstPadProbeCallback) keyframe_waiter_probe, output, NULL);
+    }
+    if (gst_pad_link_full (slot->src_pad, output->decoder_sink,
+            GST_PAD_LINK_CHECK_NOTHING) != GST_PAD_LINK_OK) {
+      GST_ERROR_OBJECT (dbin, "could not link to %s:%s",
+          GST_DEBUG_PAD_NAME (output->decoder_sink));
+      goto cleanup;
+    }
+  } else {
+    output->decoder_src = gst_object_ref (slot->src_pad);
+    output->decoder_sink = NULL;
+  }
+  output->linked = TRUE;
+  if (!gst_ghost_pad_set_target ((GstGhostPad *) output->src_pad,
+          output->decoder_src)) {
+    GST_ERROR_OBJECT (dbin, "Could not expose decoder pad");
+    goto cleanup;
+  }
+  if (output->src_exposed == FALSE) {
+    output->src_exposed = TRUE;
+    gst_element_add_pad (GST_ELEMENT_CAST (dbin), output->src_pad);
+  }
+
+  if (output->decoder)
+    gst_element_sync_state_with_parent (output->decoder);
+
+  output->slot = slot;
+  return;
+
+cleanup:
+  {
+    GST_DEBUG_OBJECT (dbin, "Cleanup");
+    if (output->decoder_sink) {
+      gst_object_unref (output->decoder_sink);
+      output->decoder_sink = NULL;
+    }
+    if (output->decoder_src) {
+      gst_object_unref (output->decoder_src);
+      output->decoder_src = NULL;
+    }
+    if (output->decoder) {
+      gst_element_set_state (output->decoder, GST_STATE_NULL);
+      gst_bin_remove ((GstBin *) dbin, output->decoder);
+      output->decoder = NULL;
+    }
+  }
+}
+
+static GstPadProbeReturn
+idle_reconfigure (GstPad * pad, GstPadProbeInfo * info, MultiQueueSlot * slot)
+{
+  GstMessage *msg = NULL;
+  DecodebinOutputStream *output;
+
+  SELECTION_LOCK (slot->dbin);
+  output = get_output_for_slot (slot);
+
+  GST_DEBUG_OBJECT (pad, "output : %p", output);
+
+  if (output) {
+    reconfigure_output_stream (output, slot);
+    msg = is_selection_done (slot->dbin);
+  }
+  SELECTION_UNLOCK (slot->dbin);
+  if (msg)
+    gst_element_post_message ((GstElement *) slot->dbin, msg);
+
+  return GST_PAD_PROBE_REMOVE;
+}
+
+static MultiQueueSlot *
+find_slot_for_stream_id (GstDecodebin3 * dbin, const gchar * sid)
+{
+  GList *tmp;
+
+  for (tmp = dbin->slots; tmp; tmp = tmp->next) {
+    MultiQueueSlot *slot = (MultiQueueSlot *) tmp->data;
+    const gchar *stream_id;
+    if (slot->active_stream) {
+      stream_id = gst_stream_get_stream_id (slot->active_stream);
+      if (!g_strcmp0 (sid, stream_id))
+        return slot;
+    }
+    if (slot->pending_stream && slot->pending_stream != slot->active_stream) {
+      stream_id = gst_stream_get_stream_id (slot->pending_stream);
+      if (!g_strcmp0 (sid, stream_id))
+        return slot;
+    }
+  }
+
+  return NULL;
+}
+
+/* This function handles the reassignment of a slot. Call this from
+ * the streaming thread of a slot. */
+static gboolean
+reassign_slot (GstDecodebin3 * dbin, MultiQueueSlot * slot)
+{
+  DecodebinOutputStream *output;
+  MultiQueueSlot *target_slot = NULL;
+  GList *tmp;
+  const gchar *sid, *tsid;
+
+  SELECTION_LOCK (dbin);
+  output = slot->output;
+
+  if (G_UNLIKELY (slot->active_stream == NULL)) {
+    GST_DEBUG_OBJECT (slot->src_pad,
+        "Called on inactive slot (active_stream == NULL)");
+    SELECTION_UNLOCK (dbin);
+    return FALSE;
+  }
+
+  if (G_UNLIKELY (output == NULL)) {
+    GST_DEBUG_OBJECT (slot->src_pad,
+        "Slot doesn't have any output to be removed");
+    SELECTION_UNLOCK (dbin);
+    return FALSE;
+  }
+
+  sid = gst_stream_get_stream_id (slot->active_stream);
+  GST_DEBUG_OBJECT (slot->src_pad, "slot %s %p", sid, slot);
+
+  /* Recheck whether this stream is still in the list of streams to deactivate */
+  if (stream_in_list (dbin->requested_selection, sid)) {
+    /* Stream is in the list of requested streams, don't remove */
+    SELECTION_UNLOCK (dbin);
+    GST_DEBUG_OBJECT (slot->src_pad,
+        "Stream '%s' doesn't need to be deactivated", sid);
+    return FALSE;
+  }
+
+  /* Unlink slot from output */
+  /* FIXME : Handle flushing ? */
+  /* FIXME : Handle outputs without decoders */
+  GST_DEBUG_OBJECT (slot->src_pad, "Unlinking from decoder %p",
+      output->decoder_sink);
+  if (output->decoder_sink)
+    gst_pad_unlink (slot->src_pad, output->decoder_sink);
+  output->linked = FALSE;
+  slot->output = NULL;
+  output->slot = NULL;
+  /* Remove sid from active selection */
+  for (tmp = dbin->active_selection; tmp; tmp = tmp->next)
+    if (!g_strcmp0 (sid, tmp->data)) {
+      dbin->active_selection = g_list_delete_link (dbin->active_selection, tmp);
+      break;
+    }
+
+  /* Can we re-assign this output to a requested stream ? */
+  GST_DEBUG_OBJECT (slot->src_pad, "Attempting to re-assing output stream");
+  for (tmp = dbin->to_activate; tmp; tmp = tmp->next) {
+    MultiQueueSlot *tslot = find_slot_for_stream_id (dbin, tmp->data);
+    GST_LOG_OBJECT (tslot->src_pad, "Checking slot %p (output:%p , stream:%s)",
+        tslot, tslot->output, gst_stream_get_stream_id (tslot->active_stream));
+    if (tslot && tslot->type == output->type && tslot->output == NULL) {
+      GST_DEBUG_OBJECT (tslot->src_pad, "Using as reassigned slot");
+      target_slot = tslot;
+      tsid = tmp->data;
+      /* Pass target stream id to requested selection */
+      dbin->requested_selection =
+          g_list_append (dbin->requested_selection, tmp->data);
+      dbin->to_activate = g_list_remove (dbin->to_activate, tmp->data);
+      break;
+    }
+  }
+
+  if (target_slot) {
+    GST_DEBUG_OBJECT (slot->src_pad, "Assigning output to slot %p '%s'",
+        target_slot, tsid);
+    target_slot->output = output;
+    output->slot = target_slot;
+    dbin->active_selection =
+        g_list_append (dbin->active_selection, (gchar *) tsid);
+    SELECTION_UNLOCK (dbin);
+
+    /* Wakeup the target slot so that it retries to send events/buffers
+     * thereby triggering the output reconfiguration codepath */
+    gst_pad_add_probe (target_slot->src_pad, GST_PAD_PROBE_TYPE_IDLE,
+        (GstPadProbeCallback) idle_reconfigure, target_slot, NULL);
+    /* gst_pad_send_event (target_slot->src_pad, gst_event_new_reconfigure ()); */
+  } else {
+    GstMessage *msg;
+
+    dbin->output_streams = g_list_remove (dbin->output_streams, output);
+    free_output_stream (dbin, output);
+    msg = is_selection_done (slot->dbin);
+    SELECTION_UNLOCK (dbin);
+
+    if (msg)
+      gst_element_post_message ((GstElement *) slot->dbin, msg);
+  }
+
+  return TRUE;
+}
+
+/* Idle probe called when a slot should be unassigned from its output stream.
+ * This is needed to ensure nothing is flowing when unlinking the slot.
+ *
+ * Also, this method will search for a pending stream which could re-use
+ * the output stream. */
+static GstPadProbeReturn
+slot_unassign_probe (GstPad * pad, GstPadProbeInfo * info,
+    MultiQueueSlot * slot)
+{
+  GstDecodebin3 *dbin = slot->dbin;
+
+  reassign_slot (dbin, slot);
+
+  return GST_PAD_PROBE_REMOVE;
+}
+
+static gboolean
+handle_stream_switch (GstDecodebin3 * dbin, GList * select_streams,
+    guint32 seqnum)
+{
+  gboolean ret = TRUE;
+  GList *tmp;
+  /* List of slots to (de)activate. */
+  GList *to_deactivate = NULL;
+  GList *to_activate = NULL;
+  /* List of unknown stream id, most likely means the event
+   * should be sent upstream so that elements can expose the requested stream */
+  GList *unknown = NULL;
+  GList *to_reassign = NULL;
+  GList *future_request_streams = NULL;
+  GList *pending_streams = NULL;
+  GList *slots_to_reassign = NULL;
+
+  SELECTION_LOCK (dbin);
+  if (G_UNLIKELY (seqnum != dbin->select_streams_seqnum)) {
+    GST_DEBUG_OBJECT (dbin, "New SELECT_STREAMS has arrived in the meantime");
+    SELECTION_UNLOCK (dbin);
+    return TRUE;
+  }
+  /* Remove pending select_streams */
+  g_list_free (dbin->pending_select_streams);
+  dbin->pending_select_streams = NULL;
+
+  /* COMPARE the requested streams to the active and requested streams
+   * on multiqueue. */
+
+  /* First check the slots to activate and which ones are unknown */
+  for (tmp = select_streams; tmp; tmp = tmp->next) {
+    const gchar *sid = (const gchar *) tmp->data;
+    MultiQueueSlot *slot;
+    GST_DEBUG_OBJECT (dbin, "Checking stream '%s'", sid);
+    slot = find_slot_for_stream_id (dbin, sid);
+    /* Find the corresponding slot */
+    if (slot == NULL) {
+      if (stream_in_collection (dbin, (gchar *) sid)) {
+        pending_streams = g_list_append (pending_streams, (gchar *) sid);
+      } else {
+        GST_DEBUG_OBJECT (dbin, "We don't have a slot for stream '%s'", sid);
+        unknown = g_list_append (unknown, (gchar *) sid);
+      }
+    } else if (slot->output == NULL) {
+      GST_DEBUG_OBJECT (dbin, "We need to activate slot %p for stream '%s')",
+          slot, sid);
+      to_activate = g_list_append (to_activate, slot);
+    } else {
+      GST_DEBUG_OBJECT (dbin,
+          "Stream '%s' from slot %p is already active on output %p", sid, slot,
+          slot->output);
+      future_request_streams =
+          g_list_append (future_request_streams, (gchar *) sid);
+    }
+  }
+
+  for (tmp = dbin->slots; tmp; tmp = tmp->next) {
+    MultiQueueSlot *slot = (MultiQueueSlot *) tmp->data;
+    /* For slots that have an output, check if it's part of the streams to
+     * be active */
+    if (slot->output) {
+      gboolean slot_to_deactivate = TRUE;
+
+      if (slot->active_stream) {
+        if (stream_in_list (select_streams,
+                gst_stream_get_stream_id (slot->active_stream)))
+          slot_to_deactivate = FALSE;
+      }
+      if (slot_to_deactivate && slot->pending_stream
+          && slot->pending_stream != slot->active_stream) {
+        if (stream_in_list (select_streams,
+                gst_stream_get_stream_id (slot->pending_stream)))
+          slot_to_deactivate = FALSE;
+      }
+      if (slot_to_deactivate) {
+        GST_DEBUG_OBJECT (dbin,
+            "Slot %p (%s) should be deactivated, no longer used", slot,
+            gst_stream_get_stream_id (slot->active_stream));
+        to_deactivate = g_list_append (to_deactivate, slot);
+      }
+    }
+  }
+
+  if (to_deactivate != NULL) {
+    GST_DEBUG_OBJECT (dbin, "Check if we can reassign slots");
+    /* We need to compare what needs to be activated and deactivated in order
+     * to determine whether there are outputs that can be transferred */
+    /* Take the stream-id of the slots that are to be activated, for which there
+     * is a slot of the same type that needs to be deactivated */
+    tmp = to_deactivate;
+    while (tmp) {
+      MultiQueueSlot *slot_to_deactivate = (MultiQueueSlot *) tmp->data;
+      gboolean removeit = FALSE;
+      GList *tmp2, *next;
+      GST_DEBUG_OBJECT (dbin,
+          "Checking if slot to deactivate (%p) has a candidate slot to activate",
+          slot_to_deactivate);
+      for (tmp2 = to_activate; tmp2; tmp2 = tmp2->next) {
+        MultiQueueSlot *slot_to_activate = (MultiQueueSlot *) tmp2->data;
+        GST_DEBUG_OBJECT (dbin, "Comparing to slot %p", slot_to_activate);
+        if (slot_to_activate->type == slot_to_deactivate->type) {
+          GST_DEBUG_OBJECT (dbin, "Re-using");
+          to_reassign = g_list_append (to_reassign, (gchar *)
+              gst_stream_get_stream_id (slot_to_activate->active_stream));
+          slots_to_reassign =
+              g_list_append (slots_to_reassign, slot_to_deactivate);
+          to_activate = g_list_remove (to_activate, slot_to_activate);
+          removeit = TRUE;
+          break;
+        }
+      }
+      next = tmp->next;
+      if (removeit)
+        to_deactivate = g_list_delete_link (to_deactivate, tmp);
+      tmp = next;
+    }
+  }
+
+  for (tmp = to_deactivate; tmp; tmp = tmp->next) {
+    MultiQueueSlot *slot = (MultiQueueSlot *) tmp->data;
+    GST_DEBUG_OBJECT (dbin,
+        "Really need to deactivate slot %p, but no available alternative",
+        slot);
+
+    slots_to_reassign = g_list_append (slots_to_reassign, slot);
+  }
+
+  /* The only slots left to activate are the ones that won't be reassigned and
+   * therefore really need to have a new output created */
+  for (tmp = to_activate; tmp; tmp = tmp->next) {
+    MultiQueueSlot *slot = (MultiQueueSlot *) tmp->data;
+    if (slot->active_stream)
+      future_request_streams =
+          g_list_append (future_request_streams,
+          (gchar *) gst_stream_get_stream_id (slot->active_stream));
+    else if (slot->pending_stream)
+      future_request_streams =
+          g_list_append (future_request_streams,
+          (gchar *) gst_stream_get_stream_id (slot->pending_stream));
+    else
+      GST_ERROR_OBJECT (dbin, "No stream for slot %p !!", slot);
+  }
+
+  if (to_activate == NULL && pending_streams != NULL) {
+    GST_DEBUG_OBJECT (dbin, "Stream switch requested for future collection");
+    if (dbin->requested_selection)
+      g_list_free (dbin->requested_selection);
+    dbin->requested_selection = select_streams;
+    g_list_free (to_deactivate);
+    g_list_free (pending_streams);
+    to_deactivate = NULL;
+  } else {
+    if (dbin->requested_selection)
+      g_list_free (dbin->requested_selection);
+    dbin->requested_selection = future_request_streams;
+    dbin->requested_selection =
+        g_list_concat (dbin->requested_selection, pending_streams);
+    if (dbin->to_activate)
+      g_list_free (dbin->to_activate);
+    dbin->to_activate = to_reassign;
+  }
+
+  dbin->selection_updated = TRUE;
+  SELECTION_UNLOCK (dbin);
+
+  if (unknown)
+    GST_FIXME_OBJECT (dbin, "Got request for an unknown stream");
+
+  /* For all streams to deactivate, add an idle probe where we will do
+   * the unassignment and switch over */
+  for (tmp = slots_to_reassign; tmp; tmp = tmp->next) {
+    MultiQueueSlot *slot = (MultiQueueSlot *) tmp->data;
+    gst_pad_add_probe (slot->src_pad, GST_PAD_PROBE_TYPE_IDLE,
+        (GstPadProbeCallback) slot_unassign_probe, slot, NULL);
+  }
+
+  return ret;
+}
+
+static GstPadProbeReturn
+ghost_pad_event_probe (GstPad * pad, GstPadProbeInfo * info,
+    DecodebinOutputStream * output)
+{
+  GstPadProbeReturn ret = GST_PAD_PROBE_OK;
+  GstDecodebin3 *dbin = output->dbin;
+  GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
+
+  GST_DEBUG_OBJECT (pad, "Got event %p %s", event, GST_EVENT_TYPE_NAME (event));
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_SELECT_STREAMS:
+    {
+      GstPad *peer;
+      GList *streams = NULL;
+      guint32 seqnum = gst_event_get_seqnum (event);
+
+      SELECTION_LOCK (dbin);
+      if (seqnum == dbin->select_streams_seqnum) {
+        SELECTION_UNLOCK (dbin);
+        GST_DEBUG_OBJECT (pad,
+            "Already handled/handling that SELECT_STREAMS event");
+        break;
+      }
+      dbin->select_streams_seqnum = seqnum;
+      if (dbin->pending_select_streams != NULL) {
+        GST_LOG_OBJECT (dbin, "Replacing pending select streams");
+        g_list_free (dbin->pending_select_streams);
+        dbin->pending_select_streams = NULL;
+      }
+      gst_event_parse_select_streams (event, &streams);
+      dbin->pending_select_streams = g_list_copy (streams);
+      SELECTION_UNLOCK (dbin);
+
+      /* Send event upstream */
+      if ((peer = gst_pad_get_peer (pad))) {
+        gst_pad_send_event (peer, event);
+        gst_object_unref (peer);
+      } else {
+        gst_event_unref (event);
+      }
+      /* Finally handle the switch */
+      if (streams)
+        handle_stream_switch (dbin, streams, seqnum);
+      ret = GST_PAD_PROBE_HANDLED;
+    }
+      break;
+    default:
+      break;
+  }
+
+  return ret;
+}
+
+static gboolean
+gst_decodebin3_send_event (GstElement * element, GstEvent * event)
+{
+  GST_DEBUG_OBJECT (element, "event %s", GST_EVENT_TYPE_NAME (event));
+  if (GST_EVENT_TYPE (event) == GST_EVENT_SELECT_STREAMS) {
+    GstDecodebin3 *dbin = (GstDecodebin3 *) element;
+    GList *streams = NULL;
+    guint32 seqnum = gst_event_get_seqnum (event);
+
+    SELECTION_LOCK (dbin);
+    if (seqnum == dbin->select_streams_seqnum) {
+      SELECTION_UNLOCK (dbin);
+      GST_DEBUG_OBJECT (dbin,
+          "Already handled/handling that SELECT_STREAMS event");
+      return TRUE;
+    }
+    dbin->select_streams_seqnum = seqnum;
+    if (dbin->pending_select_streams != NULL) {
+      GST_LOG_OBJECT (dbin, "Replacing pending select streams");
+      g_list_free (dbin->pending_select_streams);
+      dbin->pending_select_streams = NULL;
+    }
+    gst_event_parse_select_streams (event, &streams);
+    dbin->pending_select_streams = g_list_copy (streams);
+    SELECTION_UNLOCK (dbin);
+
+    /* FIXME : We don't have an upstream ?? */
+#if 0
+    /* Send event upstream */
+    if ((peer = gst_pad_get_peer (pad))) {
+      gst_pad_send_event (peer, event);
+      gst_object_unref (peer);
+    }
+#endif
+    /* Finally handle the switch */
+    if (streams)
+      handle_stream_switch (dbin, streams, seqnum);
+
+    gst_event_unref (event);
+    return TRUE;
+  }
+  return GST_ELEMENT_CLASS (parent_class)->send_event (element, event);
+}
+
+
+static void
+free_multiqueue_slot (GstDecodebin3 * dbin, MultiQueueSlot * slot)
+{
+  if (slot->probe_id)
+    gst_pad_remove_probe (slot->src_pad, slot->probe_id);
+  if (slot->input) {
+    if (slot->input->srcpad)
+      gst_pad_unlink (slot->input->srcpad, slot->sink_pad);
+  }
+
+  gst_element_release_request_pad (dbin->multiqueue, slot->sink_pad);
+  gst_object_replace ((GstObject **) & slot->sink_pad, NULL);
+  gst_object_replace ((GstObject **) & slot->src_pad, NULL);
+  gst_object_replace ((GstObject **) & slot->active_stream, NULL);
+  g_free (slot);
+}
+
+/* Create a DecodebinOutputStream for a given type
+ * Note: It will be empty initially, it needs to be configured
+ * afterwards */
+static DecodebinOutputStream *
+create_output_stream (GstDecodebin3 * dbin, GstStreamType type)
+{
+  DecodebinOutputStream *res = g_new0 (DecodebinOutputStream, 1);
+  gchar *pad_name;
+  const gchar *prefix;
+  GstStaticPadTemplate *templ;
+  GstPadTemplate *ptmpl;
+  guint32 *counter;
+  GstPad *internal_pad;
+
+  GST_DEBUG_OBJECT (dbin, "Created new output stream %p for type %s",
+      res, gst_stream_type_get_name (type));
+
+  res->type = type;
+  res->dbin = dbin;
+
+  switch (type) {
+    case GST_STREAM_TYPE_VIDEO:
+      templ = &video_src_template;
+      counter = &dbin->vpadcount;
+      prefix = "video";
+      break;
+    case GST_STREAM_TYPE_AUDIO:
+      templ = &audio_src_template;
+      counter = &dbin->apadcount;
+      prefix = "audio";
+      break;
+    case GST_STREAM_TYPE_TEXT:
+      templ = &text_src_template;
+      counter = &dbin->tpadcount;
+      prefix = "text";
+      break;
+    default:
+      templ = &src_template;
+      counter = &dbin->opadcount;
+      prefix = "src";
+      break;
+  }
+
+  pad_name = g_strdup_printf ("%s_%u", prefix, *counter);
+  *counter += 1;
+  ptmpl = gst_static_pad_template_get (templ);
+  res->src_pad = gst_ghost_pad_new_no_target_from_template (pad_name, ptmpl);
+  gst_object_unref (ptmpl);
+  g_free (pad_name);
+  gst_pad_set_active (res->src_pad, TRUE);
+  /* Put an event probe on the internal proxy pad to detect upstream
+   * events */
+  internal_pad =
+      (GstPad *) gst_proxy_pad_get_internal ((GstProxyPad *) res->src_pad);
+  gst_pad_add_probe (internal_pad, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
+      (GstPadProbeCallback) ghost_pad_event_probe, res, NULL);
+  gst_object_unref (internal_pad);
+
+  dbin->output_streams = g_list_append (dbin->output_streams, res);
+
+  return res;
+}
+
+static void
+free_output_stream (GstDecodebin3 * dbin, DecodebinOutputStream * output)
+{
+  if (output->slot) {
+    if (output->decoder_sink && output->decoder)
+      gst_pad_unlink (output->slot->src_pad, output->decoder_sink);
+
+    output->slot->output = NULL;
+    output->slot = NULL;
+  }
+  gst_object_replace ((GstObject **) & output->decoder_sink, NULL);
+  gst_ghost_pad_set_target ((GstGhostPad *) output->src_pad, NULL);
+  gst_object_replace ((GstObject **) & output->decoder_src, NULL);
+  if (output->src_exposed) {
+    gst_element_remove_pad ((GstElement *) dbin, output->src_pad);
+  }
+  if (output->decoder) {
+    gst_element_set_locked_state (output->decoder, TRUE);
+    gst_element_set_state (output->decoder, GST_STATE_NULL);
+    gst_bin_remove ((GstBin *) dbin, output->decoder);
+  }
+  g_free (output);
+}
+
+static GstStateChangeReturn
+gst_decodebin3_change_state (GstElement * element, GstStateChange transition)
+{
+  GstDecodebin3 *dbin = (GstDecodebin3 *) element;
+  GstStateChangeReturn ret;
+
+  /* Upwards */
+  switch (transition) {
+    default:
+      break;
+  }
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+  if (ret == GST_STATE_CHANGE_FAILURE)
+    goto beach;
+
+  switch (transition) {
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+    {
+      GList *tmp;
+
+      /* Free output streams */
+      for (tmp = dbin->output_streams; tmp; tmp = tmp->next) {
+        DecodebinOutputStream *output = (DecodebinOutputStream *) tmp->data;
+        free_output_stream (dbin, output);
+      }
+      g_list_free (dbin->output_streams);
+      dbin->output_streams = NULL;
+      /* Free multiqueue slots */
+      for (tmp = dbin->slots; tmp; tmp = tmp->next) {
+        MultiQueueSlot *slot = (MultiQueueSlot *) tmp->data;
+        free_multiqueue_slot (dbin, slot);
+      }
+      g_list_free (dbin->slots);
+      dbin->slots = NULL;
+      /* Free inputs */
+    }
+      break;
+    default:
+      break;
+  }
+beach:
+  return ret;
+}
+
+gboolean
+gst_decodebin3_plugin_init (GstPlugin * plugin)
+{
+  GST_DEBUG_CATEGORY_INIT (decodebin3_debug, "decodebin3", 0, "decoder bin");
+
+  return gst_element_register (plugin, "decodebin3", GST_RANK_NONE,
+      GST_TYPE_DECODEBIN3);
+}
diff --git a/gst/playback/gstparsebin.c b/gst/playback/gstparsebin.c
new file mode 100644
index 0000000..84de64d
--- /dev/null
+++ b/gst/playback/gstparsebin.c
@@ -0,0 +1,4410 @@
+/* GStreamer
+ * Copyright (C) <2006> Edward Hervey <edward@fluendo.com>
+ * Copyright (C) <2009> Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * Copyright (C) <2011> Hewlett-Packard Development Company, L.P.
+ *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
+ * Copyright (C) <2013> Collabora Ltd.
+ *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * Copyright (C) <2015-2016> Centricular Ltd
+ *  @author: Edward Hervey <edward@centricular.com>
+ *  @author: Jan Schmidt <jan@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.
+ */
+
+/**
+ * SECTION:element-parsebin
+ *
+ * #GstBin that auto-magically constructs a parsing pipeline
+ * using available parsers and demuxers via auto-plugging.
+ *
+ * parsebin unpacks the contents of the input stream to the
+ * level of parsed elementary streams, but unlike decodebin
+ * it doesn't connect decoder elements. The output pads
+ * produce packetised encoded data with timestamps where possible,
+ * or send missing-element messages where not.
+ *
+ * <emphasis>parsebin is still experimental API and a technology preview.
+ * Its behaviour and exposed API is subject to change.</emphasis>
+ */
+
+/* Implementation notes:
+ *
+ * The following section describes how ParseBin works internally.
+ *
+ * The first part of ParseBin is its typefind element, which tries
+ * to determine the media type of the input stream. If the type is found
+ * autoplugging starts.
+ *
+ * ParseBin internally organizes the elements it autoplugged into
+ * GstParseChains and GstParseGroups. A parse chain is a single chain
+ * of parsing, this
+ * means that if ParseBin ever autoplugs an element with two+ srcpads
+ * (e.g. a demuxer) this will end the chain and everything following this
+ * demuxer will be put into parse groups below the chain. Otherwise,
+ * if an element has a single srcpad that outputs raw data the parse chain
+ * is ended too and a GstParsePad is stored and blocked.
+ *
+ * A parse group combines a number of chains that are created by a
+ * demuxer element.
+ *
+ * This continues until the top-level parse chain is complete. A parse
+ * chain is complete if it either ends with a blocked elementary stream,
+ * if autoplugging stopped because no suitable plugins could be found
+ * or if the active group is complete. A parse group on the other hand
+ * is complete if all child chains are complete.
+ *
+ * If this happens at some point, all end pads of all active groups are exposed.
+ * For this ParseBin adds the end pads, and then unblocks them. Now playback starts.
+ *
+ * If one of the chains that end on a endpad receives EOS ParseBin checks
+ * if all chains and groups are drained. In that case everything goes into EOS.
+ * If there is a chain where the active group is drained but there exist next
+ * groups, the active group is hidden (endpads are removed) and the next group
+ * is exposed. This means that in some cases more pads may be created even
+ * after the initial no-more-pads signal. This happens for example with
+ * so-called "chained oggs", most commonly found among ogg/vorbis internet
+ * radio streams.
+ *
+ * Note 1: If we're talking about blocked endpads this really means that the
+ * *target* pads of the endpads are blocked. Pads that are exposed to the outside
+ * should never ever be blocked!
+ *
+ * Note 2: If a group is complete and the parent's chain demuxer adds new pads
+ * but never signaled no-more-pads this additional pads will be ignored!
+ *
+ */
+
+/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
+ * with newer GLib versions (>= 2.31.0) */
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst-i18n-plugin.h>
+
+#include <string.h>
+#include <gst/gst.h>
+#include <gst/pbutils/pbutils.h>
+
+#include "gstplay-enum.h"
+#include "gstplayback.h"
+
+/* Also used by gsturidecodebin.c */
+gint _parse_bin_compare_factories_func (gconstpointer p1, gconstpointer p2);
+
+/* generic templates */
+static GstStaticPadTemplate decoder_bin_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS_ANY);
+
+static GstStaticPadTemplate decoder_bin_src_template =
+GST_STATIC_PAD_TEMPLATE ("src_%u",
+    GST_PAD_SRC,
+    GST_PAD_SOMETIMES,
+    GST_STATIC_CAPS_ANY);
+
+GST_DEBUG_CATEGORY_STATIC (gst_parse_bin_debug);
+#define GST_CAT_DEFAULT gst_parse_bin_debug
+
+typedef struct _GstPendingPad GstPendingPad;
+typedef struct _GstParseElement GstParseElement;
+typedef struct _GstParseChain GstParseChain;
+typedef struct _GstParseGroup GstParseGroup;
+typedef struct _GstParsePad GstParsePad;
+typedef GstGhostPadClass GstParsePadClass;
+typedef struct _GstParseBin GstParseBin;
+typedef struct _GstParseBinClass GstParseBinClass;
+
+#define GST_TYPE_PARSE_BIN             (gst_parse_bin_get_type())
+#define GST_PARSE_BIN_CAST(obj)        ((GstParseBin*)(obj))
+#define GST_PARSE_BIN(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PARSE_BIN,GstParseBin))
+#define GST_PARSE_BIN_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PARSE_BIN,GstParseBinClass))
+#define GST_IS_parse_bin(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PARSE_BIN))
+#define GST_IS_parse_bin_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PARSE_BIN))
+
+/**
+ *  GstParseBin:
+ *
+ *  The opaque #GstParseBin data structure
+ */
+struct _GstParseBin
+{
+  GstBin bin;                   /* we extend GstBin */
+
+  /* properties */
+  gchar *encoding;              /* encoding of subtitles */
+  guint64 connection_speed;
+
+  GstElement *typefind;         /* this holds the typefind object */
+
+  GMutex expose_lock;           /* Protects exposal and removal of groups */
+  GstParseChain *parse_chain;   /* Top level parse chain */
+  guint nbpads;                 /* unique identifier for source pads */
+
+  GMutex factories_lock;
+  guint32 factories_cookie;     /* Cookie from last time when factories was updated */
+  GList *factories;             /* factories we can use for selecting elements */
+
+  GMutex subtitle_lock;         /* Protects changes to subtitles and encoding */
+  GList *subtitles;             /* List of elements with subtitle-encoding,
+                                 * protected by above mutex! */
+
+  gboolean have_type;           /* if we received the have_type signal */
+  guint have_type_id;           /* signal id for have-type from typefind */
+
+  gboolean async_pending;       /* async-start has been emitted */
+
+  GMutex dyn_lock;              /* lock protecting pad blocking */
+  gboolean shutdown;            /* if we are shutting down */
+  GList *blocked_pads;          /* pads that have set to block */
+
+  gboolean expose_allstreams;   /* Whether to expose unknow type streams or not */
+
+  GList *filtered;              /* elements for which error messages are filtered */
+  GList *filtered_errors;       /* filtered error messages */
+};
+
+struct _GstParseBinClass
+{
+  GstBinClass parent_class;
+
+  /* signal fired when we found a pad that we cannot decode */
+  void (*unknown_type) (GstElement * element, GstPad * pad, GstCaps * caps);
+
+  /* signal fired to know if we continue trying to decode the given caps */
+    gboolean (*autoplug_continue) (GstElement * element, GstPad * pad,
+      GstCaps * caps);
+  /* signal fired to get a list of factories to try to autoplug */
+  GValueArray *(*autoplug_factories) (GstElement * element, GstPad * pad,
+      GstCaps * caps);
+  /* signal fired to sort the factories */
+  GValueArray *(*autoplug_sort) (GstElement * element, GstPad * pad,
+      GstCaps * caps, GValueArray * factories);
+  /* signal fired to select from the proposed list of factories */
+    GstAutoplugSelectResult (*autoplug_select) (GstElement * element,
+      GstPad * pad, GstCaps * caps, GstElementFactory * factory);
+  /* signal fired when a autoplugged element that is not linked downstream
+   * or exposed wants to query something */
+    gboolean (*autoplug_query) (GstElement * element, GstPad * pad,
+      GstQuery * query);
+
+  /* fired when the last group is drained */
+  void (*drained) (GstElement * element);
+};
+
+/* signals */
+enum
+{
+  SIGNAL_UNKNOWN_TYPE,
+  SIGNAL_AUTOPLUG_CONTINUE,
+  SIGNAL_AUTOPLUG_FACTORIES,
+  SIGNAL_AUTOPLUG_SELECT,
+  SIGNAL_AUTOPLUG_SORT,
+  SIGNAL_AUTOPLUG_QUERY,
+  SIGNAL_DRAINED,
+  LAST_SIGNAL
+};
+
+#define DEFAULT_SUBTITLE_ENCODING NULL
+#define DEFAULT_USE_BUFFERING     FALSE
+#define DEFAULT_LOW_PERCENT       10
+#define DEFAULT_HIGH_PERCENT      99
+/* by default we use the automatic values above */
+#define DEFAULT_EXPOSE_ALL_STREAMS  TRUE
+#define DEFAULT_CONNECTION_SPEED    0
+
+/* Properties */
+enum
+{
+  PROP_0,
+  PROP_SUBTITLE_ENCODING,
+  PROP_SINK_CAPS,
+  PROP_EXPOSE_ALL_STREAMS,
+  PROP_CONNECTION_SPEED
+};
+
+static GstBinClass *parent_class;
+static guint gst_parse_bin_signals[LAST_SIGNAL] = { 0 };
+
+static void do_async_start (GstParseBin * parsebin);
+static void do_async_done (GstParseBin * parsebin);
+
+static void type_found (GstElement * typefind, guint probability,
+    GstCaps * caps, GstParseBin * parse_bin);
+
+static gboolean gst_parse_bin_autoplug_continue (GstElement * element,
+    GstPad * pad, GstCaps * caps);
+static GValueArray *gst_parse_bin_autoplug_factories (GstElement *
+    element, GstPad * pad, GstCaps * caps);
+static GValueArray *gst_parse_bin_autoplug_sort (GstElement * element,
+    GstPad * pad, GstCaps * caps, GValueArray * factories);
+static GstAutoplugSelectResult gst_parse_bin_autoplug_select (GstElement *
+    element, GstPad * pad, GstCaps * caps, GstElementFactory * factory);
+static gboolean gst_parse_bin_autoplug_query (GstElement * element,
+    GstPad * pad, GstQuery * query);
+
+static void gst_parse_bin_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_parse_bin_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+static void caps_notify_cb (GstPad * pad, GParamSpec * unused,
+    GstParseChain * chain);
+
+static GstStateChangeReturn gst_parse_bin_change_state (GstElement * element,
+    GstStateChange transition);
+static void gst_parse_bin_handle_message (GstBin * bin, GstMessage * message);
+static void gst_parse_pad_update_caps (GstParsePad * parsepad, GstCaps * caps);
+static void gst_parse_pad_update_tags (GstParsePad * parsepad,
+    GstTagList * tags);
+static GstEvent *gst_parse_pad_stream_start_event (GstParsePad * parsepad,
+    GstEvent * event);
+static void gst_parse_pad_update_stream_collection (GstParsePad * parsepad,
+    GstStreamCollection * collection);
+
+static GstCaps *get_pad_caps (GstPad * pad);
+
+#define EXPOSE_LOCK(parsebin) G_STMT_START {				\
+    GST_LOG_OBJECT (parsebin,						\
+		    "expose locking from thread %p",			\
+		    g_thread_self ());					\
+    g_mutex_lock (&GST_PARSE_BIN_CAST(parsebin)->expose_lock);		\
+    GST_LOG_OBJECT (parsebin,						\
+		    "expose locked from thread %p",			\
+		    g_thread_self ());					\
+} G_STMT_END
+
+#define EXPOSE_UNLOCK(parsebin) G_STMT_START {				\
+    GST_LOG_OBJECT (parsebin,						\
+		    "expose unlocking from thread %p",			\
+		    g_thread_self ());					\
+    g_mutex_unlock (&GST_PARSE_BIN_CAST(parsebin)->expose_lock);		\
+} G_STMT_END
+
+#define DYN_LOCK(parsebin) G_STMT_START {			\
+    GST_LOG_OBJECT (parsebin,						\
+		    "dynlocking from thread %p",			\
+		    g_thread_self ());					\
+    g_mutex_lock (&GST_PARSE_BIN_CAST(parsebin)->dyn_lock);			\
+    GST_LOG_OBJECT (parsebin,						\
+		    "dynlocked from thread %p",				\
+		    g_thread_self ());					\
+} G_STMT_END
+
+#define DYN_UNLOCK(parsebin) G_STMT_START {			\
+    GST_LOG_OBJECT (parsebin,						\
+		    "dynunlocking from thread %p",			\
+		    g_thread_self ());					\
+    g_mutex_unlock (&GST_PARSE_BIN_CAST(parsebin)->dyn_lock);		\
+} G_STMT_END
+
+#define SUBTITLE_LOCK(parsebin) G_STMT_START {				\
+    GST_LOG_OBJECT (parsebin,						\
+		    "subtitle locking from thread %p",			\
+		    g_thread_self ());					\
+    g_mutex_lock (&GST_PARSE_BIN_CAST(parsebin)->subtitle_lock);		\
+    GST_LOG_OBJECT (parsebin,						\
+		    "subtitle lock from thread %p",			\
+		    g_thread_self ());					\
+} G_STMT_END
+
+#define SUBTITLE_UNLOCK(parsebin) G_STMT_START {				\
+    GST_LOG_OBJECT (parsebin,						\
+		    "subtitle unlocking from thread %p",		\
+		    g_thread_self ());					\
+    g_mutex_unlock (&GST_PARSE_BIN_CAST(parsebin)->subtitle_lock);		\
+} G_STMT_END
+
+struct _GstPendingPad
+{
+  GstPad *pad;
+  GstParseChain *chain;
+  gulong event_probe_id;
+  gulong notify_caps_id;
+};
+
+struct _GstParseElement
+{
+  GstElement *element;
+  GstElement *capsfilter;       /* Optional capsfilter for Parser/Convert */
+  gulong pad_added_id;
+  gulong pad_removed_id;
+  gulong no_more_pads_id;
+};
+
+/* GstParseGroup
+ *
+ * Streams belonging to the same group/chain of a media file
+ *
+ * When changing something here lock the parent chain!
+ */
+struct _GstParseGroup
+{
+  GstParseBin *parsebin;
+  GstParseChain *parent;
+
+  gboolean no_more_pads;        /* TRUE if the demuxer signaled no-more-pads */
+  gboolean drained;             /* TRUE if the all children are drained */
+
+  GList *children;              /* List of GstParseChains in this group */
+};
+
+struct _GstParseChain
+{
+  GstParseGroup *parent;
+  GstParseBin *parsebin;
+
+  GMutex lock;                  /* Protects this chain and its groups */
+
+  GstPad *pad;                  /* srcpad that caused creation of this chain */
+  GstCaps *start_caps;          /* The initial caps of this chain */
+
+  gboolean drained;             /* TRUE if the all children are drained */
+  gboolean demuxer;             /* TRUE if elements->data is a demuxer */
+  gboolean parsed;              /* TRUE if any elements are a parser */
+  GList *elements;              /* All elements in this group, first
+                                   is the latest and most downstream element */
+
+  /* Note: there are only groups if the last element of this chain
+   * is a demuxer, otherwise the chain will end with an endpad.
+   * The other way around this means, that endpad only exists if this
+   * chain doesn't end with a demuxer! */
+
+  GstParseGroup *active_group;  /* Currently active group */
+  GList *next_groups;           /* head is newest group, tail is next group.
+                                   a new group will be created only if the head
+                                   group had no-more-pads. If it's only exposed
+                                   all new pads will be ignored! */
+  GList *pending_pads;          /* Pads that have no fixed caps yet */
+
+  GstParsePad *current_pad;     /* Current ending pad of the chain that can't
+                                 * be exposed yet but would be the same as endpad
+                                 * once it can be exposed */
+  GstParsePad *endpad;          /* Pad of this chain that could be exposed */
+  gboolean deadend;             /* This chain is incomplete and can't be completed,
+                                   e.g. no suitable decoder could be found
+                                   e.g. stream got EOS without buffers
+                                 */
+  gchar *deadend_details;
+  GstCaps *endcaps;             /* Caps that were used when linking to the endpad
+                                   or that resulted in the deadend
+                                 */
+
+  /* FIXME: This should be done directly via a thread! */
+  GList *old_groups;            /* Groups that should be freed later */
+};
+
+static void gst_parse_chain_free (GstParseChain * chain);
+static GstParseChain *gst_parse_chain_new (GstParseBin * parsebin,
+    GstParseGroup * group, GstPad * pad, GstCaps * start_caps);
+static void gst_parse_group_hide (GstParseGroup * group);
+static void gst_parse_group_free (GstParseGroup * group);
+static GstParseGroup *gst_parse_group_new (GstParseBin * parsebin,
+    GstParseChain * chain);
+static gboolean gst_parse_chain_is_complete (GstParseChain * chain);
+static gboolean gst_parse_chain_expose (GstParseChain * chain,
+    GList ** endpads, gboolean * missing_plugin,
+    GString * missing_plugin_details, gboolean * last_group,
+    gboolean * uncollected_streams);
+static void build_fallback_collection (GstParseChain * chain,
+    GstStreamCollection * collection);
+static gboolean gst_parse_chain_is_drained (GstParseChain * chain);
+static gboolean gst_parse_group_is_complete (GstParseGroup * group);
+static gboolean gst_parse_group_is_drained (GstParseGroup * group);
+
+static gboolean gst_parse_bin_expose (GstParseBin * parsebin);
+
+#define CHAIN_MUTEX_LOCK(chain) G_STMT_START {				\
+    GST_LOG_OBJECT (chain->parsebin,					\
+		    "locking chain %p from thread %p",			\
+		    chain, g_thread_self ());				\
+    g_mutex_lock (&chain->lock);						\
+    GST_LOG_OBJECT (chain->parsebin,					\
+		    "locked chain %p from thread %p",			\
+		    chain, g_thread_self ());				\
+} G_STMT_END
+
+#define CHAIN_MUTEX_UNLOCK(chain) G_STMT_START {                        \
+    GST_LOG_OBJECT (chain->parsebin,					\
+		    "unlocking chain %p from thread %p",		\
+		    chain, g_thread_self ());				\
+    g_mutex_unlock (&chain->lock);					\
+} G_STMT_END
+
+/* GstParsePad
+ *
+ * GstPad private used for source pads of chains
+ */
+struct _GstParsePad
+{
+  GstGhostPad parent;
+  GstParseBin *parsebin;
+  GstParseChain *chain;
+
+  gboolean blocked;             /* the *target* pad is blocked */
+  gboolean exposed;             /* the pad is exposed */
+  gboolean drained;             /* an EOS has been seen on the pad */
+
+  gulong block_id;
+
+  gboolean in_a_fallback_collection;
+  GstStreamCollection *active_collection;
+  GstStream *active_stream;
+};
+
+GType gst_parse_pad_get_type (void);
+G_DEFINE_TYPE (GstParsePad, gst_parse_pad, GST_TYPE_GHOST_PAD);
+#define GST_TYPE_PARSE_PAD (gst_parse_pad_get_type ())
+#define GST_PARSE_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PARSE_PAD,GstParsePad))
+
+static GstParsePad *gst_parse_pad_new (GstParseBin * parsebin,
+    GstParseChain * chain);
+static void gst_parse_pad_activate (GstParsePad * parsepad,
+    GstParseChain * chain);
+static void gst_parse_pad_unblock (GstParsePad * parsepad);
+static void gst_parse_pad_set_blocked (GstParsePad * parsepad,
+    gboolean blocked);
+static gboolean gst_parse_pad_query (GstPad * pad, GstObject * parent,
+    GstQuery * query);
+static GstPadProbeReturn
+gst_parse_pad_event (GstPad * pad, GstPadProbeInfo * info, gpointer user_data);
+
+
+static void gst_pending_pad_free (GstPendingPad * ppad);
+static GstPadProbeReturn pad_event_cb (GstPad * pad, GstPadProbeInfo * info,
+    gpointer data);
+
+/********************************
+ * Standard GObject boilerplate *
+ ********************************/
+
+static void gst_parse_bin_class_init (GstParseBinClass * klass);
+static void gst_parse_bin_init (GstParseBin * parse_bin);
+static void gst_parse_bin_dispose (GObject * object);
+static void gst_parse_bin_finalize (GObject * object);
+
+static GType
+gst_parse_bin_get_type (void)
+{
+  static GType gst_parse_bin_type = 0;
+
+  if (!gst_parse_bin_type) {
+    static const GTypeInfo gst_parse_bin_info = {
+      sizeof (GstParseBinClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) gst_parse_bin_class_init,
+      NULL,
+      NULL,
+      sizeof (GstParseBin),
+      0,
+      (GInstanceInitFunc) gst_parse_bin_init,
+      NULL
+    };
+
+    gst_parse_bin_type =
+        g_type_register_static (GST_TYPE_BIN, "GstParseBin",
+        &gst_parse_bin_info, 0);
+  }
+
+  return gst_parse_bin_type;
+}
+
+static gboolean
+_gst_boolean_accumulator (GSignalInvocationHint * ihint,
+    GValue * return_accu, const GValue * handler_return, gpointer dummy)
+{
+  gboolean myboolean;
+
+  myboolean = g_value_get_boolean (handler_return);
+  if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
+    g_value_set_boolean (return_accu, myboolean);
+
+  /* stop emission if FALSE */
+  return myboolean;
+}
+
+static gboolean
+_gst_boolean_or_accumulator (GSignalInvocationHint * ihint,
+    GValue * return_accu, const GValue * handler_return, gpointer dummy)
+{
+  gboolean myboolean;
+  gboolean retboolean;
+
+  myboolean = g_value_get_boolean (handler_return);
+  retboolean = g_value_get_boolean (return_accu);
+
+  if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
+    g_value_set_boolean (return_accu, myboolean || retboolean);
+
+  return TRUE;
+}
+
+/* we collect the first result */
+static gboolean
+_gst_array_accumulator (GSignalInvocationHint * ihint,
+    GValue * return_accu, const GValue * handler_return, gpointer dummy)
+{
+  gpointer array;
+
+  array = g_value_get_boxed (handler_return);
+  if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
+    g_value_set_boxed (return_accu, array);
+
+  return FALSE;
+}
+
+static gboolean
+_gst_select_accumulator (GSignalInvocationHint * ihint,
+    GValue * return_accu, const GValue * handler_return, gpointer dummy)
+{
+  GstAutoplugSelectResult res;
+
+  res = g_value_get_enum (handler_return);
+  if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
+    g_value_set_enum (return_accu, res);
+
+  /* Call the next handler in the chain (if any) when the current callback
+   * returns TRY. This makes it possible to register separate autoplug-select
+   * handlers that implement different TRY/EXPOSE/SKIP strategies.
+   */
+  if (res == GST_AUTOPLUG_SELECT_TRY)
+    return TRUE;
+
+  return FALSE;
+}
+
+static gboolean
+_gst_array_hasvalue_accumulator (GSignalInvocationHint * ihint,
+    GValue * return_accu, const GValue * handler_return, gpointer dummy)
+{
+  gpointer array;
+
+  array = g_value_get_boxed (handler_return);
+  if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
+    g_value_set_boxed (return_accu, array);
+
+  if (array != NULL)
+    return FALSE;
+
+  return TRUE;
+}
+
+static void
+gst_parse_bin_class_init (GstParseBinClass * klass)
+{
+  GObjectClass *gobject_klass;
+  GstElementClass *gstelement_klass;
+  GstBinClass *gstbin_klass;
+
+  gobject_klass = (GObjectClass *) klass;
+  gstelement_klass = (GstElementClass *) klass;
+  gstbin_klass = (GstBinClass *) klass;
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  gobject_klass->dispose = gst_parse_bin_dispose;
+  gobject_klass->finalize = gst_parse_bin_finalize;
+  gobject_klass->set_property = gst_parse_bin_set_property;
+  gobject_klass->get_property = gst_parse_bin_get_property;
+
+  /**
+   * GstParseBin::unknown-type:
+   * @bin: The ParseBin.
+   * @pad: The new pad containing caps that cannot be resolved to a 'final'
+   *       stream type.
+   * @caps: The #GstCaps of the pad that cannot be resolved.
+   *
+   * This signal is emitted when a pad for which there is no further possible
+   * decoding is added to the ParseBin.
+   */
+  gst_parse_bin_signals[SIGNAL_UNKNOWN_TYPE] =
+      g_signal_new ("unknown-type", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstParseBinClass, unknown_type),
+      NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2,
+      GST_TYPE_PAD, GST_TYPE_CAPS);
+
+  /**
+   * GstParseBin::autoplug-continue:
+   * @bin: The ParseBin.
+   * @pad: The #GstPad.
+   * @caps: The #GstCaps found.
+   *
+   * This signal is emitted whenever ParseBin finds a new stream. It is
+   * emitted before looking for any elements that can handle that stream.
+   *
+   * <note>
+   *   Invocation of signal handlers stops after the first signal handler
+   *   returns #FALSE. Signal handlers are invoked in the order they were
+   *   connected in.
+   * </note>
+   *
+   * Returns: #TRUE if you wish ParseBin to look for elements that can
+   * handle the given @caps. If #FALSE, those caps will be considered as
+   * final and the pad will be exposed as such (see 'pad-added' signal of
+   * #GstElement).
+   */
+  gst_parse_bin_signals[SIGNAL_AUTOPLUG_CONTINUE] =
+      g_signal_new ("autoplug-continue", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstParseBinClass, autoplug_continue),
+      _gst_boolean_accumulator, NULL, g_cclosure_marshal_generic,
+      G_TYPE_BOOLEAN, 2, GST_TYPE_PAD, GST_TYPE_CAPS);
+
+  /**
+   * GstParseBin::autoplug-factories:
+   * @bin: The ParseBin.
+   * @pad: The #GstPad.
+   * @caps: The #GstCaps found.
+   *
+   * This function is emited when an array of possible factories for @caps on
+   * @pad is needed. ParseBin will by default return an array with all
+   * compatible factories, sorted by rank.
+   *
+   * If this function returns NULL, @pad will be exposed as a final caps.
+   *
+   * If this function returns an empty array, the pad will be considered as
+   * having an unhandled type media type.
+   *
+   * <note>
+   *   Only the signal handler that is connected first will ever by invoked.
+   *   Don't connect signal handlers with the #G_CONNECT_AFTER flag to this
+   *   signal, they will never be invoked!
+   * </note>
+   *
+   * Returns: a #GValueArray* with a list of factories to try. The factories are
+   * by default tried in the returned order or based on the index returned by
+   * "autoplug-select".
+   */
+  gst_parse_bin_signals[SIGNAL_AUTOPLUG_FACTORIES] =
+      g_signal_new ("autoplug-factories", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstParseBinClass,
+          autoplug_factories), _gst_array_accumulator, NULL,
+      g_cclosure_marshal_generic, G_TYPE_VALUE_ARRAY, 2,
+      GST_TYPE_PAD, GST_TYPE_CAPS);
+
+  /**
+   * GstParseBin::autoplug-sort:
+   * @bin: The ParseBin.
+   * @pad: The #GstPad.
+   * @caps: The #GstCaps.
+   * @factories: A #GValueArray of possible #GstElementFactory to use.
+   *
+   * Once ParseBin has found the possible #GstElementFactory objects to try
+   * for @caps on @pad, this signal is emited. The purpose of the signal is for
+   * the application to perform additional sorting or filtering on the element
+   * factory array.
+   *
+   * The callee should copy and modify @factories or return #NULL if the
+   * order should not change.
+   *
+   * <note>
+   *   Invocation of signal handlers stops after one signal handler has
+   *   returned something else than #NULL. Signal handlers are invoked in
+   *   the order they were connected in.
+   *   Don't connect signal handlers with the #G_CONNECT_AFTER flag to this
+   *   signal, they will never be invoked!
+   * </note>
+   *
+   * Returns: A new sorted array of #GstElementFactory objects.
+   */
+  gst_parse_bin_signals[SIGNAL_AUTOPLUG_SORT] =
+      g_signal_new ("autoplug-sort", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstParseBinClass, autoplug_sort),
+      _gst_array_hasvalue_accumulator, NULL,
+      g_cclosure_marshal_generic, G_TYPE_VALUE_ARRAY, 3, GST_TYPE_PAD,
+      GST_TYPE_CAPS, G_TYPE_VALUE_ARRAY | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+  /**
+   * GstParseBin::autoplug-select:
+   * @bin: The ParseBin.
+   * @pad: The #GstPad.
+   * @caps: The #GstCaps.
+   * @factory: A #GstElementFactory to use.
+   *
+   * This signal is emitted once ParseBin has found all the possible
+   * #GstElementFactory that can be used to handle the given @caps. For each of
+   * those factories, this signal is emitted.
+   *
+   * The signal handler should return a #GST_TYPE_AUTOPLUG_SELECT_RESULT enum
+   * value indicating what ParseBin should do next.
+   *
+   * A value of #GST_AUTOPLUG_SELECT_TRY will try to autoplug an element from
+   * @factory.
+   *
+   * A value of #GST_AUTOPLUG_SELECT_EXPOSE will expose @pad without plugging
+   * any element to it.
+   *
+   * A value of #GST_AUTOPLUG_SELECT_SKIP will skip @factory and move to the
+   * next factory.
+   *
+   * <note>
+   *   The signal handler will not be invoked if any of the previously
+   *   registered signal handlers (if any) return a value other than
+   *   GST_AUTOPLUG_SELECT_TRY. Which also means that if you return
+   *   GST_AUTOPLUG_SELECT_TRY from one signal handler, handlers that get
+   *   registered next (again, if any) can override that decision.
+   * </note>
+   *
+   * Returns: a #GST_TYPE_AUTOPLUG_SELECT_RESULT that indicates the required
+   * operation. the default handler will always return
+   * #GST_AUTOPLUG_SELECT_TRY.
+   */
+  gst_parse_bin_signals[SIGNAL_AUTOPLUG_SELECT] =
+      g_signal_new ("autoplug-select", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstParseBinClass, autoplug_select),
+      _gst_select_accumulator, NULL,
+      g_cclosure_marshal_generic,
+      GST_TYPE_AUTOPLUG_SELECT_RESULT, 3, GST_TYPE_PAD, GST_TYPE_CAPS,
+      GST_TYPE_ELEMENT_FACTORY);
+
+  /**
+   * GstParseBin::autoplug-query:
+   * @bin: The ParseBin.
+   * @child: The child element doing the query
+   * @pad: The #GstPad.
+   * @element: The #GstElement.
+   * @query: The #GstQuery.
+   *
+   * This signal is emitted whenever an autoplugged element that is
+   * not linked downstream yet and not exposed does a query. It can
+   * be used to tell the element about the downstream supported caps
+   * for example.
+   *
+   * Returns: #TRUE if the query was handled, #FALSE otherwise.
+   */
+  gst_parse_bin_signals[SIGNAL_AUTOPLUG_QUERY] =
+      g_signal_new ("autoplug-query", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstParseBinClass, autoplug_query),
+      _gst_boolean_or_accumulator, NULL, g_cclosure_marshal_generic,
+      G_TYPE_BOOLEAN, 3, GST_TYPE_PAD, GST_TYPE_ELEMENT,
+      GST_TYPE_QUERY | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+  /**
+   * GstParseBin::drained
+   * @bin: The ParseBin
+   *
+   * This signal is emitted once ParseBin has finished decoding all the data.
+   */
+  gst_parse_bin_signals[SIGNAL_DRAINED] =
+      g_signal_new ("drained", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstParseBinClass, drained),
+      NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);
+
+  g_object_class_install_property (gobject_klass, PROP_SUBTITLE_ENCODING,
+      g_param_spec_string ("subtitle-encoding", "subtitle encoding",
+          "Encoding to assume if input subtitles are not in UTF-8 encoding. "
+          "If not set, the GST_SUBTITLE_ENCODING environment variable will "
+          "be checked for an encoding to use. If that is not set either, "
+          "ISO-8859-15 will be assumed.", NULL,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_klass, PROP_SINK_CAPS,
+      g_param_spec_boxed ("sink-caps", "Sink Caps",
+          "The caps of the input data. (NULL = use typefind element)",
+          GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstParseBin::expose-all-streams
+   *
+   * Expose streams of unknown type.
+   *
+   * If set to %FALSE, then only the streams that can be decoded to the final
+   * caps (see 'caps' property) will have a pad exposed. Streams that do not
+   * match those caps but could have been decoded will not have decoder plugged
+   * in internally and will not have a pad exposed.
+   */
+  g_object_class_install_property (gobject_klass, PROP_EXPOSE_ALL_STREAMS,
+      g_param_spec_boolean ("expose-all-streams", "Expose All Streams",
+          "Expose all streams, including those of unknown type or that don't match the 'caps' property",
+          DEFAULT_EXPOSE_ALL_STREAMS,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstParseBin2::connection-speed
+   *
+   * Network connection speed in kbps (0 = unknownw)
+   */
+  g_object_class_install_property (gobject_klass, PROP_CONNECTION_SPEED,
+      g_param_spec_uint64 ("connection-speed", "Connection Speed",
+          "Network connection speed in kbps (0 = unknown)",
+          0, G_MAXUINT64 / 1000, DEFAULT_CONNECTION_SPEED,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+
+
+  klass->autoplug_continue =
+      GST_DEBUG_FUNCPTR (gst_parse_bin_autoplug_continue);
+  klass->autoplug_factories =
+      GST_DEBUG_FUNCPTR (gst_parse_bin_autoplug_factories);
+  klass->autoplug_sort = GST_DEBUG_FUNCPTR (gst_parse_bin_autoplug_sort);
+  klass->autoplug_select = GST_DEBUG_FUNCPTR (gst_parse_bin_autoplug_select);
+  klass->autoplug_query = GST_DEBUG_FUNCPTR (gst_parse_bin_autoplug_query);
+
+  gst_element_class_add_pad_template (gstelement_klass,
+      gst_static_pad_template_get (&decoder_bin_sink_template));
+  gst_element_class_add_pad_template (gstelement_klass,
+      gst_static_pad_template_get (&decoder_bin_src_template));
+
+  gst_element_class_set_static_metadata (gstelement_klass,
+      "Parse Bin", "Generic/Bin/Parser",
+      "Parse and de-multiplex to elementary stream",
+      "Jan Schmidt <jan@centricular.com>, "
+      "Edward Hervey <edward@centricular.com>");
+
+  gstelement_klass->change_state =
+      GST_DEBUG_FUNCPTR (gst_parse_bin_change_state);
+
+  gstbin_klass->handle_message =
+      GST_DEBUG_FUNCPTR (gst_parse_bin_handle_message);
+
+  g_type_class_ref (GST_TYPE_PARSE_PAD);
+}
+
+gint
+_parse_bin_compare_factories_func (gconstpointer p1, gconstpointer p2)
+{
+  GstPluginFeature *f1, *f2;
+  gboolean is_parser1, is_parser2;
+
+  f1 = (GstPluginFeature *) p1;
+  f2 = (GstPluginFeature *) p2;
+
+  is_parser1 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f1),
+      GST_ELEMENT_FACTORY_TYPE_PARSER);
+  is_parser2 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f2),
+      GST_ELEMENT_FACTORY_TYPE_PARSER);
+
+
+  /* We want all parsers first as we always want to plug parsers
+   * before decoders */
+  if (is_parser1 && !is_parser2)
+    return -1;
+  else if (!is_parser1 && is_parser2)
+    return 1;
+
+  /* And if it's a both a parser we first sort by rank
+   * and then by factory name */
+  return gst_plugin_feature_rank_compare_func (p1, p2);
+}
+
+/* Must be called with factories lock! */
+static void
+gst_parse_bin_update_factories_list (GstParseBin * parsebin)
+{
+  guint cookie;
+
+  cookie = gst_registry_get_feature_list_cookie (gst_registry_get ());
+  if (!parsebin->factories || parsebin->factories_cookie != cookie) {
+    if (parsebin->factories)
+      gst_plugin_feature_list_free (parsebin->factories);
+    parsebin->factories =
+        gst_element_factory_list_get_elements
+        (GST_ELEMENT_FACTORY_TYPE_DECODABLE, GST_RANK_MARGINAL);
+    parsebin->factories =
+        g_list_sort (parsebin->factories, _parse_bin_compare_factories_func);
+    parsebin->factories_cookie = cookie;
+  }
+}
+
+static void
+gst_parse_bin_init (GstParseBin * parse_bin)
+{
+  /* first filter out the interesting element factories */
+  g_mutex_init (&parse_bin->factories_lock);
+
+  /* we create the typefind element only once */
+  parse_bin->typefind = gst_element_factory_make ("typefind", "typefind");
+  if (!parse_bin->typefind) {
+    g_warning ("can't find typefind element, ParseBin will not work");
+  } else {
+    GstPad *pad;
+    GstPad *gpad;
+    GstPadTemplate *pad_tmpl;
+
+    /* add the typefind element */
+    if (!gst_bin_add (GST_BIN (parse_bin), parse_bin->typefind)) {
+      g_warning ("Could not add typefind element, ParseBin will not work");
+      gst_object_unref (parse_bin->typefind);
+      parse_bin->typefind = NULL;
+    }
+
+    /* get the sinkpad */
+    pad = gst_element_get_static_pad (parse_bin->typefind, "sink");
+
+    /* get the pad template */
+    pad_tmpl = gst_static_pad_template_get (&decoder_bin_sink_template);
+
+    /* ghost the sink pad to ourself */
+    gpad = gst_ghost_pad_new_from_template ("sink", pad, pad_tmpl);
+    gst_pad_set_active (gpad, TRUE);
+    gst_element_add_pad (GST_ELEMENT (parse_bin), gpad);
+
+    gst_object_unref (pad_tmpl);
+    gst_object_unref (pad);
+  }
+
+  g_mutex_init (&parse_bin->expose_lock);
+  parse_bin->parse_chain = NULL;
+
+  g_mutex_init (&parse_bin->dyn_lock);
+  parse_bin->shutdown = FALSE;
+  parse_bin->blocked_pads = NULL;
+
+  g_mutex_init (&parse_bin->subtitle_lock);
+
+  parse_bin->encoding = g_strdup (DEFAULT_SUBTITLE_ENCODING);
+
+  parse_bin->expose_allstreams = DEFAULT_EXPOSE_ALL_STREAMS;
+  parse_bin->connection_speed = DEFAULT_CONNECTION_SPEED;
+}
+
+static void
+gst_parse_bin_dispose (GObject * object)
+{
+  GstParseBin *parse_bin;
+
+  parse_bin = GST_PARSE_BIN (object);
+
+  if (parse_bin->factories)
+    gst_plugin_feature_list_free (parse_bin->factories);
+  parse_bin->factories = NULL;
+
+  if (parse_bin->parse_chain)
+    gst_parse_chain_free (parse_bin->parse_chain);
+  parse_bin->parse_chain = NULL;
+
+  g_free (parse_bin->encoding);
+  parse_bin->encoding = NULL;
+
+  g_list_free (parse_bin->subtitles);
+  parse_bin->subtitles = NULL;
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gst_parse_bin_finalize (GObject * object)
+{
+  GstParseBin *parse_bin;
+
+  parse_bin = GST_PARSE_BIN (object);
+
+  g_mutex_clear (&parse_bin->expose_lock);
+  g_mutex_clear (&parse_bin->dyn_lock);
+  g_mutex_clear (&parse_bin->subtitle_lock);
+  g_mutex_clear (&parse_bin->factories_lock);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gst_parse_bin_set_sink_caps (GstParseBin * parsebin, GstCaps * caps)
+{
+  GST_DEBUG_OBJECT (parsebin, "Setting new caps: %" GST_PTR_FORMAT, caps);
+
+  g_object_set (parsebin->typefind, "force-caps", caps, NULL);
+}
+
+static GstCaps *
+gst_parse_bin_get_sink_caps (GstParseBin * parsebin)
+{
+  GstCaps *caps;
+
+  GST_DEBUG_OBJECT (parsebin, "Getting currently set caps");
+
+  g_object_get (parsebin->typefind, "force-caps", &caps, NULL);
+
+  return caps;
+}
+
+static void
+gst_parse_bin_set_subs_encoding (GstParseBin * parsebin, const gchar * encoding)
+{
+  GList *walk;
+
+  GST_DEBUG_OBJECT (parsebin, "Setting new encoding: %s",
+      GST_STR_NULL (encoding));
+
+  SUBTITLE_LOCK (parsebin);
+  g_free (parsebin->encoding);
+  parsebin->encoding = g_strdup (encoding);
+
+  /* set the subtitle encoding on all added elements */
+  for (walk = parsebin->subtitles; walk; walk = g_list_next (walk)) {
+    g_object_set (G_OBJECT (walk->data), "subtitle-encoding",
+        parsebin->encoding, NULL);
+  }
+  SUBTITLE_UNLOCK (parsebin);
+}
+
+static gchar *
+gst_parse_bin_get_subs_encoding (GstParseBin * parsebin)
+{
+  gchar *encoding;
+
+  GST_DEBUG_OBJECT (parsebin, "Getting currently set encoding");
+
+  SUBTITLE_LOCK (parsebin);
+  encoding = g_strdup (parsebin->encoding);
+  SUBTITLE_UNLOCK (parsebin);
+
+  return encoding;
+}
+
+static void
+gst_parse_bin_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstParseBin *parsebin;
+
+  parsebin = GST_PARSE_BIN (object);
+
+  switch (prop_id) {
+    case PROP_SUBTITLE_ENCODING:
+      gst_parse_bin_set_subs_encoding (parsebin, g_value_get_string (value));
+      break;
+    case PROP_SINK_CAPS:
+      gst_parse_bin_set_sink_caps (parsebin, g_value_get_boxed (value));
+      break;
+    case PROP_EXPOSE_ALL_STREAMS:
+      parsebin->expose_allstreams = g_value_get_boolean (value);
+      break;
+    case PROP_CONNECTION_SPEED:
+      GST_OBJECT_LOCK (parsebin);
+      parsebin->connection_speed = g_value_get_uint64 (value) * 1000;
+      GST_OBJECT_UNLOCK (parsebin);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_parse_bin_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GstParseBin *parsebin;
+
+  parsebin = GST_PARSE_BIN (object);
+  switch (prop_id) {
+    case PROP_SUBTITLE_ENCODING:
+      g_value_take_string (value, gst_parse_bin_get_subs_encoding (parsebin));
+      break;
+    case PROP_SINK_CAPS:
+      g_value_take_boxed (value, gst_parse_bin_get_sink_caps (parsebin));
+      break;
+    case PROP_EXPOSE_ALL_STREAMS:
+      g_value_set_boolean (value, parsebin->expose_allstreams);
+      break;
+    case PROP_CONNECTION_SPEED:
+      GST_OBJECT_LOCK (parsebin);
+      g_value_set_uint64 (value, parsebin->connection_speed / 1000);
+      GST_OBJECT_UNLOCK (parsebin);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+
+/*****
+ * Default autoplug signal handlers
+ *****/
+static gboolean
+gst_parse_bin_autoplug_continue (GstElement * element, GstPad * pad,
+    GstCaps * caps)
+{
+  GST_DEBUG_OBJECT (element, "autoplug-continue returns TRUE");
+
+  /* by default we always continue */
+  return TRUE;
+}
+
+static GValueArray *
+gst_parse_bin_autoplug_factories (GstElement * element, GstPad * pad,
+    GstCaps * caps)
+{
+  GList *list, *tmp;
+  GValueArray *result;
+  GstParseBin *parsebin = GST_PARSE_BIN_CAST (element);
+
+  GST_DEBUG_OBJECT (element, "finding factories");
+
+  /* return all compatible factories for caps */
+  g_mutex_lock (&parsebin->factories_lock);
+  gst_parse_bin_update_factories_list (parsebin);
+  list =
+      gst_element_factory_list_filter (parsebin->factories, caps, GST_PAD_SINK,
+      gst_caps_is_fixed (caps));
+  g_mutex_unlock (&parsebin->factories_lock);
+
+  result = g_value_array_new (g_list_length (list));
+  for (tmp = list; tmp; tmp = tmp->next) {
+    GstElementFactory *factory = GST_ELEMENT_FACTORY_CAST (tmp->data);
+    GValue val = { 0, };
+
+    g_value_init (&val, G_TYPE_OBJECT);
+    g_value_set_object (&val, factory);
+    g_value_array_append (result, &val);
+    g_value_unset (&val);
+  }
+  gst_plugin_feature_list_free (list);
+
+  GST_DEBUG_OBJECT (element, "autoplug-factories returns %p", result);
+
+  return result;
+}
+
+static GValueArray *
+gst_parse_bin_autoplug_sort (GstElement * element, GstPad * pad,
+    GstCaps * caps, GValueArray * factories)
+{
+  return NULL;
+}
+
+static GstAutoplugSelectResult
+gst_parse_bin_autoplug_select (GstElement * element, GstPad * pad,
+    GstCaps * caps, GstElementFactory * factory)
+{
+  /* Try factory. */
+  return GST_AUTOPLUG_SELECT_TRY;
+}
+
+static gboolean
+gst_parse_bin_autoplug_query (GstElement * element, GstPad * pad,
+    GstQuery * query)
+{
+  /* No query handled here */
+  return FALSE;
+}
+
+/********
+ * Discovery methods
+ *****/
+
+static gboolean is_demuxer_element (GstElement * srcelement);
+
+static gboolean connect_pad (GstParseBin * parsebin, GstElement * src,
+    GstParsePad * parsepad, GstPad * pad, GstCaps * caps,
+    GValueArray * factories, GstParseChain * chain, gchar ** deadend_details);
+static GList *connect_element (GstParseBin * parsebin, GstParseElement * delem,
+    GstParseChain * chain);
+static void expose_pad (GstParseBin * parsebin, GstElement * src,
+    GstParsePad * parsepad, GstPad * pad, GstCaps * caps,
+    GstParseChain * chain);
+
+static void pad_added_cb (GstElement * element, GstPad * pad,
+    GstParseChain * chain);
+static void pad_removed_cb (GstElement * element, GstPad * pad,
+    GstParseChain * chain);
+static void no_more_pads_cb (GstElement * element, GstParseChain * chain);
+
+static GstParseGroup *gst_parse_chain_get_current_group (GstParseChain * chain);
+
+static gboolean
+clear_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
+{
+  GST_DEBUG_OBJECT (pad, "clearing sticky event %" GST_PTR_FORMAT, *event);
+  gst_event_unref (*event);
+  *event = NULL;
+  return TRUE;
+}
+
+static gboolean
+copy_sticky_events (GstPad * pad, GstEvent ** eventptr, gpointer user_data)
+{
+  GstParsePad *ppad = GST_PARSE_PAD (user_data);
+  GstEvent *event = gst_event_ref (*eventptr);
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_CAPS:{
+      GstCaps *caps = NULL;
+      gst_event_parse_caps (event, &caps);
+      gst_parse_pad_update_caps (ppad, caps);
+      break;
+    }
+    case GST_EVENT_STREAM_START:{
+      event = gst_parse_pad_stream_start_event (ppad, event);
+      break;
+    }
+    case GST_EVENT_STREAM_COLLECTION:{
+      GstStreamCollection *collection = NULL;
+      gst_event_parse_stream_collection (event, &collection);
+      gst_parse_pad_update_stream_collection (ppad, collection);
+      break;
+    }
+    default:
+      break;
+  }
+
+  GST_DEBUG_OBJECT (ppad, "store sticky event %" GST_PTR_FORMAT, event);
+  gst_pad_store_sticky_event (GST_PAD_CAST (ppad), event);
+  gst_event_unref (event);
+
+  return TRUE;
+}
+
+static void
+parse_pad_set_target (GstParsePad * parsepad, GstPad * target)
+{
+  GstPad *old_target = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (parsepad));
+  if (old_target)
+    gst_object_unref (old_target);
+
+  if (old_target == target)
+    return;
+
+  gst_pad_sticky_events_foreach (GST_PAD_CAST (parsepad),
+      clear_sticky_events, NULL);
+  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (parsepad), target);
+
+  if (target == NULL) {
+    GST_LOG_OBJECT (parsepad->parsebin, "Setting pad %" GST_PTR_FORMAT
+        " target to NULL", parsepad);
+  } else {
+    GST_LOG_OBJECT (parsepad->parsebin, "Setting pad %" GST_PTR_FORMAT
+        " target to %" GST_PTR_FORMAT, parsepad, target);
+    gst_pad_sticky_events_foreach (target, copy_sticky_events, parsepad);
+  }
+}
+
+/* called when a new pad is discovered. It will perform some basic actions
+ * before trying to link something to it.
+ *
+ *  - Check the caps, don't do anything when there are no caps or when they have
+ *    no good type.
+ *  - signal AUTOPLUG_CONTINUE to check if we need to continue autoplugging this
+ *    pad.
+ *  - if the caps are non-fixed, setup a handler to continue autoplugging when
+ *    the caps become fixed (connect to notify::caps).
+ *  - get list of factories to autoplug.
+ *  - continue autoplugging to one of the factories.
+ */
+static void
+analyze_new_pad (GstParseBin * parsebin, GstElement * src, GstPad * pad,
+    GstCaps * caps, GstParseChain * chain)
+{
+  gboolean apcontinue = TRUE;
+  GValueArray *factories = NULL, *result = NULL;
+  GstParsePad *parsepad;
+  GstElementFactory *factory;
+  const gchar *classification;
+  gboolean is_parser_converter = FALSE;
+  gboolean res;
+  gchar *deadend_details = NULL;
+
+  GST_DEBUG_OBJECT (parsebin, "Pad %s:%s caps:%" GST_PTR_FORMAT,
+      GST_DEBUG_PAD_NAME (pad), caps);
+
+  if (chain->elements
+      && src != ((GstParseElement *) chain->elements->data)->element
+      && src != ((GstParseElement *) chain->elements->data)->capsfilter) {
+    GST_ERROR_OBJECT (parsebin,
+        "New pad from not the last element in this chain");
+    return;
+  }
+
+  if (chain->demuxer) {
+    GstParseGroup *group;
+    GstParseChain *oldchain = chain;
+    GstParseElement *demux = (chain->elements ? chain->elements->data : NULL);
+
+    if (chain->current_pad)
+      gst_object_unref (chain->current_pad);
+    chain->current_pad = NULL;
+
+    /* we are adding a new pad for a demuxer (see is_demuxer_element(),
+     * start a new chain for it */
+    CHAIN_MUTEX_LOCK (oldchain);
+    group = gst_parse_chain_get_current_group (chain);
+    if (group && !g_list_find (group->children, chain)) {
+      chain = gst_parse_chain_new (parsebin, group, pad, caps);
+      group->children = g_list_prepend (group->children, chain);
+    }
+    CHAIN_MUTEX_UNLOCK (oldchain);
+    if (!group) {
+      GST_WARNING_OBJECT (parsebin, "No current group");
+      return;
+    }
+
+    /* If this is not a dynamic pad demuxer, we're no-more-pads
+     * already before anything else happens
+     */
+    if (demux == NULL || !demux->no_more_pads_id)
+      group->no_more_pads = TRUE;
+  }
+
+  /* From here on we own a reference to the caps as
+   * we might create new caps below and would need
+   * to unref them later */
+  if (caps)
+    gst_caps_ref (caps);
+
+  if ((caps == NULL) || gst_caps_is_empty (caps))
+    goto unknown_type;
+
+  if (gst_caps_is_any (caps))
+    goto any_caps;
+
+  if (!chain->current_pad)
+    chain->current_pad = gst_parse_pad_new (parsebin, chain);
+
+  parsepad = gst_object_ref (chain->current_pad);
+  gst_pad_set_active (GST_PAD_CAST (parsepad), TRUE);
+  parse_pad_set_target (parsepad, pad);
+
+  /* 1. Emit 'autoplug-continue' the result will tell us if this pads needs
+   * further autoplugging. Only do this for fixed caps, for unfixed caps
+   * we will later come here again from the notify::caps handler. The
+   * problem with unfixed caps is that, we can't reliably tell if the output
+   * is e.g. accepted by a sink because only parts of the possible final
+   * caps might be accepted by the sink. */
+  if (gst_caps_is_fixed (caps))
+    g_signal_emit (G_OBJECT (parsebin),
+        gst_parse_bin_signals[SIGNAL_AUTOPLUG_CONTINUE], 0, parsepad, caps,
+        &apcontinue);
+  else
+    apcontinue = TRUE;
+
+  /* 1.a if autoplug-continue is FALSE or caps is a raw format, goto pad_is_final */
+  if (!apcontinue)
+    goto expose_pad;
+
+  /* 1.b For Parser/Converter that can output different stream formats
+   * we insert a capsfilter with the sorted caps of all possible next
+   * elements and continue with the capsfilter srcpad */
+  factory = gst_element_get_factory (src);
+  classification =
+      gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);
+  is_parser_converter = (strstr (classification, "Parser")
+      && strstr (classification, "Converter"));
+
+  /* FIXME: We just need to be sure that the next element is not a parser */
+  /* 1.c when the caps are not fixed yet, we can't be sure what element to
+   * connect. We delay autoplugging until the caps are fixed */
+  if (!is_parser_converter && !gst_caps_is_fixed (caps)) {
+    goto non_fixed;
+  } else if (!is_parser_converter) {
+    gst_caps_unref (caps);
+    caps = gst_pad_get_current_caps (pad);
+    if (!caps) {
+      GST_DEBUG_OBJECT (parsebin,
+          "No final caps set yet, delaying autoplugging");
+      gst_object_unref (parsepad);
+      goto setup_caps_delay;
+    }
+  }
+
+  /* 1.d else get the factories and if there's no compatible factory goto
+   * unknown_type */
+  g_signal_emit (G_OBJECT (parsebin),
+      gst_parse_bin_signals[SIGNAL_AUTOPLUG_FACTORIES], 0, parsepad, caps,
+      &factories);
+
+  /* NULL means that we can expose the pad */
+  if (factories == NULL)
+    goto expose_pad;
+
+  /* if the array is empty, we have a type for which we have no decoder */
+  if (factories->n_values == 0) {
+    /* if not we have a unhandled type with no compatible factories */
+    g_value_array_free (factories);
+    gst_object_unref (parsepad);
+    goto unknown_type;
+  }
+
+  /* 1.e sort some more. */
+  g_signal_emit (G_OBJECT (parsebin),
+      gst_parse_bin_signals[SIGNAL_AUTOPLUG_SORT], 0, parsepad, caps, factories,
+      &result);
+  if (result) {
+    g_value_array_free (factories);
+    factories = result;
+  }
+
+  /* 1.g now get the factory template caps and insert the capsfilter if this
+   * is a parser/converter
+   */
+  if (is_parser_converter) {
+    GstCaps *filter_caps;
+    gint i;
+    GstPad *p;
+    GstParseElement *delem;
+
+    g_assert (chain->elements != NULL);
+    delem = (GstParseElement *) chain->elements->data;
+
+    filter_caps = gst_caps_new_empty ();
+    for (i = 0; i < factories->n_values; i++) {
+      GstElementFactory *factory =
+          g_value_get_object (g_value_array_get_nth (factories, i));
+      GstCaps *tcaps, *intersection;
+      const GList *tmps;
+
+      GST_DEBUG ("Trying factory %s",
+          gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
+
+      if (gst_element_get_factory (src) == factory ||
+          gst_element_factory_list_is_type (factory,
+              GST_ELEMENT_FACTORY_TYPE_PARSER)) {
+        GST_DEBUG ("Skipping factory");
+        continue;
+      }
+
+      for (tmps = gst_element_factory_get_static_pad_templates (factory); tmps;
+          tmps = tmps->next) {
+        GstStaticPadTemplate *st = (GstStaticPadTemplate *) tmps->data;
+        if (st->direction != GST_PAD_SINK || st->presence != GST_PAD_ALWAYS)
+          continue;
+        tcaps = gst_static_pad_template_get_caps (st);
+        intersection =
+            gst_caps_intersect_full (tcaps, caps, GST_CAPS_INTERSECT_FIRST);
+        filter_caps = gst_caps_merge (filter_caps, intersection);
+        gst_caps_unref (tcaps);
+      }
+    }
+
+    /* Append the parser caps to prevent any not-negotiated errors */
+    filter_caps = gst_caps_merge (filter_caps, gst_caps_ref (caps));
+
+    delem->capsfilter = gst_element_factory_make ("capsfilter", NULL);
+    g_object_set (G_OBJECT (delem->capsfilter), "caps", filter_caps, NULL);
+    gst_caps_unref (filter_caps);
+    gst_element_set_state (delem->capsfilter, GST_STATE_PAUSED);
+    gst_bin_add (GST_BIN_CAST (parsebin), gst_object_ref (delem->capsfilter));
+
+    parse_pad_set_target (parsepad, NULL);
+    p = gst_element_get_static_pad (delem->capsfilter, "sink");
+    gst_pad_link_full (pad, p, GST_PAD_LINK_CHECK_NOTHING);
+    gst_object_unref (p);
+    p = gst_element_get_static_pad (delem->capsfilter, "src");
+    parse_pad_set_target (parsepad, p);
+    pad = p;
+
+    gst_caps_unref (caps);
+
+    caps = gst_pad_get_current_caps (pad);
+    if (!caps) {
+      GST_DEBUG_OBJECT (parsebin,
+          "No final caps set yet, delaying autoplugging");
+      gst_object_unref (parsepad);
+      g_value_array_free (factories);
+      goto setup_caps_delay;
+    }
+  }
+
+  /* 1.h else continue autoplugging something from the list. */
+  GST_LOG_OBJECT (pad, "Let's continue discovery on this pad");
+  res =
+      connect_pad (parsebin, src, parsepad, pad, caps, factories, chain,
+      &deadend_details);
+
+  /* Need to unref the capsfilter srcpad here if
+   * we inserted a capsfilter */
+  if (is_parser_converter)
+    gst_object_unref (pad);
+
+  gst_object_unref (parsepad);
+  g_value_array_free (factories);
+
+  if (!res)
+    goto unknown_type;
+
+  gst_caps_unref (caps);
+
+  return;
+
+expose_pad:
+  {
+    GST_LOG_OBJECT (parsebin, "Pad is final. autoplug-continue:%d", apcontinue);
+    expose_pad (parsebin, src, parsepad, pad, caps, chain);
+    gst_object_unref (parsepad);
+    gst_caps_unref (caps);
+    return;
+  }
+
+unknown_type:
+  {
+    GST_LOG_OBJECT (pad, "Unknown type, posting message and firing signal");
+
+    chain->deadend_details = deadend_details;
+    chain->deadend = TRUE;
+    chain->endcaps = caps;
+    gst_object_replace ((GstObject **) & chain->current_pad, NULL);
+
+    gst_element_post_message (GST_ELEMENT_CAST (parsebin),
+        gst_missing_decoder_message_new (GST_ELEMENT_CAST (parsebin), caps));
+
+    g_signal_emit (G_OBJECT (parsebin),
+        gst_parse_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, pad, caps);
+
+    /* Try to expose anything */
+    EXPOSE_LOCK (parsebin);
+    if (parsebin->parse_chain) {
+      if (gst_parse_chain_is_complete (parsebin->parse_chain)) {
+        gst_parse_bin_expose (parsebin);
+      }
+    }
+    EXPOSE_UNLOCK (parsebin);
+
+    if (src == parsebin->typefind) {
+      if (!caps || gst_caps_is_empty (caps)) {
+        GST_ELEMENT_ERROR (parsebin, STREAM, TYPE_NOT_FOUND,
+            (_("Could not determine type of stream")), (NULL));
+      }
+      do_async_done (parsebin);
+    }
+    return;
+  }
+#if 1
+non_fixed:
+  {
+    GST_DEBUG_OBJECT (pad, "pad has non-fixed caps delay autoplugging");
+    gst_object_unref (parsepad);
+    goto setup_caps_delay;
+  }
+#endif
+any_caps:
+  {
+    GST_DEBUG_OBJECT (pad, "pad has ANY caps, delaying auto-plugging");
+    goto setup_caps_delay;
+  }
+setup_caps_delay:
+  {
+    GstPendingPad *ppad;
+
+    /* connect to caps notification */
+    CHAIN_MUTEX_LOCK (chain);
+    GST_LOG_OBJECT (parsebin, "Chain %p has now %d dynamic pads", chain,
+        g_list_length (chain->pending_pads));
+    ppad = g_slice_new0 (GstPendingPad);
+    ppad->pad = gst_object_ref (pad);
+    ppad->chain = chain;
+    ppad->event_probe_id =
+        gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
+        pad_event_cb, ppad, NULL);
+    chain->pending_pads = g_list_prepend (chain->pending_pads, ppad);
+    ppad->notify_caps_id = g_signal_connect (pad, "notify::caps",
+        G_CALLBACK (caps_notify_cb), chain);
+    CHAIN_MUTEX_UNLOCK (chain);
+
+    /* If we're here because we have a Parser/Converter
+     * we have to unref the pad */
+    if (is_parser_converter)
+      gst_object_unref (pad);
+    if (caps)
+      gst_caps_unref (caps);
+
+    return;
+  }
+}
+
+static void
+add_error_filter (GstParseBin * parsebin, GstElement * element)
+{
+  GST_OBJECT_LOCK (parsebin);
+  parsebin->filtered = g_list_prepend (parsebin->filtered, element);
+  GST_OBJECT_UNLOCK (parsebin);
+}
+
+static void
+remove_error_filter (GstParseBin * parsebin, GstElement * element,
+    GstMessage ** error)
+{
+  GList *l;
+
+  GST_OBJECT_LOCK (parsebin);
+  parsebin->filtered = g_list_remove (parsebin->filtered, element);
+
+  if (error)
+    *error = NULL;
+
+  l = parsebin->filtered_errors;
+  while (l) {
+    GstMessage *msg = l->data;
+
+    if (GST_MESSAGE_SRC (msg) == GST_OBJECT_CAST (element)) {
+      /* Get the last error of this element, i.e. the earliest */
+      if (error)
+        gst_message_replace (error, msg);
+      gst_message_unref (msg);
+      l = parsebin->filtered_errors =
+          g_list_delete_link (parsebin->filtered_errors, l);
+    } else {
+      l = l->next;
+    }
+  }
+  GST_OBJECT_UNLOCK (parsebin);
+}
+
+typedef struct
+{
+  gboolean ret;
+  GstPad *peer;
+} SendStickyEventsData;
+
+static gboolean
+send_sticky_event (GstPad * pad, GstEvent ** event, gpointer user_data)
+{
+  SendStickyEventsData *data = user_data;
+  gboolean ret;
+
+  ret = gst_pad_send_event (data->peer, gst_event_ref (*event));
+  if (!ret)
+    data->ret = FALSE;
+
+  return data->ret;
+}
+
+static gboolean
+send_sticky_events (GstParseBin * parsebin, GstPad * pad)
+{
+  SendStickyEventsData data;
+
+  data.ret = TRUE;
+  data.peer = gst_pad_get_peer (pad);
+
+  gst_pad_sticky_events_foreach (pad, send_sticky_event, &data);
+
+  gst_object_unref (data.peer);
+
+  return data.ret;
+}
+
+static gchar *
+error_message_to_string (GstMessage * msg)
+{
+  GError *err;
+  gchar *debug, *message, *full_message;
+
+  gst_message_parse_error (msg, &err, &debug);
+
+  message = gst_error_get_message (err->domain, err->code);
+
+  if (debug)
+    full_message = g_strdup_printf ("%s\n%s\n%s", message, err->message, debug);
+  else
+    full_message = g_strdup_printf ("%s\n%s", message, err->message);
+
+  g_free (message);
+  g_free (debug);
+  g_clear_error (&err);
+
+  return full_message;
+}
+
+/* We consider elements as "simple demuxer" when they are a demuxer
+ * with one and only one ALWAYS source pad.
+ */
+static gboolean
+is_simple_demuxer_factory (GstElementFactory * factory)
+{
+  if (strstr (gst_element_factory_get_metadata (factory,
+              GST_ELEMENT_METADATA_KLASS), "Demuxer")) {
+    const GList *tmp;
+    gint num_alway_srcpads = 0;
+
+    for (tmp = gst_element_factory_get_static_pad_templates (factory);
+        tmp; tmp = tmp->next) {
+      GstStaticPadTemplate *template = tmp->data;
+
+      if (template->direction == GST_PAD_SRC) {
+        if (template->presence == GST_PAD_ALWAYS) {
+          if (num_alway_srcpads >= 0)
+            num_alway_srcpads++;
+        } else {
+          num_alway_srcpads = -1;
+        }
+      }
+
+    }
+
+    if (num_alway_srcpads == 1)
+      return TRUE;
+  }
+
+  return FALSE;
+}
+
+/* connect_pad:
+ *
+ * Try to connect the given pad to an element created from one of the factories,
+ * and recursively.
+ *
+ * Note that parsepad is ghosting pad, and so pad is linked; be sure to unset parsepad's
+ * target before trying to link pad.
+ *
+ * Returns TRUE if an element was properly created and linked
+ */
+static gboolean
+connect_pad (GstParseBin * parsebin, GstElement * src, GstParsePad * parsepad,
+    GstPad * pad, GstCaps * caps, GValueArray * factories,
+    GstParseChain * chain, gchar ** deadend_details)
+{
+  gboolean res = FALSE;
+  GString *error_details = NULL;
+
+  g_return_val_if_fail (factories != NULL, FALSE);
+  g_return_val_if_fail (factories->n_values > 0, FALSE);
+
+  GST_DEBUG_OBJECT (parsebin,
+      "pad %s:%s , chain:%p, %d factories, caps %" GST_PTR_FORMAT,
+      GST_DEBUG_PAD_NAME (pad), chain, factories->n_values, caps);
+
+  error_details = g_string_new ("");
+
+  /* 2. Try to create an element and link to it */
+  while (factories->n_values > 0) {
+    GstAutoplugSelectResult ret;
+    GstElementFactory *factory;
+    GstParseElement *delem;
+    GstElement *element;
+    GstPad *sinkpad;
+    GParamSpec *pspec;
+    gboolean subtitle;
+    GList *to_connect = NULL;
+    gboolean is_parser_converter = FALSE, is_simple_demuxer = FALSE;
+
+    /* Set parsepad target to pad again, it might've been unset
+     * below but we came back here because something failed
+     */
+    parse_pad_set_target (parsepad, pad);
+
+    /* take first factory */
+    factory = g_value_get_object (g_value_array_get_nth (factories, 0));
+    /* Remove selected factory from the list. */
+    g_value_array_remove (factories, 0);
+
+    GST_LOG_OBJECT (src, "trying factory %" GST_PTR_FORMAT, factory);
+
+    /* Check if the caps are really supported by the factory. The
+     * factory list is non-empty-subset filtered while caps
+     * are only accepted by a pad if they are a subset of the
+     * pad caps.
+     *
+     * FIXME: Only do this for fixed caps here. Non-fixed caps
+     * can happen if a Parser/Converter was autoplugged before
+     * this. We then assume that it will be able to convert to
+     * everything that the decoder would want.
+     *
+     * A subset check will fail here because the parser caps
+     * will be generic and while the decoder will only
+     * support a subset of the parser caps.
+     */
+    if (gst_caps_is_fixed (caps)) {
+      const GList *templs;
+      gboolean skip = FALSE;
+
+      templs = gst_element_factory_get_static_pad_templates (factory);
+
+      while (templs) {
+        GstStaticPadTemplate *templ = (GstStaticPadTemplate *) templs->data;
+
+        if (templ->direction == GST_PAD_SINK) {
+          GstCaps *templcaps = gst_static_caps_get (&templ->static_caps);
+
+          if (!gst_caps_is_subset (caps, templcaps)) {
+            GST_DEBUG_OBJECT (src,
+                "caps %" GST_PTR_FORMAT " not subset of %" GST_PTR_FORMAT, caps,
+                templcaps);
+            gst_caps_unref (templcaps);
+            skip = TRUE;
+            break;
+          }
+
+          gst_caps_unref (templcaps);
+        }
+        templs = g_list_next (templs);
+      }
+      if (skip)
+        continue;
+    }
+
+    /* If the factory is for a parser we first check if the factory
+     * was already used for the current chain. If it was used already
+     * we would otherwise create an infinite loop here because the
+     * parser apparently accepts its own output as input.
+     * This is only done for parsers because it's perfectly valid
+     * to have other element classes after each other because a
+     * parser is the only one that does not change the data. A
+     * valid example for this would be multiple id3demux in a row.
+     */
+    is_parser_converter = strstr (gst_element_factory_get_metadata (factory,
+            GST_ELEMENT_METADATA_KLASS), "Parser") != NULL;
+    is_simple_demuxer = is_simple_demuxer_factory (factory);
+
+    if (is_parser_converter) {
+      gboolean skip = FALSE;
+      GList *l;
+
+      CHAIN_MUTEX_LOCK (chain);
+      for (l = chain->elements; l; l = l->next) {
+        GstParseElement *delem = (GstParseElement *) l->data;
+        GstElement *otherelement = delem->element;
+
+        if (gst_element_get_factory (otherelement) == factory) {
+          skip = TRUE;
+          break;
+        }
+      }
+
+      if (!skip && chain->parent && chain->parent->parent) {
+        GstParseChain *parent_chain = chain->parent->parent;
+        GstParseElement *pelem =
+            parent_chain->elements ? parent_chain->elements->data : NULL;
+
+        if (pelem && gst_element_get_factory (pelem->element) == factory)
+          skip = TRUE;
+      }
+      CHAIN_MUTEX_UNLOCK (chain);
+      if (skip) {
+        GST_DEBUG_OBJECT (parsebin,
+            "Skipping factory '%s' because it was already used in this chain",
+            gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST (factory)));
+        continue;
+      }
+
+    }
+
+    /* Expose pads if the next factory is a decoder */
+    if (gst_element_factory_list_is_type (factory,
+            GST_ELEMENT_FACTORY_TYPE_DECODER)) {
+      ret = GST_AUTOPLUG_SELECT_EXPOSE;
+    } else {
+      /* emit autoplug-select to see what we should do with it. */
+      g_signal_emit (G_OBJECT (parsebin),
+          gst_parse_bin_signals[SIGNAL_AUTOPLUG_SELECT],
+          0, parsepad, caps, factory, &ret);
+    }
+
+    switch (ret) {
+      case GST_AUTOPLUG_SELECT_TRY:
+        GST_DEBUG_OBJECT (parsebin, "autoplug select requested try");
+        break;
+      case GST_AUTOPLUG_SELECT_EXPOSE:
+        GST_DEBUG_OBJECT (parsebin, "autoplug select requested expose");
+        /* expose the pad, we don't have the source element */
+        expose_pad (parsebin, src, parsepad, pad, caps, chain);
+        res = TRUE;
+        goto beach;
+      case GST_AUTOPLUG_SELECT_SKIP:
+        GST_DEBUG_OBJECT (parsebin, "autoplug select requested skip");
+        continue;
+      default:
+        GST_WARNING_OBJECT (parsebin, "autoplug select returned unhandled %d",
+            ret);
+        break;
+    }
+
+    /* 2.0. Unlink pad */
+    parse_pad_set_target (parsepad, NULL);
+
+    /* 2.1. Try to create an element */
+    if ((element = gst_element_factory_create (factory, NULL)) == NULL) {
+      GST_WARNING_OBJECT (parsebin, "Could not create an element from %s",
+          gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
+      g_string_append_printf (error_details,
+          "Could not create an element from %s\n",
+          gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
+      continue;
+    }
+
+    /* Filter errors, this will prevent the element from causing the pipeline
+     * to error while we test it using READY state. */
+    add_error_filter (parsebin, element);
+
+    /* We don't yet want the bin to control the element's state */
+    gst_element_set_locked_state (element, TRUE);
+
+    /* ... add it ... */
+    if (!(gst_bin_add (GST_BIN_CAST (parsebin), element))) {
+      GST_WARNING_OBJECT (parsebin, "Couldn't add %s to the bin",
+          GST_ELEMENT_NAME (element));
+      remove_error_filter (parsebin, element, NULL);
+      g_string_append_printf (error_details, "Couldn't add %s to the bin\n",
+          GST_ELEMENT_NAME (element));
+      gst_object_unref (element);
+      continue;
+    }
+
+    /* Find its sink pad. */
+    sinkpad = NULL;
+    GST_OBJECT_LOCK (element);
+    if (element->sinkpads != NULL)
+      sinkpad = gst_object_ref (element->sinkpads->data);
+    GST_OBJECT_UNLOCK (element);
+
+    if (sinkpad == NULL) {
+      GST_WARNING_OBJECT (parsebin, "Element %s doesn't have a sink pad",
+          GST_ELEMENT_NAME (element));
+      remove_error_filter (parsebin, element, NULL);
+      g_string_append_printf (error_details,
+          "Element %s doesn't have a sink pad", GST_ELEMENT_NAME (element));
+      gst_bin_remove (GST_BIN (parsebin), element);
+      continue;
+    }
+
+    /* ... and try to link */
+    if ((gst_pad_link_full (pad, sinkpad,
+                GST_PAD_LINK_CHECK_NOTHING)) != GST_PAD_LINK_OK) {
+      GST_WARNING_OBJECT (parsebin, "Link failed on pad %s:%s",
+          GST_DEBUG_PAD_NAME (sinkpad));
+      remove_error_filter (parsebin, element, NULL);
+      g_string_append_printf (error_details, "Link failed on pad %s:%s",
+          GST_DEBUG_PAD_NAME (sinkpad));
+      gst_object_unref (sinkpad);
+      gst_bin_remove (GST_BIN (parsebin), element);
+      continue;
+    }
+
+    /* ... activate it ... */
+    if ((gst_element_set_state (element,
+                GST_STATE_READY)) == GST_STATE_CHANGE_FAILURE) {
+      GstMessage *error_msg;
+
+      GST_WARNING_OBJECT (parsebin, "Couldn't set %s to READY",
+          GST_ELEMENT_NAME (element));
+      remove_error_filter (parsebin, element, &error_msg);
+
+      if (error_msg) {
+        gchar *error_string = error_message_to_string (error_msg);
+        g_string_append_printf (error_details, "Couldn't set %s to READY:\n%s",
+            GST_ELEMENT_NAME (element), error_string);
+        gst_message_unref (error_msg);
+        g_free (error_string);
+      } else {
+        g_string_append_printf (error_details, "Couldn't set %s to READY",
+            GST_ELEMENT_NAME (element));
+      }
+      gst_object_unref (sinkpad);
+      gst_bin_remove (GST_BIN (parsebin), element);
+      continue;
+    }
+
+    /* check if we still accept the caps on the pad after setting
+     * the element to READY */
+    if (!gst_pad_query_accept_caps (sinkpad, caps)) {
+      GstMessage *error_msg;
+
+      GST_WARNING_OBJECT (parsebin, "Element %s does not accept caps",
+          GST_ELEMENT_NAME (element));
+
+      remove_error_filter (parsebin, element, &error_msg);
+
+      if (error_msg) {
+        gchar *error_string = error_message_to_string (error_msg);
+        g_string_append_printf (error_details,
+            "Element %s does not accept caps:\n%s", GST_ELEMENT_NAME (element),
+            error_string);
+        gst_message_unref (error_msg);
+        g_free (error_string);
+      } else {
+        g_string_append_printf (error_details,
+            "Element %s does not accept caps", GST_ELEMENT_NAME (element));
+      }
+
+      gst_element_set_state (element, GST_STATE_NULL);
+      gst_object_unref (sinkpad);
+      gst_bin_remove (GST_BIN (parsebin), element);
+      continue;
+    }
+
+    gst_object_unref (sinkpad);
+    GST_LOG_OBJECT (parsebin, "linked on pad %s:%s", GST_DEBUG_PAD_NAME (pad));
+
+    CHAIN_MUTEX_LOCK (chain);
+    delem = g_slice_new0 (GstParseElement);
+    delem->element = gst_object_ref (element);
+    delem->capsfilter = NULL;
+    chain->elements = g_list_prepend (chain->elements, delem);
+    chain->demuxer = is_demuxer_element (element);
+
+    /* If we plugging a parser, mark the chain as parsed */
+    chain->parsed |= is_parser_converter;
+
+    CHAIN_MUTEX_UNLOCK (chain);
+
+    /* Set connection-speed property if needed */
+    if (chain->demuxer) {
+      GParamSpec *pspec;
+
+      if ((pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (element),
+                  "connection-speed"))) {
+        guint64 speed = parsebin->connection_speed / 1000;
+        gboolean wrong_type = FALSE;
+
+        if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_UINT) {
+          GParamSpecUInt *pspecuint = G_PARAM_SPEC_UINT (pspec);
+
+          speed = CLAMP (speed, pspecuint->minimum, pspecuint->maximum);
+        } else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_INT) {
+          GParamSpecInt *pspecint = G_PARAM_SPEC_INT (pspec);
+
+          speed = CLAMP (speed, pspecint->minimum, pspecint->maximum);
+        } else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_UINT64) {
+          GParamSpecUInt64 *pspecuint = G_PARAM_SPEC_UINT64 (pspec);
+
+          speed = CLAMP (speed, pspecuint->minimum, pspecuint->maximum);
+        } else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_INT64) {
+          GParamSpecInt64 *pspecint = G_PARAM_SPEC_INT64 (pspec);
+
+          speed = CLAMP (speed, pspecint->minimum, pspecint->maximum);
+        } else {
+          GST_WARNING_OBJECT (parsebin,
+              "The connection speed property %" G_GUINT64_FORMAT " of type %s"
+              " is not usefull not setting it", speed,
+              g_type_name (G_PARAM_SPEC_TYPE (pspec)));
+          wrong_type = TRUE;
+        }
+
+        if (!wrong_type) {
+          GST_DEBUG_OBJECT (parsebin,
+              "setting connection-speed=%" G_GUINT64_FORMAT
+              " to demuxer element", speed);
+
+          g_object_set (element, "connection-speed", speed, NULL);
+        }
+      }
+    }
+
+    /* try to configure the subtitle encoding property when we can */
+    pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (element),
+        "subtitle-encoding");
+    if (pspec && G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_STRING) {
+      SUBTITLE_LOCK (parsebin);
+      GST_DEBUG_OBJECT (parsebin,
+          "setting subtitle-encoding=%s to element", parsebin->encoding);
+      g_object_set (G_OBJECT (element), "subtitle-encoding", parsebin->encoding,
+          NULL);
+      SUBTITLE_UNLOCK (parsebin);
+      subtitle = TRUE;
+    } else {
+      subtitle = FALSE;
+    }
+
+    /* link this element further */
+    to_connect = connect_element (parsebin, delem, chain);
+
+    if ((is_simple_demuxer || is_parser_converter) && to_connect) {
+      GList *l;
+      for (l = to_connect; l; l = g_list_next (l)) {
+        GstPad *opad = GST_PAD_CAST (l->data);
+        GstCaps *ocaps;
+
+        ocaps = get_pad_caps (opad);
+        analyze_new_pad (parsebin, delem->element, opad, ocaps, chain);
+        if (ocaps)
+          gst_caps_unref (ocaps);
+
+        gst_object_unref (opad);
+      }
+      g_list_free (to_connect);
+      to_connect = NULL;
+    }
+
+    /* Bring the element to the state of the parent */
+
+    /* First lock element's sinkpad stream lock so no data reaches
+     * the possible new element added when caps are sent by element
+     * while we're still sending sticky events */
+    GST_PAD_STREAM_LOCK (sinkpad);
+
+    if ((gst_element_set_state (element,
+                GST_STATE_PAUSED)) == GST_STATE_CHANGE_FAILURE ||
+        !send_sticky_events (parsebin, pad)) {
+      GstParseElement *dtmp = NULL;
+      GstElement *tmp = NULL;
+      GstMessage *error_msg;
+
+      GST_PAD_STREAM_UNLOCK (sinkpad);
+
+      GST_WARNING_OBJECT (parsebin, "Couldn't set %s to PAUSED",
+          GST_ELEMENT_NAME (element));
+
+      g_list_free_full (to_connect, (GDestroyNotify) gst_object_unref);
+      to_connect = NULL;
+
+      remove_error_filter (parsebin, element, &error_msg);
+
+      if (error_msg) {
+        gchar *error_string = error_message_to_string (error_msg);
+        g_string_append_printf (error_details, "Couldn't set %s to PAUSED:\n%s",
+            GST_ELEMENT_NAME (element), error_string);
+        gst_message_unref (error_msg);
+        g_free (error_string);
+      } else {
+        g_string_append_printf (error_details, "Couldn't set %s to PAUSED",
+            GST_ELEMENT_NAME (element));
+      }
+
+      /* Remove all elements in this chain that were just added. No
+       * other thread could've added elements in the meantime */
+      CHAIN_MUTEX_LOCK (chain);
+      do {
+        GList *l;
+
+        dtmp = chain->elements->data;
+        tmp = dtmp->element;
+
+        /* Disconnect any signal handlers that might be connected
+         * in connect_element() or analyze_pad() */
+        if (dtmp->pad_added_id)
+          g_signal_handler_disconnect (tmp, dtmp->pad_added_id);
+        if (dtmp->pad_removed_id)
+          g_signal_handler_disconnect (tmp, dtmp->pad_removed_id);
+        if (dtmp->no_more_pads_id)
+          g_signal_handler_disconnect (tmp, dtmp->no_more_pads_id);
+
+        for (l = chain->pending_pads; l;) {
+          GstPendingPad *pp = l->data;
+          GList *n;
+
+          if (GST_PAD_PARENT (pp->pad) != tmp) {
+            l = l->next;
+            continue;
+          }
+
+          gst_pending_pad_free (pp);
+
+          /* Remove element from the list, update list head and go to the
+           * next element in the list */
+          n = l->next;
+          chain->pending_pads = g_list_delete_link (chain->pending_pads, l);
+          l = n;
+        }
+
+        if (dtmp->capsfilter) {
+          gst_bin_remove (GST_BIN (parsebin), dtmp->capsfilter);
+          gst_element_set_state (dtmp->capsfilter, GST_STATE_NULL);
+          gst_object_unref (dtmp->capsfilter);
+        }
+
+        gst_bin_remove (GST_BIN (parsebin), tmp);
+        gst_element_set_state (tmp, GST_STATE_NULL);
+
+        gst_object_unref (tmp);
+        g_slice_free (GstParseElement, dtmp);
+
+        chain->elements = g_list_delete_link (chain->elements, chain->elements);
+      } while (tmp != element);
+      CHAIN_MUTEX_UNLOCK (chain);
+
+      continue;
+    } else {
+      /* Everything went well, the spice must flow now */
+      GST_PAD_STREAM_UNLOCK (sinkpad);
+    }
+
+    /* Remove error filter now, from now on we can't gracefully
+     * handle errors of the element anymore */
+    remove_error_filter (parsebin, element, NULL);
+
+    /* Now let the bin handle the state */
+    gst_element_set_locked_state (element, FALSE);
+
+    if (subtitle) {
+      SUBTITLE_LOCK (parsebin);
+      /* we added the element now, add it to the list of subtitle-encoding
+       * elements when we can set the property */
+      parsebin->subtitles = g_list_prepend (parsebin->subtitles, element);
+      SUBTITLE_UNLOCK (parsebin);
+    }
+
+    if (to_connect) {
+      GList *l;
+      for (l = to_connect; l; l = g_list_next (l)) {
+        GstPad *opad = GST_PAD_CAST (l->data);
+        GstCaps *ocaps;
+
+        ocaps = get_pad_caps (opad);
+        analyze_new_pad (parsebin, delem->element, opad, ocaps, chain);
+        if (ocaps)
+          gst_caps_unref (ocaps);
+
+        gst_object_unref (opad);
+      }
+      g_list_free (to_connect);
+      to_connect = NULL;
+    }
+
+    res = TRUE;
+    break;
+  }
+
+beach:
+  if (error_details)
+    *deadend_details = g_string_free (error_details, (error_details->len == 0
+            || res));
+  else
+    *deadend_details = NULL;
+
+  return res;
+}
+
+static GstCaps *
+get_pad_caps (GstPad * pad)
+{
+  GstCaps *caps;
+
+  /* first check the pad caps, if this is set, we are positively sure it is
+   * fixed and exactly what the element will produce. */
+  caps = gst_pad_get_current_caps (pad);
+
+  /* then use the getcaps function if we don't have caps. These caps might not
+   * be fixed in some cases, in which case analyze_new_pad will set up a
+   * notify::caps signal to continue autoplugging. */
+  if (caps == NULL)
+    caps = gst_pad_query_caps (pad, NULL);
+
+  return caps;
+}
+
+/* Returns a list of pads that can be connected to already and
+ * connects to pad-added and related signals */
+static GList *
+connect_element (GstParseBin * parsebin, GstParseElement * delem,
+    GstParseChain * chain)
+{
+  GstElement *element = delem->element;
+  GList *pads;
+  gboolean dynamic = FALSE;
+  GList *to_connect = NULL;
+
+  GST_DEBUG_OBJECT (parsebin,
+      "Attempting to connect element %s [chain:%p] further",
+      GST_ELEMENT_NAME (element), chain);
+
+  /* 1. Loop over pad templates, grabbing existing pads along the way */
+  for (pads = GST_ELEMENT_GET_CLASS (element)->padtemplates; pads;
+      pads = g_list_next (pads)) {
+    GstPadTemplate *templ = GST_PAD_TEMPLATE (pads->data);
+    const gchar *templ_name;
+
+    /* we are only interested in source pads */
+    if (GST_PAD_TEMPLATE_DIRECTION (templ) != GST_PAD_SRC)
+      continue;
+
+    templ_name = GST_PAD_TEMPLATE_NAME_TEMPLATE (templ);
+    GST_DEBUG_OBJECT (parsebin, "got a source pad template %s", templ_name);
+
+    /* figure out what kind of pad this is */
+    switch (GST_PAD_TEMPLATE_PRESENCE (templ)) {
+      case GST_PAD_ALWAYS:
+      {
+        /* get the pad that we need to autoplug */
+        GstPad *pad = gst_element_get_static_pad (element, templ_name);
+
+        if (pad) {
+          GST_DEBUG_OBJECT (parsebin, "got the pad for always template %s",
+              templ_name);
+          /* here is the pad, we need to autoplug it */
+          to_connect = g_list_prepend (to_connect, pad);
+        } else {
+          /* strange, pad is marked as always but it's not
+           * there. Fix the element */
+          GST_WARNING_OBJECT (parsebin,
+              "could not get the pad for always template %s", templ_name);
+        }
+        break;
+      }
+      case GST_PAD_SOMETIMES:
+      {
+        /* try to get the pad to see if it is already created or
+         * not */
+        GstPad *pad = gst_element_get_static_pad (element, templ_name);
+
+        if (pad) {
+          GST_DEBUG_OBJECT (parsebin, "got the pad for sometimes template %s",
+              templ_name);
+          /* the pad is created, we need to autoplug it */
+          to_connect = g_list_prepend (to_connect, pad);
+        } else {
+          GST_DEBUG_OBJECT (parsebin,
+              "did not get the sometimes pad of template %s", templ_name);
+          /* we have an element that will create dynamic pads */
+          dynamic = TRUE;
+        }
+        break;
+      }
+      case GST_PAD_REQUEST:
+        /* ignore request pads */
+        GST_DEBUG_OBJECT (parsebin, "ignoring request padtemplate %s",
+            templ_name);
+        break;
+    }
+  }
+
+  /* 2. if there are more potential pads, connect to relevant signals */
+  if (dynamic) {
+    GST_LOG_OBJECT (parsebin, "Adding signals to element %s in chain %p",
+        GST_ELEMENT_NAME (element), chain);
+    delem->pad_added_id = g_signal_connect (element, "pad-added",
+        G_CALLBACK (pad_added_cb), chain);
+    delem->pad_removed_id = g_signal_connect (element, "pad-removed",
+        G_CALLBACK (pad_removed_cb), chain);
+    delem->no_more_pads_id = g_signal_connect (element, "no-more-pads",
+        G_CALLBACK (no_more_pads_cb), chain);
+  }
+
+  /* 3. return all pads that can be connected to already */
+
+  return to_connect;
+}
+
+/* expose_pad:
+ *
+ * Expose the given pad on the chain as a decoded pad.
+ */
+static void
+expose_pad (GstParseBin * parsebin, GstElement * src, GstParsePad * parsepad,
+    GstPad * pad, GstCaps * caps, GstParseChain * chain)
+{
+  GST_DEBUG_OBJECT (parsebin, "pad %s:%s, chain:%p",
+      GST_DEBUG_PAD_NAME (pad), chain);
+
+  gst_parse_pad_activate (parsepad, chain);
+  chain->endpad = gst_object_ref (parsepad);
+  if (caps)
+    chain->endcaps = gst_caps_ref (caps);
+  else
+    chain->endcaps = NULL;
+}
+
+static void
+type_found (GstElement * typefind, guint probability,
+    GstCaps * caps, GstParseBin * parse_bin)
+{
+  GstPad *pad, *sink_pad;
+
+  GST_DEBUG_OBJECT (parse_bin, "typefind found caps %" GST_PTR_FORMAT, caps);
+
+  /* If the typefinder (but not something else) finds text/plain - i.e. that's
+   * the top-level type of the file - then error out.
+   */
+  if (gst_structure_has_name (gst_caps_get_structure (caps, 0), "text/plain")) {
+    GST_ELEMENT_ERROR (parse_bin, STREAM, WRONG_TYPE,
+        (_("This appears to be a text file")),
+        ("ParseBin cannot decode plain text files"));
+    goto exit;
+  }
+
+  /* FIXME: we can only deal with one type, we don't yet support dynamically changing
+   * caps from the typefind element */
+  if (parse_bin->have_type || parse_bin->parse_chain)
+    goto exit;
+
+  parse_bin->have_type = TRUE;
+
+  pad = gst_element_get_static_pad (typefind, "src");
+  sink_pad = gst_element_get_static_pad (typefind, "sink");
+
+  /* need some lock here to prevent race with shutdown state change
+   * which might yank away e.g. parse_chain while building stuff here.
+   * In typical cases, STREAM_LOCK is held and handles that, it need not
+   * be held (if called from a proxied setcaps), so grab it anyway */
+  GST_PAD_STREAM_LOCK (sink_pad);
+  parse_bin->parse_chain = gst_parse_chain_new (parse_bin, NULL, pad, caps);
+  analyze_new_pad (parse_bin, typefind, pad, caps, parse_bin->parse_chain);
+  GST_PAD_STREAM_UNLOCK (sink_pad);
+
+  gst_object_unref (sink_pad);
+  gst_object_unref (pad);
+
+exit:
+  return;
+}
+
+static GstPadProbeReturn
+pad_event_cb (GstPad * pad, GstPadProbeInfo * info, gpointer data)
+{
+  GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
+  GstPendingPad *ppad = (GstPendingPad *) data;
+  GstParseChain *chain = ppad->chain;
+  GstParseBin *parsebin = chain->parsebin;
+
+  g_assert (ppad);
+  g_assert (chain);
+  g_assert (parsebin);
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_EOS:
+      GST_DEBUG_OBJECT (pad, "Received EOS on a non final pad, this stream "
+          "ended too early");
+      chain->deadend = TRUE;
+      chain->drained = TRUE;
+      gst_object_replace ((GstObject **) & chain->current_pad, NULL);
+      /* we don't set the endcaps because NULL endcaps means early EOS */
+
+      EXPOSE_LOCK (parsebin);
+      if (parsebin->parse_chain)
+        if (gst_parse_chain_is_complete (parsebin->parse_chain))
+          gst_parse_bin_expose (parsebin);
+      EXPOSE_UNLOCK (parsebin);
+      break;
+    default:
+      break;
+  }
+  return GST_PAD_PROBE_OK;
+}
+
+static void
+pad_added_cb (GstElement * element, GstPad * pad, GstParseChain * chain)
+{
+  GstCaps *caps;
+  GstParseBin *parsebin;
+
+  parsebin = chain->parsebin;
+
+  GST_DEBUG_OBJECT (pad, "pad added, chain:%p", chain);
+
+  caps = get_pad_caps (pad);
+  analyze_new_pad (parsebin, element, pad, caps, chain);
+  if (caps)
+    gst_caps_unref (caps);
+
+  EXPOSE_LOCK (parsebin);
+  if (parsebin->parse_chain) {
+    if (gst_parse_chain_is_complete (parsebin->parse_chain)) {
+      GST_LOG_OBJECT (parsebin,
+          "That was the last dynamic object, now attempting to expose the group");
+      if (!gst_parse_bin_expose (parsebin))
+        GST_WARNING_OBJECT (parsebin, "Couldn't expose group");
+    }
+  } else {
+    GST_DEBUG_OBJECT (parsebin, "No parse chain, new pad ignored");
+  }
+  EXPOSE_UNLOCK (parsebin);
+}
+
+static void
+pad_removed_cb (GstElement * element, GstPad * pad, GstParseChain * chain)
+{
+  GList *l;
+
+  GST_LOG_OBJECT (pad, "pad removed, chain:%p", chain);
+
+  /* In fact, we don't have to do anything here, the active group will be
+   * removed when the group's multiqueue is drained */
+  CHAIN_MUTEX_LOCK (chain);
+  for (l = chain->pending_pads; l; l = l->next) {
+    GstPendingPad *ppad = l->data;
+    GstPad *opad = ppad->pad;
+
+    if (pad == opad) {
+      gst_pending_pad_free (ppad);
+      chain->pending_pads = g_list_delete_link (chain->pending_pads, l);
+      break;
+    }
+  }
+  CHAIN_MUTEX_UNLOCK (chain);
+}
+
+static void
+no_more_pads_cb (GstElement * element, GstParseChain * chain)
+{
+  GstParseGroup *group = NULL;
+
+  GST_LOG_OBJECT (element, "got no more pads");
+
+  CHAIN_MUTEX_LOCK (chain);
+  if (!chain->elements
+      || ((GstParseElement *) chain->elements->data)->element != element) {
+    GST_LOG_OBJECT (chain->parsebin, "no-more-pads from old chain element '%s'",
+        GST_OBJECT_NAME (element));
+    CHAIN_MUTEX_UNLOCK (chain);
+    return;
+  } else if (!chain->demuxer) {
+    GST_LOG_OBJECT (chain->parsebin,
+        "no-more-pads from a non-demuxer element '%s'",
+        GST_OBJECT_NAME (element));
+    CHAIN_MUTEX_UNLOCK (chain);
+    return;
+  }
+
+  /* when we received no_more_pads, we can complete the pads of the chain */
+  if (!chain->next_groups && chain->active_group) {
+    group = chain->active_group;
+  } else if (chain->next_groups) {
+    GList *iter;
+    for (iter = chain->next_groups; iter; iter = g_list_next (iter)) {
+      group = iter->data;
+      if (!group->no_more_pads)
+        break;
+    }
+  }
+  if (!group) {
+    GST_ERROR_OBJECT (chain->parsebin, "can't find group for element");
+    CHAIN_MUTEX_UNLOCK (chain);
+    return;
+  }
+
+  GST_DEBUG_OBJECT (element, "Setting group %p to complete", group);
+
+  group->no_more_pads = TRUE;
+  CHAIN_MUTEX_UNLOCK (chain);
+
+  EXPOSE_LOCK (chain->parsebin);
+  if (chain->parsebin->parse_chain) {
+    if (gst_parse_chain_is_complete (chain->parsebin->parse_chain)) {
+      gst_parse_bin_expose (chain->parsebin);
+    }
+  }
+  EXPOSE_UNLOCK (chain->parsebin);
+}
+
+static void
+caps_notify_cb (GstPad * pad, GParamSpec * unused, GstParseChain * chain)
+{
+  GstElement *element;
+  GList *l;
+
+  GST_LOG_OBJECT (pad, "Notified caps for pad %s:%s", GST_DEBUG_PAD_NAME (pad));
+
+  /* Disconnect this; if we still need it, we'll reconnect to this in
+   * analyze_new_pad */
+  element = GST_ELEMENT_CAST (gst_pad_get_parent (pad));
+
+  CHAIN_MUTEX_LOCK (chain);
+  for (l = chain->pending_pads; l; l = l->next) {
+    GstPendingPad *ppad = l->data;
+    if (ppad->pad == pad) {
+      gst_pending_pad_free (ppad);
+      chain->pending_pads = g_list_delete_link (chain->pending_pads, l);
+      break;
+    }
+  }
+  CHAIN_MUTEX_UNLOCK (chain);
+
+  pad_added_cb (element, pad, chain);
+
+  gst_object_unref (element);
+}
+
+/* Decide whether an element is a demuxer based on the
+ * klass and number/type of src pad templates it has */
+static gboolean
+is_demuxer_element (GstElement * srcelement)
+{
+  GstElementFactory *srcfactory;
+  GstElementClass *elemclass;
+  GList *walk;
+  const gchar *klass;
+  gint potential_src_pads = 0;
+
+  srcfactory = gst_element_get_factory (srcelement);
+  klass =
+      gst_element_factory_get_metadata (srcfactory, GST_ELEMENT_METADATA_KLASS);
+
+  /* Can't be a demuxer unless it has Demux in the klass name */
+  if (!strstr (klass, "Demux"))
+    return FALSE;
+
+  /* Walk the src pad templates and count how many the element
+   * might produce */
+  elemclass = GST_ELEMENT_GET_CLASS (srcelement);
+
+  walk = gst_element_class_get_pad_template_list (elemclass);
+  while (walk != NULL) {
+    GstPadTemplate *templ;
+
+    templ = (GstPadTemplate *) walk->data;
+    if (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC) {
+      switch (GST_PAD_TEMPLATE_PRESENCE (templ)) {
+        case GST_PAD_ALWAYS:
+        case GST_PAD_SOMETIMES:
+          if (strstr (GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "%"))
+            potential_src_pads += 2;    /* Might make multiple pads */
+          else
+            potential_src_pads += 1;
+          break;
+        case GST_PAD_REQUEST:
+          potential_src_pads += 2;
+          break;
+      }
+    }
+    walk = g_list_next (walk);
+  }
+
+  if (potential_src_pads < 2)
+    return FALSE;
+
+  return TRUE;
+}
+
+/* gst_parse_chain_get_current_group:
+ *
+ * Returns the current group of this chain, to which
+ * new chains should be attached or NULL if the last
+ * group didn't have no-more-pads.
+ *
+ * Not MT-safe: Call with parent chain lock!
+ */
+static GstParseGroup *
+gst_parse_chain_get_current_group (GstParseChain * chain)
+{
+  GstParseGroup *group;
+
+  /* Now we know that we can really return something useful */
+  if (!chain->active_group) {
+    chain->active_group = group = gst_parse_group_new (chain->parsebin, chain);
+  } else if (!chain->active_group->no_more_pads) {
+    group = chain->active_group;
+  } else {
+    GList *iter;
+    group = NULL;
+    for (iter = chain->next_groups; iter; iter = g_list_next (iter)) {
+      GstParseGroup *next_group = iter->data;
+
+      if (!next_group->no_more_pads) {
+        group = next_group;
+        break;
+      }
+    }
+  }
+  if (!group) {
+    group = gst_parse_group_new (chain->parsebin, chain);
+    chain->next_groups = g_list_append (chain->next_groups, group);
+  }
+
+  return group;
+}
+
+static void gst_parse_group_free_internal (GstParseGroup * group,
+    gboolean hide);
+
+static void
+gst_parse_chain_free_internal (GstParseChain * chain, gboolean hide)
+{
+  GList *l, *set_to_null = NULL;
+
+  CHAIN_MUTEX_LOCK (chain);
+
+  GST_DEBUG_OBJECT (chain->parsebin, "%s chain %p",
+      (hide ? "Hiding" : "Freeing"), chain);
+
+  if (chain->active_group) {
+    gst_parse_group_free_internal (chain->active_group, hide);
+    if (!hide)
+      chain->active_group = NULL;
+  }
+
+  for (l = chain->next_groups; l; l = l->next) {
+    gst_parse_group_free_internal ((GstParseGroup *) l->data, hide);
+    if (!hide)
+      l->data = NULL;
+  }
+  if (!hide) {
+    g_list_free (chain->next_groups);
+    chain->next_groups = NULL;
+  }
+
+  if (!hide) {
+    for (l = chain->old_groups; l; l = l->next) {
+      GstParseGroup *group = l->data;
+
+      gst_parse_group_free (group);
+    }
+    g_list_free (chain->old_groups);
+    chain->old_groups = NULL;
+  }
+
+  gst_object_replace ((GstObject **) & chain->current_pad, NULL);
+
+  for (l = chain->pending_pads; l; l = l->next) {
+    GstPendingPad *ppad = l->data;
+    gst_pending_pad_free (ppad);
+    l->data = NULL;
+  }
+  g_list_free (chain->pending_pads);
+  chain->pending_pads = NULL;
+
+  for (l = chain->elements; l; l = l->next) {
+    GstParseElement *delem = l->data;
+    GstElement *element = delem->element;
+
+    if (delem->pad_added_id)
+      g_signal_handler_disconnect (element, delem->pad_added_id);
+    delem->pad_added_id = 0;
+    if (delem->pad_removed_id)
+      g_signal_handler_disconnect (element, delem->pad_removed_id);
+    delem->pad_removed_id = 0;
+    if (delem->no_more_pads_id)
+      g_signal_handler_disconnect (element, delem->no_more_pads_id);
+    delem->no_more_pads_id = 0;
+
+    if (delem->capsfilter) {
+      if (GST_OBJECT_PARENT (delem->capsfilter) ==
+          GST_OBJECT_CAST (chain->parsebin))
+        gst_bin_remove (GST_BIN_CAST (chain->parsebin), delem->capsfilter);
+      if (!hide) {
+        set_to_null =
+            g_list_append (set_to_null, gst_object_ref (delem->capsfilter));
+      }
+    }
+
+    if (GST_OBJECT_PARENT (element) == GST_OBJECT_CAST (chain->parsebin))
+      gst_bin_remove (GST_BIN_CAST (chain->parsebin), element);
+    if (!hide) {
+      set_to_null = g_list_append (set_to_null, gst_object_ref (element));
+    }
+
+    SUBTITLE_LOCK (chain->parsebin);
+    /* remove possible subtitle element */
+    chain->parsebin->subtitles =
+        g_list_remove (chain->parsebin->subtitles, element);
+    SUBTITLE_UNLOCK (chain->parsebin);
+
+    if (!hide) {
+      if (delem->capsfilter) {
+        gst_object_unref (delem->capsfilter);
+        delem->capsfilter = NULL;
+      }
+
+      gst_object_unref (element);
+      l->data = NULL;
+
+      g_slice_free (GstParseElement, delem);
+    }
+  }
+  if (!hide) {
+    g_list_free (chain->elements);
+    chain->elements = NULL;
+  }
+
+  if (chain->endpad) {
+    if (chain->endpad->exposed) {
+      GstPad *endpad = GST_PAD_CAST (chain->endpad);
+      GST_DEBUG_OBJECT (chain->parsebin, "Removing pad %s:%s",
+          GST_DEBUG_PAD_NAME (endpad));
+      gst_pad_push_event (endpad, gst_event_new_eos ());
+      gst_element_remove_pad (GST_ELEMENT_CAST (chain->parsebin), endpad);
+    }
+
+    parse_pad_set_target (chain->endpad, NULL);
+    chain->endpad->exposed = FALSE;
+    if (!hide) {
+      gst_object_unref (chain->endpad);
+      chain->endpad = NULL;
+    }
+  }
+
+  if (!hide && chain->current_pad) {
+    gst_object_unref (chain->current_pad);
+    chain->current_pad = NULL;
+  }
+
+  if (chain->pad) {
+    gst_object_unref (chain->pad);
+    chain->pad = NULL;
+  }
+  if (chain->start_caps) {
+    gst_caps_unref (chain->start_caps);
+    chain->start_caps = NULL;
+  }
+
+  if (chain->endcaps) {
+    gst_caps_unref (chain->endcaps);
+    chain->endcaps = NULL;
+  }
+  g_free (chain->deadend_details);
+  chain->deadend_details = NULL;
+
+  GST_DEBUG_OBJECT (chain->parsebin, "%s chain %p", (hide ? "Hidden" : "Freed"),
+      chain);
+  CHAIN_MUTEX_UNLOCK (chain);
+
+  while (set_to_null) {
+    GstElement *element = set_to_null->data;
+    set_to_null = g_list_delete_link (set_to_null, set_to_null);
+    gst_element_set_state (element, GST_STATE_NULL);
+    gst_object_unref (element);
+  }
+
+  if (!hide) {
+    g_mutex_clear (&chain->lock);
+    g_slice_free (GstParseChain, chain);
+  }
+}
+
+/* gst_parse_chain_free:
+ *
+ * Completely frees and removes the chain and all
+ * child groups from ParseBin.
+ *
+ * MT-safe, don't hold the chain lock or any child chain's lock
+ * when calling this!
+ */
+static void
+gst_parse_chain_free (GstParseChain * chain)
+{
+  gst_parse_chain_free_internal (chain, FALSE);
+}
+
+/* gst_parse_chain_new:
+ *
+ * Creates a new parse chain and initializes it.
+ *
+ * It's up to the caller to add it to the list of child chains of
+ * a group!
+ */
+static GstParseChain *
+gst_parse_chain_new (GstParseBin * parsebin, GstParseGroup * parent,
+    GstPad * pad, GstCaps * start_caps)
+{
+  GstParseChain *chain = g_slice_new0 (GstParseChain);
+
+  GST_DEBUG_OBJECT (parsebin, "Creating new chain %p with parent group %p",
+      chain, parent);
+
+  chain->parsebin = parsebin;
+  chain->parent = parent;
+  g_mutex_init (&chain->lock);
+  chain->pad = gst_object_ref (pad);
+  if (start_caps)
+    chain->start_caps = gst_caps_ref (start_caps);
+
+  return chain;
+}
+
+/****
+ * GstParseGroup functions
+ ****/
+
+static void
+gst_parse_group_free_internal (GstParseGroup * group, gboolean hide)
+{
+  GList *l;
+
+  GST_DEBUG_OBJECT (group->parsebin, "%s group %p",
+      (hide ? "Hiding" : "Freeing"), group);
+  for (l = group->children; l; l = l->next) {
+    GstParseChain *chain = (GstParseChain *) l->data;
+
+    gst_parse_chain_free_internal (chain, hide);
+    if (!hide)
+      l->data = NULL;
+  }
+  if (!hide) {
+    g_list_free (group->children);
+    group->children = NULL;
+  }
+
+  GST_DEBUG_OBJECT (group->parsebin, "%s group %p", (hide ? "Hid" : "Freed"),
+      group);
+  if (!hide)
+    g_slice_free (GstParseGroup, group);
+}
+
+/* gst_parse_group_free:
+ *
+ * Completely frees and removes the parse group and all
+ * it's children.
+ *
+ * Never call this from any streaming thread!
+ *
+ * Not MT-safe, call with parent's chain lock!
+ */
+static void
+gst_parse_group_free (GstParseGroup * group)
+{
+  gst_parse_group_free_internal (group, FALSE);
+}
+
+/* gst_parse_group_hide:
+ *
+ * Hide the parse group only, this means that
+ * all child endpads are removed from ParseBin
+ * and all signals are unconnected.
+ *
+ * No element is set to NULL state and completely
+ * unrefed here.
+ *
+ * Can be called from streaming threads.
+ *
+ * Not MT-safe, call with parent's chain lock!
+ */
+static void
+gst_parse_group_hide (GstParseGroup * group)
+{
+  gst_parse_group_free_internal (group, TRUE);
+}
+
+/* gst_parse_chain_free_hidden_groups:
+ *
+ * Frees any parse groups that were hidden previously.
+ * This allows keeping memory use from ballooning when
+ * switching chains repeatedly.
+ *
+ * A new throwaway thread will be created to free the
+ * groups, so any delay does not block the setup of a
+ * new group.
+ *
+ * Not MT-safe, call with parent's chain lock!
+ */
+static void
+gst_parse_chain_free_hidden_groups (GList * old_groups)
+{
+  GList *l;
+
+  for (l = old_groups; l; l = l->next) {
+    GstParseGroup *group = l->data;
+
+    gst_parse_group_free (group);
+  }
+  g_list_free (old_groups);
+}
+
+static void
+gst_parse_chain_start_free_hidden_groups_thread (GstParseChain * chain)
+{
+  GThread *thread;
+  GError *error = NULL;
+  GList *old_groups;
+
+  old_groups = chain->old_groups;
+  if (!old_groups)
+    return;
+
+  chain->old_groups = NULL;
+  thread = g_thread_try_new ("free-hidden-groups",
+      (GThreadFunc) gst_parse_chain_free_hidden_groups, old_groups, &error);
+  if (!thread || error) {
+    GST_ERROR ("Failed to start free-hidden-groups thread: %s",
+        error ? error->message : "unknown reason");
+    g_clear_error (&error);
+    chain->old_groups = old_groups;
+    return;
+  }
+  GST_DEBUG_OBJECT (chain->parsebin, "Started free-hidden-groups thread");
+  /* We do not need to wait for it or get any results from it */
+  g_thread_unref (thread);
+}
+
+/* gst_parse_group_new:
+ * @parsebin: Parent ParseBin
+ * @parent: Parent chain or %NULL
+ *
+ * Creates a new GstParseGroup. It is up to the caller to add it to the list
+ * of groups.
+ */
+static GstParseGroup *
+gst_parse_group_new (GstParseBin * parsebin, GstParseChain * parent)
+{
+  GstParseGroup *group = g_slice_new0 (GstParseGroup);
+
+  GST_DEBUG_OBJECT (parsebin, "Creating new group %p with parent chain %p",
+      group, parent);
+
+  group->parsebin = parsebin;
+  group->parent = parent;
+
+  return group;
+}
+
+/* gst_parse_group_is_complete:
+ *
+ * Checks if the group is complete, this means that
+ * a) no-more-pads happened
+ * b) all child chains are complete
+ *
+ * Not MT-safe, always call with ParseBin expose lock
+ */
+static gboolean
+gst_parse_group_is_complete (GstParseGroup * group)
+{
+  GList *l;
+  gboolean complete = TRUE;
+
+  if (!group->no_more_pads) {
+    complete = FALSE;
+    goto out;
+  }
+
+  for (l = group->children; l; l = l->next) {
+    GstParseChain *chain = l->data;
+
+    /* Any blocked chain requires we complete this group
+     * since everything is synchronous, we can't proceed otherwise */
+    if (chain->endpad && chain->endpad->blocked)
+      goto out;
+
+    if (!gst_parse_chain_is_complete (chain)) {
+      complete = FALSE;
+      goto out;
+    }
+  }
+
+out:
+  GST_DEBUG_OBJECT (group->parsebin, "Group %p is complete: %d", group,
+      complete);
+  return complete;
+}
+
+/* gst_parse_chain_is_complete:
+ *
+ * Returns TRUE if the chain is complete, this means either
+ * a) This chain is a dead end, i.e. we have no suitable plugins
+ * b) This chain ends in an endpad and this is blocked or exposed
+ * c) The chain has gotten far enough to have plugged 1 parser at least.
+ *
+ * Not MT-safe, always call with ParseBin expose lock
+ */
+static gboolean
+gst_parse_chain_is_complete (GstParseChain * chain)
+{
+  gboolean complete = FALSE;
+
+  CHAIN_MUTEX_LOCK (chain);
+  if (chain->parsebin->shutdown)
+    goto out;
+
+  if (chain->deadend) {
+    complete = TRUE;
+    goto out;
+  }
+
+  if (chain->endpad && (chain->endpad->blocked || chain->endpad->exposed)) {
+    complete = TRUE;
+    goto out;
+  }
+
+  if (chain->demuxer) {
+    if (chain->active_group
+        && gst_parse_group_is_complete (chain->active_group)) {
+      complete = TRUE;
+      goto out;
+    }
+  }
+
+  if (chain->parsed) {
+    complete = TRUE;
+    goto out;
+  }
+
+out:
+  CHAIN_MUTEX_UNLOCK (chain);
+  GST_DEBUG_OBJECT (chain->parsebin, "Chain %p is complete: %d", chain,
+      complete);
+  return complete;
+}
+
+static void
+chain_remove_old_groups (GstParseChain * chain)
+{
+  GList *tmp;
+
+  /* First go in child */
+  if (chain->active_group) {
+    for (tmp = chain->active_group->children; tmp; tmp = tmp->next) {
+      GstParseChain *child = (GstParseChain *) tmp->data;
+      chain_remove_old_groups (child);
+    }
+  }
+
+  if (chain->old_groups) {
+    gst_parse_group_hide (chain->old_groups->data);
+    gst_parse_chain_start_free_hidden_groups_thread (chain);
+  }
+}
+
+static gboolean
+drain_and_switch_chains (GstParseChain * chain, GstParsePad * drainpad,
+    gboolean * last_group, gboolean * drained, gboolean * switched);
+/* drain_and_switch_chains/groups:
+ *
+ * CALL WITH CHAIN LOCK (or group parent) TAKEN !
+ *
+ * Goes down the chains/groups until it finds the chain
+ * to which the drainpad belongs.
+ *
+ * It marks that pad/chain as drained and then will figure
+ * out which group to switch to or not.
+ *
+ * last_chain will be set to TRUE if the group to which the
+ * pad belongs is the last one.
+ *
+ * drained will be set to TRUE if the chain/group is drained.
+ *
+ * Returns: TRUE if the chain contained the target pad */
+static gboolean
+drain_and_switch_group (GstParseGroup * group, GstParsePad * drainpad,
+    gboolean * last_group, gboolean * drained, gboolean * switched)
+{
+  gboolean handled = FALSE;
+  GList *tmp;
+
+  GST_DEBUG ("Checking group %p (target pad %s:%s)",
+      group, GST_DEBUG_PAD_NAME (drainpad));
+
+  /* Definitely can't be in drained groups */
+  if (G_UNLIKELY (group->drained)) {
+    goto beach;
+  }
+
+  /* Figure out if all our chains are drained with the
+   * new information */
+  group->drained = TRUE;
+  for (tmp = group->children; tmp; tmp = tmp->next) {
+    GstParseChain *chain = (GstParseChain *) tmp->data;
+    gboolean subdrained = FALSE;
+
+    handled |=
+        drain_and_switch_chains (chain, drainpad, last_group, &subdrained,
+        switched);
+    if (!subdrained)
+      group->drained = FALSE;
+  }
+
+beach:
+  GST_DEBUG ("group %p (last_group:%d, drained:%d, switched:%d, handled:%d)",
+      group, *last_group, group->drained, *switched, handled);
+  *drained = group->drained;
+  return handled;
+}
+
+static gboolean
+drain_and_switch_chains (GstParseChain * chain, GstParsePad * drainpad,
+    gboolean * last_group, gboolean * drained, gboolean * switched)
+{
+  gboolean handled = FALSE;
+  GstParseBin *parsebin = chain->parsebin;
+
+  GST_DEBUG ("Checking chain %p %s:%s (target pad %s:%s)",
+      chain, GST_DEBUG_PAD_NAME (chain->pad), GST_DEBUG_PAD_NAME (drainpad));
+
+  CHAIN_MUTEX_LOCK (chain);
+
+  /* Definitely can't be in drained chains */
+  if (G_UNLIKELY (chain->drained)) {
+    goto beach;
+  }
+
+  if (chain->endpad) {
+    /* Check if we're reached the target endchain */
+    if (drainpad != NULL && chain == drainpad->chain) {
+      GST_DEBUG ("Found the target chain");
+      drainpad->drained = TRUE;
+      handled = TRUE;
+    }
+
+    chain->drained = chain->endpad->drained;
+    goto beach;
+  }
+
+  /* We known there are groups to switch to */
+  if (chain->next_groups)
+    *last_group = FALSE;
+
+  /* Check the active group */
+  if (chain->active_group) {
+    gboolean subdrained = FALSE;
+    handled = drain_and_switch_group (chain->active_group, drainpad,
+        last_group, &subdrained, switched);
+
+    /* The group is drained, see if we can switch to another */
+    if ((handled || drainpad == NULL) && subdrained && !*switched) {
+      if (chain->next_groups) {
+        /* Switch to next group, the actual removal of the current group will
+         * be done when the next one is activated */
+        GST_DEBUG_OBJECT (parsebin, "Moving current group %p to old groups",
+            chain->active_group);
+        chain->old_groups =
+            g_list_prepend (chain->old_groups, chain->active_group);
+        GST_DEBUG_OBJECT (parsebin, "Switching to next group %p",
+            chain->next_groups->data);
+        chain->active_group = chain->next_groups->data;
+        chain->next_groups =
+            g_list_delete_link (chain->next_groups, chain->next_groups);
+        *switched = TRUE;
+        chain->drained = FALSE;
+      } else {
+        GST_DEBUG ("Group %p was the last in chain %p", chain->active_group,
+            chain);
+        chain->drained = TRUE;
+        /* We're drained ! */
+      }
+    } else {
+      if (subdrained && !chain->next_groups)
+        *drained = TRUE;
+    }
+  }
+
+beach:
+  CHAIN_MUTEX_UNLOCK (chain);
+
+  GST_DEBUG ("Chain %p (handled:%d, last_group:%d, drained:%d, switched:%d)",
+      chain, handled, *last_group, chain->drained, *switched);
+
+  *drained = chain->drained;
+
+  if (*drained)
+    g_signal_emit (parsebin, gst_parse_bin_signals[SIGNAL_DRAINED], 0, NULL);
+
+  return handled;
+}
+
+/* check if the group is drained, meaning all pads have seen an EOS
+ * event.  */
+static gboolean
+gst_parse_pad_handle_eos (GstParsePad * pad)
+{
+  gboolean last_group = TRUE;
+  gboolean switched = FALSE;
+  gboolean drained = FALSE;
+  GstParseChain *chain = pad->chain;
+  GstParseBin *parsebin = chain->parsebin;
+
+  GST_LOG_OBJECT (parsebin, "pad %p", pad);
+  EXPOSE_LOCK (parsebin);
+  if (parsebin->parse_chain) {
+    drain_and_switch_chains (parsebin->parse_chain, pad, &last_group, &drained,
+        &switched);
+
+    if (switched) {
+      /* If we resulted in a group switch, expose what's needed */
+      if (gst_parse_chain_is_complete (parsebin->parse_chain))
+        gst_parse_bin_expose (parsebin);
+    }
+  }
+  EXPOSE_UNLOCK (parsebin);
+
+  return last_group;
+}
+
+/* gst_parse_group_is_drained:
+ *
+ * Check is this group is drained and cache this result.
+ * The group is drained if all child chains are drained.
+ *
+ * Not MT-safe, call with group->parent's lock */
+static gboolean
+gst_parse_group_is_drained (GstParseGroup * group)
+{
+  GList *l;
+  gboolean drained = TRUE;
+
+  if (group->drained) {
+    drained = TRUE;
+    goto out;
+  }
+
+  for (l = group->children; l; l = l->next) {
+    GstParseChain *chain = l->data;
+
+    CHAIN_MUTEX_LOCK (chain);
+    if (!gst_parse_chain_is_drained (chain))
+      drained = FALSE;
+    CHAIN_MUTEX_UNLOCK (chain);
+    if (!drained)
+      goto out;
+  }
+  group->drained = drained;
+
+out:
+  GST_DEBUG_OBJECT (group->parsebin, "Group %p is drained: %d", group, drained);
+  return drained;
+}
+
+/* gst_parse_chain_is_drained:
+ *
+ * Check is the chain is drained, which means that
+ * either
+ *
+ * a) it's endpad is drained
+ * b) there are no pending pads, the active group is drained
+ *    and there are no next groups
+ *
+ * Not MT-safe, call with chain lock
+ */
+static gboolean
+gst_parse_chain_is_drained (GstParseChain * chain)
+{
+  gboolean drained = FALSE;
+
+  if (chain->endpad) {
+    drained = chain->endpad->drained;
+    goto out;
+  }
+
+  if (chain->pending_pads) {
+    drained = FALSE;
+    goto out;
+  }
+
+  if (chain->active_group && gst_parse_group_is_drained (chain->active_group)
+      && !chain->next_groups) {
+    drained = TRUE;
+    goto out;
+  }
+
+out:
+  GST_DEBUG_OBJECT (chain->parsebin, "Chain %p is drained: %d", chain, drained);
+  return drained;
+}
+
+/* sort_end_pads:
+ * GCompareFunc to use with lists of GstPad.
+ * Sorts pads by mime type.
+ * First video (raw, then non-raw), then audio (raw, then non-raw),
+ * then others.
+ *
+ * Return: negative if a<b, 0 if a==b, positive if a>b
+ */
+static gint
+sort_end_pads (GstParsePad * da, GstParsePad * db)
+{
+  gint va, vb;
+  GstCaps *capsa, *capsb;
+  GstStructure *sa, *sb;
+  const gchar *namea, *nameb;
+  gchar *ida, *idb;
+  gint ret;
+
+  capsa = get_pad_caps (GST_PAD_CAST (da));
+  capsb = get_pad_caps (GST_PAD_CAST (db));
+
+  sa = gst_caps_get_structure ((const GstCaps *) capsa, 0);
+  sb = gst_caps_get_structure ((const GstCaps *) capsb, 0);
+
+  namea = gst_structure_get_name (sa);
+  nameb = gst_structure_get_name (sb);
+
+  if (g_strrstr (namea, "video/x-raw"))
+    va = 0;
+  else if (g_strrstr (namea, "video/"))
+    va = 1;
+  else if (g_strrstr (namea, "image/"))
+    va = 2;
+  else if (g_strrstr (namea, "audio/x-raw"))
+    va = 3;
+  else if (g_strrstr (namea, "audio/"))
+    va = 4;
+  else
+    va = 5;
+
+  if (g_strrstr (nameb, "video/x-raw"))
+    vb = 0;
+  else if (g_strrstr (nameb, "video/"))
+    vb = 1;
+  else if (g_strrstr (nameb, "image/"))
+    vb = 2;
+  else if (g_strrstr (nameb, "audio/x-raw"))
+    vb = 3;
+  else if (g_strrstr (nameb, "audio/"))
+    vb = 4;
+  else
+    vb = 5;
+
+  gst_caps_unref (capsa);
+  gst_caps_unref (capsb);
+
+  if (va != vb)
+    return va - vb;
+
+  /* if otherwise the same, sort by stream-id */
+  ida = gst_pad_get_stream_id (GST_PAD_CAST (da));
+  idb = gst_pad_get_stream_id (GST_PAD_CAST (db));
+  ret = (ida) ? ((idb) ? strcmp (ida, idb) : -1) : 1;
+  g_free (ida);
+  g_free (idb);
+
+  return ret;
+}
+
+static gboolean
+debug_sticky_event (GstPad * pad, GstEvent ** event, gpointer user_data)
+{
+  GST_DEBUG_OBJECT (pad, "sticky event %s (%p)", GST_EVENT_TYPE_NAME (*event),
+      *event);
+  return TRUE;
+}
+
+/* Must only be called if the toplevel chain is complete and blocked! */
+/* Not MT-safe, call with ParseBin expose lock! */
+static gboolean
+gst_parse_bin_expose (GstParseBin * parsebin)
+{
+  GList *tmp, *endpads;
+  gboolean missing_plugin;
+  GString *missing_plugin_details;
+  gboolean already_exposed;
+  gboolean last_group;
+  gboolean uncollected_streams;
+  GstStreamCollection *fallback_collection = NULL;
+
+retry:
+  endpads = NULL;
+  missing_plugin = FALSE;
+  already_exposed = TRUE;
+  last_group = TRUE;
+
+  missing_plugin_details = g_string_new ("");
+
+  GST_DEBUG_OBJECT (parsebin, "Exposing currently active chains/groups");
+
+  /* Don't expose if we're currently shutting down */
+  DYN_LOCK (parsebin);
+  if (G_UNLIKELY (parsebin->shutdown)) {
+    GST_WARNING_OBJECT (parsebin,
+        "Currently, shutting down, aborting exposing");
+    DYN_UNLOCK (parsebin);
+    return FALSE;
+  }
+  DYN_UNLOCK (parsebin);
+
+  /* Get the pads that we're going to expose and mark things as exposed */
+  uncollected_streams = FALSE;
+  if (!gst_parse_chain_expose (parsebin->parse_chain, &endpads, &missing_plugin,
+          missing_plugin_details, &last_group, &uncollected_streams)) {
+    g_list_free_full (endpads, (GDestroyNotify) gst_object_unref);
+    g_string_free (missing_plugin_details, TRUE);
+    GST_ERROR_OBJECT (parsebin, "Broken chain/group tree");
+    g_return_val_if_reached (FALSE);
+    return FALSE;
+  }
+  if (endpads == NULL) {
+    if (missing_plugin) {
+      if (missing_plugin_details->len > 0) {
+        gchar *details = g_string_free (missing_plugin_details, FALSE);
+        GST_ELEMENT_ERROR (parsebin, CORE, MISSING_PLUGIN, (NULL),
+            ("no suitable plugins found:\n%s", details));
+        g_free (details);
+      } else {
+        g_string_free (missing_plugin_details, TRUE);
+        GST_ELEMENT_ERROR (parsebin, CORE, MISSING_PLUGIN, (NULL),
+            ("no suitable plugins found"));
+      }
+    } else {
+      /* in this case, the stream ended without buffers,
+       * just post a warning */
+      g_string_free (missing_plugin_details, TRUE);
+
+      GST_WARNING_OBJECT (parsebin, "All streams finished without buffers. "
+          "Last group: %d", last_group);
+      if (last_group) {
+        GST_ELEMENT_ERROR (parsebin, STREAM, FAILED, (NULL),
+            ("all streams without buffers"));
+      } else {
+        gboolean switched = FALSE;
+        gboolean drained = FALSE;
+
+        drain_and_switch_chains (parsebin->parse_chain, NULL, &last_group,
+            &drained, &switched);
+        GST_ELEMENT_WARNING (parsebin, STREAM, FAILED, (NULL),
+            ("all streams without buffers"));
+        if (switched) {
+          if (gst_parse_chain_is_complete (parsebin->parse_chain))
+            goto retry;
+          else
+            return FALSE;
+        }
+      }
+    }
+
+    do_async_done (parsebin);
+    return FALSE;
+  }
+
+  if (uncollected_streams) {
+    /* FIXME: Collect and use a stream id from the top chain as
+     * upstream ID? */
+    fallback_collection = gst_stream_collection_new (NULL);
+
+    build_fallback_collection (parsebin->parse_chain, fallback_collection);
+
+    gst_element_post_message (GST_ELEMENT (parsebin),
+        gst_message_new_stream_collection (GST_OBJECT (parsebin),
+            fallback_collection));
+  }
+
+  g_string_free (missing_plugin_details, TRUE);
+
+  /* Check if this was called when everything was exposed already,
+   * and see if we need to post a new fallback collection */
+  for (tmp = endpads; tmp && already_exposed; tmp = tmp->next) {
+    GstParsePad *parsepad = tmp->data;
+
+    already_exposed &= parsepad->exposed;
+  }
+  if (already_exposed) {
+    GST_DEBUG_OBJECT (parsebin, "Everything was exposed already!");
+    if (fallback_collection)
+      gst_object_unref (fallback_collection);
+    g_list_free_full (endpads, (GDestroyNotify) gst_object_unref);
+    return TRUE;
+  }
+
+  /* Set all already exposed pads to blocked */
+  for (tmp = endpads; tmp; tmp = tmp->next) {
+    GstParsePad *parsepad = tmp->data;
+
+    if (parsepad->exposed) {
+      GST_DEBUG_OBJECT (parsepad, "blocking exposed pad");
+      gst_parse_pad_set_blocked (parsepad, TRUE);
+    }
+  }
+
+  /* re-order pads : video, then audio, then others */
+  endpads = g_list_sort (endpads, (GCompareFunc) sort_end_pads);
+
+  /* Expose pads */
+  for (tmp = endpads; tmp; tmp = tmp->next) {
+    GstParsePad *parsepad = (GstParsePad *) tmp->data;
+    gchar *padname;
+
+    //if (!parsepad->blocked)
+    //continue;
+
+    /* 1. rewrite name */
+    padname = g_strdup_printf ("src_%u", parsebin->nbpads);
+    parsebin->nbpads++;
+    GST_DEBUG_OBJECT (parsebin, "About to expose parsepad %s as %s",
+        GST_OBJECT_NAME (parsepad), padname);
+    gst_object_set_name (GST_OBJECT (parsepad), padname);
+    g_free (padname);
+
+    gst_pad_sticky_events_foreach (GST_PAD_CAST (parsepad), debug_sticky_event,
+        parsepad);
+
+    /* 2. activate and add */
+    if (!parsepad->exposed) {
+      parsepad->exposed = TRUE;
+      if (!gst_element_add_pad (GST_ELEMENT (parsebin),
+              GST_PAD_CAST (parsepad))) {
+        /* not really fatal, we can try to add the other pads */
+        g_warning ("error adding pad to ParseBin");
+        parsepad->exposed = FALSE;
+        continue;
+      }
+#if 0
+      /* HACK: Send an empty gap event to push sticky events */
+      gst_pad_push_event (GST_PAD (parsepad),
+          gst_event_new_gap (0, GST_CLOCK_TIME_NONE));
+#endif
+    }
+
+    GST_INFO_OBJECT (parsepad, "added new decoded pad");
+  }
+
+  /* Unblock internal pads. The application should have connected stuff now
+   * so that streaming can continue. */
+  for (tmp = endpads; tmp; tmp = tmp->next) {
+    GstParsePad *parsepad = (GstParsePad *) tmp->data;
+
+    if (parsepad->exposed) {
+      GST_DEBUG_OBJECT (parsepad, "unblocking");
+      gst_parse_pad_unblock (parsepad);
+      GST_DEBUG_OBJECT (parsepad, "unblocked");
+    }
+
+    /* Send stream-collection events for any pads that don't have them,
+     * and post a stream-collection onto the bus */
+    if (parsepad->active_collection == NULL && fallback_collection) {
+      gst_pad_push_event (GST_PAD (parsepad),
+          gst_event_new_stream_collection (fallback_collection));
+    }
+    gst_object_unref (parsepad);
+  }
+  g_list_free (endpads);
+
+  if (fallback_collection)
+    gst_object_unref (fallback_collection);
+
+  /* Remove old groups */
+  chain_remove_old_groups (parsebin->parse_chain);
+
+  do_async_done (parsebin);
+  GST_DEBUG_OBJECT (parsebin, "Exposed everything");
+  return TRUE;
+}
+
+/* gst_parse_chain_expose:
+ *
+ * Check if the chain can be exposed and add all endpads
+ * to the endpads list.
+ *
+ * Not MT-safe, call with ParseBin expose lock! *
+ */
+static gboolean
+gst_parse_chain_expose (GstParseChain * chain, GList ** endpads,
+    gboolean * missing_plugin, GString * missing_plugin_details,
+    gboolean * last_group, gboolean * uncollected_streams)
+{
+  GstParseGroup *group;
+  GList *l;
+  gboolean ret = FALSE;
+
+  if (chain->deadend) {
+    if (chain->endcaps) {
+      if (chain->deadend_details) {
+        g_string_append (missing_plugin_details, chain->deadend_details);
+        g_string_append_c (missing_plugin_details, '\n');
+      } else {
+        gchar *desc = gst_pb_utils_get_codec_description (chain->endcaps);
+        gchar *caps_str = gst_caps_to_string (chain->endcaps);
+        g_string_append_printf (missing_plugin_details,
+            "Missing decoder: %s (%s)\n", desc, caps_str);
+        g_free (caps_str);
+        g_free (desc);
+      }
+      *missing_plugin = TRUE;
+    }
+    return TRUE;
+  }
+
+  if (chain->endpad == NULL && chain->parsed && chain->pending_pads) {
+    /* The chain has a pending pad from a parser, let's just
+     * expose that now as the endpad */
+    GList *cur = chain->pending_pads;
+    GstPendingPad *ppad = (GstPendingPad *) (cur->data);
+    GstPad *endpad = gst_object_ref (ppad->pad);
+    GstElement *elem =
+        GST_ELEMENT (gst_object_get_parent (GST_OBJECT (endpad)));
+
+    chain->pending_pads = g_list_remove (chain->pending_pads, ppad);
+
+    gst_pending_pad_free (ppad);
+
+    GST_DEBUG_OBJECT (chain->parsebin,
+        "Exposing pad %" GST_PTR_FORMAT " with incomplete caps "
+        "because it's parsed", endpad);
+
+    expose_pad (chain->parsebin, elem, chain->current_pad, endpad, NULL, chain);
+    gst_object_unref (endpad);
+    gst_object_unref (elem);
+  }
+
+  if (chain->endpad) {
+    GstParsePad *p = chain->endpad;
+
+    if (p->active_stream && p->active_collection == NULL
+        && !p->in_a_fallback_collection)
+      *uncollected_streams = TRUE;
+
+    *endpads = g_list_prepend (*endpads, gst_object_ref (p));
+    return TRUE;
+  }
+
+  if (chain->next_groups)
+    *last_group = FALSE;
+
+  group = chain->active_group;
+  if (!group) {
+    GstParsePad *p = chain->current_pad;
+
+    if (p->active_stream && p->active_collection == NULL
+        && !p->in_a_fallback_collection)
+      *uncollected_streams = TRUE;
+
+    return FALSE;
+  }
+
+  for (l = group->children; l; l = l->next) {
+    GstParseChain *childchain = l->data;
+
+    ret |= gst_parse_chain_expose (childchain, endpads, missing_plugin,
+        missing_plugin_details, last_group, uncollected_streams);
+  }
+
+  return ret;
+}
+
+static void
+build_fallback_collection (GstParseChain * chain,
+    GstStreamCollection * collection)
+{
+  GstParseGroup *group = chain->active_group;
+  GList *l;
+
+  /* If it's an end pad, or a not-finished chain that's
+   * not a group, put it in the collection */
+  if (chain->endpad || (chain->current_pad && group == NULL)) {
+    GstParsePad *p = chain->current_pad;
+
+    if (p->active_stream != NULL && p->active_collection == NULL) {
+      GST_DEBUG_OBJECT (p, "Adding stream to fallback collection");
+      gst_stream_collection_add_stream (collection,
+          gst_object_ref (p->active_stream));
+      p->in_a_fallback_collection = TRUE;
+    }
+    return;
+  }
+
+  if (!group)
+    return;
+
+  /* we used g_list_prepend when adding children, so iterate from last
+   * to first to maintain the original order they were added in */
+  for (l = g_list_last (group->children); l != NULL; l = l->prev) {
+    GstParseChain *childchain = l->data;
+
+    build_fallback_collection (childchain, collection);
+  }
+}
+
+/*************************
+ * GstParsePad functions
+ *************************/
+
+static void gst_parse_pad_dispose (GObject * object);
+
+static void
+gst_parse_pad_class_init (GstParsePadClass * klass)
+{
+  GObjectClass *gobject_klass;
+
+  gobject_klass = (GObjectClass *) klass;
+
+  gobject_klass->dispose = gst_parse_pad_dispose;
+}
+
+static void
+gst_parse_pad_init (GstParsePad * pad)
+{
+  pad->chain = NULL;
+  pad->blocked = FALSE;
+  pad->exposed = FALSE;
+  pad->drained = FALSE;
+  gst_object_ref_sink (pad);
+}
+
+static void
+gst_parse_pad_dispose (GObject * object)
+{
+  GstParsePad *parsepad = (GstParsePad *) (object);
+  parse_pad_set_target (parsepad, NULL);
+
+  gst_object_replace ((GstObject **) & parsepad->active_collection, NULL);
+  gst_object_replace ((GstObject **) & parsepad->active_stream, NULL);
+
+  G_OBJECT_CLASS (gst_parse_pad_parent_class)->dispose (object);
+}
+
+static GstPadProbeReturn
+source_pad_blocked_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
+{
+  GstParsePad *parsepad = user_data;
+  GstParseChain *chain;
+  GstParseBin *parsebin;
+  GstPadProbeReturn ret = GST_PAD_PROBE_OK;
+
+  if (GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM) {
+    GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
+
+    GST_LOG_OBJECT (pad, "Seeing event '%s'", GST_EVENT_TYPE_NAME (event));
+
+    if (!GST_EVENT_IS_SERIALIZED (event)) {
+      /* do not block on sticky or out of band events otherwise the allocation query
+         from demuxer might block the loop thread */
+      GST_LOG_OBJECT (pad, "Letting OOB event through");
+      return GST_PAD_PROBE_PASS;
+    }
+
+    if (GST_EVENT_IS_STICKY (event) && GST_EVENT_TYPE (event) != GST_EVENT_EOS) {
+      GstPad *peer;
+
+      /* manually push sticky events to ghost pad to avoid exposing pads
+       * that don't have the sticky events. Handle EOS separately as we
+       * want to block the pad on it if we didn't get any buffers before
+       * EOS and expose the pad then. */
+      peer = gst_pad_get_peer (pad);
+      gst_pad_send_event (peer, event);
+      gst_object_unref (peer);
+      GST_LOG_OBJECT (pad, "Manually pushed sticky event through");
+      ret = GST_PAD_PROBE_HANDLED;
+      goto done;
+    }
+  } else if (GST_PAD_PROBE_INFO_TYPE (info) &
+      GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM) {
+    GstQuery *query = GST_PAD_PROBE_INFO_QUERY (info);
+
+    if (!GST_QUERY_IS_SERIALIZED (query)) {
+      /* do not block on non-serialized queries */
+      GST_LOG_OBJECT (pad, "Letting non-serialized query through");
+      return GST_PAD_PROBE_PASS;
+    }
+    if (!gst_pad_has_current_caps (pad)) {
+      /* do not block on allocation queries before we have caps,
+       * this would deadlock because we are doing no autoplugging
+       * without caps.
+       * TODO: Try to do autoplugging based on the query caps
+       */
+      GST_LOG_OBJECT (pad, "Letting serialized query before caps through");
+      return GST_PAD_PROBE_PASS;
+    }
+  }
+  chain = parsepad->chain;
+  parsebin = chain->parsebin;
+
+  GST_LOG_OBJECT (parsepad, "blocked: parsepad->chain:%p", chain);
+
+  parsepad->blocked = TRUE;
+
+  EXPOSE_LOCK (parsebin);
+  if (parsebin->parse_chain) {
+    if (!gst_parse_bin_expose (parsebin))
+      GST_WARNING_OBJECT (parsebin, "Couldn't expose group");
+  }
+  EXPOSE_UNLOCK (parsebin);
+
+done:
+  return ret;
+}
+
+/* FIXME: We can probably do some cleverer things, and maybe move this into
+ * pbutils. Ideas:
+ *    if there are tags look if it's got an AUDIO_CODEC VIDEO_CODEC CONTAINER_FORMAT tag
+ *    Look at the factory klass designation of parsers in the chain
+ *    Consider demuxer pad names as well, sometimes they give the type away
+ */
+static GstStreamType
+guess_stream_type_from_caps (GstCaps * caps)
+{
+  GstStructure *s;
+  const gchar *name;
+
+  if (gst_caps_get_size (caps) < 1)
+    return GST_STREAM_TYPE_UNKNOWN;
+
+  s = gst_caps_get_structure (caps, 0);
+  name = gst_structure_get_name (s);
+
+  if (g_str_has_prefix (name, "video/") || g_str_has_prefix (name, "image/"))
+    return GST_STREAM_TYPE_VIDEO;
+  if (g_str_has_prefix (name, "audio/"))
+    return GST_STREAM_TYPE_AUDIO;
+  if (g_str_has_prefix (name, "text/") ||
+      g_str_has_prefix (name, "subpicture/"))
+    return GST_STREAM_TYPE_TEXT;
+
+  return GST_STREAM_TYPE_UNKNOWN;
+}
+
+static void
+gst_parse_pad_update_caps (GstParsePad * parsepad, GstCaps * caps)
+{
+  if (caps && parsepad->active_stream) {
+    GST_DEBUG_OBJECT (parsepad, "Storing caps %" GST_PTR_FORMAT
+        " on stream %" GST_PTR_FORMAT, caps, parsepad->active_stream);
+
+    if (gst_caps_is_fixed (caps))
+      gst_stream_set_caps (parsepad->active_stream, caps);
+    /* intuit a type */
+    if (gst_stream_get_stream_type (parsepad->active_stream) ==
+        GST_STREAM_TYPE_UNKNOWN) {
+      GstStreamType new_type = guess_stream_type_from_caps (caps);
+      if (new_type != GST_STREAM_TYPE_UNKNOWN)
+        gst_stream_set_stream_type (parsepad->active_stream, new_type);
+    }
+  }
+}
+
+static void
+gst_parse_pad_update_tags (GstParsePad * parsepad, GstTagList * tags)
+{
+  if (tags && gst_tag_list_get_scope (tags) == GST_TAG_SCOPE_STREAM
+      && parsepad->active_stream) {
+    GST_DEBUG_OBJECT (parsepad,
+        "Storing new tags %" GST_PTR_FORMAT " on stream %" GST_PTR_FORMAT, tags,
+        parsepad->active_stream);
+    gst_stream_set_tags (parsepad->active_stream, tags);
+  }
+}
+
+static GstEvent *
+gst_parse_pad_stream_start_event (GstParsePad * parsepad, GstEvent * event)
+{
+  GstStream *stream = NULL;
+  const gchar *stream_id = NULL;
+  gboolean repeat_event = FALSE;
+
+  gst_event_parse_stream_start (event, &stream_id);
+
+  if (parsepad->active_stream != NULL &&
+      g_str_equal (parsepad->active_stream->stream_id, stream_id))
+    repeat_event = TRUE;
+  else {
+    /* A new stream requires a new collection event, or else
+     * we'll place it in a fallback collection later */
+    gst_object_replace ((GstObject **) & parsepad->active_collection, NULL);
+    parsepad->in_a_fallback_collection = FALSE;
+  }
+
+  gst_event_parse_stream (event, &stream);
+  if (stream == NULL) {
+    GstCaps *caps = gst_pad_get_current_caps (GST_PAD_CAST (parsepad));
+    if (caps == NULL) {
+      /* Try and get caps from the parsepad peer */
+      GstPad *peer = gst_ghost_pad_get_target (GST_GHOST_PAD (parsepad));
+      caps = gst_pad_get_current_caps (peer);
+      gst_object_unref (peer);
+    }
+    if (caps == NULL && parsepad->chain && parsepad->chain->start_caps) {
+      /* Still no caps, use the chain start caps */
+      caps = gst_caps_ref (parsepad->chain->start_caps);
+    }
+
+    GST_DEBUG_OBJECT (parsepad,
+        "Saw stream_start with no GstStream. Adding one. Caps %"
+        GST_PTR_FORMAT, caps);
+
+    if (repeat_event) {
+      stream = gst_object_ref (parsepad->active_stream);
+    } else {
+      stream =
+          gst_stream_new (stream_id, NULL, GST_STREAM_TYPE_UNKNOWN,
+          GST_STREAM_FLAG_NONE);
+      gst_object_replace ((GstObject **) & parsepad->active_stream,
+          (GstObject *) stream);
+    }
+    if (caps) {
+      gst_parse_pad_update_caps (parsepad, caps);
+      gst_caps_unref (caps);
+    }
+
+    event = gst_event_make_writable (event);
+    gst_event_set_stream (event, stream);
+  }
+  gst_object_unref (stream);
+  GST_LOG_OBJECT (parsepad, "Saw stream %s (GstStream %p)",
+      stream->stream_id, stream);
+
+  return event;
+}
+
+static void
+gst_parse_pad_update_stream_collection (GstParsePad * parsepad,
+    GstStreamCollection * collection)
+{
+  GST_LOG_OBJECT (parsepad, "Got new stream collection %p", collection);
+  gst_object_replace ((GstObject **) & parsepad->active_collection,
+      (GstObject *) collection);
+  parsepad->in_a_fallback_collection = FALSE;
+}
+
+static GstPadProbeReturn
+gst_parse_pad_event (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
+{
+  GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
+  GstObject *parent = gst_pad_get_parent (pad);
+  GstParsePad *parsepad = GST_PARSE_PAD (parent);
+  gboolean forwardit = TRUE;
+
+  GST_LOG_OBJECT (pad, "%s parsepad:%p", GST_EVENT_TYPE_NAME (event), parsepad);
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_CAPS:{
+      GstCaps *caps = NULL;
+      gst_event_parse_caps (event, &caps);
+      gst_parse_pad_update_caps (parsepad, caps);
+      break;
+    }
+    case GST_EVENT_TAG:{
+      GstTagList *tags;
+      gst_event_parse_tag (event, &tags);
+      gst_parse_pad_update_tags (parsepad, tags);
+      break;
+    }
+    case GST_EVENT_STREAM_START:{
+      GST_PAD_PROBE_INFO_DATA (info) =
+          gst_parse_pad_stream_start_event (parsepad, event);
+      break;
+    }
+    case GST_EVENT_STREAM_COLLECTION:{
+      GstStreamCollection *collection = NULL;
+      gst_event_parse_stream_collection (event, &collection);
+      gst_parse_pad_update_stream_collection (parsepad, collection);
+      break;
+    }
+    case GST_EVENT_EOS:{
+      GST_DEBUG_OBJECT (pad, "we received EOS");
+
+      /* Check if all pads are drained.
+       * * If there is no next group, we will let the EOS go through.
+       * * If there is a next group but the current group isn't completely
+       *   drained, we will drop the EOS event.
+       * * If there is a next group to expose and this was the last non-drained
+       *   pad for that group, we will remove the ghostpad of the current group
+       *   first, which unlinks the peer and so drops the EOS. */
+      forwardit = gst_parse_pad_handle_eos (parsepad);
+    }
+    default:
+      break;
+  }
+  gst_object_unref (parent);
+  if (forwardit)
+    return GST_PAD_PROBE_OK;
+  else
+    return GST_PAD_PROBE_DROP;
+}
+
+static void
+gst_parse_pad_set_blocked (GstParsePad * parsepad, gboolean blocked)
+{
+  GstParseBin *parsebin = parsepad->parsebin;
+  GstPad *opad;
+
+  DYN_LOCK (parsebin);
+
+  GST_DEBUG_OBJECT (parsepad, "blocking pad: %d", blocked);
+
+  opad = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (parsepad));
+  if (!opad)
+    goto out;
+
+  /* do not block if shutting down.
+   * we do not consider/expect it blocked further below, but use other trick */
+  if (!blocked || !parsebin->shutdown) {
+    if (blocked) {
+      if (parsepad->block_id == 0)
+        parsepad->block_id =
+            gst_pad_add_probe (opad,
+            GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM |
+            GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM, source_pad_blocked_cb,
+            gst_object_ref (parsepad), (GDestroyNotify) gst_object_unref);
+    } else {
+      if (parsepad->block_id != 0) {
+        gst_pad_remove_probe (opad, parsepad->block_id);
+        parsepad->block_id = 0;
+      }
+      parsepad->blocked = FALSE;
+    }
+  }
+
+  if (blocked) {
+    if (parsebin->shutdown) {
+      /* deactivate to force flushing state to prevent NOT_LINKED errors */
+      gst_pad_set_active (GST_PAD_CAST (parsepad), FALSE);
+      /* note that deactivating the target pad would have no effect here,
+       * since elements are typically connected first (and pads exposed),
+       * and only then brought to PAUSED state (so pads activated) */
+    } else {
+      gst_object_ref (parsepad);
+      parsebin->blocked_pads =
+          g_list_prepend (parsebin->blocked_pads, parsepad);
+    }
+  } else {
+    GList *l;
+
+    if ((l = g_list_find (parsebin->blocked_pads, parsepad))) {
+      gst_object_unref (parsepad);
+      parsebin->blocked_pads = g_list_delete_link (parsebin->blocked_pads, l);
+    }
+  }
+  gst_object_unref (opad);
+out:
+  DYN_UNLOCK (parsebin);
+}
+
+static void
+gst_parse_pad_activate (GstParsePad * parsepad, GstParseChain * chain)
+{
+  g_return_if_fail (chain != NULL);
+
+  parsepad->chain = chain;
+  gst_pad_set_active (GST_PAD_CAST (parsepad), TRUE);
+  gst_parse_pad_set_blocked (parsepad, TRUE);
+}
+
+static void
+gst_parse_pad_unblock (GstParsePad * parsepad)
+{
+  gst_parse_pad_set_blocked (parsepad, FALSE);
+}
+
+static gboolean
+gst_parse_pad_query (GstPad * pad, GstObject * parent, GstQuery * query)
+{
+  GstParsePad *parsepad = GST_PARSE_PAD (parent);
+  gboolean ret = FALSE;
+
+  CHAIN_MUTEX_LOCK (parsepad->chain);
+  if (!parsepad->exposed && !parsepad->parsebin->shutdown
+      && !parsepad->chain->deadend && parsepad->chain->elements) {
+    GstParseElement *delem = parsepad->chain->elements->data;
+
+    ret = FALSE;
+    GST_DEBUG_OBJECT (parsepad->parsebin,
+        "calling autoplug-query for %s (element %s): %" GST_PTR_FORMAT,
+        GST_PAD_NAME (parsepad), GST_ELEMENT_NAME (delem->element), query);
+    g_signal_emit (G_OBJECT (parsepad->parsebin),
+        gst_parse_bin_signals[SIGNAL_AUTOPLUG_QUERY], 0, parsepad,
+        delem->element, query, &ret);
+
+    if (ret)
+      GST_DEBUG_OBJECT (parsepad->parsebin,
+          "autoplug-query returned %d: %" GST_PTR_FORMAT, ret, query);
+    else
+      GST_DEBUG_OBJECT (parsepad->parsebin, "autoplug-query returned %d", ret);
+  }
+  CHAIN_MUTEX_UNLOCK (parsepad->chain);
+
+  /* If exposed or nothing handled the query use the default handler */
+  if (!ret)
+    ret = gst_pad_query_default (pad, parent, query);
+
+  return ret;
+}
+
+/*gst_parse_pad_new:
+ *
+ * Creates a new GstParsePad for the given pad.
+ */
+static GstParsePad *
+gst_parse_pad_new (GstParseBin * parsebin, GstParseChain * chain)
+{
+  GstParsePad *parsepad;
+  GstProxyPad *ppad;
+  GstPadTemplate *pad_tmpl;
+
+  GST_DEBUG_OBJECT (parsebin, "making new decodepad");
+  pad_tmpl = gst_static_pad_template_get (&decoder_bin_src_template);
+  parsepad =
+      g_object_new (GST_TYPE_PARSE_PAD, "direction", GST_PAD_SRC,
+      "template", pad_tmpl, NULL);
+  gst_ghost_pad_construct (GST_GHOST_PAD_CAST (parsepad));
+  parsepad->chain = chain;
+  parsepad->parsebin = parsebin;
+  gst_object_unref (pad_tmpl);
+
+  ppad = gst_proxy_pad_get_internal (GST_PROXY_PAD (parsepad));
+  gst_pad_set_query_function (GST_PAD_CAST (ppad), gst_parse_pad_query);
+
+  /* Add downstream event probe */
+  GST_LOG_OBJECT (parsepad, "Adding event probe on internal pad %"
+      GST_PTR_FORMAT, ppad);
+  gst_pad_add_probe (GST_PAD_CAST (ppad),
+      GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, gst_parse_pad_event, parsepad, NULL);
+  gst_object_unref (ppad);
+
+  return parsepad;
+}
+
+static void
+gst_pending_pad_free (GstPendingPad * ppad)
+{
+  g_assert (ppad);
+  g_assert (ppad->pad);
+
+  if (ppad->event_probe_id != 0)
+    gst_pad_remove_probe (ppad->pad, ppad->event_probe_id);
+  if (ppad->notify_caps_id)
+    g_signal_handler_disconnect (ppad->pad, ppad->notify_caps_id);
+  gst_object_unref (ppad->pad);
+  g_slice_free (GstPendingPad, ppad);
+}
+
+/*****
+ * Element add/remove
+ *****/
+
+static void
+do_async_start (GstParseBin * parsebin)
+{
+  GstMessage *message;
+
+  parsebin->async_pending = TRUE;
+
+  message = gst_message_new_async_start (GST_OBJECT_CAST (parsebin));
+  parent_class->handle_message (GST_BIN_CAST (parsebin), message);
+}
+
+static void
+do_async_done (GstParseBin * parsebin)
+{
+  GstMessage *message;
+
+  if (parsebin->async_pending) {
+    message =
+        gst_message_new_async_done (GST_OBJECT_CAST (parsebin),
+        GST_CLOCK_TIME_NONE);
+    parent_class->handle_message (GST_BIN_CAST (parsebin), message);
+
+    parsebin->async_pending = FALSE;
+  }
+}
+
+/* call with dyn_lock held */
+static void
+unblock_pads (GstParseBin * parsebin)
+{
+  GList *tmp;
+
+  GST_LOG_OBJECT (parsebin, "unblocking pads");
+
+  for (tmp = parsebin->blocked_pads; tmp; tmp = tmp->next) {
+    GstParsePad *parsepad = (GstParsePad *) tmp->data;
+    GstPad *opad;
+
+    opad = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (parsepad));
+    if (!opad)
+      continue;
+
+    GST_DEBUG_OBJECT (parsepad, "unblocking");
+    if (parsepad->block_id != 0) {
+      gst_pad_remove_probe (opad, parsepad->block_id);
+      parsepad->block_id = 0;
+    }
+    parsepad->blocked = FALSE;
+    /* make flushing, prevent NOT_LINKED */
+    gst_pad_set_active (GST_PAD_CAST (parsepad), FALSE);
+    gst_object_unref (parsepad);
+    gst_object_unref (opad);
+    GST_DEBUG_OBJECT (parsepad, "unblocked");
+  }
+
+  /* clear, no more blocked pads */
+  g_list_free (parsebin->blocked_pads);
+  parsebin->blocked_pads = NULL;
+}
+
+static GstStateChangeReturn
+gst_parse_bin_change_state (GstElement * element, GstStateChange transition)
+{
+  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+  GstParseBin *parsebin = GST_PARSE_BIN (element);
+  GstParseChain *chain_to_free = NULL;
+
+  switch (transition) {
+    case GST_STATE_CHANGE_NULL_TO_READY:
+      if (parsebin->typefind == NULL)
+        goto missing_typefind;
+      break;
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+      /* Make sure we've cleared all existing chains */
+      EXPOSE_LOCK (parsebin);
+      if (parsebin->parse_chain) {
+        gst_parse_chain_free (parsebin->parse_chain);
+        parsebin->parse_chain = NULL;
+      }
+      EXPOSE_UNLOCK (parsebin);
+      DYN_LOCK (parsebin);
+      GST_LOG_OBJECT (parsebin, "clearing shutdown flag");
+      parsebin->shutdown = FALSE;
+      DYN_UNLOCK (parsebin);
+      parsebin->have_type = FALSE;
+      ret = GST_STATE_CHANGE_ASYNC;
+      do_async_start (parsebin);
+
+
+      /* connect a signal to find out when the typefind element found
+       * a type */
+      parsebin->have_type_id =
+          g_signal_connect (parsebin->typefind, "have-type",
+          G_CALLBACK (type_found), parsebin);
+      break;
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+      if (parsebin->have_type_id)
+        g_signal_handler_disconnect (parsebin->typefind,
+            parsebin->have_type_id);
+      parsebin->have_type_id = 0;
+      DYN_LOCK (parsebin);
+      GST_LOG_OBJECT (parsebin, "setting shutdown flag");
+      parsebin->shutdown = TRUE;
+      unblock_pads (parsebin);
+      DYN_UNLOCK (parsebin);
+    default:
+      break;
+  }
+
+  {
+    GstStateChangeReturn bret;
+
+    bret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+    if (G_UNLIKELY (bret == GST_STATE_CHANGE_FAILURE))
+      goto activate_failed;
+    else if (G_UNLIKELY (bret == GST_STATE_CHANGE_NO_PREROLL)) {
+      do_async_done (parsebin);
+      ret = bret;
+    }
+  }
+  switch (transition) {
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+      do_async_done (parsebin);
+      EXPOSE_LOCK (parsebin);
+      if (parsebin->parse_chain) {
+        chain_to_free = parsebin->parse_chain;
+        gst_parse_chain_free_internal (parsebin->parse_chain, TRUE);
+        parsebin->parse_chain = NULL;
+      }
+      EXPOSE_UNLOCK (parsebin);
+      if (chain_to_free)
+        gst_parse_chain_free (chain_to_free);
+      break;
+    case GST_STATE_CHANGE_READY_TO_NULL:
+    default:
+      break;
+  }
+
+  return ret;
+
+/* ERRORS */
+missing_typefind:
+  {
+    gst_element_post_message (element,
+        gst_missing_element_message_new (element, "typefind"));
+    GST_ELEMENT_ERROR (parsebin, CORE, MISSING_PLUGIN, (NULL),
+        ("no typefind!"));
+    return GST_STATE_CHANGE_FAILURE;
+  }
+activate_failed:
+  {
+    GST_DEBUG_OBJECT (element,
+        "element failed to change states -- activation problem?");
+    do_async_done (parsebin);
+    return GST_STATE_CHANGE_FAILURE;
+  }
+}
+
+static void
+gst_parse_bin_handle_message (GstBin * bin, GstMessage * msg)
+{
+  GstParseBin *parsebin = GST_PARSE_BIN (bin);
+  gboolean drop = FALSE;
+
+  switch (GST_MESSAGE_TYPE (msg)) {
+    case GST_MESSAGE_ERROR:{
+      GST_OBJECT_LOCK (parsebin);
+      drop = (g_list_find (parsebin->filtered, GST_MESSAGE_SRC (msg)) != NULL);
+      if (drop)
+        parsebin->filtered_errors =
+            g_list_prepend (parsebin->filtered_errors, gst_message_ref (msg));
+      GST_OBJECT_UNLOCK (parsebin);
+      break;
+    }
+    default:
+      break;
+  }
+
+  if (drop)
+    gst_message_unref (msg);
+  else
+    GST_BIN_CLASS (parent_class)->handle_message (bin, msg);
+}
+
+gboolean
+gst_parse_bin_plugin_init (GstPlugin * plugin)
+{
+  GST_DEBUG_CATEGORY_INIT (gst_parse_bin_debug, "parsebin", 0, "parser bin");
+
+  return gst_element_register (plugin, "parsebin", GST_RANK_NONE,
+      GST_TYPE_PARSE_BIN);
+}
diff --git a/gst/playback/gstplayback.c b/gst/playback/gstplayback.c
index 882a7ec..4789db6 100644
--- a/gst/playback/gstplayback.c
+++ b/gst/playback/gstplayback.c
@@ -46,13 +46,25 @@
   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 #endif /* ENABLE_NLS */
 
-  res = gst_play_bin2_plugin_init (plugin);
+  /* Swap in playbin3 as 'playbin' if USE_PLAYBIN3=1 */
+  {
+    const gchar *env = g_getenv ("USE_PLAYBIN3");
+    if (env && g_str_has_prefix (env, "1"))
+      res = gst_play_bin3_plugin_init (plugin, TRUE);
+    else
+      res = gst_play_bin2_plugin_init (plugin);
+  }
+
+  res &= gst_play_bin3_plugin_init (plugin, FALSE);
   res &= gst_play_sink_plugin_init (plugin);
   res &= gst_subtitle_overlay_plugin_init (plugin);
   res &= gst_stream_synchronizer_plugin_init (plugin);
 
   res &= gst_decode_bin_plugin_init (plugin);
+  res &= gst_decodebin3_plugin_init (plugin);
   res &= gst_uri_decode_bin_plugin_init (plugin);
+  res &= gst_uri_source_bin_plugin_init (plugin);
+  res &= gst_parse_bin_plugin_init (plugin);
 
   return res;
 }
diff --git a/gst/playback/gstplayback.h b/gst/playback/gstplayback.h
index b4309c7..eaa0564 100644
--- a/gst/playback/gstplayback.h
+++ b/gst/playback/gstplayback.h
@@ -24,10 +24,14 @@
 #include <gst/gst.h>
 
 gboolean gst_decode_bin_plugin_init (GstPlugin * plugin);
+gboolean gst_decodebin3_plugin_init (GstPlugin * plugin);
 gboolean gst_uri_decode_bin_plugin_init (GstPlugin * plugin);
+gboolean gst_uri_source_bin_plugin_init (GstPlugin * plugin);
+gboolean gst_parse_bin_plugin_init (GstPlugin * plugin);
 
 gboolean gst_play_bin_plugin_init (GstPlugin * plugin);
 gboolean gst_play_bin2_plugin_init (GstPlugin * plugin);
+gboolean gst_play_bin3_plugin_init (GstPlugin * plugin, gboolean as_playbin);
 
 
 #endif /* __GST_PLAY_BACK_H__ */
diff --git a/gst/playback/gstplaybackutils.c b/gst/playback/gstplaybackutils.c
index d003c91..ef98528 100644
--- a/gst/playback/gstplaybackutils.c
+++ b/gst/playback/gstplaybackutils.c
@@ -131,3 +131,30 @@
 
   return n_common_cf;
 }
+
+gint
+gst_playback_utils_compare_factories_func (gconstpointer p1, gconstpointer p2)
+{
+  GstPluginFeature *f1, *f2;
+  gboolean is_parser1, is_parser2;
+
+  f1 = (GstPluginFeature *) p1;
+  f2 = (GstPluginFeature *) p2;
+
+  is_parser1 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f1),
+      GST_ELEMENT_FACTORY_TYPE_PARSER);
+  is_parser2 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f2),
+      GST_ELEMENT_FACTORY_TYPE_PARSER);
+
+
+  /* We want all parsers first as we always want to plug parsers
+   * before decoders */
+  if (is_parser1 && !is_parser2)
+    return -1;
+  else if (!is_parser1 && is_parser2)
+    return 1;
+
+  /* And if it's a both a parser we first sort by rank
+   * and then by factory name */
+  return gst_plugin_feature_rank_compare_func (p1, p2);
+}
diff --git a/gst/playback/gstplaybackutils.h b/gst/playback/gstplaybackutils.h
index c9f895e..d7f6700 100644
--- a/gst/playback/gstplaybackutils.h
+++ b/gst/playback/gstplaybackutils.h
@@ -27,11 +27,15 @@
 #include <gst/gst.h>
 #include "gstplay-enum.h"
 
+G_GNUC_INTERNAL
 guint
 gst_playback_utils_get_n_common_capsfeatures (GstElementFactory * fact1,
                                         GstElementFactory * fact2,
                                         GstPlayFlags flags,
                                         gboolean isaudioelement);
+G_GNUC_INTERNAL
+gint
+gst_playback_utils_compare_factories_func (gconstpointer p1, gconstpointer p2);
 G_END_DECLS
 
 #endif /* __GST_PLAYBACK_UTILS_H__ */
diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c
index ad63600..15fea65 100644
--- a/gst/playback/gstplaybin2.c
+++ b/gst/playback/gstplaybin2.c
@@ -603,6 +603,7 @@
   SIGNAL_GET_AUDIO_PAD,
   SIGNAL_GET_TEXT_PAD,
   SIGNAL_SOURCE_SETUP,
+  SIGNAL_ELEMENT_SETUP,
   LAST_SIGNAL
 };
 
@@ -622,6 +623,8 @@
     GstStateChange transition);
 
 static void gst_play_bin_handle_message (GstBin * bin, GstMessage * message);
+static void gst_play_bin_deep_element_added (GstBin * playbin, GstBin * sub_bin,
+    GstElement * child);
 static gboolean gst_play_bin_query (GstElement * element, GstQuery * query);
 static void gst_play_bin_set_context (GstElement * element,
     GstContext * context);
@@ -1178,6 +1181,27 @@
       g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
 
   /**
+   * GstPlayBin::element-setup:
+   * @playbin: a #GstPlayBin
+   * @element: an element that was added to the playbin hierarchy
+   *
+   * This signal is emitted when a new element is added to playbin or any of
+   * its sub-bins. This signal can be used to configure elements, e.g. to set
+   * properties on decoders. This is functionally equivalent to connecting to
+   * the deep-element-added signal, but more convenient.
+   *
+   * This signal is usually emitted from the context of a GStreamer streaming
+   * thread, so might be called at the same time as code running in the main
+   * application thread.
+   *
+   * Since: 1.10
+   */
+  gst_play_bin_signals[SIGNAL_ELEMENT_SETUP] =
+      g_signal_new ("element-setup", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+      g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
+
+  /**
    * GstPlayBin::get-video-tags
    * @playbin: a #GstPlayBin
    * @stream: a video stream number
@@ -1321,6 +1345,8 @@
 
   gstbin_klass->handle_message =
       GST_DEBUG_FUNCPTR (gst_play_bin_handle_message);
+  gstbin_klass->deep_element_added =
+      GST_DEBUG_FUNCPTR (gst_play_bin_deep_element_added);
 }
 
 static void
@@ -3011,6 +3037,18 @@
 }
 
 static void
+gst_play_bin_deep_element_added (GstBin * playbin, GstBin * sub_bin,
+    GstElement * child)
+{
+  GST_LOG_OBJECT (playbin, "element %" GST_PTR_FORMAT " was added to "
+      "%" GST_PTR_FORMAT, child, sub_bin);
+
+  g_signal_emit (playbin, gst_play_bin_signals[SIGNAL_ELEMENT_SETUP], 0, child);
+
+  GST_BIN_CLASS (parent_class)->deep_element_added (playbin, sub_bin, child);
+}
+
+static void
 combiner_active_pad_changed (GObject * combiner, GParamSpec * pspec,
     GstPlayBin * playbin)
 {
diff --git a/gst/playback/gstplaybin3.c b/gst/playback/gstplaybin3.c
new file mode 100644
index 0000000..6c084a4
--- /dev/null
+++ b/gst/playback/gstplaybin3.c
@@ -0,0 +1,5476 @@
+/* GStreamer
+ * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com>
+ * Copyright (C) <2011> Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * Copyright (C) <2013> Collabora Ltd.
+ *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * Copyright (C) <2015> Jan Schmidt <jan@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.
+ */
+
+/**
+ * SECTION:element-playbin3
+ *
+ * playbin3 provides a stand-alone everything-in-one abstraction for an
+ * audio and/or video player. It differs from the previous playbin (playbin2)
+ * by supporting publication and selection of available streams via the
+ * #GstStreamCollection message and #GST_EVENT_SELECT_STREAMS event API.
+ *
+ * <emphasis>playbin3 is still experimental API and a technology preview.
+ * Its behaviour and exposed API is subject to change.</emphasis>
+ *
+ * playbin3 can handle both audio and video files and features
+ * <itemizedlist>
+ * <listitem>
+ * automatic file type recognition and based on that automatic
+ * selection and usage of the right audio/video/subtitle demuxers/decoders
+ * </listitem>
+ * <listitem>
+ * auxilliary files - such as external subtitles and audio tracks
+ * </listitem>
+ * <listitem>
+ * visualisations for audio files
+ * </listitem>
+ * <listitem>
+ * subtitle support for video files. Subtitles can be store in external
+ * files.
+ * </listitem>
+ * <listitem>
+ * stream selection between different video/audio/subtitles streams
+ * </listitem>
+ * <listitem>
+ * meta info (tag) extraction
+ * </listitem>
+ * <listitem>
+ * easy access to the last video sample
+ * </listitem>
+ * <listitem>
+ * buffering when playing streams over a network
+ * </listitem>
+ * <listitem>
+ * volume control with mute option
+ * </listitem>
+ * </itemizedlist>
+ *
+ * <refsect2>
+ * <title>Usage</title>
+ * <para>
+ * A playbin element can be created just like any other element using
+ * gst_element_factory_make(). The file/URI to play should be set via the #GstPlayBin3:uri
+ * property. This must be an absolute URI, relative file paths are not allowed.
+ * Example URIs are file:///home/joe/movie.avi or http://www.joedoe.com/foo.ogg
+ *
+ * Playbin3 is a #GstPipeline. It will notify the application of everything
+ * that's happening (errors, end of stream, tags found, state changes, etc.)
+ * by posting messages on its #GstBus. The application needs to watch the
+ * bus.
+ *
+ * Playback can be initiated by setting the element to PLAYING state using
+ * gst_element_set_state(). Note that the state change will take place in
+ * the background in a separate thread, when the function returns playback
+ * is probably not happening yet and any errors might not have occured yet.
+ * Applications using playbin3 should ideally be written to deal with things
+ * completely asynchroneous.
+ *
+ * When playback has finished (an EOS message has been received on the bus)
+ * or an error has occured (an ERROR message has been received on the bus) or
+ * the user wants to play a different track, playbin3 should be set back to
+ * READY or NULL state, then the #GstPlayBin3:uri property should be set to the
+ * new location and then playbin3 be set to PLAYING state again.
+ *
+ * Seeking can be done using gst_element_seek_simple() or gst_element_seek()
+ * on the playbin3 element. Again, the seek will not be executed
+ * instantaneously, but will be done in a background thread. When the seek
+ * call returns the seek will most likely still be in process. An application
+ * may wait for the seek to finish (or fail) using gst_element_get_state() with
+ * -1 as the timeout, but this will block the user interface and is not
+ * recommended at all.
+ *
+ * Applications may query the current position and duration of the stream
+ * via gst_element_query_position() and gst_element_query_duration() and
+ * setting the format passed to GST_FORMAT_TIME. If the query was successful,
+ * the duration or position will have been returned in units of nanoseconds.
+ * </para>
+ * </refsect2>
+ * <refsect2>
+ * <title>Advanced Usage: specifying the audio and video sink</title>
+ * <para>
+ * By default, if no audio sink or video sink has been specified via the
+ * #GstPlayBin3:audio-sink or #GstPlayBin3:video-sink property, playbin3 will use the autoaudiosink
+ * and autovideosink elements to find the first-best available output method.
+ * This should work in most cases, but is not always desirable. Often either
+ * the user or application might want to specify more explicitly what to use
+ * for audio and video output.
+ *
+ * If the application wants more control over how audio or video should be
+ * output, it may create the audio/video sink elements itself (for example
+ * using gst_element_factory_make()) and provide them to playbin3 using the
+ * #GstPlayBin3:audio-sink or #GstPlayBin3:video-sink property.
+ *
+ * GNOME-based applications, for example, will usually want to create
+ * gconfaudiosink and gconfvideosink elements and make playbin3 use those,
+ * so that output happens to whatever the user has configured in the GNOME
+ * Multimedia System Selector configuration dialog.
+ *
+ * The sink elements do not necessarily need to be ready-made sinks. It is
+ * possible to create container elements that look like a sink to playbin3,
+ * but in reality contain a number of custom elements linked together. This
+ * can be achieved by creating a #GstBin and putting elements in there and
+ * linking them, and then creating a sink #GstGhostPad for the bin and pointing
+ * it to the sink pad of the first element within the bin. This can be used
+ * for a number of purposes, for example to force output to a particular
+ * format or to modify or observe the data before it is output.
+ *
+ * It is also possible to 'suppress' audio and/or video output by using
+ * 'fakesink' elements (or capture it from there using the fakesink element's
+ * "handoff" signal, which, nota bene, is fired from the streaming thread!).
+ * </para>
+ * </refsect2>
+ * <refsect2>
+ * <title>Retrieving Tags and Other Meta Data</title>
+ * <para>
+ * Most of the common meta data (artist, title, etc.) can be retrieved by
+ * watching for TAG messages on the pipeline's bus (see above).
+ *
+ * Other more specific meta information like width/height/framerate of video
+ * streams or samplerate/number of channels of audio streams can be obtained
+ * from the negotiated caps on the sink pads of the sinks.
+ * </para>
+ * </refsect2>
+ * <refsect2>
+ * <title>Buffering</title>
+ * Playbin3 handles buffering automatically for the most part, but applications
+ * need to handle parts of the buffering process as well. Whenever playbin3 is
+ * buffering, it will post BUFFERING messages on the bus with a percentage
+ * value that shows the progress of the buffering process. Applications need
+ * to set playbin3 to PLAYING or PAUSED state in response to these messages.
+ * They may also want to convey the buffering progress to the user in some
+ * way. Here is how to extract the percentage information from the message:
+ * |[
+ * switch (GST_MESSAGE_TYPE (msg)) {
+ *   case GST_MESSAGE_BUFFERING: {
+ *     gint percent = 0;
+ *     gst_message_parse_buffering (msg, &percent);
+ *     g_print ("Buffering (%u percent done)", percent);
+ *     break;
+ *   }
+ *   ...
+ * }
+ * ]|
+ * Note that applications should keep/set the pipeline in the PAUSED state when
+ * a BUFFERING message is received with a buffer percent value < 100 and set
+ * the pipeline back to PLAYING state when a BUFFERING message with a value
+ * of 100 percent is received (if PLAYING is the desired state, that is).
+ * </refsect2>
+ * <refsect2>
+ * <title>Embedding the video window in your application</title>
+ * By default, playbin3 (or rather the video sinks used) will create their own
+ * window. Applications will usually want to force output to a window of their
+ * own, however. This can be done using the #GstVideoOverlay interface, which most
+ * video sinks implement. See the documentation there for more details.
+ * </refsect2>
+ * <refsect2>
+ * <title>Specifying which CD/DVD device to use</title>
+ * The device to use for CDs/DVDs needs to be set on the source element
+ * playbin3 creates before it is opened. The most generic way of doing this
+ * is to connect to playbin3's "source-setup" (or "notify::source") signal,
+ * which will be emitted by playbin3 when it has created the source element
+ * for a particular URI. In the signal callback you can check if the source
+ * element has a "device" property and set it appropriately. In some cases
+ * the device can also be set as part of the URI, but it depends on the
+ * elements involved if this will work or not. For example, for DVD menu
+ * playback, the following syntax might work (if the resindvd plugin is used):
+ * dvd://[/path/to/device]
+ * </refsect2>
+ * <refsect2>
+ * <title>Handling redirects</title>
+ * <para>
+ * Some elements may post 'redirect' messages on the bus to tell the
+ * application to open another location. These are element messages containing
+ * a structure named 'redirect' along with a 'new-location' field of string
+ * type. The new location may be a relative or an absolute URI. Examples
+ * for such redirects can be found in many quicktime movie trailers.
+ * </para>
+ * </refsect2>
+ * <refsect2>
+ * <title>Examples</title>
+ * |[
+ * gst-launch-1.0 -v playbin3 uri=file:///path/to/somefile.mp4
+ * ]| This will play back the given AVI video file, given that the video and
+ * audio decoders required to decode the content are installed. Since no
+ * special audio sink or video sink is supplied (via playbin3's audio-sink or
+ * video-sink properties) playbin3 will try to find a suitable audio and
+ * video sink automatically using the autoaudiosink and autovideosink elements.
+ * |[
+ * gst-launch-1.0 -v playbin3 uri=cdda://4
+ * ]| This will play back track 4 on an audio CD in your disc drive (assuming
+ * the drive is detected automatically by the plugin).
+ * |[
+ * gst-launch-1.0 -v playbin3 uri=dvd://
+ * ]| This will play back the DVD in your disc drive (assuming
+ * the drive is detected automatically by the plugin).
+ * </refsect2>
+ */
+
+/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
+ * with newer GLib versions (>= 2.31.0) */
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <gst/gst.h>
+
+#include <gst/gst-i18n-plugin.h>
+#include <gst/pbutils/pbutils.h>
+#include <gst/audio/streamvolume.h>
+#include <gst/video/video-info.h>
+#include <gst/video/video-multiview.h>
+#include <gst/video/videooverlay.h>
+#include <gst/video/navigation.h>
+#include <gst/video/colorbalance.h>
+#include "gstplay-enum.h"
+#include "gstplayback.h"
+#include "gstplaysink.h"
+#include "gstsubtitleoverlay.h"
+#include "gstplaybackutils.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_play_bin3_debug);
+#define GST_CAT_DEFAULT gst_play_bin3_debug
+
+#define GST_TYPE_PLAY_BIN               (gst_play_bin3_get_type())
+#define GST_PLAY_BIN3(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PLAY_BIN,GstPlayBin3))
+#define GST_PLAY_BIN3_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PLAY_BIN,GstPlayBin3Class))
+#define GST_IS_PLAY_BIN(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PLAY_BIN))
+#define GST_IS_PLAY_BIN_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PLAY_BIN))
+
+#define ULONG_TO_POINTER(number)        ((gpointer) (guintptr) (number))
+#define POINTER_TO_ULONG(number)        ((guintptr) (number))
+
+#define VOLUME_MAX_DOUBLE 10.0
+
+typedef struct _GstPlayBin3 GstPlayBin3;
+typedef struct _GstPlayBin3Class GstPlayBin3Class;
+typedef struct _GstSourceGroup GstSourceGroup;
+typedef struct _GstSourceCombine GstSourceCombine;
+
+typedef GstCaps *(*SourceCombineGetMediaCapsFunc) (void);
+
+/* has the info for a combiner and provides the link to the sink */
+struct _GstSourceCombine
+{
+  const gchar *media_type;      /* the media type for the combiner */
+  SourceCombineGetMediaCapsFunc get_media_caps; /* more complex caps for the combiner */
+  GstPlaySinkType type;         /* the sink pad type of the combiner */
+
+  GstElement *combiner;         /* the combiner */
+  GPtrArray *channels;
+  GstPad *srcpad;               /* the source pad of the combiner */
+  GstPad *sinkpad;              /* the sinkpad of the sink when the combiner
+                                 * is linked
+                                 */
+  gulong block_id;
+
+  GPtrArray *streams;           /* Sorted array of GstStream for the given type */
+  gint current_stream;          /* Currently selected GstStream */
+
+  gboolean has_active_pad;      /* stream combiner has the "active-pad" property */
+
+  gboolean has_always_ok;       /* stream combiner's sink pads have the "always-ok" property */
+};
+
+#define GST_SOURCE_GROUP_GET_LOCK(group) (&((GstSourceGroup*)(group))->lock)
+#define GST_SOURCE_GROUP_LOCK(group) (g_mutex_lock (GST_SOURCE_GROUP_GET_LOCK(group)))
+#define GST_SOURCE_GROUP_UNLOCK(group) (g_mutex_unlock (GST_SOURCE_GROUP_GET_LOCK(group)))
+
+enum
+{
+  PLAYBIN_STREAM_AUDIO = 0,
+  PLAYBIN_STREAM_VIDEO,
+  PLAYBIN_STREAM_TEXT,
+  PLAYBIN_STREAM_LAST
+};
+
+/* names matching the enum above */
+static const gchar *stream_type_names[] = {
+  "audio", "video", "text"
+};
+
+static void avelements_free (gpointer data);
+static GSequence *avelements_create (GstPlayBin3 * playbin,
+    gboolean isaudioelement);
+
+/* The GstAudioVideoElement structure holding the audio/video decoder
+ * and the audio/video sink factories together with field indicating
+ * the number of common caps features */
+typedef struct
+{
+  GstElementFactory *dec;       /* audio:video decoder */
+  GstElementFactory *sink;      /* audio:video sink */
+  guint n_comm_cf;              /* number of common caps features */
+} GstAVElement;
+
+/* a structure to hold the objects for decoding a uri and the subtitle uri
+ */
+struct _GstSourceGroup
+{
+  GstPlayBin3 *playbin;
+
+  GMutex lock;
+
+  gboolean valid;               /* the group has valid info to start playback */
+  gboolean active;              /* the group is active */
+
+  /* properties */
+  gchar *uri;
+  gchar *suburi;
+  GValueArray *streaminfo;
+  GstElement *source;
+
+
+  /* urisourcebins for uri and subtitle uri */
+  /* FIXME: Just make this an array of uris */
+  GstElement *urisourcebin;
+  GstElement *suburisourcebin;
+
+  /* Active sinks for each media type. These are initialized with
+   * the configured or currently used sink, otherwise
+   * left as NULL and playbin tries to automatically
+   * select a good sink */
+  GstElement *audio_sink;
+  GstElement *video_sink;
+  GstElement *text_sink;
+
+  gint pending;
+  gboolean sub_pending;
+
+  /* primary uri signals */
+  gulong urisrc_pad_added_id;
+  gulong urisrc_pad_removed_id;
+  gulong notify_source_id;
+  gulong autoplug_factories_id;
+  gulong autoplug_select_id;
+  gulong autoplug_continue_id;
+  gulong autoplug_query_id;
+
+  /* subtitle uri signals */
+  gulong sub_pad_added_id;
+  gulong sub_pad_removed_id;
+  gulong sub_autoplug_continue_id;
+  gulong sub_autoplug_query_id;
+
+  gulong block_id;
+
+  GMutex stream_changed_pending_lock;
+  gboolean stream_changed_pending;
+
+  /* buffering message stored for after switching */
+  GstMessage *pending_buffering_msg;
+};
+
+#define GST_PLAY_BIN3_GET_LOCK(bin) (&((GstPlayBin3*)(bin))->lock)
+#define GST_PLAY_BIN3_LOCK(bin) (g_rec_mutex_lock (GST_PLAY_BIN3_GET_LOCK(bin)))
+#define GST_PLAY_BIN3_UNLOCK(bin) (g_rec_mutex_unlock (GST_PLAY_BIN3_GET_LOCK(bin)))
+
+/* lock to protect dynamic callbacks, like no-more-pads */
+#define GST_PLAY_BIN3_DYN_LOCK(bin)    g_mutex_lock (&(bin)->dyn_lock)
+#define GST_PLAY_BIN3_DYN_UNLOCK(bin)  g_mutex_unlock (&(bin)->dyn_lock)
+
+/* lock for shutdown */
+#define GST_PLAY_BIN3_SHUTDOWN_LOCK(bin,label)           \
+G_STMT_START {                                          \
+  if (G_UNLIKELY (g_atomic_int_get (&bin->shutdown)))   \
+    goto label;                                         \
+  GST_PLAY_BIN3_DYN_LOCK (bin);                          \
+  if (G_UNLIKELY (g_atomic_int_get (&bin->shutdown))) { \
+    GST_PLAY_BIN3_DYN_UNLOCK (bin);                      \
+    goto label;                                         \
+  }                                                     \
+} G_STMT_END
+
+/* unlock for shutdown */
+#define GST_PLAY_BIN3_SHUTDOWN_UNLOCK(bin)         \
+  GST_PLAY_BIN3_DYN_UNLOCK (bin);                  \
+
+/**
+ * GstPlayBin3:
+ *
+ * playbin element structure
+ */
+struct _GstPlayBin3
+{
+  GstPipeline parent;
+
+  GRecMutex lock;               /* to protect group switching */
+
+  /* the input groups, we use a double buffer to switch between current and next */
+  GstSourceGroup groups[2];     /* array with group info */
+  GstSourceGroup *curr_group;   /* pointer to the currently playing group */
+  GstSourceGroup *next_group;   /* pointer to the next group */
+
+  /* combiners for different streams */
+  GPtrArray *channels[PLAYBIN_STREAM_LAST];     /* links to combiner pads */
+  GstSourceCombine combiner[PLAYBIN_STREAM_LAST];
+
+  /* A global decodebin3 that's used to actually do decoding */
+  gboolean decodebin_active;
+  GstElement *decodebin;
+  /* Bit-wise set of stream types we have
+   * requested from decodebin vs stream types
+   * decodebin has provided */
+  GstStreamType selected_stream_types;
+  GstStreamType active_stream_types;
+
+  /* Decodebin signals */
+  gulong db_pad_added_id;
+  gulong db_pad_removed_id;
+  gulong db_no_more_pads_id;
+  gulong db_drained_id;
+  gulong db_select_stream_id;
+
+  /* properties */
+  guint64 connection_speed;     /* connection speed in bits/sec (0 = unknown) */
+  gint current_video;           /* the currently selected stream */
+  gint current_audio;           /* the currently selected stream */
+  gint current_text;            /* the currently selected stream */
+
+  gboolean do_stream_selections;        /* Set to TRUE when any of current-{video|audio|text} are set to
+                                           say playbin should do backwards-compatibility behaviours */
+
+  guint64 buffer_duration;      /* When buffering, the max buffer duration (ns) */
+  guint buffer_size;            /* When buffering, the max buffer size (bytes) */
+  gboolean force_aspect_ratio;
+
+  /* Multiview/stereoscopic overrides */
+  GstVideoMultiviewFramePacking multiview_mode;
+  GstVideoMultiviewFlags multiview_flags;
+
+  /* our play sink */
+  GstPlaySink *playsink;
+
+  /* the last activated source */
+  GstElement *source;
+
+  /* lock protecting dynamic adding/removing */
+  GMutex dyn_lock;
+  /* if we are shutting down or not */
+  gint shutdown;
+  gboolean async_pending;       /* async-start has been emitted */
+
+  GMutex elements_lock;
+  guint32 elements_cookie;
+  GList *elements;              /* factories we can use for selecting elements */
+
+  gboolean have_selector;       /* set to FALSE when we fail to create an
+                                 * input-selector, so that we only post a
+                                 * warning once */
+
+  gboolean video_pending_flush_finish;  /* whether we are pending to send a custom
+                                         * custom-video-flush-finish event
+                                         * on pad activation */
+  gboolean audio_pending_flush_finish;  /* whether we are pending to send a custom
+                                         * custom-audio-flush-finish event
+                                         * on pad activation */
+  gboolean text_pending_flush_finish;   /* whether we are pending to send a custom
+                                         * custom-subtitle-flush-finish event
+                                         * on pad activation */
+
+  GstElement *audio_sink;       /* configured audio sink, or NULL      */
+  GstElement *video_sink;       /* configured video sink, or NULL      */
+  GstElement *text_sink;        /* configured text sink, or NULL       */
+
+  GstElement *audio_stream_combiner;    /* configured audio stream combiner, or NULL */
+  GstElement *video_stream_combiner;    /* configured video stream combiner, or NULL */
+  GstElement *text_stream_combiner;     /* configured text stream combiner, or NULL */
+
+  GSequence *aelements;         /* a list of GstAVElements for audio stream */
+  GSequence *velements;         /* a list of GstAVElements for video stream */
+
+  struct
+  {
+    gboolean valid;
+    GstFormat format;
+    gint64 duration;
+  } duration[5];                /* cached durations */
+
+  guint64 ring_buffer_max_size; /* 0 means disabled */
+
+  GList *contexts;
+
+  /* Active stream collection */
+  GstStreamCollection *collection;
+};
+
+struct _GstPlayBin3Class
+{
+  GstPipelineClass parent_class;
+
+  /* notify app that the current uri finished decoding and it is possible to
+   * queue a new one for gapless playback */
+  void (*about_to_finish) (GstPlayBin3 * playbin);
+
+  /* get the last video sample and convert it to the given caps */
+  GstSample *(*convert_sample) (GstPlayBin3 * playbin, GstCaps * caps);
+};
+
+/* props */
+#define DEFAULT_URI               NULL
+#define DEFAULT_SUBURI            NULL
+#define DEFAULT_SOURCE            NULL
+#define DEFAULT_FLAGS             GST_PLAY_FLAG_AUDIO | GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_TEXT | \
+                                  GST_PLAY_FLAG_SOFT_VOLUME | GST_PLAY_FLAG_DEINTERLACE | \
+                                  GST_PLAY_FLAG_SOFT_COLORBALANCE
+#define DEFAULT_CURRENT_VIDEO     -1
+#define DEFAULT_CURRENT_AUDIO     -1
+#define DEFAULT_CURRENT_TEXT      -1
+#define DEFAULT_AUTO_SELECT_STREAMS TRUE
+#define DEFAULT_SUBTITLE_ENCODING NULL
+#define DEFAULT_AUDIO_SINK        NULL
+#define DEFAULT_VIDEO_SINK        NULL
+#define DEFAULT_VIS_PLUGIN        NULL
+#define DEFAULT_TEXT_SINK         NULL
+#define DEFAULT_VOLUME            1.0
+#define DEFAULT_MUTE              FALSE
+#define DEFAULT_FRAME             NULL
+#define DEFAULT_FONT_DESC         NULL
+#define DEFAULT_CONNECTION_SPEED  0
+#define DEFAULT_BUFFER_DURATION   -1
+#define DEFAULT_BUFFER_SIZE       -1
+#define DEFAULT_RING_BUFFER_MAX_SIZE 0
+
+enum
+{
+  PROP_0,
+  PROP_URI,
+  PROP_CURRENT_URI,
+  PROP_SUBURI,
+  PROP_CURRENT_SUBURI,
+  PROP_SOURCE,
+  PROP_FLAGS,
+  PROP_SUBTITLE_ENCODING,
+  PROP_AUDIO_SINK,
+  PROP_VIDEO_SINK,
+  PROP_VIS_PLUGIN,
+  PROP_TEXT_SINK,
+  PROP_VIDEO_STREAM_COMBINER,
+  PROP_AUDIO_STREAM_COMBINER,
+  PROP_TEXT_STREAM_COMBINER,
+  PROP_VOLUME,
+  PROP_MUTE,
+  PROP_SAMPLE,
+  PROP_FONT_DESC,
+  PROP_CONNECTION_SPEED,
+  PROP_BUFFER_SIZE,
+  PROP_BUFFER_DURATION,
+  PROP_AV_OFFSET,
+  PROP_RING_BUFFER_MAX_SIZE,
+  PROP_FORCE_ASPECT_RATIO,
+  PROP_AUDIO_FILTER,
+  PROP_VIDEO_FILTER,
+  PROP_MULTIVIEW_MODE,
+  PROP_MULTIVIEW_FLAGS
+};
+
+/* signals */
+enum
+{
+  SIGNAL_ABOUT_TO_FINISH,
+  SIGNAL_CONVERT_SAMPLE,
+  SIGNAL_SOURCE_SETUP,
+  SIGNAL_ELEMENT_SETUP,
+  LAST_SIGNAL
+};
+
+static GstStaticCaps raw_audio_caps = GST_STATIC_CAPS ("audio/x-raw(ANY)");
+static GstStaticCaps raw_video_caps = GST_STATIC_CAPS ("video/x-raw(ANY)");
+
+static void gst_play_bin3_class_init (GstPlayBin3Class * klass);
+static void gst_play_bin3_init (GstPlayBin3 * playbin);
+static void gst_play_bin3_finalize (GObject * object);
+
+static void gst_play_bin3_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * spec);
+static void gst_play_bin3_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * spec);
+
+static GstStateChangeReturn gst_play_bin3_change_state (GstElement * element,
+    GstStateChange transition);
+
+static void gst_play_bin3_handle_message (GstBin * bin, GstMessage * message);
+static void gst_play_bin3_deep_element_added (GstBin * playbin,
+    GstBin * sub_bin, GstElement * child);
+static gboolean gst_play_bin3_query (GstElement * element, GstQuery * query);
+static void gst_play_bin3_set_context (GstElement * element,
+    GstContext * context);
+static gboolean gst_play_bin3_send_event (GstElement * element,
+    GstEvent * event);
+
+static GstSample *gst_play_bin3_convert_sample (GstPlayBin3 * playbin,
+    GstCaps * caps);
+
+static GstStateChangeReturn setup_next_source (GstPlayBin3 * playbin,
+    GstState target);
+
+static void no_more_pads_cb (GstElement * decodebin, GstPlayBin3 * playbin);
+static void pad_removed_cb (GstElement * decodebin, GstPad * pad,
+    GstPlayBin3 * playbin);
+
+static gint select_stream_cb (GstElement * decodebin,
+    GstStreamCollection * collection, GstStream * stream,
+    GstPlayBin3 * playbin);
+
+static void do_stream_selection (GstPlayBin3 * playbin);
+
+static GstElementClass *parent_class;
+
+static guint gst_play_bin3_signals[LAST_SIGNAL] = { 0 };
+
+#define REMOVE_SIGNAL(obj,id)            \
+if (id) {                                \
+  g_signal_handler_disconnect (obj, id); \
+  id = 0;                                \
+}
+
+static void gst_play_bin3_overlay_init (gpointer g_iface,
+    gpointer g_iface_data);
+static void gst_play_bin3_navigation_init (gpointer g_iface,
+    gpointer g_iface_data);
+static void gst_play_bin3_colorbalance_init (gpointer g_iface,
+    gpointer g_iface_data);
+
+static GType
+gst_play_bin3_get_type (void)
+{
+  static GType gst_play_bin3_type = 0;
+
+  if (!gst_play_bin3_type) {
+    static const GTypeInfo gst_play_bin3_info = {
+      sizeof (GstPlayBin3Class),
+      NULL,
+      NULL,
+      (GClassInitFunc) gst_play_bin3_class_init,
+      NULL,
+      NULL,
+      sizeof (GstPlayBin3),
+      0,
+      (GInstanceInitFunc) gst_play_bin3_init,
+      NULL
+    };
+    static const GInterfaceInfo svol_info = {
+      NULL, NULL, NULL
+    };
+    static const GInterfaceInfo ov_info = {
+      gst_play_bin3_overlay_init,
+      NULL, NULL
+    };
+    static const GInterfaceInfo nav_info = {
+      gst_play_bin3_navigation_init,
+      NULL, NULL
+    };
+    static const GInterfaceInfo col_info = {
+      gst_play_bin3_colorbalance_init,
+      NULL, NULL
+    };
+
+    gst_play_bin3_type = g_type_register_static (GST_TYPE_PIPELINE,
+        "GstPlayBin3", &gst_play_bin3_info, 0);
+
+    g_type_add_interface_static (gst_play_bin3_type, GST_TYPE_STREAM_VOLUME,
+        &svol_info);
+    g_type_add_interface_static (gst_play_bin3_type, GST_TYPE_VIDEO_OVERLAY,
+        &ov_info);
+    g_type_add_interface_static (gst_play_bin3_type, GST_TYPE_NAVIGATION,
+        &nav_info);
+    g_type_add_interface_static (gst_play_bin3_type, GST_TYPE_COLOR_BALANCE,
+        &col_info);
+  }
+
+  return gst_play_bin3_type;
+}
+
+static void
+gst_play_bin3_class_init (GstPlayBin3Class * klass)
+{
+  GObjectClass *gobject_klass;
+  GstElementClass *gstelement_klass;
+  GstBinClass *gstbin_klass;
+
+  gobject_klass = (GObjectClass *) klass;
+  gstelement_klass = (GstElementClass *) klass;
+  gstbin_klass = (GstBinClass *) klass;
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  gobject_klass->set_property = gst_play_bin3_set_property;
+  gobject_klass->get_property = gst_play_bin3_get_property;
+
+  gobject_klass->finalize = gst_play_bin3_finalize;
+
+  /**
+   * GstPlayBin3:uri
+   *
+   * Set the next URI that playbin will play. This property can be set from the
+   * about-to-finish signal to queue the next media file.
+   */
+  g_object_class_install_property (gobject_klass, PROP_URI,
+      g_param_spec_string ("uri", "URI", "URI of the media to play",
+          NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+   /**
+   * GstPlayBin3:current-uri
+   *
+   * The currently playing uri.
+   */
+  g_object_class_install_property (gobject_klass, PROP_CURRENT_URI,
+      g_param_spec_string ("current-uri", "Current URI",
+          "The currently playing URI", NULL,
+          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstPlayBin3:suburi
+   *
+   * Set the next subtitle URI that playbin will play. This property can be
+   * set from the about-to-finish signal to queue the next subtitle media file.
+   */
+  g_object_class_install_property (gobject_klass, PROP_SUBURI,
+      g_param_spec_string ("suburi", ".sub-URI", "Optional URI of a subtitle",
+          NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstPlayBin3:current-suburi
+   *
+   * The currently playing subtitle uri.
+   */
+  g_object_class_install_property (gobject_klass, PROP_CURRENT_SUBURI,
+      g_param_spec_string ("current-suburi", "Current .sub-URI",
+          "The currently playing URI of a subtitle",
+          NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_klass, PROP_SOURCE,
+      g_param_spec_object ("source", "Source", "Source element",
+          GST_TYPE_ELEMENT, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstPlayBin3:flags
+   *
+   * Control the behaviour of playbin.
+   */
+  g_object_class_install_property (gobject_klass, PROP_FLAGS,
+      g_param_spec_flags ("flags", "Flags", "Flags to control behaviour",
+          GST_TYPE_PLAY_FLAGS, DEFAULT_FLAGS,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_klass, PROP_SUBTITLE_ENCODING,
+      g_param_spec_string ("subtitle-encoding", "subtitle encoding",
+          "Encoding to assume if input subtitles are not in UTF-8 encoding. "
+          "If not set, the GST_SUBTITLE_ENCODING environment variable will "
+          "be checked for an encoding to use. If that is not set either, "
+          "ISO-8859-15 will be assumed.", NULL,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_klass, PROP_VIDEO_FILTER,
+      g_param_spec_object ("video-filter", "Video filter",
+          "the video filter(s) to apply, if possible",
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_klass, PROP_AUDIO_FILTER,
+      g_param_spec_object ("audio-filter", "Audio filter",
+          "the audio filter(s) to apply, if possible",
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  /**
+   * GstPlayBin3:video-sink
+   *
+   * Get or set the video sink to use for video output. If set to
+   * NULL, one will be auto-selected. To disable video entirely, unset
+   * the VIDEO flag in the #GstPlayBin3:flags property.
+   *
+   */
+  g_object_class_install_property (gobject_klass, PROP_VIDEO_SINK,
+      g_param_spec_object ("video-sink", "Video Sink",
+          "the video output element to use (NULL = default sink)",
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  /**
+   * GstPlayBin3:audio-sink
+   *
+   * Get or set the audio sink to use for audio output. If set to
+   * NULL, one will be auto-selected. To disable audio entirely, unset
+   * the AUDIO flag in the #GstPlayBin3:flags property.
+   *
+   */
+  g_object_class_install_property (gobject_klass, PROP_AUDIO_SINK,
+      g_param_spec_object ("audio-sink", "Audio Sink",
+          "the audio output element to use (NULL = default sink)",
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_klass, PROP_VIS_PLUGIN,
+      g_param_spec_object ("vis-plugin", "Vis plugin",
+          "the visualization element to use (NULL = default)",
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_klass, PROP_TEXT_SINK,
+      g_param_spec_object ("text-sink", "Text plugin",
+          "the text output element to use (NULL = default subtitleoverlay)",
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  /**
+   * GstPlayBin3:video-stream-combiner
+   *
+   * Get or set the current video stream combiner. By default, an input-selector
+   * is created and deleted as-needed.
+   */
+  g_object_class_install_property (gobject_klass, PROP_VIDEO_STREAM_COMBINER,
+      g_param_spec_object ("video-stream-combiner", "Video stream combiner",
+          "Current video stream combiner (NULL = input-selector)",
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  /**
+   * GstPlayBin3:audio-stream-combiner
+   *
+   * Get or set the current audio stream combiner. By default, an input-selector
+   * is created and deleted as-needed.
+   */
+  g_object_class_install_property (gobject_klass, PROP_AUDIO_STREAM_COMBINER,
+      g_param_spec_object ("audio-stream-combiner", "Audio stream combiner",
+          "Current audio stream combiner (NULL = input-selector)",
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  /**
+   * GstPlayBin3:text-stream-combiner
+   *
+   * Get or set the current text stream combiner. By default, an input-selector
+   * is created and deleted as-needed.
+   */
+  g_object_class_install_property (gobject_klass, PROP_TEXT_STREAM_COMBINER,
+      g_param_spec_object ("text-stream-combiner", "Text stream combiner",
+          "Current text stream combiner (NULL = input-selector)",
+          GST_TYPE_ELEMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstPlayBin3:volume:
+   *
+   * Get or set the current audio stream volume. 1.0 means 100%,
+   * 0.0 means mute. This uses a linear volume scale.
+   *
+   */
+  g_object_class_install_property (gobject_klass, PROP_VOLUME,
+      g_param_spec_double ("volume", "Volume", "The audio volume, 1.0=100%",
+          0.0, VOLUME_MAX_DOUBLE, 1.0,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_klass, PROP_MUTE,
+      g_param_spec_boolean ("mute", "Mute",
+          "Mute the audio channel without changing the volume", FALSE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstPlayBin3:sample:
+   * @playbin: a #GstPlayBin3
+   *
+   * Get the currently rendered or prerolled sample in the video sink.
+   * The #GstCaps in the sample will describe the format of the buffer.
+   */
+  g_object_class_install_property (gobject_klass, PROP_SAMPLE,
+      g_param_spec_boxed ("sample", "Sample",
+          "The last sample (NULL = no video available)",
+          GST_TYPE_SAMPLE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_klass, PROP_FONT_DESC,
+      g_param_spec_string ("subtitle-font-desc",
+          "Subtitle font description",
+          "Pango font description of font "
+          "to be used for subtitle rendering", NULL,
+          G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_klass, PROP_CONNECTION_SPEED,
+      g_param_spec_uint64 ("connection-speed", "Connection Speed",
+          "Network connection speed in kbps (0 = unknown)",
+          0, G_MAXUINT64 / 1000, DEFAULT_CONNECTION_SPEED,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_klass, PROP_BUFFER_SIZE,
+      g_param_spec_int ("buffer-size", "Buffer size (bytes)",
+          "Buffer size when buffering network streams",
+          -1, G_MAXINT, DEFAULT_BUFFER_SIZE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_klass, PROP_BUFFER_DURATION,
+      g_param_spec_int64 ("buffer-duration", "Buffer duration (ns)",
+          "Buffer duration when buffering network streams",
+          -1, G_MAXINT64, DEFAULT_BUFFER_DURATION,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  /**
+   * GstPlayBin3:av-offset:
+   *
+   * Control the synchronisation offset between the audio and video streams.
+   * Positive values make the audio ahead of the video and negative values make
+   * the audio go behind the video.
+   */
+  g_object_class_install_property (gobject_klass, PROP_AV_OFFSET,
+      g_param_spec_int64 ("av-offset", "AV Offset",
+          "The synchronisation offset between audio and video in nanoseconds",
+          G_MININT64, G_MAXINT64, 0,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstPlayBin3:ring-buffer-max-size
+   *
+   * The maximum size of the ring buffer in bytes. If set to 0, the ring
+   * buffer is disabled. Default 0.
+   */
+  g_object_class_install_property (gobject_klass, PROP_RING_BUFFER_MAX_SIZE,
+      g_param_spec_uint64 ("ring-buffer-max-size",
+          "Max. ring buffer size (bytes)",
+          "Max. amount of data in the ring buffer (bytes, 0 = ring buffer disabled)",
+          0, G_MAXUINT, DEFAULT_RING_BUFFER_MAX_SIZE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstPlayBin3::force-aspect-ratio:
+   *
+   * Requests the video sink to enforce the video display aspect ratio.
+   */
+  g_object_class_install_property (gobject_klass, PROP_FORCE_ASPECT_RATIO,
+      g_param_spec_boolean ("force-aspect-ratio", "Force Aspect Ratio",
+          "When enabled, scaling will respect original aspect ratio", TRUE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstPlayBin3::video-multiview-mode:
+   *
+   * Set the stereoscopic mode for video streams that don't contain
+   * any information in the stream, so they can be correctly played
+   * as 3D streams. If a video already has multiview information
+   * encoded, this property can override other modes in the set,
+   * but cannot be used to re-interpret MVC or mixed-mono streams.
+   *
+   * See Also: The #GstPlayBin3::video-multiview-flags property
+   *
+   */
+  g_object_class_install_property (gobject_klass, PROP_MULTIVIEW_MODE,
+      g_param_spec_enum ("video-multiview-mode",
+          "Multiview Mode Override",
+          "Re-interpret a video stream as one of several frame-packed stereoscopic modes.",
+          GST_TYPE_VIDEO_MULTIVIEW_FRAME_PACKING,
+          GST_VIDEO_MULTIVIEW_FRAME_PACKING_NONE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstPlayBin3::video-multiview-flags:
+   *
+   * When overriding the multiview mode of an input stream,
+   * these flags modify details of the view layout.
+   *
+   * See Also: The #GstPlayBin3::video-multiview-mode property
+   */
+  g_object_class_install_property (gobject_klass, PROP_MULTIVIEW_FLAGS,
+      g_param_spec_flags ("video-multiview-flags",
+          "Multiview Flags Override",
+          "Override details of the multiview frame layout",
+          GST_TYPE_VIDEO_MULTIVIEW_FLAGS, GST_VIDEO_MULTIVIEW_FLAGS_NONE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstPlayBin3::about-to-finish
+   * @playbin: a #GstPlayBin3
+   *
+   * This signal is emitted when the current uri is about to finish. You can
+   * set the uri and suburi to make sure that playback continues.
+   *
+   * This signal is emitted from the context of a GStreamer streaming thread.
+   */
+  gst_play_bin3_signals[SIGNAL_ABOUT_TO_FINISH] =
+      g_signal_new ("about-to-finish", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST,
+      G_STRUCT_OFFSET (GstPlayBin3Class, about_to_finish), NULL, NULL,
+      g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);
+
+
+  /**
+   * GstPlayBin3::source-setup:
+   * @playbin: a #GstPlayBin3
+   * @source: source element
+   *
+   * This signal is emitted after the source element has been created, so
+   * it can be configured by setting additional properties (e.g. set a
+   * proxy server for an http source, or set the device and read speed for
+   * an audio cd source). This is functionally equivalent to connecting to
+   * the notify::source signal, but more convenient.
+   *
+   * This signal is usually emitted from the context of a GStreamer streaming
+   * thread.
+   */
+  gst_play_bin3_signals[SIGNAL_SOURCE_SETUP] =
+      g_signal_new ("source-setup", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+      g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
+
+  /**
+   * GstPlayBin3::element-setup:
+   * @playbin: a #GstPlayBin3
+   * @element: an element that was added to the playbin hierarchy
+   *
+   * This signal is emitted when a new element is added to playbin or any of
+   * its sub-bins. This signal can be used to configure elements, e.g. to set
+   * properties on decoders. This is functionally equivalent to connecting to
+   * the deep-element-added signal, but more convenient.
+   *
+   * This signal is usually emitted from the context of a GStreamer streaming
+   * thread, so might be called at the same time as code running in the main
+   * application thread.
+   *
+   * Since: 1.10
+   */
+  gst_play_bin3_signals[SIGNAL_ELEMENT_SETUP] =
+      g_signal_new ("element-setup", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+      g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
+
+  /**
+   * GstPlayBin3::convert-sample
+   * @playbin: a #GstPlayBin3
+   * @caps: the target format of the frame
+   *
+   * Action signal to retrieve the currently playing video frame in the format
+   * specified by @caps.
+   * If @caps is %NULL, no conversion will be performed and this function is
+   * equivalent to the #GstPlayBin3::frame property.
+   *
+   * Returns: a #GstSample of the current video frame converted to #caps.
+   * The caps on the sample will describe the final layout of the buffer data.
+   * %NULL is returned when no current buffer can be retrieved or when the
+   * conversion failed.
+   */
+  gst_play_bin3_signals[SIGNAL_CONVERT_SAMPLE] =
+      g_signal_new ("convert-sample", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+      G_STRUCT_OFFSET (GstPlayBin3Class, convert_sample), NULL, NULL,
+      g_cclosure_marshal_generic, GST_TYPE_SAMPLE, 1, GST_TYPE_CAPS);
+
+  klass->convert_sample = gst_play_bin3_convert_sample;
+
+  gst_element_class_set_static_metadata (gstelement_klass,
+      "Player Bin 3", "Generic/Bin/Player",
+      "Autoplug and play media from an uri",
+      "Wim Taymans <wim.taymans@gmail.com>");
+
+  gstelement_klass->change_state =
+      GST_DEBUG_FUNCPTR (gst_play_bin3_change_state);
+  gstelement_klass->query = GST_DEBUG_FUNCPTR (gst_play_bin3_query);
+  gstelement_klass->set_context = GST_DEBUG_FUNCPTR (gst_play_bin3_set_context);
+  gstelement_klass->send_event = GST_DEBUG_FUNCPTR (gst_play_bin3_send_event);
+
+  gstbin_klass->handle_message =
+      GST_DEBUG_FUNCPTR (gst_play_bin3_handle_message);
+  gstbin_klass->deep_element_added =
+      GST_DEBUG_FUNCPTR (gst_play_bin3_deep_element_added);
+}
+
+static void
+do_async_start (GstPlayBin3 * playbin)
+{
+  GstMessage *message;
+
+  playbin->async_pending = TRUE;
+
+  message = gst_message_new_async_start (GST_OBJECT_CAST (playbin));
+  GST_BIN_CLASS (parent_class)->handle_message (GST_BIN_CAST (playbin),
+      message);
+}
+
+static void
+do_async_done (GstPlayBin3 * playbin)
+{
+  GstMessage *message;
+
+  if (playbin->async_pending) {
+    GST_DEBUG_OBJECT (playbin, "posting ASYNC_DONE");
+    message =
+        gst_message_new_async_done (GST_OBJECT_CAST (playbin),
+        GST_CLOCK_TIME_NONE);
+    GST_BIN_CLASS (parent_class)->handle_message (GST_BIN_CAST (playbin),
+        message);
+
+    playbin->async_pending = FALSE;
+  }
+}
+
+/* init combiners. The combiner is found by finding the first prefix that
+ * matches the media. */
+static void
+init_combiners (GstPlayBin3 * playbin)
+{
+  gint i;
+
+  /* store the array for the different channels */
+  for (i = 0; i < PLAYBIN_STREAM_LAST; i++)
+    playbin->channels[i] = g_ptr_array_new ();
+
+  playbin->combiner[PLAYBIN_STREAM_AUDIO].media_type = "audio";
+  playbin->combiner[PLAYBIN_STREAM_AUDIO].type = GST_PLAY_SINK_TYPE_AUDIO;
+  playbin->combiner[PLAYBIN_STREAM_AUDIO].channels = playbin->channels[0];
+  playbin->combiner[PLAYBIN_STREAM_AUDIO].streams =
+      g_ptr_array_new_with_free_func ((GDestroyNotify) gst_object_unref);
+  playbin->combiner[PLAYBIN_STREAM_AUDIO].current_stream = -1;
+
+  playbin->combiner[PLAYBIN_STREAM_VIDEO].media_type = "video";
+  playbin->combiner[PLAYBIN_STREAM_VIDEO].type = GST_PLAY_SINK_TYPE_VIDEO;
+  playbin->combiner[PLAYBIN_STREAM_VIDEO].channels = playbin->channels[1];
+  playbin->combiner[PLAYBIN_STREAM_VIDEO].streams =
+      g_ptr_array_new_with_free_func ((GDestroyNotify) gst_object_unref);
+  playbin->combiner[PLAYBIN_STREAM_VIDEO].current_stream = -1;
+
+  playbin->combiner[PLAYBIN_STREAM_TEXT].media_type = "text";
+  playbin->combiner[PLAYBIN_STREAM_TEXT].get_media_caps =
+      gst_subtitle_overlay_create_factory_caps;
+  playbin->combiner[PLAYBIN_STREAM_TEXT].type = GST_PLAY_SINK_TYPE_TEXT;
+  playbin->combiner[PLAYBIN_STREAM_TEXT].channels = playbin->channels[2];
+  playbin->combiner[PLAYBIN_STREAM_TEXT].streams =
+      g_ptr_array_new_with_free_func ((GDestroyNotify) gst_object_unref);
+  playbin->combiner[PLAYBIN_STREAM_TEXT].current_stream = -1;
+}
+
+/* Update the combiner information to be in sync with the current collection */
+static void
+update_combiner_info (GstPlayBin3 * playbin)
+{
+  guint i, len;
+
+  if (playbin->collection == NULL)
+    return;
+
+  GST_DEBUG_OBJECT (playbin, "Updating combiner info");
+
+  /* Wipe current combiner streams */
+  g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_AUDIO].streams, TRUE);
+  g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_VIDEO].streams, TRUE);
+  g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_TEXT].streams, TRUE);
+  playbin->combiner[PLAYBIN_STREAM_AUDIO].streams =
+      g_ptr_array_new_with_free_func ((GDestroyNotify) gst_object_unref);
+  playbin->combiner[PLAYBIN_STREAM_AUDIO].current_stream = -1;
+  playbin->combiner[PLAYBIN_STREAM_VIDEO].streams =
+      g_ptr_array_new_with_free_func ((GDestroyNotify) gst_object_unref);
+  playbin->combiner[PLAYBIN_STREAM_VIDEO].current_stream = -1;
+  playbin->combiner[PLAYBIN_STREAM_TEXT].streams =
+      g_ptr_array_new_with_free_func ((GDestroyNotify) gst_object_unref);
+  playbin->combiner[PLAYBIN_STREAM_TEXT].current_stream = -1;
+
+  len = gst_stream_collection_get_size (playbin->collection);
+  for (i = 0; i < len; i++) {
+    GstStream *stream =
+        gst_stream_collection_get_stream (playbin->collection, i);
+    GstStreamType stype = gst_stream_get_stream_type (stream);
+
+    switch (stype) {
+      case GST_STREAM_TYPE_AUDIO:
+        g_ptr_array_add (playbin->combiner[PLAYBIN_STREAM_AUDIO].streams,
+            gst_object_ref (stream));
+        break;
+      case GST_STREAM_TYPE_VIDEO:
+        g_ptr_array_add (playbin->combiner[PLAYBIN_STREAM_VIDEO].streams,
+            gst_object_ref (stream));
+        break;
+      case GST_STREAM_TYPE_TEXT:
+        g_ptr_array_add (playbin->combiner[PLAYBIN_STREAM_TEXT].streams,
+            gst_object_ref (stream));
+        break;
+      default:
+        break;
+    }
+  }
+
+  GST_DEBUG_OBJECT (playbin, "There are %d audio streams",
+      playbin->combiner[PLAYBIN_STREAM_AUDIO].streams->len);
+  GST_DEBUG_OBJECT (playbin, "There are %d video streams",
+      playbin->combiner[PLAYBIN_STREAM_VIDEO].streams->len);
+  GST_DEBUG_OBJECT (playbin, "There are %d text streams",
+      playbin->combiner[PLAYBIN_STREAM_TEXT].streams->len);
+}
+
+/* Set the given stream as the selected stream */
+static void
+set_selected_stream (GstPlayBin3 * playbin, GstStream * stream)
+{
+  GstSourceCombine *combine = NULL;
+
+  switch (gst_stream_get_stream_type (stream)) {
+    case GST_STREAM_TYPE_AUDIO:
+      combine = &playbin->combiner[PLAYBIN_STREAM_AUDIO];
+      break;
+    case GST_STREAM_TYPE_VIDEO:
+      combine = &playbin->combiner[PLAYBIN_STREAM_VIDEO];
+      break;
+    case GST_STREAM_TYPE_TEXT:
+      combine = &playbin->combiner[PLAYBIN_STREAM_TEXT];
+      break;
+    default:
+      break;
+  }
+
+  if (combine) {
+    if (combine->combiner == NULL) {
+      guint i, len;
+
+      GST_DEBUG_OBJECT (playbin, "Called for %s (%p)",
+          gst_stream_get_stream_id (stream), combine->combiner);
+
+      combine->current_stream = -1;
+      len = combine->streams->len;
+      for (i = 0; i < len; i++) {
+        GstStream *cand = g_ptr_array_index (combine->streams, i);
+        if (cand == stream) {
+          GST_DEBUG_OBJECT (playbin, "Setting current to %d", i);
+          combine->current_stream = i;
+          break;
+        }
+      }
+    }
+  }
+}
+
+static void
+init_group (GstPlayBin3 * playbin, GstSourceGroup * group)
+{
+  g_mutex_init (&group->lock);
+
+  group->stream_changed_pending = FALSE;
+  g_mutex_init (&group->stream_changed_pending_lock);
+
+  group->playbin = playbin;
+}
+
+static void
+free_group (GstPlayBin3 * playbin, GstSourceGroup * group)
+{
+  g_free (group->uri);
+  g_free (group->suburi);
+
+  g_mutex_clear (&group->lock);
+  group->stream_changed_pending = FALSE;
+  g_mutex_clear (&group->stream_changed_pending_lock);
+
+  if (group->pending_buffering_msg)
+    gst_message_unref (group->pending_buffering_msg);
+  group->pending_buffering_msg = NULL;
+
+  gst_object_replace ((GstObject **) & group->audio_sink, NULL);
+  gst_object_replace ((GstObject **) & group->video_sink, NULL);
+  gst_object_replace ((GstObject **) & group->text_sink, NULL);
+}
+
+static void
+notify_volume_cb (GObject * combiner, GParamSpec * pspec, GstPlayBin3 * playbin)
+{
+  g_object_notify (G_OBJECT (playbin), "volume");
+}
+
+static void
+notify_mute_cb (GObject * combiner, GParamSpec * pspec, GstPlayBin3 * playbin)
+{
+  g_object_notify (G_OBJECT (playbin), "mute");
+}
+
+static void
+colorbalance_value_changed_cb (GstColorBalance * balance,
+    GstColorBalanceChannel * channel, gint value, GstPlayBin3 * playbin)
+{
+  gst_color_balance_value_changed (GST_COLOR_BALANCE (playbin), channel, value);
+}
+
+static gint
+compare_factories_func (gconstpointer p1, gconstpointer p2)
+{
+  GstPluginFeature *f1, *f2;
+  gboolean is_sink1, is_sink2;
+  gboolean is_parser1, is_parser2;
+
+  f1 = (GstPluginFeature *) p1;
+  f2 = (GstPluginFeature *) p2;
+
+  is_sink1 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f1),
+      GST_ELEMENT_FACTORY_TYPE_SINK);
+  is_sink2 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f2),
+      GST_ELEMENT_FACTORY_TYPE_SINK);
+  is_parser1 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f1),
+      GST_ELEMENT_FACTORY_TYPE_PARSER);
+  is_parser2 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f2),
+      GST_ELEMENT_FACTORY_TYPE_PARSER);
+
+  /* First we want all sinks as we prefer a sink if it directly
+   * supports the current caps */
+  if (is_sink1 && !is_sink2)
+    return -1;
+  else if (!is_sink1 && is_sink2)
+    return 1;
+
+  /* Then we want all parsers as we always want to plug parsers
+   * before decoders */
+  if (is_parser1 && !is_parser2)
+    return -1;
+  else if (!is_parser1 && is_parser2)
+    return 1;
+
+  /* And if it's a both a parser or sink we first sort by rank
+   * and then by factory name */
+  return gst_plugin_feature_rank_compare_func (p1, p2);
+}
+
+/* Must be called with elements lock! */
+static void
+gst_play_bin3_update_elements_list (GstPlayBin3 * playbin)
+{
+  GList *res, *tmp;
+  guint cookie;
+
+  cookie = gst_registry_get_feature_list_cookie (gst_registry_get ());
+
+  if (!playbin->elements || playbin->elements_cookie != cookie) {
+    if (playbin->elements)
+      gst_plugin_feature_list_free (playbin->elements);
+    res =
+        gst_element_factory_list_get_elements
+        (GST_ELEMENT_FACTORY_TYPE_DECODABLE, GST_RANK_MARGINAL);
+    tmp =
+        gst_element_factory_list_get_elements
+        (GST_ELEMENT_FACTORY_TYPE_AUDIOVIDEO_SINKS, GST_RANK_MARGINAL);
+    playbin->elements = g_list_concat (res, tmp);
+    playbin->elements = g_list_sort (playbin->elements, compare_factories_func);
+  }
+
+  if (!playbin->aelements || playbin->elements_cookie != cookie) {
+    if (playbin->aelements)
+      g_sequence_free (playbin->aelements);
+    playbin->aelements = avelements_create (playbin, TRUE);
+  }
+
+  if (!playbin->velements || playbin->elements_cookie != cookie) {
+    if (playbin->velements)
+      g_sequence_free (playbin->velements);
+    playbin->velements = avelements_create (playbin, FALSE);
+  }
+
+  playbin->elements_cookie = cookie;
+}
+
+static void
+gst_play_bin3_init (GstPlayBin3 * playbin)
+{
+  g_rec_mutex_init (&playbin->lock);
+  g_mutex_init (&playbin->dyn_lock);
+
+  /* assume we can create an input-selector */
+  playbin->have_selector = TRUE;
+
+  init_combiners (playbin);
+
+  /* init groups */
+  playbin->curr_group = &playbin->groups[0];
+  playbin->next_group = &playbin->groups[1];
+  init_group (playbin, &playbin->groups[0]);
+  init_group (playbin, &playbin->groups[1]);
+
+  /* first filter out the interesting element factories */
+  g_mutex_init (&playbin->elements_lock);
+
+  /* add sink */
+  playbin->playsink =
+      g_object_new (GST_TYPE_PLAY_SINK, "name", "playsink", "send-event-mode",
+      1, NULL);
+  gst_bin_add (GST_BIN_CAST (playbin), GST_ELEMENT_CAST (playbin->playsink));
+  gst_play_sink_set_flags (playbin->playsink, DEFAULT_FLAGS);
+  /* Connect to notify::volume and notify::mute signals for proxying */
+  g_signal_connect (playbin->playsink, "notify::volume",
+      G_CALLBACK (notify_volume_cb), playbin);
+  g_signal_connect (playbin->playsink, "notify::mute",
+      G_CALLBACK (notify_mute_cb), playbin);
+  g_signal_connect (playbin->playsink, "value-changed",
+      G_CALLBACK (colorbalance_value_changed_cb), playbin);
+
+  playbin->current_video = DEFAULT_CURRENT_VIDEO;
+  playbin->current_audio = DEFAULT_CURRENT_AUDIO;
+  playbin->current_text = DEFAULT_CURRENT_TEXT;
+
+  playbin->buffer_duration = DEFAULT_BUFFER_DURATION;
+  playbin->buffer_size = DEFAULT_BUFFER_SIZE;
+  playbin->ring_buffer_max_size = DEFAULT_RING_BUFFER_MAX_SIZE;
+
+  playbin->force_aspect_ratio = TRUE;
+
+  playbin->multiview_mode = GST_VIDEO_MULTIVIEW_FRAME_PACKING_NONE;
+  playbin->multiview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
+}
+
+static void
+gst_play_bin3_finalize (GObject * object)
+{
+  GstPlayBin3 *playbin;
+  gint i;
+
+  playbin = GST_PLAY_BIN3 (object);
+
+  free_group (playbin, &playbin->groups[0]);
+  free_group (playbin, &playbin->groups[1]);
+
+  for (i = 0; i < PLAYBIN_STREAM_LAST; i++)
+    g_ptr_array_free (playbin->channels[i], TRUE);
+
+  if (playbin->source)
+    gst_object_unref (playbin->source);
+
+  /* Setting states to NULL is safe here because playsink
+   * will already be gone and none of these sinks will be
+   * a child of playsink
+   */
+  if (playbin->video_sink) {
+    gst_element_set_state (playbin->video_sink, GST_STATE_NULL);
+    gst_object_unref (playbin->video_sink);
+  }
+  if (playbin->audio_sink) {
+    gst_element_set_state (playbin->audio_sink, GST_STATE_NULL);
+    gst_object_unref (playbin->audio_sink);
+  }
+  if (playbin->text_sink) {
+    gst_element_set_state (playbin->text_sink, GST_STATE_NULL);
+    gst_object_unref (playbin->text_sink);
+  }
+
+  if (playbin->video_stream_combiner) {
+    gst_element_set_state (playbin->video_stream_combiner, GST_STATE_NULL);
+    gst_object_unref (playbin->video_stream_combiner);
+  }
+  if (playbin->audio_stream_combiner) {
+    gst_element_set_state (playbin->audio_stream_combiner, GST_STATE_NULL);
+    gst_object_unref (playbin->audio_stream_combiner);
+  }
+  if (playbin->text_stream_combiner) {
+    gst_element_set_state (playbin->text_stream_combiner, GST_STATE_NULL);
+    gst_object_unref (playbin->text_stream_combiner);
+  }
+
+  g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_AUDIO].streams, TRUE);
+  g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_VIDEO].streams, TRUE);
+  g_ptr_array_free (playbin->combiner[PLAYBIN_STREAM_TEXT].streams, TRUE);
+
+  if (playbin->decodebin)
+    gst_object_unref (playbin->decodebin);
+
+  if (playbin->elements)
+    gst_plugin_feature_list_free (playbin->elements);
+
+  if (playbin->aelements)
+    g_sequence_free (playbin->aelements);
+
+  if (playbin->velements)
+    g_sequence_free (playbin->velements);
+
+  if (playbin->collection)
+    gst_object_unref (playbin->collection);
+
+  g_list_free_full (playbin->contexts, (GDestroyNotify) gst_context_unref);
+
+  g_rec_mutex_clear (&playbin->lock);
+  g_mutex_clear (&playbin->dyn_lock);
+  g_mutex_clear (&playbin->elements_lock);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gboolean
+gst_playbin_uri_is_valid (GstPlayBin3 * playbin, const gchar * uri)
+{
+  const gchar *c;
+
+  GST_LOG_OBJECT (playbin, "checking uri '%s'", uri);
+
+  /* this just checks the protocol */
+  if (!gst_uri_is_valid (uri))
+    return FALSE;
+
+  for (c = uri; *c != '\0'; ++c) {
+    if (!g_ascii_isprint (*c))
+      goto invalid;
+    if (*c == ' ')
+      goto invalid;
+  }
+
+  return TRUE;
+
+invalid:
+  {
+    GST_WARNING_OBJECT (playbin, "uri '%s' not valid, character #%u",
+        uri, (guint) ((guintptr) c - (guintptr) uri));
+    return FALSE;
+  }
+}
+
+static void
+gst_play_bin3_set_uri (GstPlayBin3 * playbin, const gchar * uri)
+{
+  GstSourceGroup *group;
+
+  if (uri == NULL) {
+    g_warning ("cannot set NULL uri");
+    return;
+  }
+
+  if (!gst_playbin_uri_is_valid (playbin, uri)) {
+    if (g_str_has_prefix (uri, "file:")) {
+      GST_WARNING_OBJECT (playbin, "not entirely correct file URI '%s' - make "
+          "sure to escape spaces and non-ASCII characters properly and specify "
+          "an absolute path. Use gst_filename_to_uri() to convert filenames "
+          "to URIs", uri);
+    } else {
+      /* GST_ERROR_OBJECT (playbin, "malformed URI '%s'", uri); */
+    }
+  }
+
+  GST_PLAY_BIN3_LOCK (playbin);
+  group = playbin->next_group;
+
+  GST_SOURCE_GROUP_LOCK (group);
+  /* store the uri in the next group we will play */
+  g_free (group->uri);
+  group->uri = g_strdup (uri);
+  group->valid = TRUE;
+  GST_SOURCE_GROUP_UNLOCK (group);
+
+  GST_DEBUG ("set new uri to %s", uri);
+  GST_PLAY_BIN3_UNLOCK (playbin);
+}
+
+static void
+gst_play_bin3_set_suburi (GstPlayBin3 * playbin, const gchar * suburi)
+{
+  GstSourceGroup *group;
+
+  GST_PLAY_BIN3_LOCK (playbin);
+  group = playbin->next_group;
+
+  GST_SOURCE_GROUP_LOCK (group);
+  g_free (group->suburi);
+  group->suburi = g_strdup (suburi);
+  GST_SOURCE_GROUP_UNLOCK (group);
+
+  GST_DEBUG ("setting new .sub uri to %s", suburi);
+
+  GST_PLAY_BIN3_UNLOCK (playbin);
+}
+
+static void
+gst_play_bin3_set_flags (GstPlayBin3 * playbin, GstPlayFlags flags)
+{
+  GstPlayFlags old_flags;
+  old_flags = gst_play_sink_get_flags (playbin->playsink);
+
+  if (flags != old_flags) {
+    gst_play_sink_set_flags (playbin->playsink, flags);
+    gst_play_sink_reconfigure (playbin->playsink);
+  }
+}
+
+static GstPlayFlags
+gst_play_bin3_get_flags (GstPlayBin3 * playbin)
+{
+  GstPlayFlags flags;
+
+  flags = gst_play_sink_get_flags (playbin->playsink);
+
+  return flags;
+}
+
+/* get the currently playing group or if nothing is playing, the next
+ * group. Must be called with the PLAY_BIN_LOCK. */
+static GstSourceGroup *
+get_group (GstPlayBin3 * playbin)
+{
+  GstSourceGroup *result;
+
+  if (!(result = playbin->curr_group))
+    result = playbin->next_group;
+
+  return result;
+}
+
+
+static GstSample *
+gst_play_bin3_convert_sample (GstPlayBin3 * playbin, GstCaps * caps)
+{
+  return gst_play_sink_convert_sample (playbin->playsink, caps);
+}
+
+/* Returns current stream number, or -1 if none has been selected yet */
+static int
+get_current_stream_number (GstPlayBin3 * playbin, GstSourceCombine * combine,
+    GPtrArray * channels)
+{
+  /* Internal API cleanup would make this easier... */
+  int i;
+  GstPad *pad, *current;
+  GstObject *combiner = NULL;
+  int ret = -1;
+
+  if (!combine->has_active_pad) {
+    GST_WARNING_OBJECT (playbin,
+        "combiner doesn't have the \"active-pad\" property");
+    return ret;
+  }
+
+  for (i = 0; i < channels->len; i++) {
+    pad = g_ptr_array_index (channels, i);
+    if ((combiner = gst_pad_get_parent (pad))) {
+      g_object_get (combiner, "active-pad", &current, NULL);
+      gst_object_unref (combiner);
+
+      if (pad == current) {
+        gst_object_unref (current);
+        ret = i;
+        break;
+      }
+
+      if (current)
+        gst_object_unref (current);
+    }
+  }
+
+  return ret;
+}
+
+static gboolean
+gst_play_bin3_send_custom_event (GstObject * combiner, const gchar * event_name)
+{
+  GstPad *src;
+  GstPad *peer;
+  GstStructure *s;
+  GstEvent *event;
+  gboolean ret = FALSE;
+
+  src = gst_element_get_static_pad (GST_ELEMENT_CAST (combiner), "src");
+  peer = gst_pad_get_peer (src);
+  if (peer) {
+    s = gst_structure_new_empty (event_name);
+    event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM_OOB, s);
+    gst_pad_send_event (peer, event);
+    gst_object_unref (peer);
+    ret = TRUE;
+  }
+  gst_object_unref (src);
+  return ret;
+}
+
+static gboolean
+gst_play_bin3_set_current_stream (GstPlayBin3 * playbin,
+    gint stream_type, gint * current_value, gint stream,
+    gboolean * flush_marker)
+{
+  GstSourceCombine *combine;
+  GPtrArray *channels;
+  GstPad *sinkpad;
+
+  GST_PLAY_BIN3_LOCK (playbin);
+  /* This function is only called if the app sets
+   * one of the current-* properties, which means it doesn't
+   * handle collections or select-streams yet */
+  playbin->do_stream_selections = TRUE;
+
+  combine = playbin->combiner + stream_type;
+  channels = playbin->channels[stream_type];
+
+  GST_DEBUG_OBJECT (playbin, "Changing current %s stream %d -> %d",
+      stream_type_names[stream_type], *current_value, stream);
+
+  if (combine->combiner == NULL) {
+    /* FIXME: Check that the current_value is within range */
+    *current_value = stream;
+    do_stream_selection (playbin);
+    GST_PLAY_BIN3_UNLOCK (playbin);
+    return TRUE;
+  }
+
+  GST_DEBUG_OBJECT (playbin, "Using old style combiner");
+
+  if (!combine->has_active_pad)
+    goto no_active_pad;
+  if (channels == NULL)
+    goto no_channels;
+
+  if (stream == -1 || channels->len <= stream) {
+    sinkpad = NULL;
+  } else {
+    /* take channel from selected stream */
+    sinkpad = g_ptr_array_index (channels, stream);
+  }
+
+  if (sinkpad)
+    gst_object_ref (sinkpad);
+  GST_PLAY_BIN3_UNLOCK (playbin);
+
+  if (sinkpad) {
+    GstObject *combiner;
+
+    if ((combiner = gst_pad_get_parent (sinkpad))) {
+      GstPad *old_sinkpad;
+
+      g_object_get (combiner, "active-pad", &old_sinkpad, NULL);
+
+      if (old_sinkpad != sinkpad) {
+        /* FIXME: Is there actually any reason playsink
+         * needs special names for each type of stream we flush? */
+        gchar *flush_event_name = g_strdup_printf ("playsink-custom-%s-flush",
+            stream_type_names[stream_type]);
+        if (gst_play_bin3_send_custom_event (combiner, flush_event_name))
+          *flush_marker = TRUE;
+        g_free (flush_event_name);
+
+        /* activate the selected pad */
+        g_object_set (combiner, "active-pad", sinkpad, NULL);
+      }
+
+      if (old_sinkpad)
+        gst_object_unref (old_sinkpad);
+
+      gst_object_unref (combiner);
+    }
+    gst_object_unref (sinkpad);
+  }
+  return TRUE;
+
+no_active_pad:
+  {
+    GST_PLAY_BIN3_UNLOCK (playbin);
+    GST_WARNING_OBJECT (playbin,
+        "can't switch %s, the stream combiner's sink pads don't have the \"active-pad\" property",
+        stream_type_names[stream_type]);
+    return FALSE;
+  }
+no_channels:
+  {
+    GST_PLAY_BIN3_UNLOCK (playbin);
+    GST_DEBUG_OBJECT (playbin, "can't switch video, we have no channels");
+    return FALSE;
+  }
+}
+
+static gboolean
+gst_play_bin3_set_current_video_stream (GstPlayBin3 * playbin, gint stream)
+{
+  return gst_play_bin3_set_current_stream (playbin, PLAYBIN_STREAM_VIDEO,
+      &playbin->current_video, stream, &playbin->video_pending_flush_finish);
+}
+
+static gboolean
+gst_play_bin3_set_current_audio_stream (GstPlayBin3 * playbin, gint stream)
+{
+  return gst_play_bin3_set_current_stream (playbin, PLAYBIN_STREAM_AUDIO,
+      &playbin->current_audio, stream, &playbin->audio_pending_flush_finish);
+}
+
+static gboolean
+gst_play_bin3_set_current_text_stream (GstPlayBin3 * playbin, gint stream)
+{
+  return gst_play_bin3_set_current_stream (playbin, PLAYBIN_STREAM_TEXT,
+      &playbin->current_text, stream, &playbin->text_pending_flush_finish);
+}
+
+static void
+source_combine_remove_pads (GstPlayBin3 * playbin, GstSourceCombine * combine)
+{
+  if (combine->sinkpad) {
+    GST_LOG_OBJECT (playbin, "unlinking from sink");
+    gst_pad_unlink (combine->srcpad, combine->sinkpad);
+
+    /* release back */
+    GST_LOG_OBJECT (playbin, "release sink pad");
+    gst_play_sink_release_pad (playbin->playsink, combine->sinkpad);
+    gst_object_unref (combine->sinkpad);
+    combine->sinkpad = NULL;
+  }
+  gst_object_unref (combine->srcpad);
+  combine->srcpad = NULL;
+}
+
+static GstPadProbeReturn
+block_serialized_data_cb (GstPad * pad, GstPadProbeInfo * info,
+    gpointer user_data)
+{
+  if (GST_IS_EVENT (info->data) && !GST_EVENT_IS_SERIALIZED (info->data)) {
+    GST_DEBUG_OBJECT (pad, "Letting non-serialized event %s pass",
+        GST_EVENT_TYPE_NAME (info->data));
+    return GST_PAD_PROBE_PASS;
+  }
+
+  return GST_PAD_PROBE_OK;
+}
+
+static void
+gst_play_bin3_set_sink (GstPlayBin3 * playbin, GstPlaySinkType type,
+    const gchar * dbg, GstElement ** elem, GstElement * sink)
+{
+  GST_INFO_OBJECT (playbin, "Setting %s sink to %" GST_PTR_FORMAT, dbg, sink);
+
+  gst_play_sink_set_sink (playbin->playsink, type, sink);
+
+  if (*elem)
+    gst_object_unref (*elem);
+  *elem = sink ? gst_object_ref (sink) : NULL;
+}
+
+static void
+gst_play_bin3_set_stream_combiner (GstPlayBin3 * playbin, GstElement ** elem,
+    const gchar * dbg, GstElement * combiner)
+{
+  GST_INFO_OBJECT (playbin, "Setting %s stream combiner to %" GST_PTR_FORMAT,
+      dbg, combiner);
+
+  GST_PLAY_BIN3_LOCK (playbin);
+  if (*elem != combiner) {
+    GstElement *old;
+
+    old = *elem;
+    if (combiner)
+      gst_object_ref_sink (combiner);
+
+    *elem = combiner;
+    if (old)
+      gst_object_unref (old);
+  }
+  GST_LOG_OBJECT (playbin, "%s stream combiner now %" GST_PTR_FORMAT, dbg,
+      *elem);
+  GST_PLAY_BIN3_UNLOCK (playbin);
+}
+
+static void
+gst_play_bin3_set_encoding (GstPlayBin3 * playbin, const gchar * encoding)
+{
+  GstElement *elem;
+
+  GST_PLAY_BIN3_LOCK (playbin);
+
+  /* set subtitles on decodebin. */
+  if ((elem = playbin->decodebin))
+    g_object_set (G_OBJECT (elem), "subtitle-encoding", encoding, NULL);
+
+  gst_play_sink_set_subtitle_encoding (playbin->playsink, encoding);
+  GST_PLAY_BIN3_UNLOCK (playbin);
+}
+
+static void
+gst_play_bin3_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstPlayBin3 *playbin = GST_PLAY_BIN3 (object);
+
+  switch (prop_id) {
+    case PROP_URI:
+      gst_play_bin3_set_uri (playbin, g_value_get_string (value));
+      break;
+    case PROP_SUBURI:
+      gst_play_bin3_set_suburi (playbin, g_value_get_string (value));
+      break;
+    case PROP_FLAGS:
+      gst_play_bin3_set_flags (playbin, g_value_get_flags (value));
+      if (playbin->curr_group) {
+        GST_SOURCE_GROUP_LOCK (playbin->curr_group);
+        if (playbin->curr_group->urisourcebin) {
+          g_object_set (playbin->curr_group->urisourcebin, "download",
+              (g_value_get_flags (value) & GST_PLAY_FLAG_DOWNLOAD) != 0, NULL);
+        }
+        GST_SOURCE_GROUP_UNLOCK (playbin->curr_group);
+      }
+      break;
+    case PROP_SUBTITLE_ENCODING:
+      gst_play_bin3_set_encoding (playbin, g_value_get_string (value));
+      break;
+    case PROP_VIDEO_FILTER:
+      gst_play_sink_set_filter (playbin->playsink, GST_PLAY_SINK_TYPE_VIDEO,
+          GST_ELEMENT (g_value_get_object (value)));
+      break;
+    case PROP_AUDIO_FILTER:
+      gst_play_sink_set_filter (playbin->playsink, GST_PLAY_SINK_TYPE_AUDIO,
+          GST_ELEMENT (g_value_get_object (value)));
+      break;
+    case PROP_VIDEO_SINK:
+      gst_play_bin3_set_sink (playbin, GST_PLAY_SINK_TYPE_VIDEO, "video",
+          &playbin->video_sink, g_value_get_object (value));
+      break;
+    case PROP_AUDIO_SINK:
+      gst_play_bin3_set_sink (playbin, GST_PLAY_SINK_TYPE_AUDIO, "audio",
+          &playbin->audio_sink, g_value_get_object (value));
+      break;
+    case PROP_VIS_PLUGIN:
+      gst_play_sink_set_vis_plugin (playbin->playsink,
+          g_value_get_object (value));
+      break;
+    case PROP_TEXT_SINK:
+      gst_play_bin3_set_sink (playbin, GST_PLAY_SINK_TYPE_TEXT, "text",
+          &playbin->text_sink, g_value_get_object (value));
+      break;
+    case PROP_VIDEO_STREAM_COMBINER:
+      gst_play_bin3_set_stream_combiner (playbin,
+          &playbin->video_stream_combiner, "video", g_value_get_object (value));
+      break;
+    case PROP_AUDIO_STREAM_COMBINER:
+      gst_play_bin3_set_stream_combiner (playbin,
+          &playbin->audio_stream_combiner, "audio", g_value_get_object (value));
+      break;
+    case PROP_TEXT_STREAM_COMBINER:
+      gst_play_bin3_set_stream_combiner (playbin,
+          &playbin->text_stream_combiner, "text", g_value_get_object (value));
+      break;
+    case PROP_VOLUME:
+      gst_play_sink_set_volume (playbin->playsink, g_value_get_double (value));
+      break;
+    case PROP_MUTE:
+      gst_play_sink_set_mute (playbin->playsink, g_value_get_boolean (value));
+      break;
+    case PROP_FONT_DESC:
+      gst_play_sink_set_font_desc (playbin->playsink,
+          g_value_get_string (value));
+      break;
+    case PROP_CONNECTION_SPEED:
+      GST_PLAY_BIN3_LOCK (playbin);
+      playbin->connection_speed = g_value_get_uint64 (value) * 1000;
+      GST_PLAY_BIN3_UNLOCK (playbin);
+      break;
+    case PROP_BUFFER_SIZE:
+      playbin->buffer_size = g_value_get_int (value);
+      break;
+    case PROP_BUFFER_DURATION:
+      playbin->buffer_duration = g_value_get_int64 (value);
+      break;
+    case PROP_AV_OFFSET:
+      gst_play_sink_set_av_offset (playbin->playsink,
+          g_value_get_int64 (value));
+      break;
+    case PROP_RING_BUFFER_MAX_SIZE:
+      playbin->ring_buffer_max_size = g_value_get_uint64 (value);
+      if (playbin->curr_group) {
+        GST_SOURCE_GROUP_LOCK (playbin->curr_group);
+        if (playbin->curr_group->urisourcebin) {
+          g_object_set (playbin->curr_group->urisourcebin,
+              "ring-buffer-max-size", playbin->ring_buffer_max_size, NULL);
+        }
+        GST_SOURCE_GROUP_UNLOCK (playbin->curr_group);
+      }
+      break;
+    case PROP_FORCE_ASPECT_RATIO:
+      g_object_set (playbin->playsink, "force-aspect-ratio",
+          g_value_get_boolean (value), NULL);
+      break;
+    case PROP_MULTIVIEW_MODE:
+      GST_PLAY_BIN3_LOCK (playbin);
+      playbin->multiview_mode = g_value_get_enum (value);
+      GST_PLAY_BIN3_UNLOCK (playbin);
+      break;
+    case PROP_MULTIVIEW_FLAGS:
+      GST_PLAY_BIN3_LOCK (playbin);
+      playbin->multiview_flags = g_value_get_flags (value);
+      GST_PLAY_BIN3_UNLOCK (playbin);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static GstElement *
+gst_play_bin3_get_current_sink (GstPlayBin3 * playbin, GstElement ** elem,
+    const gchar * dbg, GstPlaySinkType type)
+{
+  GstElement *sink = gst_play_sink_get_sink (playbin->playsink, type);
+
+  GST_LOG_OBJECT (playbin, "play_sink_get_sink() returned %s sink %"
+      GST_PTR_FORMAT ", the originally set %s sink is %" GST_PTR_FORMAT,
+      dbg, sink, dbg, *elem);
+
+  if (sink == NULL) {
+    GST_PLAY_BIN3_LOCK (playbin);
+    if ((sink = *elem))
+      gst_object_ref (sink);
+    GST_PLAY_BIN3_UNLOCK (playbin);
+  }
+
+  return sink;
+}
+
+static GstElement *
+gst_play_bin3_get_current_stream_combiner (GstPlayBin3 * playbin,
+    GstElement ** elem, const gchar * dbg, int stream_type)
+{
+  GstElement *combiner;
+
+  GST_PLAY_BIN3_LOCK (playbin);
+  if ((combiner = playbin->combiner[stream_type].combiner))
+    gst_object_ref (combiner);
+  else if ((combiner = *elem))
+    gst_object_ref (combiner);
+  GST_PLAY_BIN3_UNLOCK (playbin);
+
+  return combiner;
+}
+
+static void
+gst_play_bin3_get_property (GObject * object, guint prop_id, GValue * value,
+    GParamSpec * pspec)
+{
+  GstPlayBin3 *playbin = GST_PLAY_BIN3 (object);
+
+  switch (prop_id) {
+    case PROP_URI:
+    {
+      GstSourceGroup *group;
+
+      GST_PLAY_BIN3_LOCK (playbin);
+      group = playbin->next_group;
+      g_value_set_string (value, group->uri);
+      GST_PLAY_BIN3_UNLOCK (playbin);
+      break;
+    }
+    case PROP_CURRENT_URI:
+    {
+      GstSourceGroup *group;
+
+      GST_PLAY_BIN3_LOCK (playbin);
+      group = get_group (playbin);
+      g_value_set_string (value, group->uri);
+      GST_PLAY_BIN3_UNLOCK (playbin);
+      break;
+    }
+    case PROP_SUBURI:
+    {
+      GstSourceGroup *group;
+
+      GST_PLAY_BIN3_LOCK (playbin);
+      group = playbin->next_group;
+      g_value_set_string (value, group->suburi);
+      GST_PLAY_BIN3_UNLOCK (playbin);
+      break;
+    }
+    case PROP_CURRENT_SUBURI:
+    {
+      GstSourceGroup *group;
+
+      GST_PLAY_BIN3_LOCK (playbin);
+      group = get_group (playbin);
+      g_value_set_string (value, group->suburi);
+      GST_PLAY_BIN3_UNLOCK (playbin);
+      break;
+    }
+    case PROP_SOURCE:
+    {
+      GST_OBJECT_LOCK (playbin);
+      g_value_set_object (value, playbin->source);
+      GST_OBJECT_UNLOCK (playbin);
+      break;
+    }
+    case PROP_FLAGS:
+      g_value_set_flags (value, gst_play_bin3_get_flags (playbin));
+      break;
+    case PROP_SUBTITLE_ENCODING:
+      GST_PLAY_BIN3_LOCK (playbin);
+      g_value_take_string (value,
+          gst_play_sink_get_subtitle_encoding (playbin->playsink));
+      GST_PLAY_BIN3_UNLOCK (playbin);
+      break;
+    case PROP_VIDEO_FILTER:
+      g_value_take_object (value,
+          gst_play_sink_get_filter (playbin->playsink,
+              GST_PLAY_SINK_TYPE_VIDEO));
+      break;
+    case PROP_AUDIO_FILTER:
+      g_value_take_object (value,
+          gst_play_sink_get_filter (playbin->playsink,
+              GST_PLAY_SINK_TYPE_AUDIO));
+      break;
+    case PROP_VIDEO_SINK:
+      g_value_take_object (value,
+          gst_play_bin3_get_current_sink (playbin, &playbin->video_sink,
+              "video", GST_PLAY_SINK_TYPE_VIDEO));
+      break;
+    case PROP_AUDIO_SINK:
+      g_value_take_object (value,
+          gst_play_bin3_get_current_sink (playbin, &playbin->audio_sink,
+              "audio", GST_PLAY_SINK_TYPE_AUDIO));
+      break;
+    case PROP_VIS_PLUGIN:
+      g_value_take_object (value,
+          gst_play_sink_get_vis_plugin (playbin->playsink));
+      break;
+    case PROP_TEXT_SINK:
+      g_value_take_object (value,
+          gst_play_bin3_get_current_sink (playbin, &playbin->text_sink,
+              "text", GST_PLAY_SINK_TYPE_TEXT));
+      break;
+    case PROP_VIDEO_STREAM_COMBINER:
+      g_value_take_object (value,
+          gst_play_bin3_get_current_stream_combiner (playbin,
+              &playbin->video_stream_combiner, "video", PLAYBIN_STREAM_VIDEO));
+      break;
+    case PROP_AUDIO_STREAM_COMBINER:
+      g_value_take_object (value,
+          gst_play_bin3_get_current_stream_combiner (playbin,
+              &playbin->audio_stream_combiner, "audio", PLAYBIN_STREAM_AUDIO));
+      break;
+    case PROP_TEXT_STREAM_COMBINER:
+      g_value_take_object (value,
+          gst_play_bin3_get_current_stream_combiner (playbin,
+              &playbin->text_stream_combiner, "text", PLAYBIN_STREAM_TEXT));
+      break;
+    case PROP_VOLUME:
+      g_value_set_double (value, gst_play_sink_get_volume (playbin->playsink));
+      break;
+    case PROP_MUTE:
+      g_value_set_boolean (value, gst_play_sink_get_mute (playbin->playsink));
+      break;
+    case PROP_SAMPLE:
+      gst_value_take_sample (value,
+          gst_play_sink_get_last_sample (playbin->playsink));
+      break;
+    case PROP_FONT_DESC:
+      g_value_take_string (value,
+          gst_play_sink_get_font_desc (playbin->playsink));
+      break;
+    case PROP_CONNECTION_SPEED:
+      GST_PLAY_BIN3_LOCK (playbin);
+      g_value_set_uint64 (value, playbin->connection_speed / 1000);
+      GST_PLAY_BIN3_UNLOCK (playbin);
+      break;
+    case PROP_BUFFER_SIZE:
+      GST_OBJECT_LOCK (playbin);
+      g_value_set_int (value, playbin->buffer_size);
+      GST_OBJECT_UNLOCK (playbin);
+      break;
+    case PROP_BUFFER_DURATION:
+      GST_OBJECT_LOCK (playbin);
+      g_value_set_int64 (value, playbin->buffer_duration);
+      GST_OBJECT_UNLOCK (playbin);
+      break;
+    case PROP_AV_OFFSET:
+      g_value_set_int64 (value,
+          gst_play_sink_get_av_offset (playbin->playsink));
+      break;
+    case PROP_RING_BUFFER_MAX_SIZE:
+      g_value_set_uint64 (value, playbin->ring_buffer_max_size);
+      break;
+    case PROP_FORCE_ASPECT_RATIO:{
+      gboolean v;
+
+      g_object_get (playbin->playsink, "force-aspect-ratio", &v, NULL);
+      g_value_set_boolean (value, v);
+      break;
+    }
+    case PROP_MULTIVIEW_MODE:
+      GST_OBJECT_LOCK (playbin);
+      g_value_set_enum (value, playbin->multiview_mode);
+      GST_OBJECT_UNLOCK (playbin);
+      break;
+    case PROP_MULTIVIEW_FLAGS:
+      GST_OBJECT_LOCK (playbin);
+      g_value_set_flags (value, playbin->multiview_flags);
+      GST_OBJECT_UNLOCK (playbin);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_play_bin3_update_cached_duration_from_query (GstPlayBin3 * playbin,
+    gboolean valid, GstQuery * query)
+{
+  GstFormat fmt;
+  gint64 duration;
+  gint i;
+
+  GST_DEBUG_OBJECT (playbin, "Updating cached duration from query");
+  gst_query_parse_duration (query, &fmt, &duration);
+
+  for (i = 0; i < G_N_ELEMENTS (playbin->duration); i++) {
+    if (playbin->duration[i].format == 0 || fmt == playbin->duration[i].format) {
+      playbin->duration[i].valid = valid;
+      playbin->duration[i].format = fmt;
+      playbin->duration[i].duration = valid ? duration : -1;
+      break;
+    }
+  }
+}
+
+static void
+gst_play_bin3_update_cached_duration (GstPlayBin3 * playbin)
+{
+  const GstFormat formats[] =
+      { GST_FORMAT_TIME, GST_FORMAT_BYTES, GST_FORMAT_DEFAULT };
+  gboolean ret;
+  GstQuery *query;
+  gint i;
+
+  GST_DEBUG_OBJECT (playbin, "Updating cached durations before group switch");
+  for (i = 0; i < G_N_ELEMENTS (formats); i++) {
+    query = gst_query_new_duration (formats[i]);
+    ret =
+        GST_ELEMENT_CLASS (parent_class)->query (GST_ELEMENT_CAST (playbin),
+        query);
+    gst_play_bin3_update_cached_duration_from_query (playbin, ret, query);
+    gst_query_unref (query);
+  }
+}
+
+static gboolean
+gst_play_bin3_query (GstElement * element, GstQuery * query)
+{
+  GstPlayBin3 *playbin = GST_PLAY_BIN3 (element);
+  gboolean ret;
+
+  /* During a group switch we shouldn't allow duration queries
+   * because it's not clear if the old or new group's duration
+   * is returned and if the sinks are already playing new data
+   * or old data. See bug #585969
+   *
+   * While we're at it, also don't do any other queries during
+   * a group switch or any other event that causes topology changes
+   * by taking the playbin lock in any case.
+   */
+  GST_PLAY_BIN3_LOCK (playbin);
+
+  if (GST_QUERY_TYPE (query) == GST_QUERY_DURATION) {
+    GstSourceGroup *group = playbin->curr_group;
+    gboolean pending;
+
+    GST_SOURCE_GROUP_LOCK (group);
+
+    pending = group->pending || group->stream_changed_pending;
+
+    if (pending) {
+      GstFormat fmt;
+      gint i;
+
+      ret = FALSE;
+      gst_query_parse_duration (query, &fmt, NULL);
+      for (i = 0; i < G_N_ELEMENTS (playbin->duration); i++) {
+        if (fmt == playbin->duration[i].format) {
+          ret = playbin->duration[i].valid;
+          gst_query_set_duration (query, fmt,
+              (ret ? playbin->duration[i].duration : -1));
+          break;
+        }
+      }
+      /* if nothing cached yet, we might as well request duration,
+       * such as during initial startup */
+      if (ret) {
+        GST_DEBUG_OBJECT (playbin,
+            "Taking cached duration because of pending group switch: %d", ret);
+        GST_SOURCE_GROUP_UNLOCK (group);
+        GST_PLAY_BIN3_UNLOCK (playbin);
+        return ret;
+      }
+    }
+    GST_SOURCE_GROUP_UNLOCK (group);
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->query (element, query);
+
+  if (GST_QUERY_TYPE (query) == GST_QUERY_DURATION)
+    gst_play_bin3_update_cached_duration_from_query (playbin, ret, query);
+  GST_PLAY_BIN3_UNLOCK (playbin);
+
+  return ret;
+}
+
+static gint
+get_combiner_stream_id (GstPlayBin3 * playbin, GstSourceCombine * combine,
+    GList * full_list)
+{
+  gint i;
+  GList *tmp;
+
+  for (i = 0; combine->streams->len; i++) {
+    GstStream *stream = (GstStream *) g_ptr_array_index (combine->streams, i);
+    const gchar *sid = gst_stream_get_stream_id (stream);
+    for (tmp = full_list; tmp; tmp = tmp->next) {
+      gchar *orig = (gchar *) tmp->data;
+      if (!g_strcmp0 (orig, sid))
+        return i;
+    }
+  }
+
+  /* Fallback */
+  return -1;
+}
+
+static GList *
+extend_list_of_streams (GstPlayBin3 * playbin, GstStreamType stype,
+    GList * list)
+{
+  GList *tmp, *res;
+  gint i, nb;
+
+  res = list;
+
+  nb = gst_stream_collection_get_size (playbin->collection);
+  for (i = 0; i < nb; i++) {
+    GstStream *stream =
+        gst_stream_collection_get_stream (playbin->collection, i);
+    GstStreamType curtype = gst_stream_get_stream_type (stream);
+    if (stype == curtype) {
+      gboolean already_there = FALSE;
+      const gchar *sid = gst_stream_get_stream_id (stream);
+      for (tmp = res; tmp; tmp = tmp->next) {
+        const gchar *other = (const gchar *) tmp->data;
+        if (!g_strcmp0 (sid, other)) {
+          already_there = TRUE;
+          break;
+        }
+      }
+      if (!already_there) {
+        GST_DEBUG_OBJECT (playbin, "Adding stream %s", sid);
+        res = g_list_append (res, g_strdup (sid));
+      }
+    }
+  }
+
+  return res;
+}
+
+static GstEvent *
+update_select_streams_event (GstPlayBin3 * playbin, GstEvent * event)
+{
+  GList *streams = NULL;
+  GList *to_use;
+  gint combine_id;
+
+  if (!playbin->audio_stream_combiner && !playbin->video_stream_combiner &&
+      !playbin->text_stream_combiner) {
+    /* Nothing to do */
+    GST_DEBUG_OBJECT (playbin,
+        "No custom combiners, no need to modify SELECT_STREAMS event");
+    return event;
+  }
+
+  gst_event_parse_select_streams (event, &streams);
+  to_use = g_list_copy_deep (streams, (GCopyFunc) g_strdup, NULL);
+
+  /* For each combiner, we want to add all streams of that type to the
+   * selection */
+  if (playbin->audio_stream_combiner) {
+    to_use = extend_list_of_streams (playbin, GST_STREAM_TYPE_AUDIO, to_use);
+    combine_id =
+        get_combiner_stream_id (playbin,
+        &playbin->combiner[PLAYBIN_STREAM_AUDIO], streams);
+    if (combine_id != -1)
+      gst_play_bin3_set_current_audio_stream (playbin, combine_id);
+  }
+  if (playbin->video_stream_combiner) {
+    to_use = extend_list_of_streams (playbin, GST_STREAM_TYPE_VIDEO, to_use);
+    combine_id =
+        get_combiner_stream_id (playbin,
+        &playbin->combiner[PLAYBIN_STREAM_VIDEO], streams);
+    if (combine_id != -1)
+      gst_play_bin3_set_current_video_stream (playbin, combine_id);
+  }
+  if (playbin->text_stream_combiner) {
+    to_use = extend_list_of_streams (playbin, GST_STREAM_TYPE_TEXT, to_use);
+    combine_id =
+        get_combiner_stream_id (playbin,
+        &playbin->combiner[PLAYBIN_STREAM_TEXT], streams);
+    if (combine_id != -1)
+      gst_play_bin3_set_current_text_stream (playbin, combine_id);
+  }
+
+  gst_event_unref (event);
+  return gst_event_new_select_streams (to_use);
+}
+
+static gboolean
+gst_play_bin3_send_event (GstElement * element, GstEvent * event)
+{
+  GstPlayBin3 *playbin = GST_PLAY_BIN3 (element);
+
+  if (GST_EVENT_TYPE (event) == GST_EVENT_SELECT_STREAMS) {
+    gboolean res;
+
+    GST_PLAY_BIN3_LOCK (playbin);
+    GST_LOG_OBJECT (playbin,
+        "App sent select-streams, we won't do anything ourselves now");
+    /* This is probably already false, but it doesn't hurt to be sure */
+    playbin->do_stream_selections = FALSE;
+
+    /* If we have custom combiners, we need to extend the selection with
+     * the list of all streams for that given type since we will be handling
+     * the selection with that combiner */
+    event = update_select_streams_event (playbin, event);
+
+    /* Send this event directly to decodebin, so it works even
+     * if decodebin didn't add any pads yet */
+    res = gst_element_send_event (playbin->decodebin, event);
+    GST_PLAY_BIN3_UNLOCK (playbin);
+
+    return res;
+  }
+
+  /* Send event directly to playsink instead of letting GstBin iterate
+   * over all sink elements. The latter might send the event multiple times
+   * in case the SEEK causes a reconfiguration of the pipeline, as can easily
+   * happen with adaptive streaming demuxers.
+   *
+   * What would then happen is that the iterator would be reset, we send the
+   * event again, and on the second time it will fail in the majority of cases
+   * because the pipeline is still being reconfigured
+   */
+  if (GST_EVENT_IS_UPSTREAM (event)) {
+    return gst_element_send_event (GST_ELEMENT_CAST (playbin->playsink), event);
+  }
+
+  return GST_ELEMENT_CLASS (parent_class)->send_event (element, event);
+}
+
+/* Called with playbin lock held */
+static void
+do_stream_selection (GstPlayBin3 * playbin)
+{
+  GstStreamCollection *collection;
+  guint i, nb_streams;
+  GList *streams = NULL;
+  gint nb_video = 0, nb_audio = 0, nb_text = 0;
+  GstStreamType chosen_stream_types = 0;
+
+  collection = playbin->collection;
+  if (collection == NULL) {
+    GST_LOG_OBJECT (playbin, "No stream collection. Not doing stream-select");
+    return;
+  }
+
+  nb_streams = gst_stream_collection_get_size (collection);
+  if (nb_streams == 0) {
+    GST_INFO_OBJECT (playbin, "Empty collection received! Ignoring");
+  }
+
+  /* Iterate the collection and choose the streams that match
+   * either the current-* setting, or all streams of a type if there's
+   * a combiner for that type */
+  for (i = 0; i < nb_streams; i++) {
+    GstStream *stream = gst_stream_collection_get_stream (collection, i);
+    GstStreamType stream_type = gst_stream_get_stream_type (stream);
+    const gchar *stream_id = gst_stream_get_stream_id (stream);
+    gint pb_stream_type = -1;
+    gboolean select_this = FALSE;
+
+    switch (stream_type) {
+      case GST_STREAM_TYPE_AUDIO:
+        pb_stream_type = PLAYBIN_STREAM_AUDIO;
+        /* Select the stream if it's the current one or if there's a custom selector */
+        select_this =
+            (nb_audio == playbin->current_audio ||
+            (playbin->current_audio == -1 && nb_audio == 0) ||
+            playbin->audio_stream_combiner != NULL);
+        nb_audio++;
+        break;
+      case GST_STREAM_TYPE_VIDEO:
+        pb_stream_type = PLAYBIN_STREAM_AUDIO;
+        select_this =
+            (nb_video == playbin->current_video ||
+            (playbin->current_video == -1 && nb_video == 0) ||
+            playbin->video_stream_combiner != NULL);
+        nb_video++;
+        break;
+      case GST_STREAM_TYPE_TEXT:
+        pb_stream_type = PLAYBIN_STREAM_TEXT;
+        select_this =
+            (nb_text == playbin->current_text ||
+            (playbin->current_text == -1 && nb_text == 0) ||
+            playbin->text_stream_combiner != NULL);
+        nb_text++;
+        break;
+      default:
+        break;
+    }
+    if (pb_stream_type < 0) {
+      GST_DEBUG_OBJECT (playbin,
+          "Stream %d (id %s) of unhandled type %s. Ignoring", i, stream_id,
+          gst_stream_type_get_name (stream_type));
+      continue;
+    }
+    if (select_this) {
+      GST_DEBUG_OBJECT (playbin, "Selecting stream %s of type %s",
+          stream_id, gst_stream_type_get_name (stream_type));
+      /* Don't build the list if we're not in charge of stream selection */
+      if (playbin->do_stream_selections)
+        streams = g_list_append (streams, (gpointer) stream_id);
+      chosen_stream_types |= stream_type;
+    }
+  }
+
+  if (streams) {
+    GstEvent *ev = gst_event_new_select_streams (streams);
+    gst_element_send_event (playbin->decodebin, ev);
+    g_list_free (streams);
+  }
+  playbin->selected_stream_types = chosen_stream_types;
+}
+
+/* mime types we are not handling on purpose right now, don't post a
+ * missing-plugin message for these */
+static const gchar *blacklisted_mimes[] = {
+  NULL
+};
+
+static void
+gst_play_bin3_handle_message (GstBin * bin, GstMessage * msg)
+{
+  GstPlayBin3 *playbin = GST_PLAY_BIN3 (bin);
+
+  if (gst_is_missing_plugin_message (msg)) {
+    gchar *detail;
+    guint i;
+
+    detail = gst_missing_plugin_message_get_installer_detail (msg);
+    for (i = 0; detail != NULL && blacklisted_mimes[i] != NULL; ++i) {
+      if (strstr (detail, "|decoder-") && strstr (detail, blacklisted_mimes[i])) {
+        GST_LOG_OBJECT (bin, "suppressing message %" GST_PTR_FORMAT, msg);
+        gst_message_unref (msg);
+        g_free (detail);
+        return;
+      }
+    }
+    g_free (detail);
+  } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_STREAM_START) {
+    GstSourceGroup *new_group = playbin->curr_group;
+    GstMessage *buffering_msg = NULL;
+
+    GST_SOURCE_GROUP_LOCK (new_group);
+    new_group->stream_changed_pending = FALSE;
+    if (new_group->pending_buffering_msg) {
+      buffering_msg = new_group->pending_buffering_msg;
+      new_group->pending_buffering_msg = NULL;
+    }
+    GST_SOURCE_GROUP_UNLOCK (new_group);
+
+    GST_DEBUG_OBJECT (playbin, "Stream start from new group %p", new_group);
+
+    if (buffering_msg) {
+      GST_DEBUG_OBJECT (playbin, "Posting pending buffering message: %"
+          GST_PTR_FORMAT, buffering_msg);
+      GST_BIN_CLASS (parent_class)->handle_message (bin, buffering_msg);
+    }
+
+  } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_BUFFERING) {
+    GstSourceGroup *group = playbin->curr_group;
+    gboolean pending;
+
+    /* drop buffering messages from child queues while we are switching
+     * groups (because the application set a new uri in about-to-finish)
+     * if the playsink queue still has buffers to play */
+
+    GST_SOURCE_GROUP_LOCK (group);
+    pending = group->stream_changed_pending;
+
+    if (pending) {
+      GST_DEBUG_OBJECT (playbin, "Storing buffering message from pending group "
+          "%p %" GST_PTR_FORMAT, group, msg);
+      gst_message_replace (&group->pending_buffering_msg, msg);
+      gst_message_unref (msg);
+      msg = NULL;
+    }
+    GST_SOURCE_GROUP_UNLOCK (group);
+  } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_STREAM_COLLECTION) {
+    GstStreamCollection *collection = NULL;
+    GstObject *src = GST_MESSAGE_SRC (msg);
+    gboolean pstate = playbin->do_stream_selections;
+
+    gst_message_parse_stream_collection (msg, &collection);
+
+    if (collection) {
+      GST_PLAY_BIN3_LOCK (playbin);
+      GST_DEBUG_OBJECT (playbin,
+          "STREAM_COLLECTION: Got a collection from %" GST_PTR_FORMAT, src);
+      gst_object_replace ((GstObject **) & playbin->collection,
+          (GstObject *) collection);
+      update_combiner_info (playbin);
+      if (pstate)
+        playbin->do_stream_selections = FALSE;
+      do_stream_selection (playbin);
+      if (pstate)
+        playbin->do_stream_selections = TRUE;
+      GST_PLAY_BIN3_UNLOCK (playbin);
+
+      gst_object_unref (collection);
+    }
+  } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_STREAMS_SELECTED) {
+    GstStreamCollection *collection = NULL;
+    GstObject *src = GST_MESSAGE_SRC (msg);
+    gboolean pstate = playbin->do_stream_selections;
+
+    gst_message_parse_streams_selected (msg, &collection);
+    if (collection) {
+      guint i, len;
+      GST_PLAY_BIN3_LOCK (playbin);
+      GST_DEBUG_OBJECT (playbin,
+          "STREAMS_SELECTED: Got a collection from %" GST_PTR_FORMAT, src);
+      gst_object_replace ((GstObject **) & playbin->collection,
+          (GstObject *) collection);
+      update_combiner_info (playbin);
+      len = gst_message_streams_selected_get_size (msg);
+      for (i = 0; i < len; i++) {
+        GstStream *stream;
+
+        stream = gst_message_streams_selected_get_stream (msg, i);
+        set_selected_stream (playbin, stream);
+        gst_object_unref (stream);
+      }
+      if (pstate)
+        playbin->do_stream_selections = FALSE;
+      do_stream_selection (playbin);
+      if (pstate)
+        playbin->do_stream_selections = TRUE;
+      GST_PLAY_BIN3_UNLOCK (playbin);
+
+      gst_object_unref (collection);
+    }
+  }
+
+  if (msg)
+    GST_BIN_CLASS (parent_class)->handle_message (bin, msg);
+}
+
+static void
+gst_play_bin3_deep_element_added (GstBin * playbin, GstBin * sub_bin,
+    GstElement * child)
+{
+  GST_LOG_OBJECT (playbin, "element %" GST_PTR_FORMAT " was added to "
+      "%" GST_PTR_FORMAT, child, sub_bin);
+
+  g_signal_emit (playbin, gst_play_bin3_signals[SIGNAL_ELEMENT_SETUP], 0,
+      child);
+
+  GST_BIN_CLASS (parent_class)->deep_element_added (playbin, sub_bin, child);
+}
+
+static void
+combiner_active_pad_changed (GObject * combiner, GParamSpec * pspec,
+    GstPlayBin3 * playbin)
+{
+  const gchar *property;
+  GstSourceCombine *combine = NULL;
+  GPtrArray *channels = NULL;
+  int i;
+
+  GST_PLAY_BIN3_LOCK (playbin);
+
+  for (i = 0; i < PLAYBIN_STREAM_LAST; i++) {
+    if (combiner == G_OBJECT (playbin->combiner[i].combiner)) {
+      combine = &playbin->combiner[i];
+      channels = playbin->channels[i];
+    }
+  }
+
+  /* We got a pad-change after our group got switched out; no need to notify */
+  if (!combine) {
+    GST_PLAY_BIN3_UNLOCK (playbin);
+    return;
+  }
+
+  switch (combine->type) {
+    case GST_PLAY_SINK_TYPE_VIDEO:
+    case GST_PLAY_SINK_TYPE_VIDEO_RAW:
+      property = "current-video";
+      playbin->current_video = get_current_stream_number (playbin,
+          combine, channels);
+
+      if (playbin->video_pending_flush_finish) {
+        playbin->video_pending_flush_finish = FALSE;
+        GST_PLAY_BIN3_UNLOCK (playbin);
+        gst_play_bin3_send_custom_event (GST_OBJECT (combiner),
+            "playsink-custom-video-flush-finish");
+        goto notify;
+      }
+      break;
+    case GST_PLAY_SINK_TYPE_AUDIO:
+    case GST_PLAY_SINK_TYPE_AUDIO_RAW:
+      property = "current-audio";
+      playbin->current_audio = get_current_stream_number (playbin,
+          combine, channels);
+
+      if (playbin->audio_pending_flush_finish) {
+        playbin->audio_pending_flush_finish = FALSE;
+        GST_PLAY_BIN3_UNLOCK (playbin);
+        gst_play_bin3_send_custom_event (GST_OBJECT (combiner),
+            "playsink-custom-audio-flush-finish");
+        goto notify;
+      }
+      break;
+    case GST_PLAY_SINK_TYPE_TEXT:
+      property = "current-text";
+      playbin->current_text = get_current_stream_number (playbin,
+          combine, channels);
+
+      if (playbin->text_pending_flush_finish) {
+        playbin->text_pending_flush_finish = FALSE;
+        GST_PLAY_BIN3_UNLOCK (playbin);
+        gst_play_bin3_send_custom_event (GST_OBJECT (combiner),
+            "playsink-custom-subtitle-flush-finish");
+        goto notify;
+      }
+      break;
+    default:
+      property = NULL;
+  }
+  GST_PLAY_BIN3_UNLOCK (playbin);
+
+notify:
+  if (property)
+    g_object_notify (G_OBJECT (playbin), property);
+}
+
+static GstCaps *
+update_video_multiview_caps (GstPlayBin3 * playbin, GstCaps * caps)
+{
+  GstVideoMultiviewMode mv_mode;
+  GstVideoMultiviewMode cur_mv_mode;
+  GstVideoMultiviewFlags mv_flags, cur_mv_flags;
+  GstStructure *s;
+  const gchar *mview_mode_str;
+  GstCaps *out_caps;
+
+  GST_OBJECT_LOCK (playbin);
+  mv_mode = (GstVideoMultiviewMode) playbin->multiview_mode;
+  mv_flags = playbin->multiview_flags;
+  GST_OBJECT_UNLOCK (playbin);
+
+  if (mv_mode == GST_VIDEO_MULTIVIEW_MODE_NONE)
+    return NULL;
+
+  cur_mv_mode = GST_VIDEO_MULTIVIEW_MODE_NONE;
+  cur_mv_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
+
+  s = gst_caps_get_structure (caps, 0);
+
+  gst_structure_get_flagset (s, "multiview-flags", &cur_mv_flags, NULL);
+  if ((mview_mode_str = gst_structure_get_string (s, "multiview-mode")))
+    cur_mv_mode = gst_video_multiview_mode_from_caps_string (mview_mode_str);
+
+  /* We can't override an existing annotated multiview mode, except
+   * maybe (in the future) we could change some flags. */
+  if ((gint) cur_mv_mode > GST_VIDEO_MULTIVIEW_MAX_FRAME_PACKING) {
+    GST_INFO_OBJECT (playbin, "Cannot override existing multiview mode");
+    return NULL;
+  }
+
+  mview_mode_str = gst_video_multiview_mode_to_caps_string (mv_mode);
+  g_assert (mview_mode_str != NULL);
+  out_caps = gst_caps_copy (caps);
+  s = gst_caps_get_structure (out_caps, 0);
+
+  gst_structure_set (s, "multiview-mode", G_TYPE_STRING, mview_mode_str,
+      "multiview-flags", GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, mv_flags,
+      GST_FLAG_SET_MASK_EXACT, NULL);
+
+  return out_caps;
+}
+
+static GstPadProbeReturn
+_decodebin_event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer udata)
+{
+  GstPadProbeReturn ret = GST_PAD_PROBE_OK;
+  GstPlayBin3 *playbin = (GstPlayBin3 *) udata;
+  GstEvent *event = GST_PAD_PROBE_INFO_DATA (info);
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_CAPS:{
+      GstCaps *caps = NULL;
+      const GstStructure *s;
+      const gchar *name;
+
+      gst_event_parse_caps (event, &caps);
+      /* If video caps, check if we should override multiview flags */
+      s = gst_caps_get_structure (caps, 0);
+      name = gst_structure_get_name (s);
+      if (g_str_has_prefix (name, "video/")) {
+        caps = update_video_multiview_caps (playbin, caps);
+        if (caps) {
+          gst_event_unref (event);
+          event = gst_event_new_caps (caps);
+          GST_PAD_PROBE_INFO_DATA (info) = event;
+          gst_caps_unref (caps);
+        }
+      }
+      break;
+    }
+    default:
+      break;
+  }
+
+  return ret;
+}
+
+/* this function is called when a new pad is added to decodebin. We check the
+ * type of the pad and add it to the combiner element
+ */
+static void
+pad_added_cb (GstElement * decodebin, GstPad * pad, GstPlayBin3 * playbin)
+{
+  GstPad *sinkpad;
+  GstPadLinkReturn res;
+  GstSourceCombine *combine = NULL;
+  GstStreamType stream_type;
+  gint pb_stream_type = -1;
+  GstElement *custom_combiner = NULL;
+  gulong event_probe_handler;
+  gchar *pad_name;
+
+  GST_PLAY_BIN3_SHUTDOWN_LOCK (playbin, shutdown);
+
+  pad_name = gst_object_get_name (GST_OBJECT (pad));
+
+  GST_DEBUG_OBJECT (playbin, "decoded pad %s:%s added",
+      GST_DEBUG_PAD_NAME (pad));
+
+  /* major type of the pad, this determines the combiner to use,
+     try exact match first */
+  if (g_str_has_prefix (pad_name, "video")) {
+    stream_type = GST_STREAM_TYPE_VIDEO;
+    pb_stream_type = PLAYBIN_STREAM_VIDEO;
+    custom_combiner = playbin->video_stream_combiner;
+  } else if (g_str_has_prefix (pad_name, "audio")) {
+    stream_type = GST_STREAM_TYPE_AUDIO;
+    pb_stream_type = PLAYBIN_STREAM_AUDIO;
+    custom_combiner = playbin->audio_stream_combiner;
+  } else if (g_str_has_prefix (pad_name, "text")) {
+    stream_type = GST_STREAM_TYPE_TEXT;
+    pb_stream_type = PLAYBIN_STREAM_TEXT;
+    custom_combiner = playbin->text_stream_combiner;
+  }
+
+  g_free (pad_name);
+
+  /* no stream type found for the media type, don't bother linking it to a
+   * combiner. This will leave the pad unlinked and thus ignored. */
+  if (pb_stream_type < 0) {
+    GST_PLAY_BIN3_SHUTDOWN_UNLOCK (playbin);
+    goto unknown_type;
+  }
+
+  combine = &playbin->combiner[pb_stream_type];
+
+  if (custom_combiner && combine->combiner == NULL) {
+    combine->combiner = custom_combiner;
+    /* find out which properties the stream combiner supports */
+    combine->has_active_pad =
+        g_object_class_find_property (G_OBJECT_GET_CLASS (combine->combiner),
+        "active-pad") != NULL;
+
+    if (!custom_combiner) {
+      /* sync-mode=1, use clock */
+      if (combine->type == GST_PLAY_SINK_TYPE_TEXT)
+        g_object_set (combine->combiner, "sync-streams", TRUE,
+            "sync-mode", 1, "cache-buffers", TRUE, NULL);
+      else
+        g_object_set (combine->combiner, "sync-streams", TRUE, NULL);
+    }
+
+    if (combine->has_active_pad)
+      g_signal_connect (combine->combiner, "notify::active-pad",
+          G_CALLBACK (combiner_active_pad_changed), playbin);
+
+    GST_DEBUG_OBJECT (playbin, "adding new stream combiner %p",
+        combine->combiner);
+    gst_element_set_state (combine->combiner, GST_STATE_PAUSED);
+    gst_bin_add (GST_BIN_CAST (playbin), combine->combiner);
+  }
+
+  GST_PLAY_BIN3_SHUTDOWN_UNLOCK (playbin);
+
+  if (combine->srcpad == NULL) {
+    if (combine->combiner) {
+      /* save source pad of the combiner */
+      combine->srcpad = gst_element_get_static_pad (combine->combiner, "src");
+    } else {
+      /* no combiner, use the pad as the source pad then */
+      combine->srcpad = gst_object_ref (pad);
+    }
+
+    /* block the combiner srcpad. It's possible that multiple source elements
+     * pushing data into the combiners before we have a chance to collect all
+     * streams and connect the sinks, resulting in not-linked errors. After we
+     * configure the sinks we will unblock them all. */
+    GST_DEBUG_OBJECT (playbin, "blocking %" GST_PTR_FORMAT, combine->srcpad);
+    combine->block_id =
+        gst_pad_add_probe (combine->srcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
+        block_serialized_data_cb, NULL, NULL);
+  }
+
+  /* get sinkpad for the new stream */
+  if (combine->combiner) {
+    if ((sinkpad = gst_element_get_request_pad (combine->combiner, "sink_%u"))) {
+      GST_DEBUG_OBJECT (playbin, "got pad %s:%s from combiner",
+          GST_DEBUG_PAD_NAME (sinkpad));
+
+      /* find out which properties the sink pad supports */
+      combine->has_always_ok =
+          g_object_class_find_property (G_OBJECT_GET_CLASS (sinkpad),
+          "always-ok") != NULL;
+
+      /* store the combiner for the pad */
+      g_object_set_data (G_OBJECT (sinkpad), "playbin.combine", combine);
+
+      /* store the pad in the array */
+      GST_DEBUG_OBJECT (playbin, "pad %p added to array", sinkpad);
+      g_ptr_array_add (combine->channels, sinkpad);
+
+      res = gst_pad_link (pad, sinkpad);
+      if (GST_PAD_LINK_FAILED (res))
+        goto link_failed;
+
+      /* store combiner pad so we can release it */
+      g_object_set_data (G_OBJECT (pad), "playbin.sinkpad", sinkpad);
+
+      GST_DEBUG_OBJECT (playbin, "linked pad %s:%s to combiner %p",
+          GST_DEBUG_PAD_NAME (pad), combine->combiner);
+    } else {
+      goto request_pad_failed;
+    }
+  } else {
+    /* no combiner, don't configure anything, we'll link the new pad directly to
+     * the sink. */
+    sinkpad = NULL;
+
+    /* store the combiner for the pad */
+    g_object_set_data (G_OBJECT (pad), "playbin.combine", combine);
+  }
+
+  event_probe_handler =
+      gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
+      _decodebin_event_probe, playbin, NULL);
+  g_object_set_data (G_OBJECT (pad), "playbin.event_probe_id",
+      ULONG_TO_POINTER (event_probe_handler));
+
+  playbin->active_stream_types |= stream_type;
+
+  /* If we're expecting either audio or video,
+   * wait for them to appear before configuring playsink */
+  if ((playbin->selected_stream_types & ~playbin->active_stream_types &
+          (GST_STREAM_TYPE_VIDEO | GST_STREAM_TYPE_AUDIO))
+      == 0) {
+    no_more_pads_cb (decodebin, playbin);
+  } else {
+    GST_LOG_OBJECT (playbin, "Active stream types 0x%x, want 0x%x. Waiting",
+        playbin->active_stream_types, playbin->selected_stream_types);
+  }
+
+  return;
+
+  /* ERRORS */
+unknown_type:
+  GST_DEBUG_OBJECT (playbin, "Ignoring pad with unknown type");
+  return;
+
+link_failed:
+  {
+    GST_ERROR_OBJECT (playbin,
+        "failed to link pad %s:%s to combiner, reason %s (%d)",
+        GST_DEBUG_PAD_NAME (pad), gst_pad_link_get_name (res), res);
+    return;
+  }
+request_pad_failed:
+  GST_ELEMENT_ERROR (playbin, CORE, PAD,
+      ("Internal playbin error."),
+      ("Failed to get request pad from combiner %p.", combine->combiner));
+  return;
+shutdown:
+  {
+    GST_DEBUG ("ignoring, we are shutting down. Pad will be left unlinked");
+    /* not going to done as we didn't request the caps */
+    return;
+  }
+}
+
+/* called when a pad is removed from the decodebin. We unlink the pad from
+ * the combiner. This will make the combiner select a new pad. */
+static void
+pad_removed_cb (GstElement * decodebin, GstPad * pad, GstPlayBin3 * playbin)
+{
+  GstPad *peer;
+  GstElement *combiner;
+  GstSourceCombine *combine;
+  gulong event_probe_handler;
+
+  GST_DEBUG_OBJECT (playbin,
+      "decoded pad %s:%s removed", GST_DEBUG_PAD_NAME (pad));
+
+  GST_PLAY_BIN3_LOCK (playbin);
+
+  if ((event_probe_handler =
+          POINTER_TO_ULONG (g_object_get_data (G_OBJECT (pad),
+                  "playbin.event_probe_id")))) {
+    gst_pad_remove_probe (pad, event_probe_handler);
+    g_object_set_data (G_OBJECT (pad), "playbin.event_probe_id", NULL);
+  }
+
+  if ((combine = g_object_get_data (G_OBJECT (pad), "playbin.combine"))) {
+    g_assert (combine->combiner == NULL);
+    g_assert (combine->srcpad == pad);
+    source_combine_remove_pads (playbin, combine);
+    goto exit;
+  }
+
+  /* get the combiner sinkpad */
+  if (!(peer = g_object_get_data (G_OBJECT (pad), "playbin.sinkpad")))
+    goto not_linked;
+
+  /* unlink the pad now (can fail, the pad is unlinked before it's removed) */
+  gst_pad_unlink (pad, peer);
+
+  /* get combiner */
+  combiner = GST_ELEMENT_CAST (gst_pad_get_parent (peer));
+  g_assert (combiner != NULL);
+
+  if ((combine = g_object_get_data (G_OBJECT (peer), "playbin.combine"))) {
+    /* remove the pad from the array */
+    g_ptr_array_remove (combine->channels, peer);
+    GST_DEBUG_OBJECT (playbin, "pad %p removed from array", peer);
+
+    if (!combine->channels->len && combine->combiner) {
+      GST_DEBUG_OBJECT (playbin, "all combiner sinkpads removed");
+      GST_DEBUG_OBJECT (playbin, "removing combiner %p", combine->combiner);
+      source_combine_remove_pads (playbin, combine);
+      gst_element_set_state (combine->combiner, GST_STATE_NULL);
+      gst_bin_remove (GST_BIN_CAST (playbin), combine->combiner);
+      combine->combiner = NULL;
+    }
+  }
+
+  /* release the pad to the combiner, this will make the combiner choose a new
+   * pad. */
+  gst_element_release_request_pad (combiner, peer);
+  gst_object_unref (peer);
+
+  gst_object_unref (combiner);
+exit:
+  GST_PLAY_BIN3_UNLOCK (playbin);
+
+  return;
+
+  /* ERRORS */
+not_linked:
+  {
+    GST_DEBUG_OBJECT (playbin, "pad not linked");
+    goto exit;
+  }
+}
+
+
+static gint
+select_stream_cb (GstElement * decodebin, GstStreamCollection * collection,
+    GstStream * stream, GstPlayBin3 * playbin)
+{
+  GstStreamType stype = gst_stream_get_stream_type (stream);
+  GstElement *combiner = NULL;
+
+  switch (stype) {
+    case GST_STREAM_TYPE_AUDIO:
+      combiner = playbin->audio_stream_combiner;
+      break;
+    case GST_STREAM_TYPE_VIDEO:
+      combiner = playbin->video_stream_combiner;
+      break;
+    case GST_STREAM_TYPE_TEXT:
+      combiner = playbin->text_stream_combiner;
+      break;
+    default:
+      break;
+  }
+
+  if (combiner) {
+    GST_DEBUG_OBJECT (playbin, "Got a combiner, requesting stream activation");
+    return 1;
+  }
+
+  /* Let decodebin3 decide otherwise */
+  return -1;
+}
+
+/* we get called when all pads are available and we must connect the sinks to
+ * them.
+ * The main purpose of the code is to see if we have video/audio and subtitles
+ * and pick the right pipelines to display them.
+ *
+ * The combiners installed on the group tell us about the presence of
+ * audio/video and subtitle streams. This allows us to see if we need
+ * visualisation, video or/and audio.
+ */
+static void
+no_more_pads_cb (GstElement * decodebin, GstPlayBin3 * playbin)
+{
+  GstSourceGroup *group;
+  GstPadLinkReturn res;
+  gint i;
+  gboolean configure;
+
+  GST_DEBUG_OBJECT (playbin, "no more pads");
+
+  GST_PLAY_BIN3_SHUTDOWN_LOCK (playbin, shutdown);
+
+  GST_PLAY_BIN3_LOCK (playbin);
+  group = playbin->curr_group;
+
+  for (i = 0; i < PLAYBIN_STREAM_LAST; i++) {
+    GstSourceCombine *combine = &playbin->combiner[i];
+
+    /* check if the specific media type was detected and thus has a combiner
+     * created for it. If there is the media type, get a sinkpad from the sink
+     * and link it. We only do this if we have not yet requested the sinkpad
+     * before. */
+    if (combine->srcpad && combine->sinkpad == NULL) {
+      GST_DEBUG_OBJECT (playbin, "requesting new sink pad %d", combine->type);
+      combine->sinkpad =
+          gst_play_sink_request_pad (playbin->playsink, combine->type);
+      gst_object_ref (combine->sinkpad);
+    } else if (combine->srcpad && combine->sinkpad) {
+      GST_DEBUG_OBJECT (playbin, "re-using sink pad %d", combine->type);
+    } else if (combine->sinkpad && combine->srcpad == NULL) {
+      GST_DEBUG_OBJECT (playbin, "releasing sink pad %d", combine->type);
+      gst_play_sink_release_pad (playbin->playsink, combine->sinkpad);
+      gst_object_unref (combine->sinkpad);
+      combine->sinkpad = NULL;
+    }
+    if (combine->sinkpad && combine->srcpad &&
+        !gst_pad_is_linked (combine->srcpad)) {
+      res = gst_pad_link (combine->srcpad, combine->sinkpad);
+      GST_DEBUG_OBJECT (playbin, "linked type %s, result: %d",
+          combine->media_type, res);
+      if (res != GST_PAD_LINK_OK) {
+        GST_ELEMENT_ERROR (playbin, CORE, PAD,
+            ("Internal playbin error."),
+            ("Failed to link combiner to sink. Error %d", res));
+      }
+    }
+  }
+  GST_PLAY_BIN3_UNLOCK (playbin);
+
+  GST_SOURCE_GROUP_LOCK (group);
+  GST_DEBUG_OBJECT (playbin, "pending %d > %d", group->pending,
+      group->pending - 1);
+
+  if (group->pending > 0)
+    group->pending--;
+
+  if (group->pending == 0) {
+    /* we are the last group to complete, we will configure the output and then
+     * signal the other waiters. */
+    GST_LOG_OBJECT (playbin, "last group complete");
+    configure = TRUE;
+  } else {
+    GST_LOG_OBJECT (playbin, "have more pending groups");
+    configure = FALSE;
+  }
+  GST_SOURCE_GROUP_UNLOCK (group);
+
+  if (configure) {
+    /* if we have custom sinks, configure them now */
+    GST_SOURCE_GROUP_LOCK (group);
+
+    if (group->audio_sink) {
+      GST_INFO_OBJECT (playbin, "setting custom audio sink %" GST_PTR_FORMAT,
+          group->audio_sink);
+      gst_play_sink_set_sink (playbin->playsink, GST_PLAY_SINK_TYPE_AUDIO,
+          group->audio_sink);
+    }
+
+    if (group->video_sink) {
+      GST_INFO_OBJECT (playbin, "setting custom video sink %" GST_PTR_FORMAT,
+          group->video_sink);
+      gst_play_sink_set_sink (playbin->playsink, GST_PLAY_SINK_TYPE_VIDEO,
+          group->video_sink);
+    }
+
+    if (group->text_sink) {
+      GST_INFO_OBJECT (playbin, "setting custom text sink %" GST_PTR_FORMAT,
+          group->text_sink);
+      gst_play_sink_set_sink (playbin->playsink, GST_PLAY_SINK_TYPE_TEXT,
+          group->text_sink);
+    }
+
+    GST_SOURCE_GROUP_UNLOCK (group);
+
+    /* signal the other combiners that they can continue now. */
+    GST_PLAY_BIN3_LOCK (playbin);
+    /* unblock all combiners */
+    for (i = 0; i < PLAYBIN_STREAM_LAST; i++) {
+      GstSourceCombine *combine = &playbin->combiner[i];
+
+      if (combine->srcpad) {
+        GST_DEBUG_OBJECT (playbin, "unblocking %" GST_PTR_FORMAT,
+            combine->srcpad);
+        if (combine->block_id) {
+          gst_pad_remove_probe (combine->srcpad, combine->block_id);
+          combine->block_id = 0;
+        }
+      }
+    }
+    GST_PLAY_BIN3_UNLOCK (playbin);
+    gst_play_sink_reconfigure (playbin->playsink);
+  }
+
+  GST_PLAY_BIN3_SHUTDOWN_UNLOCK (playbin);
+
+  if (configure) {
+    do_async_done (playbin);
+  }
+
+  return;
+
+shutdown:
+  {
+    GST_DEBUG ("ignoring, we are shutting down");
+    /* Request a flushing pad from playsink that we then link to the combiner.
+     * Then we unblock the combiners so that they stop with a WRONG_STATE
+     * instead of a NOT_LINKED error.
+     */
+    GST_PLAY_BIN3_LOCK (playbin);
+    for (i = 0; i < PLAYBIN_STREAM_LAST; i++) {
+      GstSourceCombine *combine = &playbin->combiner[i];
+
+      if (combine->srcpad) {
+        if (combine->sinkpad == NULL) {
+          GST_DEBUG_OBJECT (playbin, "requesting new flushing sink pad");
+          combine->sinkpad =
+              gst_play_sink_request_pad (playbin->playsink,
+              GST_PLAY_SINK_TYPE_FLUSHING);
+          gst_object_ref (combine->sinkpad);
+          res = gst_pad_link (combine->srcpad, combine->sinkpad);
+          GST_DEBUG_OBJECT (playbin, "linked flushing, result: %d", res);
+        }
+        GST_DEBUG_OBJECT (playbin, "unblocking %" GST_PTR_FORMAT,
+            combine->srcpad);
+        if (combine->block_id) {
+          gst_pad_remove_probe (combine->srcpad, combine->block_id);
+          combine->block_id = 0;
+        }
+      }
+    }
+    GST_PLAY_BIN3_UNLOCK (playbin);
+    return;
+  }
+}
+
+#if 0
+static void
+drained_cb (GstElement * decodebin, GstSourceGroup * group)
+{
+  GstPlayBin3 *playbin;
+
+  playbin = group->playbin;
+
+  GST_DEBUG_OBJECT (playbin, "about to finish in group %p", group);
+
+  /* after this call, we should have a next group to activate or we EOS */
+  g_signal_emit (G_OBJECT (playbin),
+      gst_play_bin3_signals[SIGNAL_ABOUT_TO_FINISH], 0, NULL);
+
+  /* now activate the next group. If the app did not set a uri, this will
+   * fail and we can do EOS */
+  setup_next_source (playbin, GST_STATE_PAUSED);
+}
+#endif
+
+/* Like gst_element_factory_can_sink_any_caps() but doesn't
+ * allow ANY caps on the sinkpad template */
+static gboolean
+_factory_can_sink_caps (GstElementFactory * factory, GstCaps * caps)
+{
+  const GList *templs;
+
+  templs = gst_element_factory_get_static_pad_templates (factory);
+
+  while (templs) {
+    GstStaticPadTemplate *templ = (GstStaticPadTemplate *) templs->data;
+
+    if (templ->direction == GST_PAD_SINK) {
+      GstCaps *templcaps = gst_static_caps_get (&templ->static_caps);
+
+      if (!gst_caps_is_any (templcaps)
+          && gst_caps_is_subset (caps, templcaps)) {
+        gst_caps_unref (templcaps);
+        return TRUE;
+      }
+      gst_caps_unref (templcaps);
+    }
+    templs = g_list_next (templs);
+  }
+
+  return FALSE;
+}
+
+static void
+avelements_free (gpointer avelement)
+{
+  GstAVElement *elm = (GstAVElement *) avelement;
+
+  if (elm->dec)
+    gst_object_unref (elm->dec);
+  if (elm->sink)
+    gst_object_unref (elm->sink);
+  g_slice_free (GstAVElement, elm);
+}
+
+static gint
+avelement_compare_decoder (gconstpointer p1, gconstpointer p2,
+    gpointer user_data)
+{
+  GstAVElement *v1, *v2;
+
+  v1 = (GstAVElement *) p1;
+  v2 = (GstAVElement *) p2;
+
+  return strcmp (GST_OBJECT_NAME (v1->dec), GST_OBJECT_NAME (v2->dec));
+}
+
+static gint
+avelement_lookup_decoder (gconstpointer p1, gconstpointer p2,
+    gpointer user_data)
+{
+  GstAVElement *v1;
+  GstElementFactory *f2;
+
+  v1 = (GstAVElement *) p1;
+  f2 = (GstElementFactory *) p2;
+
+  return strcmp (GST_OBJECT_NAME (v1->dec), GST_OBJECT_NAME (f2));
+}
+
+static gint
+avelement_compare (gconstpointer p1, gconstpointer p2)
+{
+  GstAVElement *v1, *v2;
+  GstPluginFeature *fd1, *fd2, *fs1, *fs2;
+  gint64 diff, v1_rank, v2_rank;
+
+  v1 = (GstAVElement *) p1;
+  v2 = (GstAVElement *) p2;
+
+  fd1 = (GstPluginFeature *) v1->dec;
+  fd2 = (GstPluginFeature *) v2->dec;
+
+  /* If both have a sink, we also compare their ranks */
+  if (v1->sink && v2->sink) {
+    fs1 = (GstPluginFeature *) v1->sink;
+    fs2 = (GstPluginFeature *) v2->sink;
+    v1_rank =
+        gst_plugin_feature_get_rank (fd1) * gst_plugin_feature_get_rank (fs1);
+    v2_rank =
+        gst_plugin_feature_get_rank (fd2) * gst_plugin_feature_get_rank (fs2);
+  } else {
+    v1_rank = gst_plugin_feature_get_rank (fd1);
+    v2_rank = gst_plugin_feature_get_rank (fd2);
+    fs1 = fs2 = NULL;
+  }
+
+  /* comparison based on the rank */
+  diff = v2_rank - v1_rank;
+  if (diff < 0)
+    return -1;
+  else if (diff > 0)
+    return 1;
+
+  /* comparison based on number of common caps features */
+  diff = v2->n_comm_cf - v1->n_comm_cf;
+  if (diff != 0)
+    return diff;
+
+  if (fs1 && fs2) {
+    /* comparison based on the name of sink elements */
+    diff = strcmp (GST_OBJECT_NAME (fs1), GST_OBJECT_NAME (fs2));
+    if (diff != 0)
+      return diff;
+  }
+
+  /* comparison based on the name of decoder elements */
+  return strcmp (GST_OBJECT_NAME (fd1), GST_OBJECT_NAME (fd2));
+}
+
+static GSequence *
+avelements_create (GstPlayBin3 * playbin, gboolean isaudioelement)
+{
+  GstElementFactory *d_factory, *s_factory;
+  GList *dec_list, *sink_list, *dl, *sl;
+  GSequence *ave_seq = NULL;
+  GstAVElement *ave;
+  guint n_common_cf = 0;
+
+  if (isaudioelement) {
+    sink_list = gst_element_factory_list_get_elements
+        (GST_ELEMENT_FACTORY_TYPE_SINK |
+        GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO, GST_RANK_MARGINAL);
+    dec_list =
+        gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_DECODER
+        | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO, GST_RANK_MARGINAL);
+  } else {
+    sink_list = gst_element_factory_list_get_elements
+        (GST_ELEMENT_FACTORY_TYPE_SINK |
+        GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO |
+        GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE, GST_RANK_MARGINAL);
+
+    dec_list =
+        gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_DECODER
+        | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO |
+        GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE, GST_RANK_MARGINAL);
+  }
+
+  /* create a list of audio/video elements. Each element in the list
+   * is holding an audio/video decoder and an audio/video sink in which
+   * the decoders srcpad template caps and sink element's sinkpad template
+   * caps are compatible */
+  dl = dec_list;
+  sl = sink_list;
+
+  ave_seq = g_sequence_new ((GDestroyNotify) avelements_free);
+
+  for (; dl; dl = dl->next) {
+    d_factory = (GstElementFactory *) dl->data;
+    for (; sl; sl = sl->next) {
+      s_factory = (GstElementFactory *) sl->data;
+
+      n_common_cf =
+          gst_playback_utils_get_n_common_capsfeatures (d_factory, s_factory,
+          gst_play_bin3_get_flags (playbin), isaudioelement);
+      if (n_common_cf < 1)
+        continue;
+
+      ave = g_slice_new (GstAVElement);
+      ave->dec = gst_object_ref (d_factory);
+      ave->sink = gst_object_ref (s_factory);
+      ave->n_comm_cf = n_common_cf;
+      g_sequence_append (ave_seq, ave);
+    }
+    sl = sink_list;
+  }
+  g_sequence_sort (ave_seq, (GCompareDataFunc) avelement_compare_decoder, NULL);
+
+  gst_plugin_feature_list_free (dec_list);
+  gst_plugin_feature_list_free (sink_list);
+
+  return ave_seq;
+}
+
+static gboolean
+avelement_iter_is_equal (GSequenceIter * iter, GstElementFactory * factory)
+{
+  GstAVElement *ave;
+
+  if (!iter)
+    return FALSE;
+
+  ave = g_sequence_get (iter);
+  if (!ave)
+    return FALSE;
+
+  return strcmp (GST_OBJECT_NAME (ave->dec), GST_OBJECT_NAME (factory)) == 0;
+}
+
+static GList *
+create_decoders_list (GList * factory_list, GSequence * avelements)
+{
+  GList *dec_list = NULL, *tmp;
+  GList *ave_list = NULL;
+  GList *ave_free_list = NULL;
+  GstAVElement *ave, *best_ave;
+
+  g_return_val_if_fail (factory_list != NULL, NULL);
+  g_return_val_if_fail (avelements != NULL, NULL);
+
+  for (tmp = factory_list; tmp; tmp = tmp->next) {
+    GstElementFactory *factory = (GstElementFactory *) tmp->data;
+
+    /* if there are parsers or sink elements, add them first */
+    if (gst_element_factory_list_is_type (factory,
+            GST_ELEMENT_FACTORY_TYPE_PARSER) ||
+        gst_element_factory_list_is_type (factory,
+            GST_ELEMENT_FACTORY_TYPE_SINK)) {
+      dec_list = g_list_prepend (dec_list, gst_object_ref (factory));
+    } else {
+      GSequenceIter *seq_iter;
+
+      seq_iter =
+          g_sequence_lookup (avelements, factory,
+          (GCompareDataFunc) avelement_lookup_decoder, NULL);
+      if (!seq_iter) {
+        GstAVElement *ave = g_slice_new0 (GstAVElement);
+
+        ave->dec = factory;
+        ave->sink = NULL;
+        /* There's at least raw */
+        ave->n_comm_cf = 1;
+
+        ave_list = g_list_prepend (ave_list, ave);
+
+        /* We need to free these later */
+        ave_free_list = g_list_prepend (ave_free_list, ave);
+        continue;
+      }
+
+      /* Go to first iter with that decoder */
+      do {
+        GSequenceIter *tmp_seq_iter;
+
+        tmp_seq_iter = g_sequence_iter_prev (seq_iter);
+        if (!avelement_iter_is_equal (tmp_seq_iter, factory))
+          break;
+        seq_iter = tmp_seq_iter;
+      } while (!g_sequence_iter_is_begin (seq_iter));
+
+      /* Get the best ranked GstAVElement for that factory */
+      best_ave = NULL;
+      while (!g_sequence_iter_is_end (seq_iter)
+          && avelement_iter_is_equal (seq_iter, factory)) {
+        ave = g_sequence_get (seq_iter);
+
+        if (!best_ave || avelement_compare (ave, best_ave) < 0)
+          best_ave = ave;
+
+        seq_iter = g_sequence_iter_next (seq_iter);
+      }
+      ave_list = g_list_prepend (ave_list, best_ave);
+    }
+  }
+
+  /* Sort all GstAVElements by their relative ranks and insert
+   * into the decoders list */
+  ave_list = g_list_sort (ave_list, (GCompareFunc) avelement_compare);
+  for (tmp = ave_list; tmp; tmp = tmp->next) {
+    ave = (GstAVElement *) tmp->data;
+    dec_list = g_list_prepend (dec_list, gst_object_ref (ave->dec));
+  }
+  g_list_free (ave_list);
+  gst_plugin_feature_list_free (factory_list);
+
+  for (tmp = ave_free_list; tmp; tmp = tmp->next)
+    g_slice_free (GstAVElement, tmp->data);
+  g_list_free (ave_free_list);
+
+  dec_list = g_list_reverse (dec_list);
+
+  return dec_list;
+}
+
+/* Called when we must provide a list of factories to plug to @pad with @caps.
+ * We first check if we have a sink that can handle the format and if we do, we
+ * return NULL, to expose the pad. If we have no sink (or the sink does not
+ * work), we return the list of elements that can connect. */
+static GValueArray *
+autoplug_factories_cb (GstElement * decodebin, GstPad * pad,
+    GstCaps * caps, GstSourceGroup * group)
+{
+  GstPlayBin3 *playbin;
+  GList *factory_list, *tmp;
+  GValueArray *result;
+  gboolean unref_caps = FALSE;
+  gboolean isaudiodeclist = FALSE;
+  gboolean isvideodeclist = FALSE;
+
+  if (!caps) {
+    caps = gst_caps_new_any ();
+    unref_caps = TRUE;
+  }
+
+  playbin = group->playbin;
+
+  GST_DEBUG_OBJECT (playbin, "factories group %p for %s:%s, %" GST_PTR_FORMAT,
+      group, GST_DEBUG_PAD_NAME (pad), caps);
+
+  /* filter out the elements based on the caps. */
+  g_mutex_lock (&playbin->elements_lock);
+  gst_play_bin3_update_elements_list (playbin);
+  factory_list =
+      gst_element_factory_list_filter (playbin->elements, caps, GST_PAD_SINK,
+      gst_caps_is_fixed (caps));
+  g_mutex_unlock (&playbin->elements_lock);
+
+  GST_DEBUG_OBJECT (playbin, "found factories %p", factory_list);
+  GST_PLUGIN_FEATURE_LIST_DEBUG (factory_list);
+
+  /* check whether the caps are asking for a list of audio/video decoders */
+  tmp = factory_list;
+  if (!gst_caps_is_any (caps)) {
+    for (; tmp; tmp = tmp->next) {
+      GstElementFactory *factory = (GstElementFactory *) tmp->data;
+
+      isvideodeclist = gst_element_factory_list_is_type (factory,
+          GST_ELEMENT_FACTORY_TYPE_DECODER |
+          GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO |
+          GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE);
+      isaudiodeclist = gst_element_factory_list_is_type (factory,
+          GST_ELEMENT_FACTORY_TYPE_DECODER |
+          GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO);
+
+      if (isaudiodeclist || isvideodeclist)
+        break;
+    }
+  }
+
+  if (isaudiodeclist || isvideodeclist) {
+    GSequence **ave_list;
+    if (isaudiodeclist)
+      ave_list = &playbin->aelements;
+    else
+      ave_list = &playbin->velements;
+
+    g_mutex_lock (&playbin->elements_lock);
+    /* sort factory_list based on the GstAVElement list priority */
+    factory_list = create_decoders_list (factory_list, *ave_list);
+    g_mutex_unlock (&playbin->elements_lock);
+  }
+
+  /* 2 additional elements for the already set audio/video sinks */
+  result = g_value_array_new (g_list_length (factory_list) + 2);
+
+  /* Check if we already have an audio/video sink and if this is the case
+   * put it as the first element of the array */
+  if (group->audio_sink) {
+    GstElementFactory *factory = gst_element_get_factory (group->audio_sink);
+
+    if (factory && _factory_can_sink_caps (factory, caps)) {
+      GValue val = { 0, };
+
+      g_value_init (&val, G_TYPE_OBJECT);
+      g_value_set_object (&val, factory);
+      result = g_value_array_append (result, &val);
+      g_value_unset (&val);
+    }
+  }
+
+  if (group->video_sink) {
+    GstElementFactory *factory = gst_element_get_factory (group->video_sink);
+
+    if (factory && _factory_can_sink_caps (factory, caps)) {
+      GValue val = { 0, };
+
+      g_value_init (&val, G_TYPE_OBJECT);
+      g_value_set_object (&val, factory);
+      result = g_value_array_append (result, &val);
+      g_value_unset (&val);
+    }
+  }
+
+  for (tmp = factory_list; tmp; tmp = tmp->next) {
+    GstElementFactory *factory = GST_ELEMENT_FACTORY_CAST (tmp->data);
+    GValue val = { 0, };
+
+    if (group->audio_sink && gst_element_factory_list_is_type (factory,
+            GST_ELEMENT_FACTORY_TYPE_SINK |
+            GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO)) {
+      continue;
+    }
+    if (group->video_sink && gst_element_factory_list_is_type (factory,
+            GST_ELEMENT_FACTORY_TYPE_SINK | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO
+            | GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE)) {
+      continue;
+    }
+
+    g_value_init (&val, G_TYPE_OBJECT);
+    g_value_set_object (&val, factory);
+    g_value_array_append (result, &val);
+    g_value_unset (&val);
+  }
+  gst_plugin_feature_list_free (factory_list);
+
+  if (unref_caps)
+    gst_caps_unref (caps);
+
+  return result;
+}
+
+static void
+gst_play_bin3_set_context (GstElement * element, GstContext * context)
+{
+  GstPlayBin3 *playbin = GST_PLAY_BIN3 (element);
+
+  /* Proxy contexts to the sinks, they might not be in playsink yet */
+  GST_PLAY_BIN3_LOCK (playbin);
+  if (playbin->audio_sink)
+    gst_element_set_context (playbin->audio_sink, context);
+  if (playbin->video_sink)
+    gst_element_set_context (playbin->video_sink, context);
+  if (playbin->text_sink)
+    gst_element_set_context (playbin->text_sink, context);
+
+  GST_SOURCE_GROUP_LOCK (playbin->curr_group);
+
+  if (playbin->curr_group->audio_sink)
+    gst_element_set_context (playbin->curr_group->audio_sink, context);
+  if (playbin->curr_group->video_sink)
+    gst_element_set_context (playbin->curr_group->video_sink, context);
+  if (playbin->curr_group->text_sink)
+    gst_element_set_context (playbin->curr_group->text_sink, context);
+
+  GST_SOURCE_GROUP_UNLOCK (playbin->curr_group);
+  GST_PLAY_BIN3_UNLOCK (playbin);
+
+  GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
+}
+
+/* Pass sink messages to the application, e.g. NEED_CONTEXT messages */
+static void
+gst_play_bin3_update_context (GstPlayBin3 * playbin, GstContext * context)
+{
+  GList *l;
+  const gchar *context_type;
+
+  GST_OBJECT_LOCK (playbin);
+  context_type = gst_context_get_context_type (context);
+  for (l = playbin->contexts; l; l = l->next) {
+    GstContext *tmp = l->data;
+    const gchar *tmp_type = gst_context_get_context_type (tmp);
+
+    /* Always store newest context but never replace
+     * a persistent one by a non-persistent one */
+    if (strcmp (context_type, tmp_type) == 0 &&
+        (gst_context_is_persistent (context) ||
+            !gst_context_is_persistent (tmp))) {
+      gst_context_replace ((GstContext **) & l->data, context);
+      break;
+    }
+  }
+  /* Not found? Add */
+  if (l == NULL)
+    playbin->contexts =
+        g_list_prepend (playbin->contexts, gst_context_ref (context));
+  GST_OBJECT_UNLOCK (playbin);
+}
+
+static GstBusSyncReply
+activate_sink_bus_handler (GstBus * bus, GstMessage * msg,
+    GstPlayBin3 * playbin)
+{
+  if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
+    /* Only proxy errors from a fixed sink. If that fails we can just error out
+     * early as stuff will fail later anyway */
+    if (playbin->audio_sink
+        && gst_object_has_as_ancestor (GST_MESSAGE_SRC (msg),
+            GST_OBJECT_CAST (playbin->audio_sink)))
+      gst_element_post_message (GST_ELEMENT_CAST (playbin), msg);
+    else if (playbin->video_sink
+        && gst_object_has_as_ancestor (GST_MESSAGE_SRC (msg),
+            GST_OBJECT_CAST (playbin->video_sink)))
+      gst_element_post_message (GST_ELEMENT_CAST (playbin), msg);
+    else if (playbin->text_sink
+        && gst_object_has_as_ancestor (GST_MESSAGE_SRC (msg),
+            GST_OBJECT_CAST (playbin->text_sink)))
+      gst_element_post_message (GST_ELEMENT_CAST (playbin), msg);
+    else
+      gst_message_unref (msg);
+  } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_NEED_CONTEXT) {
+    const gchar *context_type;
+    GList *l;
+
+    gst_message_parse_context_type (msg, &context_type);
+    GST_OBJECT_LOCK (playbin);
+    for (l = playbin->contexts; l; l = l->next) {
+      GstContext *tmp = l->data;
+      const gchar *tmp_type = gst_context_get_context_type (tmp);
+
+      if (strcmp (context_type, tmp_type) == 0) {
+        gst_element_set_context (GST_ELEMENT (GST_MESSAGE_SRC (msg)), l->data);
+        break;
+      }
+    }
+    GST_OBJECT_UNLOCK (playbin);
+
+    /* Forward if we couldn't answer the message */
+    if (l == NULL) {
+      gst_element_post_message (GST_ELEMENT_CAST (playbin), msg);
+    } else {
+      gst_message_unref (msg);
+    }
+  } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_HAVE_CONTEXT) {
+    GstContext *context;
+
+    gst_message_parse_have_context (msg, &context);
+    gst_play_bin3_update_context (playbin, context);
+    gst_context_unref (context);
+
+    gst_element_post_message (GST_ELEMENT_CAST (playbin), msg);
+  } else {
+    gst_element_post_message (GST_ELEMENT_CAST (playbin), msg);
+  }
+
+  /* Doesn't really matter, nothing is using this bus */
+  return GST_BUS_DROP;
+}
+
+static gboolean
+activate_sink (GstPlayBin3 * playbin, GstElement * sink, gboolean * activated)
+{
+  GstState state;
+  GstBus *bus = NULL;
+  GstStateChangeReturn sret;
+  gboolean ret = FALSE;
+
+  if (activated)
+    *activated = FALSE;
+
+  GST_OBJECT_LOCK (sink);
+  state = GST_STATE (sink);
+  GST_OBJECT_UNLOCK (sink);
+  if (state >= GST_STATE_READY) {
+    ret = TRUE;
+    goto done;
+  }
+
+  if (!GST_OBJECT_PARENT (sink)) {
+    bus = gst_bus_new ();
+    gst_bus_set_sync_handler (bus,
+        (GstBusSyncHandler) activate_sink_bus_handler, playbin, NULL);
+    gst_element_set_bus (sink, bus);
+  }
+
+  sret = gst_element_set_state (sink, GST_STATE_READY);
+  if (sret == GST_STATE_CHANGE_FAILURE)
+    goto done;
+
+  if (activated)
+    *activated = TRUE;
+  ret = TRUE;
+
+done:
+  if (bus) {
+    gst_element_set_bus (sink, NULL);
+    gst_object_unref (bus);
+  }
+
+  return ret;
+}
+
+/* autoplug-continue decides, if a pad has raw caps that can be exposed
+ * directly or if further decoding is necessary. We use this to expose
+ * supported subtitles directly */
+
+/* FIXME 0.11: Remove the checks for ANY caps, a sink should specify
+ * explicitly the caps it supports and if it claims to support ANY
+ * caps it really should support everything */
+static gboolean
+autoplug_continue_cb (GstElement * element, GstPad * pad, GstCaps * caps,
+    GstSourceGroup * group)
+{
+  gboolean ret = TRUE;
+  GstPad *sinkpad = NULL;
+  gboolean activated_sink;
+
+  GST_SOURCE_GROUP_LOCK (group);
+
+  if (group->text_sink &&
+      activate_sink (group->playbin, group->text_sink, &activated_sink)) {
+    sinkpad = gst_element_get_static_pad (group->text_sink, "sink");
+    if (sinkpad) {
+      GstCaps *sinkcaps;
+
+      sinkcaps = gst_pad_query_caps (sinkpad, NULL);
+      if (!gst_caps_is_any (sinkcaps))
+        ret = !gst_pad_query_accept_caps (sinkpad, caps);
+      gst_caps_unref (sinkcaps);
+      gst_object_unref (sinkpad);
+    }
+    if (activated_sink)
+      gst_element_set_state (group->text_sink, GST_STATE_NULL);
+  } else {
+    GstCaps *subcaps = gst_subtitle_overlay_create_factory_caps ();
+    ret = !gst_caps_is_subset (caps, subcaps);
+    gst_caps_unref (subcaps);
+  }
+  /* If autoplugging can stop don't do additional checks */
+  if (!ret)
+    goto done;
+
+  if (group->audio_sink &&
+      activate_sink (group->playbin, group->audio_sink, &activated_sink)) {
+
+    sinkpad = gst_element_get_static_pad (group->audio_sink, "sink");
+    if (sinkpad) {
+      GstCaps *sinkcaps;
+
+      sinkcaps = gst_pad_query_caps (sinkpad, NULL);
+      if (!gst_caps_is_any (sinkcaps))
+        ret = !gst_pad_query_accept_caps (sinkpad, caps);
+      gst_caps_unref (sinkcaps);
+      gst_object_unref (sinkpad);
+    }
+    if (activated_sink)
+      gst_element_set_state (group->audio_sink, GST_STATE_NULL);
+  }
+  if (!ret)
+    goto done;
+
+  if (group->video_sink
+      && activate_sink (group->playbin, group->video_sink, &activated_sink)) {
+    sinkpad = gst_element_get_static_pad (group->video_sink, "sink");
+    if (sinkpad) {
+      GstCaps *sinkcaps;
+
+      sinkcaps = gst_pad_query_caps (sinkpad, NULL);
+      if (!gst_caps_is_any (sinkcaps))
+        ret = !gst_pad_query_accept_caps (sinkpad, caps);
+      gst_caps_unref (sinkcaps);
+      gst_object_unref (sinkpad);
+    }
+    if (activated_sink)
+      gst_element_set_state (group->video_sink, GST_STATE_NULL);
+  }
+
+done:
+  GST_SOURCE_GROUP_UNLOCK (group);
+
+  GST_DEBUG_OBJECT (group->playbin,
+      "continue autoplugging group %p for %s:%s, %" GST_PTR_FORMAT ": %d",
+      group, GST_DEBUG_PAD_NAME (pad), caps, ret);
+
+  return ret;
+}
+
+static gboolean
+sink_accepts_caps (GstPlayBin3 * playbin, GstElement * sink, GstCaps * caps)
+{
+  GstPad *sinkpad;
+
+  if ((sinkpad = gst_element_get_static_pad (sink, "sink"))) {
+    /* Got the sink pad, now let's see if the element actually does accept the
+     * caps that we have */
+    if (!gst_pad_query_accept_caps (sinkpad, caps)) {
+      gst_object_unref (sinkpad);
+      return FALSE;
+    }
+    gst_object_unref (sinkpad);
+  }
+
+  return TRUE;
+}
+
+/* We are asked to select an element. See if the next element to check
+ * is a sink. If this is the case, we see if the sink works by setting it to
+ * READY. If the sink works, we return SELECT_EXPOSE to make decodebin
+ * expose the raw pad so that we can setup the mixers. */
+static GstAutoplugSelectResult
+autoplug_select_cb (GstElement * decodebin, GstPad * pad,
+    GstCaps * caps, GstElementFactory * factory, GstSourceGroup * group)
+{
+  GstPlayBin3 *playbin;
+  GstElement *element;
+  const gchar *klass;
+  GstPlaySinkType type;
+  GstElement **sinkp;
+  GList *ave_list = NULL, *l;
+  GstAVElement *ave = NULL;
+  GSequence *ave_seq = NULL;
+  GSequenceIter *seq_iter;
+
+  playbin = group->playbin;
+
+  GST_DEBUG_OBJECT (playbin, "select group %p for %s:%s, %" GST_PTR_FORMAT,
+      group, GST_DEBUG_PAD_NAME (pad), caps);
+
+  GST_DEBUG_OBJECT (playbin, "checking factory %s", GST_OBJECT_NAME (factory));
+
+  /* if it's not a sink, we make sure the element is compatible with
+   * the fixed sink */
+  if (!gst_element_factory_list_is_type (factory,
+          GST_ELEMENT_FACTORY_TYPE_SINK)) {
+    gboolean isvideodec = gst_element_factory_list_is_type (factory,
+        GST_ELEMENT_FACTORY_TYPE_DECODER |
+        GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO |
+        GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE);
+    gboolean isaudiodec = gst_element_factory_list_is_type (factory,
+        GST_ELEMENT_FACTORY_TYPE_DECODER |
+        GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO);
+
+    if (!isvideodec && !isaudiodec)
+      return GST_AUTOPLUG_SELECT_TRY;
+
+    GST_SOURCE_GROUP_LOCK (group);
+    g_mutex_lock (&playbin->elements_lock);
+
+    if (isaudiodec) {
+      ave_seq = playbin->aelements;
+      sinkp = &group->audio_sink;
+    } else {
+      ave_seq = playbin->velements;
+      sinkp = &group->video_sink;
+    }
+
+    seq_iter =
+        g_sequence_lookup (ave_seq, factory,
+        (GCompareDataFunc) avelement_lookup_decoder, NULL);
+    if (seq_iter) {
+      /* Go to first iter with that decoder */
+      do {
+        GSequenceIter *tmp_seq_iter;
+
+        tmp_seq_iter = g_sequence_iter_prev (seq_iter);
+        if (!avelement_iter_is_equal (tmp_seq_iter, factory))
+          break;
+        seq_iter = tmp_seq_iter;
+      } while (!g_sequence_iter_is_begin (seq_iter));
+
+      while (!g_sequence_iter_is_end (seq_iter)
+          && avelement_iter_is_equal (seq_iter, factory)) {
+        ave = g_sequence_get (seq_iter);
+        ave_list = g_list_prepend (ave_list, ave);
+        seq_iter = g_sequence_iter_next (seq_iter);
+      }
+
+      /* Sort all GstAVElements by their relative ranks and insert
+       * into the decoders list */
+      ave_list = g_list_sort (ave_list, (GCompareFunc) avelement_compare);
+    } else {
+      ave_list = g_list_prepend (ave_list, NULL);
+    }
+
+    /* if it is a decoder and we don't have a fixed sink, then find out 
+     * the matching audio/video sink from GstAVElements list */
+    for (l = ave_list; l; l = l->next) {
+      gboolean created_sink = FALSE;
+
+      ave = (GstAVElement *) l->data;
+
+      if (((isaudiodec && !group->audio_sink) ||
+              (isvideodec && !group->video_sink))) {
+        if (ave && ave->sink) {
+          GST_DEBUG_OBJECT (playbin,
+              "Trying to create sink '%s' for decoder '%s'",
+              gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (ave->sink)),
+              gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
+          if ((*sinkp = gst_element_factory_create (ave->sink, NULL)) == NULL) {
+            GST_WARNING_OBJECT (playbin,
+                "Could not create an element from %s",
+                gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (ave->sink)));
+            continue;
+          } else {
+            if (!activate_sink (playbin, *sinkp, NULL)) {
+              gst_object_unref (*sinkp);
+              *sinkp = NULL;
+              GST_WARNING_OBJECT (playbin,
+                  "Could not activate sink %s",
+                  gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (ave->sink)));
+              continue;
+            }
+            gst_object_ref_sink (*sinkp);
+            created_sink = TRUE;
+          }
+        }
+      }
+
+      /* If it is a decoder and we have a fixed sink for the media
+       * type it outputs, check that the decoder is compatible with this sink */
+      if ((isaudiodec && group->audio_sink) || (isvideodec
+              && group->video_sink)) {
+        gboolean compatible = FALSE;
+        GstPad *sinkpad;
+        GstCaps *caps;
+        GstElement *sink;
+
+        sink = *sinkp;
+
+        if ((sinkpad = gst_element_get_static_pad (sink, "sink"))) {
+          GstPlayFlags flags = gst_play_bin3_get_flags (playbin);
+          GstCaps *raw_caps =
+              (isaudiodec) ? gst_static_caps_get (&raw_audio_caps) :
+              gst_static_caps_get (&raw_video_caps);
+
+          caps = gst_pad_query_caps (sinkpad, NULL);
+
+          /* If the sink supports raw audio/video, we first check
+           * if the decoder could output any raw audio/video format
+           * and assume it is compatible with the sink then. We don't
+           * do a complete compatibility check here if converters
+           * are plugged between the decoder and the sink because
+           * the converters will convert between raw formats and
+           * even if the decoder format is not supported by the decoder
+           * a converter will convert it.
+           *
+           * We assume here that the converters can convert between
+           * any raw format.
+           */
+          if ((isaudiodec && !(flags & GST_PLAY_FLAG_NATIVE_AUDIO)
+                  && gst_caps_can_intersect (caps, raw_caps)) || (!isaudiodec
+                  && !(flags & GST_PLAY_FLAG_NATIVE_VIDEO)
+                  && gst_caps_can_intersect (caps, raw_caps))) {
+            compatible =
+                gst_element_factory_can_src_any_caps (factory, raw_caps)
+                || gst_element_factory_can_src_any_caps (factory, caps);
+          } else {
+            compatible = gst_element_factory_can_src_any_caps (factory, caps);
+          }
+
+          gst_object_unref (sinkpad);
+          gst_caps_unref (caps);
+        }
+
+        if (compatible)
+          break;
+
+        GST_DEBUG_OBJECT (playbin, "%s not compatible with the fixed sink",
+            GST_OBJECT_NAME (factory));
+
+        /* If it is not compatible, either continue with the next possible
+         * sink or if we have a fixed sink, skip the decoder */
+        if (created_sink) {
+          gst_element_set_state (*sinkp, GST_STATE_NULL);
+          gst_object_unref (*sinkp);
+          *sinkp = NULL;
+        } else {
+          g_mutex_unlock (&playbin->elements_lock);
+          GST_SOURCE_GROUP_UNLOCK (group);
+          return GST_AUTOPLUG_SELECT_SKIP;
+        }
+      }
+    }
+    g_list_free (ave_list);
+    g_mutex_unlock (&playbin->elements_lock);
+    GST_SOURCE_GROUP_UNLOCK (group);
+    return GST_AUTOPLUG_SELECT_TRY;
+  }
+
+  /* it's a sink, see if an instance of it actually works */
+  GST_DEBUG_OBJECT (playbin, "we found a sink '%s'", GST_OBJECT_NAME (factory));
+
+  klass =
+      gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);
+
+  /* figure out the klass */
+  if (strstr (klass, "Audio")) {
+    GST_DEBUG_OBJECT (playbin, "we found an audio sink");
+    type = GST_PLAY_SINK_TYPE_AUDIO;
+    sinkp = &group->audio_sink;
+  } else if (strstr (klass, "Video")) {
+    GST_DEBUG_OBJECT (playbin, "we found a video sink");
+    type = GST_PLAY_SINK_TYPE_VIDEO;
+    sinkp = &group->video_sink;
+  } else {
+    /* unknown klass, skip this element */
+    GST_WARNING_OBJECT (playbin, "unknown sink klass %s found", klass);
+    return GST_AUTOPLUG_SELECT_SKIP;
+  }
+
+  /* if we are asked to do visualisations and it's an audio sink, skip the
+   * element. We can only do visualisations with raw sinks */
+  if (gst_play_sink_get_flags (playbin->playsink) & GST_PLAY_FLAG_VIS) {
+    if (type == GST_PLAY_SINK_TYPE_AUDIO) {
+      GST_DEBUG_OBJECT (playbin, "skip audio sink because of vis");
+      return GST_AUTOPLUG_SELECT_SKIP;
+    }
+  }
+
+  /* now see if we already have a sink element */
+  GST_SOURCE_GROUP_LOCK (group);
+  if (*sinkp && GST_STATE (*sinkp) >= GST_STATE_READY) {
+    GstElement *sink = gst_object_ref (*sinkp);
+
+    if (sink_accepts_caps (playbin, sink, caps)) {
+      GST_DEBUG_OBJECT (playbin,
+          "Existing sink '%s' accepts caps: %" GST_PTR_FORMAT,
+          GST_ELEMENT_NAME (sink), caps);
+      gst_object_unref (sink);
+      GST_SOURCE_GROUP_UNLOCK (group);
+      return GST_AUTOPLUG_SELECT_EXPOSE;
+    } else {
+      GST_DEBUG_OBJECT (playbin,
+          "Existing sink '%s' does not accept caps: %" GST_PTR_FORMAT,
+          GST_ELEMENT_NAME (sink), caps);
+      gst_object_unref (sink);
+      GST_SOURCE_GROUP_UNLOCK (group);
+      return GST_AUTOPLUG_SELECT_SKIP;
+    }
+  }
+  GST_DEBUG_OBJECT (playbin, "we have no pending sink, try to create '%s'",
+      gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
+
+  if ((*sinkp = gst_element_factory_create (factory, NULL)) == NULL) {
+    GST_WARNING_OBJECT (playbin, "Could not create an element from %s",
+        gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
+    GST_SOURCE_GROUP_UNLOCK (group);
+    return GST_AUTOPLUG_SELECT_SKIP;
+  }
+
+  element = *sinkp;
+
+  if (!activate_sink (playbin, element, NULL)) {
+    GST_WARNING_OBJECT (playbin, "Could not activate sink %s",
+        gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
+    *sinkp = NULL;
+    gst_object_unref (element);
+    GST_SOURCE_GROUP_UNLOCK (group);
+    return GST_AUTOPLUG_SELECT_SKIP;
+  }
+
+  /* Check if the selected sink actually supports the
+   * caps and can be set to READY*/
+  if (!sink_accepts_caps (playbin, element, caps)) {
+    *sinkp = NULL;
+    gst_element_set_state (element, GST_STATE_NULL);
+    gst_object_unref (element);
+    GST_SOURCE_GROUP_UNLOCK (group);
+    return GST_AUTOPLUG_SELECT_SKIP;
+  }
+
+  /* remember the sink in the group now, the element is floating, we take
+   * ownership now 
+   *
+   * store the sink in the group, we will configure it later when we
+   * reconfigure the sink */
+  GST_DEBUG_OBJECT (playbin, "remember sink");
+  gst_object_ref_sink (element);
+  GST_SOURCE_GROUP_UNLOCK (group);
+
+  /* tell decodebin to expose the pad because we are going to use this
+   * sink */
+  GST_DEBUG_OBJECT (playbin, "we found a working sink, expose pad");
+
+  return GST_AUTOPLUG_SELECT_EXPOSE;
+}
+
+#define GST_PLAY_BIN3_FILTER_CAPS(filter,caps) G_STMT_START {                  \
+  if ((filter)) {                                                             \
+    GstCaps *intersection =                                                   \
+        gst_caps_intersect_full ((filter), (caps), GST_CAPS_INTERSECT_FIRST); \
+    gst_caps_unref ((caps));                                                  \
+    (caps) = intersection;                                                    \
+  }                                                                           \
+} G_STMT_END
+
+static gboolean
+autoplug_query_caps (GstElement * uridecodebin, GstPad * pad,
+    GstElement * element, GstQuery * query, GstSourceGroup * group)
+{
+  GstCaps *filter, *result = NULL;
+  GstElement *sink;
+  GstPad *sinkpad = NULL;
+  GstElementFactory *factory;
+  GstElementFactoryListType factory_type;
+  gboolean have_sink = FALSE;
+
+  GST_SOURCE_GROUP_LOCK (group);
+  gst_query_parse_caps (query, &filter);
+
+  factory = gst_element_get_factory (element);
+  if (!factory)
+    goto done;
+
+  if (gst_element_factory_list_is_type (factory,
+          GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO |
+          GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE)) {
+    factory_type =
+        GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO |
+        GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE;
+
+    if ((sink = group->video_sink)) {
+      sinkpad = gst_element_get_static_pad (sink, "sink");
+      if (sinkpad) {
+        GstCaps *sinkcaps;
+
+        sinkcaps = gst_pad_query_caps (sinkpad, filter);
+        if (!gst_caps_is_any (sinkcaps)) {
+          if (!result)
+            result = sinkcaps;
+          else
+            result = gst_caps_merge (result, sinkcaps);
+        } else {
+          gst_caps_unref (sinkcaps);
+        }
+        gst_object_unref (sinkpad);
+      }
+      have_sink = TRUE;
+    }
+  } else if (gst_element_factory_list_is_type (factory,
+          GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO)) {
+    factory_type = GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO;
+
+    if ((sink = group->audio_sink)) {
+      sinkpad = gst_element_get_static_pad (sink, "sink");
+      if (sinkpad) {
+        GstCaps *sinkcaps;
+
+        sinkcaps = gst_pad_query_caps (sinkpad, filter);
+        if (!gst_caps_is_any (sinkcaps)) {
+          if (!result)
+            result = sinkcaps;
+          else
+            result = gst_caps_merge (result, sinkcaps);
+        } else {
+          gst_caps_unref (sinkcaps);
+        }
+        gst_object_unref (sinkpad);
+      }
+      have_sink = TRUE;
+    }
+  } else if (gst_element_factory_list_is_type (factory,
+          GST_ELEMENT_FACTORY_TYPE_MEDIA_SUBTITLE)) {
+    factory_type = GST_ELEMENT_FACTORY_TYPE_MEDIA_SUBTITLE;
+
+    if ((sink = group->playbin->text_sink)) {
+      sinkpad = gst_element_get_static_pad (sink, "sink");
+      if (sinkpad) {
+        GstCaps *sinkcaps;
+
+        sinkcaps = gst_pad_query_caps (sinkpad, filter);
+        if (!gst_caps_is_any (sinkcaps)) {
+          if (!result)
+            result = sinkcaps;
+          else
+            result = gst_caps_merge (result, sinkcaps);
+        } else {
+          gst_caps_unref (sinkcaps);
+        }
+        gst_object_unref (sinkpad);
+      }
+      have_sink = TRUE;
+    } else {
+      GstCaps *subcaps = gst_subtitle_overlay_create_factory_caps ();
+      GST_PLAY_BIN3_FILTER_CAPS (filter, subcaps);
+      if (!result)
+        result = subcaps;
+      else
+        result = gst_caps_merge (result, subcaps);
+    }
+  } else {
+    goto done;
+  }
+
+  if (!have_sink) {
+    GValueArray *factories;
+    gint i, n;
+
+    factories = autoplug_factories_cb (uridecodebin, pad, NULL, group);
+    n = factories->n_values;
+    for (i = 0; i < n; i++) {
+      GValue *v = g_value_array_get_nth (factories, i);
+      GstElementFactory *f = g_value_get_object (v);
+      const GList *templates;
+      const GList *l;
+      GstCaps *templ_caps;
+
+      if (!gst_element_factory_list_is_type (f, factory_type))
+        continue;
+
+      templates = gst_element_factory_get_static_pad_templates (f);
+
+      for (l = templates; l; l = l->next) {
+        templ_caps = gst_static_pad_template_get_caps (l->data);
+
+        if (!gst_caps_is_any (templ_caps)) {
+          GST_PLAY_BIN3_FILTER_CAPS (filter, templ_caps);
+          if (!result)
+            result = templ_caps;
+          else
+            result = gst_caps_merge (result, templ_caps);
+        } else {
+          gst_caps_unref (templ_caps);
+        }
+      }
+    }
+    g_value_array_free (factories);
+  }
+
+done:
+  GST_SOURCE_GROUP_UNLOCK (group);
+
+  if (!result)
+    return FALSE;
+
+  /* Add the actual decoder/parser/etc caps at the very end to
+   * make sure we don't cause empty caps to be returned, e.g.
+   * if a parser asks us but a decoder is required after it
+   * because no sink can handle the format directly.
+   */
+  {
+    GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD (pad));
+
+    if (target) {
+      GstCaps *target_caps = gst_pad_get_pad_template_caps (target);
+      GST_PLAY_BIN3_FILTER_CAPS (filter, target_caps);
+      result = gst_caps_merge (result, target_caps);
+      gst_object_unref (target);
+    }
+  }
+
+
+  gst_query_set_caps_result (query, result);
+  gst_caps_unref (result);
+
+  return TRUE;
+}
+
+static gboolean
+autoplug_query_context (GstElement * uridecodebin, GstPad * pad,
+    GstElement * element, GstQuery * query, GstSourceGroup * group)
+{
+  GstElement *sink;
+  GstPad *sinkpad = NULL;
+  GstElementFactory *factory;
+  gboolean res = FALSE;
+
+  GST_SOURCE_GROUP_LOCK (group);
+
+  factory = gst_element_get_factory (element);
+  if (!factory)
+    goto done;
+
+  if (gst_element_factory_list_is_type (factory,
+          GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO |
+          GST_ELEMENT_FACTORY_TYPE_MEDIA_IMAGE)) {
+    if ((sink = group->video_sink)) {
+      sinkpad = gst_element_get_static_pad (sink, "sink");
+      if (sinkpad) {
+        res = gst_pad_query (sinkpad, query);
+        gst_object_unref (sinkpad);
+      }
+    }
+  } else if (gst_element_factory_list_is_type (factory,
+          GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO)) {
+    if ((sink = group->audio_sink)) {
+      sinkpad = gst_element_get_static_pad (sink, "sink");
+      if (sinkpad) {
+        res = gst_pad_query (sinkpad, query);
+        gst_object_unref (sinkpad);
+      }
+    }
+  } else if (gst_element_factory_list_is_type (factory,
+          GST_ELEMENT_FACTORY_TYPE_MEDIA_SUBTITLE)) {
+    if ((sink = group->playbin->text_sink)) {
+      sinkpad = gst_element_get_static_pad (sink, "sink");
+      if (sinkpad) {
+        res = gst_pad_query (sinkpad, query);
+        gst_object_unref (sinkpad);
+      }
+    }
+  } else {
+    goto done;
+  }
+
+done:
+  GST_SOURCE_GROUP_UNLOCK (group);
+
+  return res;
+}
+
+static gboolean
+autoplug_query_cb (GstElement * uridecodebin, GstPad * pad,
+    GstElement * element, GstQuery * query, GstSourceGroup * group)
+{
+
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_CAPS:
+      return autoplug_query_caps (uridecodebin, pad, element, query, group);
+    case GST_QUERY_CONTEXT:
+      return autoplug_query_context (uridecodebin, pad, element, query, group);
+    default:
+      return FALSE;
+  }
+}
+
+static void
+notify_source_cb (GstElement * urisourcebin, GParamSpec * pspec,
+    GstSourceGroup * group)
+{
+  GstPlayBin3 *playbin;
+  GstElement *source;
+
+  playbin = group->playbin;
+
+  g_object_get (urisourcebin, "source", &source, NULL);
+
+  GST_OBJECT_LOCK (playbin);
+  if (playbin->source)
+    gst_object_unref (playbin->source);
+  playbin->source = source;
+  GST_OBJECT_UNLOCK (playbin);
+
+  g_object_notify (G_OBJECT (playbin), "source");
+
+  g_signal_emit (playbin, gst_play_bin3_signals[SIGNAL_SOURCE_SETUP],
+      0, playbin->source);
+}
+
+/* must be called with the group lock */
+static gboolean
+group_set_locked_state_unlocked (GstPlayBin3 * playbin, GstSourceGroup * group,
+    gboolean locked)
+{
+  GST_DEBUG_OBJECT (playbin, "locked_state %d on group %p", locked, group);
+
+  if (group->urisourcebin)
+    gst_element_set_locked_state (group->urisourcebin, locked);
+  if (group->suburisourcebin)
+    gst_element_set_locked_state (group->suburisourcebin, locked);
+
+  return TRUE;
+}
+
+static gboolean
+make_or_reuse_element (GstPlayBin3 * playbin, const gchar * name,
+    GstElement ** elem)
+{
+  if (*elem) {
+    GST_DEBUG_OBJECT (playbin, "reusing existing %s", name);
+    gst_element_set_state (*elem, GST_STATE_READY);
+    /* no need to take extra ref, we already have one
+     * and the bin will add one since it is no longer floating,
+     * as we added a non-floating ref when removing it from the
+     * bin earlier */
+  } else {
+    GstElement *new_elem;
+    GST_DEBUG_OBJECT (playbin, "making new %s", name);
+    new_elem = gst_element_factory_make (name, NULL);
+    if (!new_elem)
+      return FALSE;
+    *elem = gst_object_ref (new_elem);
+  }
+
+  if (GST_OBJECT_PARENT (*elem) != GST_OBJECT_CAST (playbin))
+    gst_bin_add (GST_BIN_CAST (playbin), *elem);
+  return TRUE;
+}
+
+static void
+urisrc_pad_added (GstElement * urisrc, GstPad * pad, GstSourceGroup * group)
+{
+  GstPadLinkReturn res;
+  GstPad *sinkpad = NULL;
+  GstPlayBin3 *playbin;
+
+  GST_SOURCE_GROUP_LOCK (group);
+  playbin = group->playbin;
+  if (urisrc == group->urisourcebin) {
+    /* Primary stream, link to the main pad of decodebin3 */
+    sinkpad = gst_element_get_static_pad (playbin->decodebin, "sink");
+    if (gst_pad_is_linked (sinkpad)) {
+      gst_object_unref (GST_OBJECT (sinkpad));
+      sinkpad = NULL;
+    }
+  }
+
+  if (sinkpad == NULL) {
+    /* Auxiliary stream, request a new pad from decodebin */
+    if ((sinkpad = gst_element_get_request_pad (playbin->decodebin, "sink_%u"))) {
+      g_object_set_data (G_OBJECT (pad), "playbin.sinkpad", sinkpad);
+    }
+  }
+  if (sinkpad) {
+    GST_DEBUG_OBJECT (playbin, "New pad %" GST_PTR_FORMAT
+        " from urisourcebin %" GST_PTR_FORMAT " linking to %"
+        GST_PTR_FORMAT, pad, urisrc, sinkpad);
+
+    res = gst_pad_link (pad, sinkpad);
+    gst_object_unref (sinkpad);
+
+    if (GST_PAD_LINK_FAILED (res))
+      goto link_failed;
+  }
+  GST_SOURCE_GROUP_UNLOCK (group);
+  return;
+
+link_failed:
+  {
+    GST_ERROR_OBJECT (playbin,
+        "failed to link pad %s:%s to decodebin, reason %s (%d)",
+        GST_DEBUG_PAD_NAME (pad), gst_pad_link_get_name (res), res);
+    GST_SOURCE_GROUP_UNLOCK (group);
+    return;
+  }
+}
+
+static void
+urisrc_pad_removed_cb (GstElement * urisrc, GstPad * pad,
+    GstSourceGroup * group)
+{
+}
+
+/* must be called with PLAY_BIN_LOCK */
+static GstStateChangeReturn
+activate_decodebin (GstPlayBin3 * playbin, GstState target)
+{
+  GstStateChangeReturn state_ret;
+  GstElement *decodebin = NULL;
+
+  if (playbin->decodebin_active)
+    return GST_STATE_CHANGE_SUCCESS;
+
+  GST_LOG_OBJECT (playbin, "Adding and activating decodebin");
+
+  if (!make_or_reuse_element (playbin, "decodebin3", &playbin->decodebin))
+    goto no_decodebin;
+  decodebin = playbin->decodebin;
+
+  /* connect pads and other things */
+  playbin->db_pad_added_id = g_signal_connect (decodebin, "pad-added",
+      G_CALLBACK (pad_added_cb), playbin);
+  playbin->db_pad_removed_id = g_signal_connect (decodebin, "pad-removed",
+      G_CALLBACK (pad_removed_cb), playbin);
+  playbin->db_no_more_pads_id = g_signal_connect (decodebin, "no-more-pads",
+      G_CALLBACK (no_more_pads_cb), playbin);
+  playbin->db_select_stream_id = g_signal_connect (decodebin, "select-stream",
+      G_CALLBACK (select_stream_cb), playbin);
+  /* is called when the decodebin is out of data and we can switch to the
+   * next uri */
+#if 0
+  /* FIXME: Re-enable if/when decodebin3 supports 'drained' */
+  playbin->db_drained_id =
+      g_signal_connect (decodebin, "drained", G_CALLBACK (drained_cb), playbin);
+#endif
+
+  gst_element_set_locked_state (decodebin, TRUE);
+  if ((state_ret =
+          gst_element_set_state (decodebin,
+              target)) == GST_STATE_CHANGE_FAILURE)
+    goto decodebin_failure;
+  gst_element_set_locked_state (decodebin, FALSE);
+
+  playbin->decodebin_active = TRUE;
+
+  return state_ret;
+
+
+no_decodebin:
+  {
+    GstMessage *msg;
+
+    msg =
+        gst_missing_element_message_new (GST_ELEMENT_CAST (playbin),
+        "decodebin3");
+    gst_element_post_message (GST_ELEMENT_CAST (playbin), msg);
+
+    GST_ELEMENT_ERROR (playbin, CORE, MISSING_PLUGIN,
+        (_("Could not create \"decodebin3\" element.")), (NULL));
+
+    goto error_cleanup;
+  }
+decodebin_failure:
+  {
+    GST_DEBUG_OBJECT (playbin, "failed state change of decodebin");
+    goto error_cleanup;
+  }
+error_cleanup:{
+    if (decodebin) {
+      REMOVE_SIGNAL (playbin->decodebin, playbin->db_pad_added_id);
+      REMOVE_SIGNAL (playbin->decodebin, playbin->db_pad_removed_id);
+      REMOVE_SIGNAL (playbin->decodebin, playbin->db_no_more_pads_id);
+      REMOVE_SIGNAL (playbin->decodebin, playbin->db_drained_id);
+      REMOVE_SIGNAL (playbin->decodebin, playbin->db_select_stream_id);
+      gst_element_set_state (decodebin, GST_STATE_NULL);
+      gst_bin_remove (GST_BIN_CAST (playbin), decodebin);
+    }
+    return GST_STATE_CHANGE_FAILURE;
+  }
+}
+
+/* must be called with PLAY_BIN_LOCK */
+static void
+deactivate_decodebin (GstPlayBin3 * playbin)
+{
+  if (playbin->decodebin) {
+    GST_LOG_OBJECT (playbin, "Deactivating and removing decodebin");
+    REMOVE_SIGNAL (playbin->decodebin, playbin->db_pad_added_id);
+    REMOVE_SIGNAL (playbin->decodebin, playbin->db_pad_removed_id);
+    REMOVE_SIGNAL (playbin->decodebin, playbin->db_no_more_pads_id);
+    REMOVE_SIGNAL (playbin->decodebin, playbin->db_drained_id);
+    REMOVE_SIGNAL (playbin->decodebin, playbin->db_select_stream_id);
+    gst_bin_remove (GST_BIN_CAST (playbin), playbin->decodebin);
+    playbin->decodebin_active = FALSE;
+    playbin->active_stream_types = 0;
+  }
+}
+
+/* must be called with PLAY_BIN_LOCK */
+static GstStateChangeReturn
+activate_group (GstPlayBin3 * playbin, GstSourceGroup * group, GstState target)
+{
+  GstElement *urisrcbin = NULL;
+  GstElement *suburisrcbin = NULL;
+  GstPlayFlags flags;
+  gboolean audio_sink_activated = FALSE;
+  gboolean video_sink_activated = FALSE;
+  gboolean text_sink_activated = FALSE;
+  GstStateChangeReturn state_ret;
+
+  g_return_val_if_fail (group->valid, GST_STATE_CHANGE_FAILURE);
+  g_return_val_if_fail (!group->active, GST_STATE_CHANGE_FAILURE);
+
+  GST_DEBUG_OBJECT (playbin, "activating group %p", group);
+
+  GST_SOURCE_GROUP_LOCK (group);
+
+  /* First set up the custom sinks */
+  if (playbin->audio_sink)
+    group->audio_sink = gst_object_ref (playbin->audio_sink);
+  else
+    group->audio_sink =
+        gst_play_sink_get_sink (playbin->playsink, GST_PLAY_SINK_TYPE_AUDIO);
+
+  if (group->audio_sink) {
+    if (!activate_sink (playbin, group->audio_sink, &audio_sink_activated)) {
+      if (group->audio_sink == playbin->audio_sink) {
+        goto sink_failure;
+      } else {
+        gst_object_unref (group->audio_sink);
+        group->audio_sink = NULL;
+      }
+    }
+  }
+
+  if (playbin->video_sink)
+    group->video_sink = gst_object_ref (playbin->video_sink);
+  else
+    group->video_sink =
+        gst_play_sink_get_sink (playbin->playsink, GST_PLAY_SINK_TYPE_VIDEO);
+
+  if (group->video_sink) {
+    if (!activate_sink (playbin, group->video_sink, &video_sink_activated)) {
+      if (group->video_sink == playbin->video_sink) {
+        goto sink_failure;
+      } else {
+        gst_object_unref (group->video_sink);
+        group->video_sink = NULL;
+      }
+    }
+  }
+
+  if (playbin->text_sink)
+    group->text_sink = gst_object_ref (playbin->text_sink);
+  else
+    group->text_sink =
+        gst_play_sink_get_sink (playbin->playsink, GST_PLAY_SINK_TYPE_TEXT);
+
+  if (group->text_sink) {
+    if (!activate_sink (playbin, group->text_sink, &text_sink_activated)) {
+      if (group->text_sink == playbin->text_sink) {
+        goto sink_failure;
+      } else {
+        gst_object_unref (group->text_sink);
+        group->text_sink = NULL;
+      }
+    }
+  }
+
+
+  if (!make_or_reuse_element (playbin, "urisourcebin", &group->urisourcebin))
+    goto no_urisrcbin;
+  urisrcbin = group->urisourcebin;
+
+  flags = gst_play_sink_get_flags (playbin->playsink);
+
+  g_object_set (urisrcbin,
+      /* configure connection speed */
+      "connection-speed", playbin->connection_speed / 1000,
+      /* configure uri */
+      "uri", group->uri,
+      /* configure download buffering */
+      "download", ((flags & GST_PLAY_FLAG_DOWNLOAD) != 0),
+      /* configure buffering of demuxed/parsed data */
+      "use-buffering", ((flags & GST_PLAY_FLAG_BUFFERING) != 0),
+      /* configure buffering parameters */
+      "buffer-duration", playbin->buffer_duration,
+      "buffer-size", playbin->buffer_size,
+      "ring-buffer-max-size", playbin->ring_buffer_max_size, NULL);
+
+  /* we have 1 pending no-more-pads */
+  group->pending = 1;
+
+  group->notify_source_id = g_signal_connect (urisrcbin, "notify::source",
+      G_CALLBACK (notify_source_cb), group);
+
+  /* will be called when a new media type is found. We return a list of decoders
+   * including sinks for decodebin to try */
+  group->autoplug_factories_id =
+      g_signal_connect (urisrcbin, "autoplug-factories",
+      G_CALLBACK (autoplug_factories_cb), group);
+  group->autoplug_select_id =
+      g_signal_connect (urisrcbin, "autoplug-select",
+      G_CALLBACK (autoplug_select_cb), group);
+  group->autoplug_continue_id =
+      g_signal_connect (urisrcbin, "autoplug-continue",
+      G_CALLBACK (autoplug_continue_cb), group);
+  group->autoplug_query_id =
+      g_signal_connect (urisrcbin, "autoplug-query",
+      G_CALLBACK (autoplug_query_cb), group);
+
+  group->urisrc_pad_added_id = g_signal_connect (urisrcbin, "pad-added",
+      G_CALLBACK (urisrc_pad_added), group);
+  group->urisrc_pad_removed_id = g_signal_connect (urisrcbin,
+      "pad-removed", G_CALLBACK (urisrc_pad_removed_cb), group);
+
+  if (group->suburi) {
+    /* subtitles */
+    if (!make_or_reuse_element (playbin, "urisourcebin",
+            &group->suburisourcebin))
+      goto no_urisrcbin;
+    suburisrcbin = group->suburisourcebin;
+
+    g_object_set (suburisrcbin,
+        /* configure connection speed */
+        "connection-speed", playbin->connection_speed,
+        /* configure uri */
+        "uri", group->suburi, NULL);
+
+    /* connect pads and other things */
+    group->sub_pad_added_id = g_signal_connect (suburisrcbin, "pad-added",
+        G_CALLBACK (urisrc_pad_added), group);
+    group->sub_pad_removed_id = g_signal_connect (suburisrcbin,
+        "pad-removed", G_CALLBACK (urisrc_pad_removed_cb), group);
+
+    group->sub_autoplug_continue_id =
+        g_signal_connect (suburisrcbin, "autoplug-continue",
+        G_CALLBACK (autoplug_continue_cb), group);
+
+    group->sub_autoplug_query_id =
+        g_signal_connect (suburisrcbin, "autoplug-query",
+        G_CALLBACK (autoplug_query_cb), group);
+
+    /* we have 2 pending no-more-pads */
+    group->pending = 2;
+    group->sub_pending = TRUE;
+  } else {
+    group->sub_pending = FALSE;
+  }
+
+  /* release the group lock before setting the state of the source bins, they
+   * might fire signals in this thread that we need to handle with the
+   * group_lock taken. */
+  GST_SOURCE_GROUP_UNLOCK (group);
+
+  if (suburisrcbin) {
+    if (gst_element_set_state (suburisrcbin,
+            target) == GST_STATE_CHANGE_FAILURE) {
+      GST_DEBUG_OBJECT (playbin,
+          "failed state change of subtitle urisourcebin");
+      GST_SOURCE_GROUP_LOCK (group);
+
+      REMOVE_SIGNAL (suburisrcbin, group->sub_pad_added_id);
+      REMOVE_SIGNAL (suburisrcbin, group->sub_pad_removed_id);
+      REMOVE_SIGNAL (suburisrcbin, group->sub_autoplug_continue_id);
+      REMOVE_SIGNAL (suburisrcbin, group->sub_autoplug_query_id);
+      /* Might already be removed because of an error message */
+      if (GST_OBJECT_PARENT (suburisrcbin) == GST_OBJECT_CAST (playbin))
+        gst_bin_remove (GST_BIN_CAST (playbin), suburisrcbin);
+      if (group->sub_pending) {
+        group->pending--;
+        group->sub_pending = FALSE;
+      }
+      gst_element_set_state (suburisrcbin, GST_STATE_READY);
+      g_free (group->suburi);
+      group->suburi = NULL;
+      GST_SOURCE_GROUP_UNLOCK (group);
+    }
+  }
+  if ((state_ret =
+          gst_element_set_state (urisrcbin,
+              target)) == GST_STATE_CHANGE_FAILURE)
+    goto urisrcbin_failure;
+
+  GST_SOURCE_GROUP_LOCK (group);
+  /* allow state changes of the playbin affect the group elements now */
+  group_set_locked_state_unlocked (playbin, group, FALSE);
+  group->active = TRUE;
+  GST_SOURCE_GROUP_UNLOCK (group);
+
+  return state_ret;
+
+  /* ERRORS */
+no_urisrcbin:
+  {
+    GstMessage *msg;
+
+    GST_SOURCE_GROUP_UNLOCK (group);
+    msg =
+        gst_missing_element_message_new (GST_ELEMENT_CAST (playbin),
+        "urisourcebin");
+    gst_element_post_message (GST_ELEMENT_CAST (playbin), msg);
+
+    GST_ELEMENT_ERROR (playbin, CORE, MISSING_PLUGIN,
+        (_("Could not create \"urisourcebin\" element.")), (NULL));
+
+    GST_SOURCE_GROUP_LOCK (group);
+
+    goto error_cleanup;
+  }
+urisrcbin_failure:
+  {
+    GST_DEBUG_OBJECT (playbin, "failed state change of urisrcbin");
+    GST_SOURCE_GROUP_LOCK (group);
+    goto error_cleanup;
+  }
+sink_failure:
+  {
+    GST_ERROR_OBJECT (playbin, "failed to activate sinks");
+    goto error_cleanup;
+  }
+
+error_cleanup:
+  {
+    /* delete any custom sinks we might have */
+    if (group->audio_sink) {
+      /* If this is a automatically created sink set it to NULL */
+      if (audio_sink_activated)
+        gst_element_set_state (group->audio_sink, GST_STATE_NULL);
+      gst_object_unref (group->audio_sink);
+    }
+    group->audio_sink = NULL;
+
+    if (group->video_sink) {
+      /* If this is a automatically created sink set it to NULL */
+      if (video_sink_activated)
+        gst_element_set_state (group->video_sink, GST_STATE_NULL);
+      gst_object_unref (group->video_sink);
+    }
+    group->video_sink = NULL;
+
+    if (group->text_sink) {
+      /* If this is a automatically created sink set it to NULL */
+      if (text_sink_activated)
+        gst_element_set_state (group->text_sink, GST_STATE_NULL);
+      gst_object_unref (group->text_sink);
+    }
+    group->text_sink = NULL;
+
+    if (urisrcbin) {
+      REMOVE_SIGNAL (group->urisourcebin, group->urisrc_pad_added_id);
+      REMOVE_SIGNAL (group->urisourcebin, group->urisrc_pad_removed_id);
+      REMOVE_SIGNAL (group->urisourcebin, group->notify_source_id);
+      REMOVE_SIGNAL (group->urisourcebin, group->autoplug_factories_id);
+      REMOVE_SIGNAL (group->urisourcebin, group->autoplug_select_id);
+      REMOVE_SIGNAL (group->urisourcebin, group->autoplug_continue_id);
+      REMOVE_SIGNAL (group->urisourcebin, group->autoplug_query_id);
+
+      gst_element_set_state (urisrcbin, GST_STATE_NULL);
+      gst_bin_remove (GST_BIN_CAST (playbin), urisrcbin);
+    }
+
+    GST_SOURCE_GROUP_UNLOCK (group);
+
+    return GST_STATE_CHANGE_FAILURE;
+  }
+}
+
+/* unlink a group of urisrcbin from the decodebin.
+ * must be called with PLAY_BIN_LOCK */
+static gboolean
+deactivate_group (GstPlayBin3 * playbin, GstSourceGroup * group)
+{
+  gint i;
+
+  g_return_val_if_fail (group->active, FALSE);
+  g_return_val_if_fail (group->valid, FALSE);
+
+  GST_DEBUG_OBJECT (playbin, "unlinking group %p", group);
+
+  GST_SOURCE_GROUP_LOCK (group);
+  group->active = FALSE;
+  for (i = 0; i < PLAYBIN_STREAM_LAST; i++) {
+    GstSourceCombine *combine = &playbin->combiner[i];
+
+    GST_DEBUG_OBJECT (playbin, "unlinking combiner %s", combine->media_type);
+
+    if (combine->srcpad) {
+      source_combine_remove_pads (playbin, combine);
+    }
+
+    if (combine->combiner) {
+      gint n;
+
+      /* release and unref requests pad from the combiner */
+      for (n = 0; n < combine->channels->len; n++) {
+        GstPad *sinkpad = g_ptr_array_index (combine->channels, n);
+
+        gst_element_release_request_pad (combine->combiner, sinkpad);
+        gst_object_unref (sinkpad);
+      }
+      g_ptr_array_set_size (combine->channels, 0);
+
+      gst_element_set_state (combine->combiner, GST_STATE_NULL);
+      gst_bin_remove (GST_BIN_CAST (playbin), combine->combiner);
+      combine->combiner = NULL;
+    }
+  }
+#if 0
+  /* delete any custom sinks we might have.
+   * conditionally set them to null if they aren't inside playsink yet */
+  if (group->audio_sink) {
+    if (!gst_object_has_as_ancestor (GST_OBJECT_CAST (group->audio_sink),
+            GST_OBJECT_CAST (playbin->playsink))) {
+      gst_element_set_state (group->audio_sink, GST_STATE_NULL);
+    }
+    gst_object_unref (group->audio_sink);
+  }
+  group->audio_sink = NULL;
+  if (group->video_sink) {
+    if (!gst_object_has_as_ancestor (GST_OBJECT_CAST (group->video_sink),
+            GST_OBJECT_CAST (playbin->playsink))) {
+      gst_element_set_state (group->video_sink, GST_STATE_NULL);
+    }
+    gst_object_unref (group->video_sink);
+  }
+  group->video_sink = NULL;
+  if (group->text_sink) {
+    if (!gst_object_has_as_ancestor (GST_OBJECT_CAST (group->text_sink),
+            GST_OBJECT_CAST (playbin->playsink))) {
+      gst_element_set_state (group->text_sink, GST_STATE_NULL);
+    }
+    gst_object_unref (group->text_sink);
+  }
+  group->text_sink = NULL;
+#endif
+
+  if (group->urisourcebin) {
+    REMOVE_SIGNAL (group->urisourcebin, group->urisrc_pad_added_id);
+    REMOVE_SIGNAL (group->urisourcebin, group->urisrc_pad_removed_id);
+    REMOVE_SIGNAL (group->urisourcebin, group->notify_source_id);
+    REMOVE_SIGNAL (group->urisourcebin, group->autoplug_factories_id);
+    REMOVE_SIGNAL (group->urisourcebin, group->autoplug_select_id);
+    REMOVE_SIGNAL (group->urisourcebin, group->autoplug_continue_id);
+    REMOVE_SIGNAL (group->urisourcebin, group->autoplug_query_id);
+    gst_bin_remove (GST_BIN_CAST (playbin), group->urisourcebin);
+  }
+
+  if (group->suburisourcebin) {
+    REMOVE_SIGNAL (group->suburisourcebin, group->sub_pad_added_id);
+    REMOVE_SIGNAL (group->suburisourcebin, group->sub_pad_removed_id);
+    REMOVE_SIGNAL (group->suburisourcebin, group->sub_autoplug_continue_id);
+    REMOVE_SIGNAL (group->suburisourcebin, group->sub_autoplug_query_id);
+
+    /* Might already be removed because of errors */
+    if (GST_OBJECT_PARENT (group->suburisourcebin) == GST_OBJECT_CAST (playbin))
+      gst_bin_remove (GST_BIN_CAST (playbin), group->suburisourcebin);
+  }
+
+  GST_SOURCE_GROUP_UNLOCK (group);
+
+  return TRUE;
+}
+
+/* setup the next group to play, this assumes the next_group is valid and
+ * configured. It swaps out the current_group and activates the valid
+ * next_group. */
+static GstStateChangeReturn
+setup_next_source (GstPlayBin3 * playbin, GstState target)
+{
+  GstSourceGroup *new_group, *old_group;
+  GstStateChangeReturn state_ret;
+
+  GST_DEBUG_OBJECT (playbin, "setup sources");
+
+  /* see if there is a next group */
+  GST_PLAY_BIN3_LOCK (playbin);
+  new_group = playbin->next_group;
+  if (!new_group || !new_group->valid)
+    goto no_next_group;
+
+  /* first unlink the current source, if any */
+  old_group = playbin->curr_group;
+  if (old_group && old_group->valid && old_group->active) {
+    new_group->stream_changed_pending = TRUE;
+
+    gst_play_bin3_update_cached_duration (playbin);
+    /* unlink our pads with the sink */
+    deactivate_group (playbin, old_group);
+    old_group->valid = FALSE;
+  }
+
+  /* swap old and new */
+  playbin->curr_group = new_group;
+  playbin->next_group = old_group;
+
+  /* Get decodebin ready now */
+  if ((state_ret =
+          activate_decodebin (playbin, target)) == GST_STATE_CHANGE_FAILURE)
+    goto activate_failed;
+
+  /* activate the new group */
+  if ((state_ret =
+          activate_group (playbin, new_group,
+              target)) == GST_STATE_CHANGE_FAILURE)
+    goto activate_failed;
+
+  GST_PLAY_BIN3_UNLOCK (playbin);
+
+  return state_ret;
+
+  /* ERRORS */
+no_next_group:
+  {
+    GST_DEBUG_OBJECT (playbin, "no next group");
+    if (target == GST_STATE_READY && new_group && new_group->uri == NULL)
+      GST_ELEMENT_ERROR (playbin, RESOURCE, NOT_FOUND, ("No URI set"), (NULL));
+    GST_PLAY_BIN3_UNLOCK (playbin);
+    return GST_STATE_CHANGE_FAILURE;
+  }
+activate_failed:
+  {
+    new_group->stream_changed_pending = FALSE;
+    GST_DEBUG_OBJECT (playbin, "activate failed");
+    new_group->valid = FALSE;
+    GST_PLAY_BIN3_UNLOCK (playbin);
+    return GST_STATE_CHANGE_FAILURE;
+  }
+}
+
+/* The group that is currently playing is copied again to the
+ * next_group so that it will start playing the next time.
+ */
+static gboolean
+save_current_group (GstPlayBin3 * playbin)
+{
+  GstSourceGroup *curr_group;
+
+  GST_DEBUG_OBJECT (playbin, "save current group");
+
+  /* see if there is a current group */
+  GST_PLAY_BIN3_LOCK (playbin);
+  curr_group = playbin->curr_group;
+  if (curr_group && curr_group->valid && curr_group->active) {
+    /* unlink our pads with the sink */
+    deactivate_group (playbin, curr_group);
+  }
+  /* swap old and new */
+  playbin->curr_group = playbin->next_group;
+  playbin->next_group = curr_group;
+  GST_PLAY_BIN3_UNLOCK (playbin);
+
+  return TRUE;
+}
+
+/* clear the locked state from all groups. This function is called before a
+ * state change to NULL is performed on them. */
+static gboolean
+groups_set_locked_state (GstPlayBin3 * playbin, gboolean locked)
+{
+  GST_DEBUG_OBJECT (playbin, "setting locked state to %d on all groups",
+      locked);
+
+  GST_PLAY_BIN3_LOCK (playbin);
+  GST_SOURCE_GROUP_LOCK (playbin->curr_group);
+  group_set_locked_state_unlocked (playbin, playbin->curr_group, locked);
+  GST_SOURCE_GROUP_UNLOCK (playbin->curr_group);
+  GST_SOURCE_GROUP_LOCK (playbin->next_group);
+  group_set_locked_state_unlocked (playbin, playbin->next_group, locked);
+  GST_SOURCE_GROUP_UNLOCK (playbin->next_group);
+  GST_PLAY_BIN3_UNLOCK (playbin);
+
+  return TRUE;
+}
+
+static GstStateChangeReturn
+gst_play_bin3_change_state (GstElement * element, GstStateChange transition)
+{
+  GstStateChangeReturn ret;
+  GstPlayBin3 *playbin;
+  gboolean do_save = FALSE;
+
+  playbin = GST_PLAY_BIN3 (element);
+
+  switch (transition) {
+    case GST_STATE_CHANGE_NULL_TO_READY:
+      memset (&playbin->duration, 0, sizeof (playbin->duration));
+      break;
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+      GST_LOG_OBJECT (playbin, "clearing shutdown flag");
+      memset (&playbin->duration, 0, sizeof (playbin->duration));
+      g_atomic_int_set (&playbin->shutdown, 0);
+      do_async_start (playbin);
+      break;
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+    async_down:
+      /* FIXME unlock our waiting groups */
+      GST_LOG_OBJECT (playbin, "setting shutdown flag");
+      g_atomic_int_set (&playbin->shutdown, 1);
+      memset (&playbin->duration, 0, sizeof (playbin->duration));
+
+      /* wait for all callbacks to end by taking the lock.
+       * No dynamic (critical) new callbacks will
+       * be able to happen as we set the shutdown flag. */
+      GST_PLAY_BIN3_DYN_LOCK (playbin);
+      GST_LOG_OBJECT (playbin, "dynamic lock taken, we can continue shutdown");
+      GST_PLAY_BIN3_DYN_UNLOCK (playbin);
+      if (!do_save)
+        break;
+    case GST_STATE_CHANGE_READY_TO_NULL:
+      /* we go async to PAUSED, so if that fails, we never make it to PAUSED
+       * and no state change PAUSED to READY passes here,
+       * though it is a nice-to-have ... */
+      if (!g_atomic_int_get (&playbin->shutdown)) {
+        do_save = TRUE;
+        goto async_down;
+      }
+      memset (&playbin->duration, 0, sizeof (playbin->duration));
+
+      /* unlock so that all groups go to NULL */
+      groups_set_locked_state (playbin, FALSE);
+      break;
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+  if (ret == GST_STATE_CHANGE_FAILURE)
+    goto failure;
+
+  switch (transition) {
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+      if ((ret =
+              setup_next_source (playbin,
+                  GST_STATE_PAUSED)) == GST_STATE_CHANGE_FAILURE)
+        goto failure;
+      if (ret == GST_STATE_CHANGE_SUCCESS)
+        ret = GST_STATE_CHANGE_ASYNC;
+
+      break;
+    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+      do_async_done (playbin);
+      /* FIXME Release audio device when we implement that */
+      break;
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+      save_current_group (playbin);
+      break;
+    case GST_STATE_CHANGE_READY_TO_NULL:
+    {
+      guint i;
+      GList *l;
+
+      /* also do missed state change down to READY */
+      if (do_save)
+        save_current_group (playbin);
+      /* Deactive the groups, set the urisrcbins to NULL
+       * and unref them.
+       */
+      for (i = 0; i < 2; i++) {
+        if (playbin->groups[i].active && playbin->groups[i].valid) {
+          deactivate_group (playbin, &playbin->groups[i]);
+          playbin->groups[i].valid = FALSE;
+        }
+
+        if (playbin->groups[i].urisourcebin) {
+          gst_element_set_state (playbin->groups[i].urisourcebin,
+              GST_STATE_NULL);
+          gst_object_unref (playbin->groups[i].urisourcebin);
+          playbin->groups[i].urisourcebin = NULL;
+        }
+
+        if (playbin->groups[i].suburisourcebin) {
+          gst_element_set_state (playbin->groups[i].suburisourcebin,
+              GST_STATE_NULL);
+          gst_object_unref (playbin->groups[i].suburisourcebin);
+          playbin->groups[i].suburisourcebin = NULL;
+        }
+      }
+
+      deactivate_decodebin (playbin);
+      if (playbin->decodebin) {
+        gst_object_unref (playbin->decodebin);
+        playbin->decodebin = NULL;
+        playbin->decodebin_active = FALSE;
+      }
+
+      /* Set our sinks back to NULL, they might not be child of playbin */
+      if (playbin->audio_sink)
+        gst_element_set_state (playbin->audio_sink, GST_STATE_NULL);
+      if (playbin->video_sink)
+        gst_element_set_state (playbin->video_sink, GST_STATE_NULL);
+      if (playbin->text_sink)
+        gst_element_set_state (playbin->text_sink, GST_STATE_NULL);
+
+      if (playbin->video_stream_combiner)
+        gst_element_set_state (playbin->video_stream_combiner, GST_STATE_NULL);
+      if (playbin->audio_stream_combiner)
+        gst_element_set_state (playbin->audio_stream_combiner, GST_STATE_NULL);
+      if (playbin->text_stream_combiner)
+        gst_element_set_state (playbin->text_stream_combiner, GST_STATE_NULL);
+
+      /* make sure the groups don't perform a state change anymore until we
+       * enable them again */
+      groups_set_locked_state (playbin, TRUE);
+
+      /* Remove all non-persistent contexts */
+      GST_OBJECT_LOCK (playbin);
+      for (l = playbin->contexts; l;) {
+        GstContext *context = l->data;
+
+        if (!gst_context_is_persistent (context)) {
+          GList *next;
+
+          gst_context_unref (context);
+
+          next = l->next;
+          playbin->contexts = g_list_delete_link (playbin->contexts, l);
+          l = next;
+        } else {
+          l = l->next;
+        }
+      }
+
+      if (playbin->source) {
+        gst_object_unref (playbin->source);
+        playbin->source = NULL;
+      }
+
+      GST_OBJECT_UNLOCK (playbin);
+      break;
+    }
+    default:
+      break;
+  }
+
+  if (ret == GST_STATE_CHANGE_NO_PREROLL)
+    do_async_done (playbin);
+
+  return ret;
+
+  /* ERRORS */
+failure:
+  {
+    do_async_done (playbin);
+
+    if (transition == GST_STATE_CHANGE_READY_TO_PAUSED) {
+      GstSourceGroup *curr_group;
+
+      curr_group = playbin->curr_group;
+      if (curr_group) {
+        if (curr_group->active && curr_group->valid) {
+          /* unlink our pads with the sink */
+          deactivate_group (playbin, curr_group);
+        }
+        curr_group->valid = FALSE;
+      }
+
+      /* Swap current and next group back */
+      playbin->curr_group = playbin->next_group;
+      playbin->next_group = curr_group;
+    }
+    return ret;
+  }
+}
+
+static void
+gst_play_bin3_overlay_expose (GstVideoOverlay * overlay)
+{
+  GstPlayBin3 *playbin = GST_PLAY_BIN3 (overlay);
+
+  gst_video_overlay_expose (GST_VIDEO_OVERLAY (playbin->playsink));
+}
+
+static void
+gst_play_bin3_overlay_handle_events (GstVideoOverlay * overlay,
+    gboolean handle_events)
+{
+  GstPlayBin3 *playbin = GST_PLAY_BIN3 (overlay);
+
+  gst_video_overlay_handle_events (GST_VIDEO_OVERLAY (playbin->playsink),
+      handle_events);
+}
+
+static void
+gst_play_bin3_overlay_set_render_rectangle (GstVideoOverlay * overlay, gint x,
+    gint y, gint width, gint height)
+{
+  GstPlayBin3 *playbin = GST_PLAY_BIN3 (overlay);
+
+  gst_video_overlay_set_render_rectangle (GST_VIDEO_OVERLAY (playbin->playsink),
+      x, y, width, height);
+}
+
+static void
+gst_play_bin3_overlay_set_window_handle (GstVideoOverlay * overlay,
+    guintptr handle)
+{
+  GstPlayBin3 *playbin = GST_PLAY_BIN3 (overlay);
+
+  gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (playbin->playsink),
+      handle);
+}
+
+static void
+gst_play_bin3_overlay_init (gpointer g_iface, gpointer g_iface_data)
+{
+  GstVideoOverlayInterface *iface = (GstVideoOverlayInterface *) g_iface;
+  iface->expose = gst_play_bin3_overlay_expose;
+  iface->handle_events = gst_play_bin3_overlay_handle_events;
+  iface->set_render_rectangle = gst_play_bin3_overlay_set_render_rectangle;
+  iface->set_window_handle = gst_play_bin3_overlay_set_window_handle;
+}
+
+static void
+gst_play_bin3_navigation_send_event (GstNavigation * navigation,
+    GstStructure * structure)
+{
+  GstPlayBin3 *playbin = GST_PLAY_BIN3 (navigation);
+
+  gst_navigation_send_event (GST_NAVIGATION (playbin->playsink), structure);
+}
+
+static void
+gst_play_bin3_navigation_init (gpointer g_iface, gpointer g_iface_data)
+{
+  GstNavigationInterface *iface = (GstNavigationInterface *) g_iface;
+
+  iface->send_event = gst_play_bin3_navigation_send_event;
+}
+
+static const GList *
+gst_play_bin3_colorbalance_list_channels (GstColorBalance * balance)
+{
+  GstPlayBin3 *playbin = GST_PLAY_BIN3 (balance);
+
+  return
+      gst_color_balance_list_channels (GST_COLOR_BALANCE (playbin->playsink));
+}
+
+static void
+gst_play_bin3_colorbalance_set_value (GstColorBalance * balance,
+    GstColorBalanceChannel * channel, gint value)
+{
+  GstPlayBin3 *playbin = GST_PLAY_BIN3 (balance);
+
+  gst_color_balance_set_value (GST_COLOR_BALANCE (playbin->playsink), channel,
+      value);
+}
+
+static gint
+gst_play_bin3_colorbalance_get_value (GstColorBalance * balance,
+    GstColorBalanceChannel * channel)
+{
+  GstPlayBin3 *playbin = GST_PLAY_BIN3 (balance);
+
+  return gst_color_balance_get_value (GST_COLOR_BALANCE (playbin->playsink),
+      channel);
+}
+
+static GstColorBalanceType
+gst_play_bin3_colorbalance_get_balance_type (GstColorBalance * balance)
+{
+  GstPlayBin3 *playbin = GST_PLAY_BIN3 (balance);
+
+  return
+      gst_color_balance_get_balance_type (GST_COLOR_BALANCE
+      (playbin->playsink));
+}
+
+static void
+gst_play_bin3_colorbalance_init (gpointer g_iface, gpointer g_iface_data)
+{
+  GstColorBalanceInterface *iface = (GstColorBalanceInterface *) g_iface;
+
+  iface->list_channels = gst_play_bin3_colorbalance_list_channels;
+  iface->set_value = gst_play_bin3_colorbalance_set_value;
+  iface->get_value = gst_play_bin3_colorbalance_get_value;
+  iface->get_balance_type = gst_play_bin3_colorbalance_get_balance_type;
+}
+
+gboolean
+gst_play_bin3_plugin_init (GstPlugin * plugin, gboolean as_playbin)
+{
+  GST_DEBUG_CATEGORY_INIT (gst_play_bin3_debug, "playbin3", 0, "play bin");
+
+  if (as_playbin)
+    return gst_element_register (plugin, "playbin", GST_RANK_NONE,
+        GST_TYPE_PLAY_BIN);
+
+  return gst_element_register (plugin, "playbin3", GST_RANK_NONE,
+      GST_TYPE_PLAY_BIN);
+}
diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c
index e17c439..eaac018 100644
--- a/gst/playback/gstplaysink.c
+++ b/gst/playback/gstplaysink.c
@@ -620,16 +620,13 @@
       G_STRUCT_OFFSET (GstPlaySinkClass, convert_sample), NULL, NULL,
       g_cclosure_marshal_generic, GST_TYPE_SAMPLE, 1, GST_TYPE_CAPS);
 
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&audiorawtemplate));
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&audiotemplate));
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&videorawtemplate));
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&videotemplate));
-  gst_element_class_add_pad_template (gstelement_klass,
-      gst_static_pad_template_get (&texttemplate));
+  gst_element_class_add_static_pad_template (gstelement_klass,
+      &audiorawtemplate);
+  gst_element_class_add_static_pad_template (gstelement_klass, &audiotemplate);
+  gst_element_class_add_static_pad_template (gstelement_klass,
+      &videorawtemplate);
+  gst_element_class_add_static_pad_template (gstelement_klass, &videotemplate);
+  gst_element_class_add_static_pad_template (gstelement_klass, &texttemplate);
   gst_element_class_set_static_metadata (gstelement_klass, "Player Sink",
       "Generic/Bin/Sink",
       "Convenience sink for multiple streams",
@@ -680,6 +677,8 @@
 
   g_rec_mutex_init (&playsink->lock);
   GST_OBJECT_FLAG_SET (playsink, GST_ELEMENT_FLAG_SINK);
+  gst_bin_set_suppressed_flags (GST_BIN (playsink),
+      GST_ELEMENT_FLAG_SOURCE | GST_ELEMENT_FLAG_SINK);
 
   channel =
       GST_COLOR_BALANCE_CHANNEL (g_object_new (GST_TYPE_COLOR_BALANCE_CHANNEL,
@@ -1230,8 +1229,6 @@
     gst_bin_add (GST_BIN_CAST (chain->playsink), chain->bin);
   else {
     gst_bin_remove (GST_BIN_CAST (chain->playsink), chain->bin);
-    /* we don't want to lose our sink status */
-    GST_OBJECT_FLAG_SET (chain->playsink, GST_ELEMENT_FLAG_SINK);
   }
 
   chain->added = add;
diff --git a/gst/playback/gstplaysinkconvertbin.c b/gst/playback/gstplaysinkconvertbin.c
index 0930810..d4f6570 100644
--- a/gst/playback/gstplaysinkconvertbin.c
+++ b/gst/playback/gstplaysinkconvertbin.c
@@ -655,10 +655,8 @@
   gobject_class->dispose = gst_play_sink_convert_bin_dispose;
   gobject_class->finalize = gst_play_sink_convert_bin_finalize;
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sinktemplate));
+  gst_element_class_add_static_pad_template (gstelement_class, &srctemplate);
+  gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate);
   gst_element_class_set_static_metadata (gstelement_class,
       "Player Sink Converter Bin", "Bin/Converter",
       "Convenience bin for audio/video conversion",
diff --git a/gst/playback/gststreamsynchronizer.c b/gst/playback/gststreamsynchronizer.c
index 091e576..ac77266 100644
--- a/gst/playback/gststreamsynchronizer.c
+++ b/gst/playback/gststreamsynchronizer.c
@@ -373,18 +373,31 @@
             ostream->wait = FALSE;
 
             if (ostream->segment.format == GST_FORMAT_TIME) {
-              stop_running_time =
-                  gst_segment_to_running_time (&ostream->segment,
-                  GST_FORMAT_TIME, ostream->segment.stop);
+              if (ostream->segment.rate > 0)
+                stop_running_time =
+                    gst_segment_to_running_time (&ostream->segment,
+                    GST_FORMAT_TIME, ostream->segment.stop);
+              else
+                stop_running_time =
+                    gst_segment_to_running_time (&ostream->segment,
+                    GST_FORMAT_TIME, ostream->segment.start);
+
               position_running_time =
                   gst_segment_to_running_time (&ostream->segment,
                   GST_FORMAT_TIME, ostream->segment.position);
 
               position_running_time =
                   MAX (position_running_time, stop_running_time);
-              position_running_time -=
-                  gst_segment_to_running_time (&ostream->segment,
-                  GST_FORMAT_TIME, ostream->segment.start);
+
+              if (ostream->segment.rate > 0)
+                position_running_time -=
+                    gst_segment_to_running_time (&ostream->segment,
+                    GST_FORMAT_TIME, ostream->segment.start);
+              else
+                position_running_time -=
+                    gst_segment_to_running_time (&ostream->segment,
+                    GST_FORMAT_TIME, ostream->segment.stop);
+
               position_running_time = MAX (0, position_running_time);
 
               position = MAX (position, position_running_time);
@@ -497,9 +510,14 @@
           continue;
 
         if (ostream->segment.format == GST_FORMAT_TIME) {
-          start_running_time =
-              gst_segment_to_running_time (&ostream->segment,
-              GST_FORMAT_TIME, ostream->segment.start);
+          if (ostream->segment.rate > 0)
+            start_running_time =
+                gst_segment_to_running_time (&ostream->segment,
+                GST_FORMAT_TIME, ostream->segment.start);
+          else
+            start_running_time =
+                gst_segment_to_running_time (&ostream->segment,
+                GST_FORMAT_TIME, ostream->segment.stop);
 
           new_group_start_time = MAX (new_group_start_time, start_running_time);
         }
@@ -1020,10 +1038,8 @@
 
   gobject_class->finalize = gst_stream_synchronizer_finalize;
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&srctemplate));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sinktemplate));
+  gst_element_class_add_static_pad_template (element_class, &srctemplate);
+  gst_element_class_add_static_pad_template (element_class, &sinktemplate);
 
   gst_element_class_set_static_metadata (element_class,
       "Stream Synchronizer", "Generic",
diff --git a/gst/playback/gstsubtitleoverlay.c b/gst/playback/gstsubtitleoverlay.c
index adab7e5..65159e8 100644
--- a/gst/playback/gstsubtitleoverlay.c
+++ b/gst/playback/gstsubtitleoverlay.c
@@ -430,6 +430,10 @@
       gst_caps_unref (_factory_caps);
     _factory_caps = gst_caps_new_empty ();
 
+    /* The caps is cached */
+    GST_MINI_OBJECT_FLAG_SET (_factory_caps,
+        GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
+
     factories = gst_registry_feature_filter (registry,
         (GstPluginFeatureFilter) _factory_filter, FALSE, &_factory_caps);
     GST_DEBUG ("Created factory caps: %" GST_PTR_FORMAT, _factory_caps);
@@ -1018,10 +1022,17 @@
   GstCaps *subcaps;
   GList *l, *factories = NULL;
 
-  if (GST_IS_EVENT (info->data) && !GST_EVENT_IS_SERIALIZED (info->data)) {
-    GST_DEBUG_OBJECT (pad, "Letting non-serialized event %s pass",
-        GST_EVENT_TYPE_NAME (info->data));
-    return GST_PAD_PROBE_PASS;
+  if (GST_IS_EVENT (info->data)) {
+    if (!GST_EVENT_IS_SERIALIZED (info->data)) {
+      GST_DEBUG_OBJECT (pad, "Letting non-serialized event %s pass",
+          GST_EVENT_TYPE_NAME (info->data));
+      return GST_PAD_PROBE_PASS;
+    }
+    if (GST_EVENT_TYPE (info->data) == GST_EVENT_STREAM_START) {
+      GST_DEBUG_OBJECT (pad, "Letting event %s pass",
+          GST_EVENT_TYPE_NAME (info->data));
+      return GST_PAD_PROBE_PASS;
+    }
   }
 
   GST_DEBUG_OBJECT (pad, "Pad blocked");
@@ -1059,7 +1070,7 @@
 
   /* If there are no subcaps but the subtitle sink is blocked upstream
    * must behave wrong as there are no fixed caps set for the first
-   * buffer or in-order event */
+   * buffer or in-order event after stream-start */
   if (G_UNLIKELY (!subcaps && self->subtitle_sink_blocked)) {
     GST_ELEMENT_WARNING (self, CORE, NEGOTIATION, (NULL),
         ("Subtitle sink is blocked but we have no subtitle caps"));
@@ -1575,13 +1586,12 @@
           "ISO-8859-15 will be assumed.", NULL,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&srctemplate));
+  gst_element_class_add_static_pad_template (element_class, &srctemplate);
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&video_sinktemplate));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&subtitle_sinktemplate));
+  gst_element_class_add_static_pad_template (element_class,
+      &video_sinktemplate);
+  gst_element_class_add_static_pad_template (element_class,
+      &subtitle_sinktemplate);
 
   gst_element_class_set_static_metadata (element_class, "Subtitle Overlay",
       "Video/Overlay/Subtitle",
diff --git a/gst/playback/gsturidecodebin.c b/gst/playback/gsturidecodebin.c
index 2a4e7bc..d5c0307 100644
--- a/gst/playback/gsturidecodebin.c
+++ b/gst/playback/gsturidecodebin.c
@@ -41,9 +41,7 @@
 #include "gstplay-enum.h"
 #include "gstrawcaps.h"
 #include "gstplayback.h"
-
-/* From gstdecodebin2.c */
-gint _decode_bin_compare_factories_func (gconstpointer p1, gconstpointer p2);
+#include "gstplaybackutils.h"
 
 #define GST_TYPE_URI_DECODE_BIN \
   (gst_uri_decode_bin_get_type())
@@ -321,7 +319,7 @@
         gst_element_factory_list_get_elements
         (GST_ELEMENT_FACTORY_TYPE_DECODABLE, GST_RANK_MARGINAL);
     dec->factories =
-        g_list_sort (dec->factories, _decode_bin_compare_factories_func);
+        g_list_sort (dec->factories, gst_playback_utils_compare_factories_func);
     dec->factories_cookie = cookie;
   }
 }
@@ -699,8 +697,7 @@
       G_SIGNAL_RUN_LAST, 0, NULL, NULL,
       g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
+  gst_element_class_add_static_pad_template (gstelement_class, &srctemplate);
   gst_element_class_set_static_metadata (gstelement_class,
       "URI Decoder", "Generic/Bin/Decoder",
       "Autoplug and decode an URI to raw media",
@@ -743,6 +740,8 @@
   dec->ring_buffer_max_size = DEFAULT_RING_BUFFER_MAX_SIZE;
 
   GST_OBJECT_FLAG_SET (dec, GST_ELEMENT_FLAG_SOURCE);
+  gst_bin_set_suppressed_flags (GST_BIN (dec),
+      GST_ELEMENT_FLAG_SOURCE | GST_ELEMENT_FLAG_SINK);
 }
 
 static void
@@ -1683,9 +1682,6 @@
     bin->pending_decodebins = NULL;
 
   }
-
-  /* Don't loose the SOURCE flag */
-  GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_SOURCE);
 }
 
 static void
@@ -2063,8 +2059,6 @@
     GST_ELEMENT_ERROR (decoder, CORE, NEGOTIATION,
         (NULL), ("Can't link source to typefind element"));
     gst_bin_remove (GST_BIN_CAST (decoder), typefind);
-    /* Don't loose the SOURCE flag */
-    GST_OBJECT_FLAG_SET (decoder, GST_ELEMENT_FLAG_SOURCE);
     do_async_done (decoder);
     return FALSE;
   }
@@ -2113,8 +2107,6 @@
     g_hash_table_destroy (bin->streams);
     bin->streams = NULL;
   }
-  /* Don't loose the SOURCE flag */
-  GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_SOURCE);
 }
 
 /* is called when a dynamic source element created a new pad. */
diff --git a/gst/playback/gsturisourcebin.c b/gst/playback/gsturisourcebin.c
new file mode 100644
index 0000000..7720a4c
--- /dev/null
+++ b/gst/playback/gsturisourcebin.c
@@ -0,0 +1,2826 @@
+/* GStreamer
+ * Copyright (C) <2015> Jan Schmidt <jan@centricular.com>
+ * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.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.
+ */
+
+/**
+ * SECTION:element-urisourcebin
+ *
+ * urisourcebin is an element for accessing URIs in a uniform manner.
+ *
+ * It handles selecting a URI source element and potentially download
+ * buffering for network sources. It produces one or more source pads,
+ * depending on the input source, for feeding to decoding chains or decodebin.
+ *
+ * The main configuration is via the #GstURISourceBin:uri property.
+ *
+ * <emphasis>urisourcebin is still experimental API and a technology preview.
+ * Its behaviour and exposed API is subject to change.</emphasis>
+ */
+
+/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
+ * with newer GLib versions (>= 2.31.0) */
+#define GLIB_DISABLE_DEPRECATION_WARNINGS
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <string.h>
+
+#include <gst/gst.h>
+#include <gst/gst-i18n-plugin.h>
+#include <gst/pbutils/missing-plugins.h>
+
+#include "gstplay-enum.h"
+#include "gstrawcaps.h"
+#include "gstplayback.h"
+#include "gstplaybackutils.h"
+
+#define GST_TYPE_URI_DECODE_BIN \
+  (gst_uri_source_bin_get_type())
+#define GST_URI_SOURCE_BIN(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_URI_DECODE_BIN,GstURISourceBin))
+#define GST_URI_SOURCE_BIN_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_URI_DECODE_BIN,GstURISourceBinClass))
+#define GST_IS_URI_SOURCE_BIN(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_URI_DECODE_BIN))
+#define GST_IS_URI_SOURCE_BIN_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_URI_DECODE_BIN))
+#define GST_URI_SOURCE_BIN_CAST(obj) ((GstURISourceBin *) (obj))
+
+typedef struct _GstURISourceBin GstURISourceBin;
+typedef struct _GstURISourceBinClass GstURISourceBinClass;
+typedef struct _ChildSrcPadInfo ChildSrcPadInfo;
+typedef struct _OutputSlotInfo OutputSlotInfo;
+
+#define GST_URI_SOURCE_BIN_LOCK(dec) (g_mutex_lock(&((GstURISourceBin*)(dec))->lock))
+#define GST_URI_SOURCE_BIN_UNLOCK(dec) (g_mutex_unlock(&((GstURISourceBin*)(dec))->lock))
+
+/* Track a source pad from a child that
+ * is linked or needs linking to an output
+ * slot */
+struct _ChildSrcPadInfo
+{
+  guint blocking_probe_id;
+  guint event_probe_id;
+  GstPad *demux_src_pad;
+  GstCaps *cur_caps;            /* holds ref */
+
+  /* Configured output slot, if any */
+  OutputSlotInfo *output_slot;
+};
+
+struct _OutputSlotInfo
+{
+  ChildSrcPadInfo *linked_info; /* demux source pad info feeding this slot, if any */
+  GstElement *queue;            /* queue2 or downloadbuffer */
+  GstPad *sinkpad;              /* Sink pad of the queue eleemnt */
+  GstPad *srcpad;               /* Output ghost pad */
+  gboolean is_eos;              /* Did EOS get fed into the buffering element */
+};
+
+/**
+ * GstURISourceBin
+ *
+ * urisourcebin element struct
+ */
+struct _GstURISourceBin
+{
+  GstBin parent_instance;
+
+  GMutex lock;                  /* lock for constructing */
+
+  GMutex factories_lock;
+  guint32 factories_cookie;
+  GList *factories;             /* factories we can use for selecting elements */
+
+  gchar *uri;
+  guint64 connection_speed;
+
+  gboolean is_stream;
+  gboolean is_adaptive;
+  gboolean need_queue;
+  guint64 buffer_duration;      /* When buffering, buffer duration (ns) */
+  guint buffer_size;            /* When buffering, buffer size (bytes) */
+  gboolean download;
+  gboolean use_buffering;
+
+  GstElement *source;
+  GstElement *typefind;
+  guint have_type_id;           /* have-type signal id from typefind */
+
+  GstElement *demuxer;          /* Adaptive demuxer if any */
+  GSList *out_slots;
+
+  GHashTable *streams;
+  guint numpads;
+
+  /* for dynamic sources */
+  guint src_np_sig_id;          /* new-pad signal id */
+
+  gboolean async_pending;       /* async-start has been emitted */
+
+  guint64 ring_buffer_max_size; /* 0 means disabled */
+
+  GList *pending_pads;          /* Pads we have blocked pending assignment
+                                   to an output source pad */
+  GList *inactive_output_pads;  /* output pads that were unghosted */
+
+  GList *buffering_status;      /* element currently buffering messages */
+  gint last_buffering_pct;      /* Avoid sending buffering over and over */
+};
+
+struct _GstURISourceBinClass
+{
+  GstBinClass parent_class;
+
+  /* signal fired when we found a pad that we cannot decode */
+  void (*unknown_type) (GstElement * element, GstPad * pad, GstCaps * caps);
+
+  /* signal fired to know if we continue trying to decode the given caps */
+    gboolean (*autoplug_continue) (GstElement * element, GstPad * pad,
+      GstCaps * caps);
+  /* signal fired to get a list of factories to try to autoplug */
+  GValueArray *(*autoplug_factories) (GstElement * element, GstPad * pad,
+      GstCaps * caps);
+  /* signal fired to sort the factories */
+  GValueArray *(*autoplug_sort) (GstElement * element, GstPad * pad,
+      GstCaps * caps, GValueArray * factories);
+  /* signal fired to select from the proposed list of factories */
+    GstAutoplugSelectResult (*autoplug_select) (GstElement * element,
+      GstPad * pad, GstCaps * caps, GstElementFactory * factory);
+  /* signal fired when a autoplugged element that is not linked downstream
+   * or exposed wants to query something */
+    gboolean (*autoplug_query) (GstElement * element, GstPad * pad,
+      GstQuery * query);
+
+  /* emitted when all data is decoded */
+  void (*drained) (GstElement * element);
+};
+
+static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src_%u",
+    GST_PAD_SRC,
+    GST_PAD_SOMETIMES,
+    GST_STATIC_CAPS_ANY);
+
+static GstStaticCaps default_raw_caps = GST_STATIC_CAPS (DEFAULT_RAW_CAPS);
+
+GST_DEBUG_CATEGORY_STATIC (gst_uri_source_bin_debug);
+#define GST_CAT_DEFAULT gst_uri_source_bin_debug
+
+/* signals */
+enum
+{
+  SIGNAL_UNKNOWN_TYPE,
+  SIGNAL_AUTOPLUG_CONTINUE,
+  SIGNAL_AUTOPLUG_FACTORIES,
+  SIGNAL_AUTOPLUG_SELECT,
+  SIGNAL_AUTOPLUG_SORT,
+  SIGNAL_AUTOPLUG_QUERY,
+  SIGNAL_DRAINED,
+  SIGNAL_SOURCE_SETUP,
+  LAST_SIGNAL
+};
+
+/* properties */
+#define DEFAULT_PROP_URI            NULL
+#define DEFAULT_PROP_SOURCE         NULL
+#define DEFAULT_CONNECTION_SPEED    0
+#define DEFAULT_BUFFER_DURATION     -1
+#define DEFAULT_BUFFER_SIZE         -1
+#define DEFAULT_DOWNLOAD            FALSE
+#define DEFAULT_USE_BUFFERING       FALSE
+#define DEFAULT_RING_BUFFER_MAX_SIZE 0
+
+#define DEFAULT_CAPS (gst_static_caps_get (&default_raw_caps))
+enum
+{
+  PROP_0,
+  PROP_URI,
+  PROP_SOURCE,
+  PROP_CONNECTION_SPEED,
+  PROP_BUFFER_SIZE,
+  PROP_BUFFER_DURATION,
+  PROP_DOWNLOAD,
+  PROP_USE_BUFFERING,
+  PROP_RING_BUFFER_MAX_SIZE
+};
+
+static void post_missing_plugin_error (GstElement * dec,
+    const gchar * element_name);
+
+static guint gst_uri_source_bin_signals[LAST_SIGNAL] = { 0 };
+
+GType gst_uri_source_bin_get_type (void);
+#define gst_uri_source_bin_parent_class parent_class
+G_DEFINE_TYPE (GstURISourceBin, gst_uri_source_bin, GST_TYPE_BIN);
+
+static void gst_uri_source_bin_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_uri_source_bin_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+static void gst_uri_source_bin_finalize (GObject * obj);
+
+static void handle_message (GstBin * bin, GstMessage * msg);
+
+static gboolean gst_uri_source_bin_query (GstElement * element,
+    GstQuery * query);
+static GstStateChangeReturn gst_uri_source_bin_change_state (GstElement *
+    element, GstStateChange transition);
+
+static void remove_demuxer (GstURISourceBin * bin);
+static void expose_output_pad (GstURISourceBin * urisrc, GstPad * pad);
+static OutputSlotInfo *get_output_slot (GstURISourceBin * urisrc,
+    gboolean do_download, gboolean is_adaptive, GstCaps * caps);
+static void free_output_slot (OutputSlotInfo * slot, GstURISourceBin * urisrc);
+static GstPad *create_output_pad (GstURISourceBin * urisrc, GstPad * pad);
+static void remove_buffering_msgs (GstURISourceBin * bin, GstObject * src);
+
+static gboolean
+_gst_boolean_accumulator (GSignalInvocationHint * ihint,
+    GValue * return_accu, const GValue * handler_return, gpointer dummy)
+{
+  gboolean myboolean;
+
+  myboolean = g_value_get_boolean (handler_return);
+  if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
+    g_value_set_boolean (return_accu, myboolean);
+
+  /* stop emission if FALSE */
+  return myboolean;
+}
+
+static gboolean
+_gst_boolean_or_accumulator (GSignalInvocationHint * ihint,
+    GValue * return_accu, const GValue * handler_return, gpointer dummy)
+{
+  gboolean myboolean;
+  gboolean retboolean;
+
+  myboolean = g_value_get_boolean (handler_return);
+  retboolean = g_value_get_boolean (return_accu);
+
+  if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
+    g_value_set_boolean (return_accu, myboolean || retboolean);
+
+  return TRUE;
+}
+
+static gboolean
+_gst_array_accumulator (GSignalInvocationHint * ihint,
+    GValue * return_accu, const GValue * handler_return, gpointer dummy)
+{
+  gpointer array;
+
+  array = g_value_get_boxed (handler_return);
+  if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
+    g_value_set_boxed (return_accu, array);
+
+  return FALSE;
+}
+
+static gboolean
+_gst_select_accumulator (GSignalInvocationHint * ihint,
+    GValue * return_accu, const GValue * handler_return, gpointer dummy)
+{
+  GstAutoplugSelectResult res;
+
+  res = g_value_get_enum (handler_return);
+  if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
+    g_value_set_enum (return_accu, res);
+
+  /* Call the next handler in the chain (if any) when the current callback
+   * returns TRY. This makes it possible to register separate autoplug-select
+   * handlers that implement different TRY/EXPOSE/SKIP strategies.
+   */
+  if (res == GST_AUTOPLUG_SELECT_TRY)
+    return TRUE;
+
+  return FALSE;
+}
+
+static gboolean
+_gst_array_hasvalue_accumulator (GSignalInvocationHint * ihint,
+    GValue * return_accu, const GValue * handler_return, gpointer dummy)
+{
+  gpointer array;
+
+  array = g_value_get_boxed (handler_return);
+  if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
+    g_value_set_boxed (return_accu, array);
+
+  if (array != NULL)
+    return FALSE;
+
+  return TRUE;
+}
+
+static gboolean
+gst_uri_source_bin_autoplug_continue (GstElement * element, GstPad * pad,
+    GstCaps * caps)
+{
+  /* by default we always continue */
+  return TRUE;
+}
+
+/* Must be called with factories lock! */
+static void
+gst_uri_source_bin_update_factories_list (GstURISourceBin * dec)
+{
+  guint32 cookie;
+
+  cookie = gst_registry_get_feature_list_cookie (gst_registry_get ());
+  if (!dec->factories || dec->factories_cookie != cookie) {
+    if (dec->factories)
+      gst_plugin_feature_list_free (dec->factories);
+    dec->factories =
+        gst_element_factory_list_get_elements
+        (GST_ELEMENT_FACTORY_TYPE_DECODABLE, GST_RANK_MARGINAL);
+    dec->factories =
+        g_list_sort (dec->factories, gst_playback_utils_compare_factories_func);
+    dec->factories_cookie = cookie;
+  }
+}
+
+static GValueArray *
+gst_uri_source_bin_autoplug_factories (GstElement * element, GstPad * pad,
+    GstCaps * caps)
+{
+  GList *list, *tmp;
+  GValueArray *result;
+  GstURISourceBin *dec = GST_URI_SOURCE_BIN_CAST (element);
+
+  GST_DEBUG_OBJECT (element, "finding factories");
+
+  /* return all compatible factories for caps */
+  g_mutex_lock (&dec->factories_lock);
+  gst_uri_source_bin_update_factories_list (dec);
+  list =
+      gst_element_factory_list_filter (dec->factories, caps, GST_PAD_SINK,
+      gst_caps_is_fixed (caps));
+  g_mutex_unlock (&dec->factories_lock);
+
+  result = g_value_array_new (g_list_length (list));
+  for (tmp = list; tmp; tmp = tmp->next) {
+    GstElementFactory *factory = GST_ELEMENT_FACTORY_CAST (tmp->data);
+    GValue val = { 0, };
+
+    g_value_init (&val, G_TYPE_OBJECT);
+    g_value_set_object (&val, factory);
+    g_value_array_append (result, &val);
+    g_value_unset (&val);
+  }
+  gst_plugin_feature_list_free (list);
+
+  GST_DEBUG_OBJECT (element, "autoplug-factories returns %p", result);
+
+  return result;
+}
+
+static GValueArray *
+gst_uri_source_bin_autoplug_sort (GstElement * element, GstPad * pad,
+    GstCaps * caps, GValueArray * factories)
+{
+  return NULL;
+}
+
+static GstAutoplugSelectResult
+gst_uri_source_bin_autoplug_select (GstElement * element, GstPad * pad,
+    GstCaps * caps, GstElementFactory * factory)
+{
+  GST_DEBUG_OBJECT (element, "default autoplug-select returns TRY");
+
+  /* Try factory. */
+  return GST_AUTOPLUG_SELECT_TRY;
+}
+
+static gboolean
+gst_uri_source_bin_autoplug_query (GstElement * element, GstPad * pad,
+    GstQuery * query)
+{
+  /* No query handled here */
+  return FALSE;
+}
+
+static void
+gst_uri_source_bin_class_init (GstURISourceBinClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+  GstBinClass *gstbin_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gstelement_class = GST_ELEMENT_CLASS (klass);
+  gstbin_class = GST_BIN_CLASS (klass);
+
+  gobject_class->set_property = gst_uri_source_bin_set_property;
+  gobject_class->get_property = gst_uri_source_bin_get_property;
+  gobject_class->finalize = gst_uri_source_bin_finalize;
+
+  g_object_class_install_property (gobject_class, PROP_URI,
+      g_param_spec_string ("uri", "URI", "URI to decode",
+          DEFAULT_PROP_URI, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_SOURCE,
+      g_param_spec_object ("source", "Source", "Source object used",
+          GST_TYPE_ELEMENT, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_CONNECTION_SPEED,
+      g_param_spec_uint64 ("connection-speed", "Connection Speed",
+          "Network connection speed in kbps (0 = unknown)",
+          0, G_MAXUINT64 / 1000, DEFAULT_CONNECTION_SPEED,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_BUFFER_SIZE,
+      g_param_spec_int ("buffer-size", "Buffer size (bytes)",
+          "Buffer size when buffering streams (-1 default value)",
+          -1, G_MAXINT, DEFAULT_BUFFER_SIZE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_BUFFER_DURATION,
+      g_param_spec_int64 ("buffer-duration", "Buffer duration (ns)",
+          "Buffer duration when buffering streams (-1 default value)",
+          -1, G_MAXINT64, DEFAULT_BUFFER_DURATION,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstURISourceBin::download:
+   *
+   * For certain media type, enable download buffering.
+   */
+  g_object_class_install_property (gobject_class, PROP_DOWNLOAD,
+      g_param_spec_boolean ("download", "Download",
+          "Attempt download buffering when buffering network streams",
+          DEFAULT_DOWNLOAD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**  
+   * GstURISourceBin::use-buffering:
+   *
+   * Perform buffering using a queue2 element, and emit BUFFERING
+   * messages based on low-/high-percent thresholds of streaming data,
+   * such as adaptive-demuxer streams.
+   *
+   * When download buffering is activated and used for the current media
+   * type, this property does nothing.
+   *
+   */
+  g_object_class_install_property (gobject_class, PROP_USE_BUFFERING,
+      g_param_spec_boolean ("use-buffering", "Use Buffering",
+          "Perform buffering on demuxed/parsed media",
+          DEFAULT_USE_BUFFERING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstURISourceBin::ring-buffer-max-size
+   *
+   * The maximum size of the ring buffer in kilobytes. If set to 0, the ring
+   * buffer is disabled. Default is 0.
+   *
+   */
+  g_object_class_install_property (gobject_class, PROP_RING_BUFFER_MAX_SIZE,
+      g_param_spec_uint64 ("ring-buffer-max-size",
+          "Max. ring buffer size (bytes)",
+          "Max. amount of data in the ring buffer (bytes, 0 = ring buffer disabled)",
+          0, G_MAXUINT, DEFAULT_RING_BUFFER_MAX_SIZE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
+   * GstURISourceBin::unknown-type:
+   * @bin: The urisourcebin.
+   * @pad: the new pad containing caps that cannot be resolved to a 'final'.
+   * stream type.
+   * @caps: the #GstCaps of the pad that cannot be resolved.
+   *
+   * This signal is emitted when a pad for which there is no further possible
+   * decoding is added to the urisourcebin.
+   */
+  gst_uri_source_bin_signals[SIGNAL_UNKNOWN_TYPE] =
+      g_signal_new ("unknown-type", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstURISourceBinClass, unknown_type),
+      NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2,
+      GST_TYPE_PAD, GST_TYPE_CAPS);
+
+  /**
+   * GstURISourceBin::autoplug-continue:
+   * @bin: The urisourcebin.
+   * @pad: The #GstPad.
+   * @caps: The #GstCaps found.
+   *
+   * This signal is emitted whenever urisourcebin finds a new stream. It is
+   * emitted before looking for any elements that can handle that stream.
+   *
+   * <note>
+   *   Invocation of signal handlers stops after the first signal handler
+   *   returns #FALSE. Signal handlers are invoked in the order they were
+   *   connected in.
+   * </note>
+   *
+   * Returns: #TRUE if you wish urisourcebin to look for elements that can
+   * handle the given @caps. If #FALSE, those caps will be considered as
+   * final and the pad will be exposed as such (see 'pad-added' signal of
+   * #GstElement).
+   */
+  gst_uri_source_bin_signals[SIGNAL_AUTOPLUG_CONTINUE] =
+      g_signal_new ("autoplug-continue", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstURISourceBinClass,
+          autoplug_continue), _gst_boolean_accumulator, NULL,
+      g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 2, GST_TYPE_PAD,
+      GST_TYPE_CAPS);
+
+  /**
+   * GstURISourceBin::autoplug-factories:
+   * @bin: The urisourcebin.
+   * @pad: The #GstPad.
+   * @caps: The #GstCaps found.
+   *
+   * This function is emitted when an array of possible factories for @caps on
+   * @pad is needed. urisourcebin will by default return an array with all
+   * compatible factories, sorted by rank.
+   *
+   * If this function returns NULL, @pad will be exposed as a final caps.
+   *
+   * If this function returns an empty array, the pad will be considered as
+   * having an unhandled type media type.
+   *
+   * <note>
+   *   Only the signal handler that is connected first will ever by invoked.
+   *   Don't connect signal handlers with the #G_CONNECT_AFTER flag to this
+   *   signal, they will never be invoked!
+   * </note>
+   *
+   * Returns: a #GValueArray* with a list of factories to try. The factories are
+   * by default tried in the returned order or based on the index returned by
+   * "autoplug-select".
+   */
+  gst_uri_source_bin_signals[SIGNAL_AUTOPLUG_FACTORIES] =
+      g_signal_new ("autoplug-factories", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstURISourceBinClass,
+          autoplug_factories), _gst_array_accumulator, NULL,
+      g_cclosure_marshal_generic, G_TYPE_VALUE_ARRAY, 2,
+      GST_TYPE_PAD, GST_TYPE_CAPS);
+
+  /**
+   * GstURISourceBin::autoplug-sort:
+   * @bin: The urisourcebin.
+   * @pad: The #GstPad.
+   * @caps: The #GstCaps.
+   * @factories: A #GValueArray of possible #GstElementFactory to use.
+   *
+   * Once decodebin has found the possible #GstElementFactory objects to try
+   * for @caps on @pad, this signal is emited. The purpose of the signal is for
+   * the application to perform additional sorting or filtering on the element
+   * factory array.
+   *
+   * The callee should copy and modify @factories or return #NULL if the
+   * order should not change.
+   *
+   * <note>
+   *   Invocation of signal handlers stops after one signal handler has
+   *   returned something else than #NULL. Signal handlers are invoked in
+   *   the order they were connected in.
+   *   Don't connect signal handlers with the #G_CONNECT_AFTER flag to this
+   *   signal, they will never be invoked!
+   * </note>
+   *
+   * Returns: A new sorted array of #GstElementFactory objects.
+   *
+   * Since: 0.10.33
+   */
+  gst_uri_source_bin_signals[SIGNAL_AUTOPLUG_SORT] =
+      g_signal_new ("autoplug-sort", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstURISourceBinClass, autoplug_sort),
+      _gst_array_hasvalue_accumulator, NULL,
+      g_cclosure_marshal_generic, G_TYPE_VALUE_ARRAY, 3, GST_TYPE_PAD,
+      GST_TYPE_CAPS, G_TYPE_VALUE_ARRAY | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+  /**
+   * GstURISourceBin::autoplug-select:
+   * @bin: The urisourcebin.
+   * @pad: The #GstPad.
+   * @caps: The #GstCaps.
+   * @factory: A #GstElementFactory to use.
+   *
+   * This signal is emitted once urisourcebin has found all the possible
+   * #GstElementFactory that can be used to handle the given @caps. For each of
+   * those factories, this signal is emitted.
+   *
+   * The signal handler should return a #GST_TYPE_AUTOPLUG_SELECT_RESULT enum
+   * value indicating what decodebin should do next.
+   *
+   * A value of #GST_AUTOPLUG_SELECT_TRY will try to autoplug an element from
+   * @factory.
+   *
+   * A value of #GST_AUTOPLUG_SELECT_EXPOSE will expose @pad without plugging
+   * any element to it.
+   *
+   * A value of #GST_AUTOPLUG_SELECT_SKIP will skip @factory and move to the
+   * next factory.
+   *
+   * <note>
+   *   The signal handler will not be invoked if any of the previously
+   *   registered signal handlers (if any) return a value other than
+   *   GST_AUTOPLUG_SELECT_TRY. Which also means that if you return
+   *   GST_AUTOPLUG_SELECT_TRY from one signal handler, handlers that get
+   *   registered next (again, if any) can override that decision.
+   * </note>
+   *
+   * Returns: a #GST_TYPE_AUTOPLUG_SELECT_RESULT that indicates the required
+   * operation. The default handler will always return
+   * #GST_AUTOPLUG_SELECT_TRY.
+   */
+  gst_uri_source_bin_signals[SIGNAL_AUTOPLUG_SELECT] =
+      g_signal_new ("autoplug-select", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstURISourceBinClass,
+          autoplug_select), _gst_select_accumulator, NULL,
+      g_cclosure_marshal_generic,
+      GST_TYPE_AUTOPLUG_SELECT_RESULT, 3, GST_TYPE_PAD, GST_TYPE_CAPS,
+      GST_TYPE_ELEMENT_FACTORY);
+
+  /**
+   * GstDecodeBin::autoplug-query:
+   * @bin: The decodebin.
+   * @child: The child element doing the query
+   * @pad: The #GstPad.
+   * @query: The #GstQuery.
+   *
+   * This signal is emitted whenever an autoplugged element that is
+   * not linked downstream yet and not exposed does a query. It can
+   * be used to tell the element about the downstream supported caps
+   * for example.
+   *
+   * Returns: #TRUE if the query was handled, #FALSE otherwise.
+   */
+  gst_uri_source_bin_signals[SIGNAL_AUTOPLUG_QUERY] =
+      g_signal_new ("autoplug-query", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstURISourceBinClass, autoplug_query),
+      _gst_boolean_or_accumulator, NULL, g_cclosure_marshal_generic,
+      G_TYPE_BOOLEAN, 3, GST_TYPE_PAD, GST_TYPE_ELEMENT,
+      GST_TYPE_QUERY | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+  /**
+   * GstURISourceBin::drained:
+   *
+   * This signal is emitted when the data for the current uri is played.
+   */
+  gst_uri_source_bin_signals[SIGNAL_DRAINED] =
+      g_signal_new ("drained", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST,
+      G_STRUCT_OFFSET (GstURISourceBinClass, drained), NULL, NULL,
+      g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);
+
+  /**
+   * GstURISourceBin::source-setup:
+   * @bin: the urisourcebin.
+   * @source: source element
+   *
+   * This signal is emitted after the source element has been created, so
+   * it can be configured by setting additional properties (e.g. set a
+   * proxy server for an http source, or set the device and read speed for
+   * an audio cd source). This is functionally equivalent to connecting to
+   * the notify::source signal, but more convenient.
+   *
+   * Since: 1.6.1
+   */
+  gst_uri_source_bin_signals[SIGNAL_SOURCE_SETUP] =
+      g_signal_new ("source-setup", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+      g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&srctemplate));
+  gst_element_class_set_static_metadata (gstelement_class,
+      "URI reader", "Generic/Bin/Source",
+      "Download and buffer a URI as needed",
+      "Jan Schmidt <jan@centricular.com>");
+
+  gstelement_class->query = GST_DEBUG_FUNCPTR (gst_uri_source_bin_query);
+  gstelement_class->change_state =
+      GST_DEBUG_FUNCPTR (gst_uri_source_bin_change_state);
+
+  gstbin_class->handle_message = GST_DEBUG_FUNCPTR (handle_message);
+
+  klass->autoplug_continue =
+      GST_DEBUG_FUNCPTR (gst_uri_source_bin_autoplug_continue);
+  klass->autoplug_factories =
+      GST_DEBUG_FUNCPTR (gst_uri_source_bin_autoplug_factories);
+  klass->autoplug_sort = GST_DEBUG_FUNCPTR (gst_uri_source_bin_autoplug_sort);
+  klass->autoplug_select =
+      GST_DEBUG_FUNCPTR (gst_uri_source_bin_autoplug_select);
+  klass->autoplug_query = GST_DEBUG_FUNCPTR (gst_uri_source_bin_autoplug_query);
+}
+
+static void
+gst_uri_source_bin_init (GstURISourceBin * urisrc)
+{
+  /* first filter out the interesting element factories */
+  g_mutex_init (&urisrc->factories_lock);
+
+  g_mutex_init (&urisrc->lock);
+
+  urisrc->uri = g_strdup (DEFAULT_PROP_URI);
+  urisrc->connection_speed = DEFAULT_CONNECTION_SPEED;
+
+  urisrc->buffer_duration = DEFAULT_BUFFER_DURATION;
+  urisrc->buffer_size = DEFAULT_BUFFER_SIZE;
+  urisrc->download = DEFAULT_DOWNLOAD;
+  urisrc->ring_buffer_max_size = DEFAULT_RING_BUFFER_MAX_SIZE;
+  urisrc->last_buffering_pct = -1;
+
+  GST_OBJECT_FLAG_SET (urisrc, GST_ELEMENT_FLAG_SOURCE);
+  gst_bin_set_suppressed_flags (GST_BIN (urisrc),
+      GST_ELEMENT_FLAG_SOURCE | GST_ELEMENT_FLAG_SINK);
+}
+
+static void
+gst_uri_source_bin_finalize (GObject * obj)
+{
+  GstURISourceBin *urisrc = GST_URI_SOURCE_BIN (obj);
+
+  remove_demuxer (urisrc);
+  g_mutex_clear (&urisrc->lock);
+  g_mutex_clear (&urisrc->factories_lock);
+  g_free (urisrc->uri);
+  if (urisrc->factories)
+    gst_plugin_feature_list_free (urisrc->factories);
+
+  G_OBJECT_CLASS (parent_class)->finalize (obj);
+}
+
+static void
+gst_uri_source_bin_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstURISourceBin *dec = GST_URI_SOURCE_BIN (object);
+
+  switch (prop_id) {
+    case PROP_URI:
+      GST_OBJECT_LOCK (dec);
+      g_free (dec->uri);
+      dec->uri = g_value_dup_string (value);
+      GST_OBJECT_UNLOCK (dec);
+      break;
+    case PROP_CONNECTION_SPEED:
+      GST_OBJECT_LOCK (dec);
+      dec->connection_speed = g_value_get_uint64 (value) * 1000;
+      GST_OBJECT_UNLOCK (dec);
+      break;
+    case PROP_BUFFER_SIZE:
+      dec->buffer_size = g_value_get_int (value);
+      break;
+    case PROP_BUFFER_DURATION:
+      dec->buffer_duration = g_value_get_int64 (value);
+      break;
+    case PROP_DOWNLOAD:
+      dec->download = g_value_get_boolean (value);
+      break;
+    case PROP_USE_BUFFERING:
+      dec->use_buffering = g_value_get_boolean (value);
+      break;
+    case PROP_RING_BUFFER_MAX_SIZE:
+      dec->ring_buffer_max_size = g_value_get_uint64 (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_uri_source_bin_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GstURISourceBin *dec = GST_URI_SOURCE_BIN (object);
+
+  switch (prop_id) {
+    case PROP_URI:
+      GST_OBJECT_LOCK (dec);
+      g_value_set_string (value, dec->uri);
+      GST_OBJECT_UNLOCK (dec);
+      break;
+    case PROP_SOURCE:
+      GST_OBJECT_LOCK (dec);
+      g_value_set_object (value, dec->source);
+      GST_OBJECT_UNLOCK (dec);
+      break;
+    case PROP_CONNECTION_SPEED:
+      GST_OBJECT_LOCK (dec);
+      g_value_set_uint64 (value, dec->connection_speed / 1000);
+      GST_OBJECT_UNLOCK (dec);
+      break;
+    case PROP_BUFFER_SIZE:
+      GST_OBJECT_LOCK (dec);
+      g_value_set_int (value, dec->buffer_size);
+      GST_OBJECT_UNLOCK (dec);
+      break;
+    case PROP_BUFFER_DURATION:
+      GST_OBJECT_LOCK (dec);
+      g_value_set_int64 (value, dec->buffer_duration);
+      GST_OBJECT_UNLOCK (dec);
+      break;
+    case PROP_DOWNLOAD:
+      g_value_set_boolean (value, dec->download);
+      break;
+    case PROP_USE_BUFFERING:
+      g_value_set_boolean (value, dec->use_buffering);
+      break;
+    case PROP_RING_BUFFER_MAX_SIZE:
+      g_value_set_uint64 (value, dec->ring_buffer_max_size);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+do_async_start (GstURISourceBin * dbin)
+{
+  GstMessage *message;
+
+  dbin->async_pending = TRUE;
+
+  message = gst_message_new_async_start (GST_OBJECT_CAST (dbin));
+  GST_BIN_CLASS (parent_class)->handle_message (GST_BIN_CAST (dbin), message);
+}
+
+static void
+do_async_done (GstURISourceBin * dbin)
+{
+  GstMessage *message;
+
+  if (dbin->async_pending) {
+    GST_DEBUG_OBJECT (dbin, "posting ASYNC_DONE");
+    message =
+        gst_message_new_async_done (GST_OBJECT_CAST (dbin),
+        GST_CLOCK_TIME_NONE);
+    GST_BIN_CLASS (parent_class)->handle_message (GST_BIN_CAST (dbin), message);
+
+    dbin->async_pending = FALSE;
+  }
+}
+
+#define DEFAULT_QUEUE_SIZE          (3 * GST_SECOND)
+#define DEFAULT_QUEUE_MIN_THRESHOLD ((DEFAULT_QUEUE_SIZE * 30) / 100)
+#define DEFAULT_QUEUE_THRESHOLD     ((DEFAULT_QUEUE_SIZE * 95) / 100)
+
+static gboolean
+copy_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
+{
+  GstPad *gpad = GST_PAD_CAST (user_data);
+
+  GST_DEBUG_OBJECT (gpad, "store sticky event %" GST_PTR_FORMAT, *event);
+  gst_pad_store_sticky_event (gpad, *event);
+
+  return TRUE;
+}
+
+static GstPadProbeReturn
+pending_pad_blocked (GstPad * pad, GstPadProbeInfo * info, gpointer user_data);
+
+static GstPadProbeReturn
+demux_pad_events (GstPad * pad, GstPadProbeInfo * info, gpointer user_data);
+
+static void
+free_child_src_pad_info (ChildSrcPadInfo * info)
+{
+  if (info->cur_caps)
+    gst_caps_unref (info->cur_caps);
+  g_free (info);
+}
+
+/* Called by the signal handlers when a demuxer has produced a new stream */
+static void
+new_demuxer_pad_added_cb (GstElement * element, GstPad * pad,
+    GstURISourceBin * urisrc)
+{
+  ChildSrcPadInfo *info;
+
+  info = g_new0 (ChildSrcPadInfo, 1);
+  info->demux_src_pad = pad;
+  info->cur_caps = gst_pad_get_current_caps (pad);
+  if (info->cur_caps == NULL)
+    info->cur_caps = gst_pad_query_caps (pad, NULL);
+
+  g_object_set_data_full (G_OBJECT (pad), "urisourcebin.srcpadinfo",
+      info, (GDestroyNotify) free_child_src_pad_info);
+
+  GST_DEBUG_OBJECT (element, "new demuxer pad, name: <%s>. "
+      "Added as pending pad with caps %" GST_PTR_FORMAT,
+      GST_PAD_NAME (pad), info->cur_caps);
+
+  GST_URI_SOURCE_BIN_LOCK (urisrc);
+  urisrc->pending_pads = g_list_prepend (urisrc->pending_pads, pad);
+  GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+
+  /* Block the pad. On the first data on that pad if it hasn't
+   * been linked to an output slot, we'll create one */
+  info->blocking_probe_id =
+      gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
+      pending_pad_blocked, urisrc, NULL);
+  info->event_probe_id =
+      gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
+      demux_pad_events, urisrc, NULL);
+}
+
+static GstPadProbeReturn
+pending_pad_blocked (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
+{
+  ChildSrcPadInfo *child_info;
+  OutputSlotInfo *slot;
+  GstURISourceBin *urisrc = GST_URI_SOURCE_BIN (user_data);
+  GstCaps *caps;
+
+  if (!(child_info =
+          g_object_get_data (G_OBJECT (pad), "urisourcebin.srcpadinfo")))
+    goto done;
+
+  GST_LOG_OBJECT (urisrc, "Removing pad %" GST_PTR_FORMAT " from pending list",
+      pad);
+
+  GST_URI_SOURCE_BIN_LOCK (urisrc);
+
+  /* Once blocked, this pad is no longer pending, one way or another */
+  urisrc->pending_pads = g_list_remove (urisrc->pending_pads, pad);
+
+  /* If already linked to a slot, nothing more to do */
+  if (child_info->output_slot) {
+    GST_LOG_OBJECT (urisrc, "Pad %" GST_PTR_FORMAT " is linked to slot %p",
+        pad, child_info->output_slot);
+    GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+    goto done;
+  }
+
+  caps = gst_pad_get_current_caps (pad);
+  if (caps == NULL)
+    caps = gst_pad_query_caps (pad, NULL);
+
+  /* FIXME: Don't do buffering if use_buffering is FALSE */
+  slot = get_output_slot (urisrc, FALSE, TRUE, caps);
+
+  gst_caps_unref (caps);
+
+  if (slot == NULL) {
+    GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+    goto done;
+  }
+
+  GST_LOG_OBJECT (urisrc, "Pad %" GST_PTR_FORMAT " linked to slot %p", pad,
+      slot);
+
+  child_info->output_slot = slot;
+  slot->linked_info = child_info;
+  GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+
+  gst_pad_link (pad, slot->sinkpad);
+
+  expose_output_pad (urisrc, slot->srcpad);
+
+done:
+  return GST_PAD_PROBE_REMOVE;
+}
+
+/* Called with LOCK held */
+/* Looks for a suitable pending pad to connect onto this
+ * finishing output slot that's about to EOS */
+static gboolean
+link_pending_pad_to_output (GstURISourceBin * urisrc, OutputSlotInfo * slot)
+{
+  GList *cur;
+  ChildSrcPadInfo *in_info = slot->linked_info;
+  ChildSrcPadInfo *out_info = NULL;
+  gboolean res = FALSE;
+  GstCaps *cur_caps;
+
+  /* Look for a suitable pending pad */
+  cur_caps = gst_pad_get_current_caps (slot->sinkpad);
+
+  for (cur = urisrc->pending_pads; cur != NULL; cur = g_list_next (cur)) {
+    GstPad *pending = (GstPad *) (cur->data);
+    ChildSrcPadInfo *cur_info = NULL;
+    if ((cur_info =
+            g_object_get_data (G_OBJECT (pending),
+                "urisourcebin.srcpadinfo"))) {
+      /* Don't re-link to the same pad in case of EOS while still pending */
+      if (in_info == cur_info)
+        continue;
+      if (cur_caps == NULL || gst_caps_is_equal (cur_caps, cur_info->cur_caps)) {
+        GST_DEBUG_OBJECT (urisrc, "Found suitable pending pad %" GST_PTR_FORMAT
+            " with caps %" GST_PTR_FORMAT " to link to this output slot",
+            cur_info->demux_src_pad, cur_info->cur_caps);
+        out_info = cur_info;
+        break;
+      }
+    }
+  }
+
+  if (cur_caps)
+    gst_caps_unref (cur_caps);
+
+  if (out_info) {
+    /* Block any upstream stuff while we switch out the pad */
+    guint block_id =
+        gst_pad_add_probe (slot->sinkpad, GST_PAD_PROBE_TYPE_BLOCK_UPSTREAM,
+        NULL, NULL, NULL);
+    GST_DEBUG_OBJECT (urisrc, "Linking pending pad to existing output slot %p",
+        slot);
+
+    if (in_info) {
+      gst_pad_unlink (in_info->demux_src_pad, slot->sinkpad);
+      in_info->output_slot = NULL;
+      slot->linked_info = NULL;
+    }
+
+    if (gst_pad_link (out_info->demux_src_pad,
+            slot->sinkpad) == GST_PAD_LINK_OK) {
+      out_info->output_slot = slot;
+      slot->linked_info = out_info;
+      res = TRUE;
+    } else {
+      GST_ERROR_OBJECT (urisrc,
+          "Failed to link new demuxer pad to the output slot we tried");
+    }
+    gst_pad_remove_probe (slot->sinkpad, block_id);
+  }
+
+  return res;
+}
+
+static GstPadProbeReturn
+demux_pad_events (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
+{
+  GstURISourceBin *urisrc = GST_URI_SOURCE_BIN (user_data);
+  ChildSrcPadInfo *child_info;
+
+  if (!(child_info =
+          g_object_get_data (G_OBJECT (pad), "urisourcebin.srcpadinfo")))
+    goto done;
+
+  GST_URI_SOURCE_BIN_LOCK (urisrc);
+  /* If not linked to a slot, nothing more to do */
+  if (child_info->output_slot == NULL) {
+    GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+    goto done;
+  }
+
+  if (GST_IS_EVENT (GST_PAD_PROBE_INFO_DATA (info))) {
+    GstEvent *ev = GST_PAD_PROBE_INFO_EVENT (info);
+    if (GST_EVENT_TYPE (ev) == GST_EVENT_EOS && urisrc->pending_pads) {
+      GST_LOG_OBJECT (urisrc, "EOS on pad %" GST_PTR_FORMAT, pad);
+      if (!link_pending_pad_to_output (urisrc, child_info->output_slot)) {
+        GstEvent *event;
+        GstStructure *s;
+
+        /* Mark that we fed an EOS to this slot */
+        child_info->output_slot->is_eos = TRUE;
+
+        /* Actually feed a custom EOS event to avoid marking pads as EOSed */
+        s = gst_structure_new_empty ("urisourcebin-custom-eos");
+        event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);
+        gst_pad_send_event (child_info->output_slot->sinkpad, event);
+      }
+      GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+      return GST_PAD_PROBE_HANDLED;
+    } else if (GST_EVENT_TYPE (ev) == GST_EVENT_CAPS) {
+      GstCaps *caps;
+      gst_event_parse_caps (ev, &caps);
+      gst_caps_replace (&child_info->cur_caps, caps);
+    }
+  }
+  GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+
+done:
+  return GST_PAD_PROBE_OK;
+}
+
+/* Called with lock held */
+static OutputSlotInfo *
+get_output_slot (GstURISourceBin * urisrc, gboolean do_download,
+    gboolean is_adaptive, GstCaps * caps)
+{
+  OutputSlotInfo *slot;
+  GstPad *srcpad;
+  GstElement *queue;
+  const gchar *elem_name;
+
+  /* If we have caps, iterate the existing slots and look for an
+   * unlinked one that can be used */
+  if (caps && gst_caps_is_fixed (caps)) {
+    GSList *cur;
+    GstCaps *cur_caps;
+
+    for (cur = urisrc->out_slots; cur != NULL; cur = g_slist_next (cur)) {
+      slot = (OutputSlotInfo *) (cur->data);
+      if (slot->linked_info == NULL) {
+        cur_caps = gst_pad_get_current_caps (slot->sinkpad);
+        if (cur_caps == NULL || gst_caps_is_equal (caps, cur_caps)) {
+          GST_LOG_OBJECT (urisrc, "Found existing slot %p to link to", slot);
+          gst_caps_unref (cur_caps);
+          return slot;
+        }
+        gst_caps_unref (cur_caps);
+      }
+    }
+  }
+
+  /* Otherwise create the new slot */
+#if 0                           /* There's no downloadbuffer in 1.2 */
+  if (do_download)
+    elem_name = "downloadbuffer";
+  else
+#endif
+    elem_name = "queue2";
+
+  queue = gst_element_factory_make (elem_name, NULL);
+  if (!queue)
+    goto no_buffer_element;
+
+  slot = g_new0 (OutputSlotInfo, 1);
+  slot->queue = queue;
+
+  if (do_download) {
+    gchar *temp_template, *filename;
+    const gchar *tmp_dir, *prgname;
+
+    tmp_dir = g_get_user_cache_dir ();
+    prgname = g_get_prgname ();
+    if (prgname == NULL)
+      prgname = "GStreamer";
+
+    filename = g_strdup_printf ("%s-XXXXXX", prgname);
+
+    /* build our filename */
+    temp_template = g_build_filename (tmp_dir, filename, NULL);
+
+    GST_DEBUG_OBJECT (urisrc, "enable download buffering in %s (%s, %s, %s)",
+        temp_template, tmp_dir, prgname, filename);
+
+    /* configure progressive download for selected media types */
+    g_object_set (queue, "temp-template", temp_template, NULL);
+
+    g_free (filename);
+    g_free (temp_template);
+  } else {
+    if (is_adaptive) {
+      GST_LOG_OBJECT (urisrc, "Adding queue for adaptive streaming stream");
+      g_object_set (queue, "use-buffering", TRUE, "use-tags-bitrate", TRUE,
+          "use-rate-estimate", FALSE, NULL);
+    } else {
+      GST_LOG_OBJECT (urisrc, "Adding queue for buffering");
+      g_object_set (queue, "use-buffering", TRUE, NULL);
+    }
+    g_object_set (queue, "ring-buffer-max-size",
+        urisrc->ring_buffer_max_size, NULL);
+    /* Disable max-size-buffers - queue based on data rate to the default time limit */
+    g_object_set (queue, "max-size-buffers", 0, NULL);
+  }
+
+  /* If buffer size or duration are set, set them on the element */
+  if (urisrc->buffer_size != -1)
+    g_object_set (queue, "max-size-bytes", urisrc->buffer_size, NULL);
+  if (urisrc->buffer_duration != -1)
+    g_object_set (queue, "max-size-time", urisrc->buffer_duration, NULL);
+  else {
+    /* Buffer 4 seconds by default - some extra headroom over the
+     * core default, because we trigger playback sooner */
+    g_object_set (queue, "max-size-time", 4 * GST_SECOND, NULL);
+  }
+
+  /* Don't start buffering until the queue is empty (< 1%).
+   * Start playback when the queue is 60% full, leaving a bit more room
+   * for upstream to push more without getting bursty */
+  g_object_set (queue, "low-percent", 1, "high-percent", 60, NULL);
+
+  /* save queue pointer so we can remove it later */
+  urisrc->out_slots = g_slist_prepend (urisrc->out_slots, slot);
+
+  gst_bin_add (GST_BIN_CAST (urisrc), queue);
+  gst_element_sync_state_with_parent (queue);
+
+  slot->sinkpad = gst_element_get_static_pad (queue, "sink");
+
+  /* get the new raw srcpad */
+  srcpad = gst_element_get_static_pad (queue, "src");
+  g_object_set_data (G_OBJECT (srcpad), "urisourcebin.slotinfo", slot);
+
+  slot->srcpad = create_output_pad (urisrc, srcpad);
+
+  gst_object_unref (srcpad);
+
+  return slot;
+
+no_buffer_element:
+  {
+    post_missing_plugin_error (GST_ELEMENT_CAST (urisrc), elem_name);
+    return NULL;
+  }
+}
+
+static GstPadProbeReturn
+source_pad_event_probe (GstPad * pad, GstPadProbeInfo * info,
+    gpointer user_data)
+{
+  GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
+  GstURISourceBin *urisrc = user_data;
+
+  GST_LOG_OBJECT (pad, "%s, urisrc %p", GST_EVENT_TYPE_NAME (event), urisrc);
+
+  if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_DOWNSTREAM &&
+      gst_event_has_name (event, "urisourcebin-custom-eos")) {
+    OutputSlotInfo *slot;
+    GST_DEBUG_OBJECT (pad, "we received EOS");
+
+    /* Check the slot is still unlinked - maybe it got
+     * re-linked and we should drop this EOS */
+    GST_URI_SOURCE_BIN_LOCK (urisrc);
+    slot = g_object_get_data (G_OBJECT (pad), "urisourcebin.slotinfo");
+    if (slot && slot->linked_info) {
+      GST_DEBUG_OBJECT (pad,
+          "EOS pad was re-linked to pending pad, so removing EOS status");
+      slot->is_eos = FALSE;
+      GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+      return GST_PAD_PROBE_HANDLED;
+    }
+
+    /* Otherwise it's time to send EOS and clean up this pad */
+    gst_pad_push_event (slot->srcpad, gst_event_new_eos ());
+
+    /* FIXME: Can't clean the pad up from the streaming thread... */
+    urisrc->out_slots = g_slist_remove (urisrc->out_slots, slot);
+#if 0
+    free_output_slot (slot, urisrc);
+    slot = NULL;
+#endif
+
+    /* FIXME: Only emit drained if all output pads are done and there's no
+     * pending pads */
+    g_signal_emit (urisrc, gst_uri_source_bin_signals[SIGNAL_DRAINED], 0, NULL);
+
+    GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+    return GST_PAD_PROBE_HANDLED;
+  }
+  /* never drop events */
+  return GST_PAD_PROBE_OK;
+}
+
+/* called when we found a raw pad to expose. We set up a
+ * padprobe to detect EOS before exposing the pad. 
+ * Called with LOCK held. */
+static GstPad *
+create_output_pad (GstURISourceBin * urisrc, GstPad * pad)
+{
+  GstPad *newpad;
+  GstPadTemplate *pad_tmpl;
+  gchar *padname;
+
+  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
+      source_pad_event_probe, urisrc, NULL);
+
+  pad_tmpl = gst_static_pad_template_get (&srctemplate);
+
+  padname = g_strdup_printf ("src_%u", urisrc->numpads);
+  urisrc->numpads++;
+
+  newpad = gst_ghost_pad_new_from_template (padname, pad, pad_tmpl);
+  gst_object_unref (pad_tmpl);
+  g_free (padname);
+
+  return newpad;
+}
+
+static void
+expose_output_pad (GstURISourceBin * urisrc, GstPad * pad)
+{
+  GstPad *target;
+
+  if (gst_object_has_as_parent (GST_OBJECT (pad), GST_OBJECT (urisrc)))
+    return;                     /* Pad is already exposed */
+
+  target = gst_ghost_pad_get_target (GST_GHOST_PAD (pad));
+
+  gst_pad_sticky_events_foreach (target, copy_sticky_events, pad);
+  gst_object_unref (target);
+
+  gst_pad_set_active (pad, TRUE);
+  gst_element_add_pad (GST_ELEMENT_CAST (urisrc), pad);
+
+  /* Once we expose a pad, we're no longer async */
+  do_async_done (urisrc);
+}
+
+static void
+pad_removed_cb (GstElement * element, GstPad * pad, GstURISourceBin * urisrc)
+{
+  ChildSrcPadInfo *info;
+
+  GST_DEBUG_OBJECT (element, "pad removed name: <%s:%s>",
+      GST_DEBUG_PAD_NAME (pad));
+
+  /* we only care about srcpads */
+  if (!GST_PAD_IS_SRC (pad))
+    return;
+
+  if (!(info = g_object_get_data (G_OBJECT (pad), "urisourcebin.srcpadinfo")))
+    goto no_info;
+
+  GST_URI_SOURCE_BIN_LOCK (urisrc);
+  /* Make sure this isn't in the pending pads list */
+  urisrc->pending_pads = g_list_remove (urisrc->pending_pads, pad);
+
+  /* Send EOS to the output slot if the demuxer didn't already */
+  if (info->output_slot) {
+    if (!info->output_slot->is_eos) {
+      GstStructure *s;
+      GstEvent *event;
+
+      GST_LOG_OBJECT (element,
+          "Pad %" GST_PTR_FORMAT " was removed without EOS. Sending.", pad);
+
+      s = gst_structure_new_empty ("urisourcebin-custom-eos");
+      event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);
+      gst_pad_send_event (info->output_slot->sinkpad, event);
+      info->output_slot->is_eos = TRUE;
+    }
+    /* After the pad goes away, the slot is free to reuse */
+    info->output_slot->linked_info = NULL;
+    info->output_slot = NULL;
+  } else {
+    GST_LOG_OBJECT (urisrc, "Removed pad has no output slot");
+  }
+  GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+
+  return;
+
+  /* ERRORS */
+no_info:
+  {
+    GST_WARNING_OBJECT (element, "no info found for pad");
+    return;
+  }
+}
+
+/* helper function to lookup stuff in lists */
+static gboolean
+array_has_value (const gchar * values[], const gchar * value)
+{
+  gint i;
+
+  for (i = 0; values[i]; i++) {
+    if (g_str_has_prefix (value, values[i]))
+      return TRUE;
+  }
+  return FALSE;
+}
+
+static gboolean
+array_has_uri_value (const gchar * values[], const gchar * value)
+{
+  gint i;
+
+  for (i = 0; values[i]; i++) {
+    if (!g_ascii_strncasecmp (value, values[i], strlen (values[i])))
+      return TRUE;
+  }
+  return FALSE;
+}
+
+/* list of URIs that we consider to be streams and that need buffering.
+ * We have no mechanism yet to figure this out with a query. */
+static const gchar *stream_uris[] = { "http://", "https://", "mms://",
+  "mmsh://", "mmsu://", "mmst://", "fd://", "myth://", "ssh://",
+  "ftp://", "sftp://",
+  NULL
+};
+
+/* list of URIs that need a queue because they are pretty bursty */
+static const gchar *queue_uris[] = { "cdda://", NULL };
+
+/* blacklisted URIs, we know they will always fail. */
+static const gchar *blacklisted_uris[] = { NULL };
+
+/* media types that use adaptive streaming */
+static const gchar *adaptive_media[] = {
+  "application/x-hls", "application/vnd.ms-sstr+xml",
+  "application/dash+xml", NULL
+};
+
+#define IS_STREAM_URI(uri)          (array_has_uri_value (stream_uris, uri))
+#define IS_QUEUE_URI(uri)           (array_has_uri_value (queue_uris, uri))
+#define IS_BLACKLISTED_URI(uri)     (array_has_uri_value (blacklisted_uris, uri))
+#define IS_ADAPTIVE_MEDIA(media)    (array_has_value (adaptive_media, media))
+
+/*
+ * Generate and configure a source element.
+ */
+static GstElement *
+gen_source_element (GstURISourceBin * urisrc)
+{
+  GObjectClass *source_class;
+  GstElement *source;
+  GParamSpec *pspec;
+  GstQuery *query;
+  GstSchedulingFlags flags;
+  GError *err = NULL;
+
+  if (!urisrc->uri)
+    goto no_uri;
+
+  GST_LOG_OBJECT (urisrc, "finding source for %s", urisrc->uri);
+
+  if (!gst_uri_is_valid (urisrc->uri))
+    goto invalid_uri;
+
+  if (IS_BLACKLISTED_URI (urisrc->uri))
+    goto uri_blacklisted;
+
+  source = gst_element_make_from_uri (GST_URI_SRC, urisrc->uri, "source", &err);
+  if (!source)
+    goto no_source;
+
+  GST_LOG_OBJECT (urisrc, "found source type %s", G_OBJECT_TYPE_NAME (source));
+
+  query = gst_query_new_scheduling ();
+  if (gst_element_query (source, query)) {
+    gst_query_parse_scheduling (query, &flags, NULL, NULL, NULL);
+    urisrc->is_stream = flags & GST_SCHEDULING_FLAG_BANDWIDTH_LIMITED;
+  } else
+    urisrc->is_stream = IS_STREAM_URI (urisrc->uri);
+  gst_query_unref (query);
+
+  GST_LOG_OBJECT (urisrc, "source is stream: %d", urisrc->is_stream);
+
+  urisrc->need_queue = IS_QUEUE_URI (urisrc->uri);
+  GST_LOG_OBJECT (urisrc, "source needs queue: %d", urisrc->need_queue);
+
+  source_class = G_OBJECT_GET_CLASS (source);
+
+  pspec = g_object_class_find_property (source_class, "connection-speed");
+  if (pspec != NULL) {
+    guint64 speed = urisrc->connection_speed / 1000;
+    gboolean wrong_type = FALSE;
+
+    if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_UINT) {
+      GParamSpecUInt *pspecuint = G_PARAM_SPEC_UINT (pspec);
+
+      speed = CLAMP (speed, pspecuint->minimum, pspecuint->maximum);
+    } else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_INT) {
+      GParamSpecInt *pspecint = G_PARAM_SPEC_INT (pspec);
+
+      speed = CLAMP (speed, pspecint->minimum, pspecint->maximum);
+    } else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_UINT64) {
+      GParamSpecUInt64 *pspecuint = G_PARAM_SPEC_UINT64 (pspec);
+
+      speed = CLAMP (speed, pspecuint->minimum, pspecuint->maximum);
+    } else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_INT64) {
+      GParamSpecInt64 *pspecint = G_PARAM_SPEC_INT64 (pspec);
+
+      speed = CLAMP (speed, pspecint->minimum, pspecint->maximum);
+    } else {
+      GST_WARNING_OBJECT (urisrc,
+          "The connection speed property %" G_GUINT64_FORMAT
+          " of type %s is not useful. Not setting it", speed,
+          g_type_name (G_PARAM_SPEC_TYPE (pspec)));
+      wrong_type = TRUE;
+    }
+
+    if (!wrong_type) {
+      g_object_set (source, "connection-speed", speed, NULL);
+
+      GST_DEBUG_OBJECT (urisrc,
+          "setting connection-speed=%" G_GUINT64_FORMAT " to source element",
+          speed);
+    }
+  }
+
+  return source;
+
+  /* ERRORS */
+no_uri:
+  {
+    GST_ELEMENT_ERROR (urisrc, RESOURCE, NOT_FOUND,
+        (_("No URI specified to play from.")), (NULL));
+    return NULL;
+  }
+invalid_uri:
+  {
+    GST_ELEMENT_ERROR (urisrc, RESOURCE, NOT_FOUND,
+        (_("Invalid URI \"%s\"."), urisrc->uri), (NULL));
+    g_clear_error (&err);
+    return NULL;
+  }
+uri_blacklisted:
+  {
+    GST_ELEMENT_ERROR (urisrc, RESOURCE, FAILED,
+        (_("This stream type cannot be played yet.")), (NULL));
+    return NULL;
+  }
+no_source:
+  {
+    /* whoops, could not create the source element, dig a little deeper to
+     * figure out what might be wrong. */
+    if (err != NULL && err->code == GST_URI_ERROR_UNSUPPORTED_PROTOCOL) {
+      gchar *prot;
+
+      prot = gst_uri_get_protocol (urisrc->uri);
+      if (prot == NULL)
+        goto invalid_uri;
+
+      gst_element_post_message (GST_ELEMENT_CAST (urisrc),
+          gst_missing_uri_source_message_new (GST_ELEMENT (urisrc), prot));
+
+      GST_ELEMENT_ERROR (urisrc, CORE, MISSING_PLUGIN,
+          (_("No URI handler implemented for \"%s\"."), prot), (NULL));
+
+      g_free (prot);
+    } else {
+      GST_ELEMENT_ERROR (urisrc, RESOURCE, NOT_FOUND,
+          ("%s", (err) ? err->message : "URI was not accepted by any element"),
+          ("No element accepted URI '%s'", urisrc->uri));
+    }
+
+    g_clear_error (&err);
+    return NULL;
+  }
+}
+
+static gboolean
+is_all_raw_caps (GstCaps * caps, GstCaps * rawcaps, gboolean * all_raw)
+{
+  GstCaps *intersection;
+  gint capssize;
+  gboolean res = FALSE;
+
+  if (caps == NULL)
+    return FALSE;
+
+  capssize = gst_caps_get_size (caps);
+  /* no caps, skip and move to the next pad */
+  if (capssize == 0 || gst_caps_is_empty (caps) || gst_caps_is_any (caps))
+    goto done;
+
+  intersection = gst_caps_intersect (caps, rawcaps);
+  *all_raw = !gst_caps_is_empty (intersection)
+      && (gst_caps_get_size (intersection) == capssize);
+  gst_caps_unref (intersection);
+
+  res = TRUE;
+
+done:
+  return res;
+}
+
+/**
+ * has_all_raw_caps:
+ * @pad: a #GstPad
+ * @all_raw: pointer to hold the result
+ *
+ * check if the caps of the pad are all raw. The caps are all raw if
+ * all of its structures contain audio/x-raw or video/x-raw.
+ *
+ * Returns: %FALSE @pad has no caps. Else TRUE and @all_raw set t the result.
+ */
+static gboolean
+has_all_raw_caps (GstPad * pad, GstCaps * rawcaps, gboolean * all_raw)
+{
+  GstCaps *caps;
+  gboolean res = FALSE;
+
+  caps = gst_pad_query_caps (pad, NULL);
+
+  GST_DEBUG_OBJECT (pad, "have caps %" GST_PTR_FORMAT, caps);
+
+  res = is_all_raw_caps (caps, rawcaps, all_raw);
+
+  gst_caps_unref (caps);
+  return res;
+}
+
+static void
+post_missing_plugin_error (GstElement * dec, const gchar * element_name)
+{
+  GstMessage *msg;
+
+  msg = gst_missing_element_message_new (dec, element_name);
+  gst_element_post_message (dec, msg);
+
+  GST_ELEMENT_ERROR (dec, CORE, MISSING_PLUGIN,
+      (_("Missing element '%s' - check your GStreamer installation."),
+          element_name), (NULL));
+  do_async_done (GST_URI_SOURCE_BIN (dec));
+}
+
+/**
+ * analyse_source:
+ * @urisrc: a #GstURISourceBin
+ * @is_raw: are all pads raw data
+ * @have_out: does the source have output
+ * @is_dynamic: is this a dynamic source
+ * @use_queue: put a queue before raw output pads
+ *
+ * Check the source of @urisrc and collect information about it.
+ *
+ * @is_raw will be set to TRUE if the source only produces raw pads. When this
+ * function returns, all of the raw pad of the source will be added
+ * to @urisrc
+ *
+ * @have_out: will be set to TRUE if the source has output pads.
+ *
+ * @is_dynamic: TRUE if the element will create (more) pads dynamically later
+ * on.
+ *
+ * Returns: FALSE if a fatal error occured while scanning.
+ */
+static gboolean
+analyse_source (GstURISourceBin * urisrc, gboolean * is_raw,
+    gboolean * have_out, gboolean * is_dynamic, gboolean use_queue)
+{
+  GstIterator *pads_iter;
+  gboolean done = FALSE;
+  gboolean res = TRUE;
+  GstPad *pad;
+  GValue item = { 0, };
+  GstCaps *rawcaps = DEFAULT_CAPS;
+
+  *have_out = FALSE;
+  *is_raw = FALSE;
+  *is_dynamic = FALSE;
+
+  pads_iter = gst_element_iterate_src_pads (urisrc->source);
+  while (!done) {
+    switch (gst_iterator_next (pads_iter, &item)) {
+      case GST_ITERATOR_ERROR:
+        res = FALSE;
+        /* FALLTROUGH */
+      case GST_ITERATOR_DONE:
+        done = TRUE;
+        break;
+      case GST_ITERATOR_RESYNC:
+        /* reset results and resync */
+        *have_out = FALSE;
+        *is_raw = FALSE;
+        *is_dynamic = FALSE;
+        gst_iterator_resync (pads_iter);
+        break;
+      case GST_ITERATOR_OK:
+        pad = g_value_dup_object (&item);
+        /* we now officially have an ouput pad */
+        *have_out = TRUE;
+
+        /* if FALSE, this pad has no caps and we continue with the next pad. */
+        if (!has_all_raw_caps (pad, rawcaps, is_raw)) {
+          gst_object_unref (pad);
+          g_value_reset (&item);
+          break;
+        }
+
+        /* caps on source pad are all raw, we can add the pad */
+        if (*is_raw) {
+          GST_URI_SOURCE_BIN_LOCK (urisrc);
+          if (use_queue) {
+            OutputSlotInfo *slot = get_output_slot (urisrc, FALSE, FALSE, NULL);
+            if (slot)
+              goto no_slot;
+
+            gst_pad_link (pad, slot->sinkpad);
+
+            /* get the new raw srcpad */
+            gst_object_unref (pad);
+            pad = slot->srcpad;
+          } else {
+            pad = create_output_pad (urisrc, pad);
+          }
+          GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+          expose_output_pad (urisrc, pad);
+          gst_object_unref (pad);
+        }
+        gst_object_unref (pad);
+        g_value_reset (&item);
+        break;
+    }
+  }
+  g_value_unset (&item);
+  gst_iterator_free (pads_iter);
+  gst_caps_unref (rawcaps);
+
+  if (!*have_out) {
+    GstElementClass *elemclass;
+    GList *walk;
+
+    /* element has no output pads, check for padtemplates that list SOMETIMES
+     * pads. */
+    elemclass = GST_ELEMENT_GET_CLASS (urisrc->source);
+
+    walk = gst_element_class_get_pad_template_list (elemclass);
+    while (walk != NULL) {
+      GstPadTemplate *templ;
+
+      templ = (GstPadTemplate *) walk->data;
+      if (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC) {
+        if (GST_PAD_TEMPLATE_PRESENCE (templ) == GST_PAD_SOMETIMES)
+          *is_dynamic = TRUE;
+        break;
+      }
+      walk = g_list_next (walk);
+    }
+  }
+
+  return res;
+no_slot:
+  {
+    GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+    gst_object_unref (pad);
+    g_value_unset (&item);
+    gst_iterator_free (pads_iter);
+    gst_caps_unref (rawcaps);
+
+    return FALSE;
+  }
+}
+
+/* Remove any adaptive demuxer element */
+static void
+remove_demuxer (GstURISourceBin * bin)
+{
+  if (bin->demuxer) {
+    GST_DEBUG_OBJECT (bin, "removing old demuxer element");
+    gst_element_set_state (bin->demuxer, GST_STATE_NULL);
+    gst_bin_remove (GST_BIN_CAST (bin), bin->demuxer);
+    bin->demuxer = NULL;
+  }
+}
+
+/* make a demuxer and connect to all the signals */
+static GstElement *
+make_demuxer (GstURISourceBin * urisrc, GstCaps * caps)
+{
+  GList *factories, *eligible, *cur;
+  GstElement *demuxer = NULL;
+
+  GST_LOG_OBJECT (urisrc, "making new adaptive demuxer");
+
+  /* now create the demuxer element */
+
+  /* FIXME: Fire a signal to get the demuxer? */
+  factories = gst_element_factory_list_get_elements
+      (GST_ELEMENT_FACTORY_TYPE_DEMUXER, GST_RANK_MARGINAL);
+  eligible =
+      gst_element_factory_list_filter (factories, caps, GST_PAD_SINK,
+      gst_caps_is_fixed (caps));
+  gst_plugin_feature_list_free (factories);
+
+  if (eligible == NULL)
+    goto no_demuxer;
+
+  eligible = g_list_sort (eligible, gst_plugin_feature_rank_compare_func);
+
+  for (cur = eligible; cur != NULL; cur = g_list_next (cur)) {
+    GstElementFactory *factory = (GstElementFactory *) (cur->data);
+    const gchar *klass =
+        gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);
+
+    /* Can't be a demuxer unless it has Demux in the klass name */
+    if (!strstr (klass, "Demux") || !strstr (klass, "Adaptive"))
+      continue;
+
+    demuxer = gst_element_factory_create (factory, NULL);
+    break;
+  }
+  gst_plugin_feature_list_free (eligible);
+
+  if (!demuxer)
+    goto no_demuxer;
+
+  GST_DEBUG_OBJECT (urisrc, "Created adaptive demuxer %" GST_PTR_FORMAT,
+      demuxer);
+
+  /* set up callbacks to create the links between
+   * demuxer streams and output */
+  g_signal_connect (demuxer,
+      "pad-added", G_CALLBACK (new_demuxer_pad_added_cb), urisrc);
+  g_signal_connect (demuxer,
+      "pad-removed", G_CALLBACK (pad_removed_cb), urisrc);
+
+  /* Propagate connection-speed property */
+  /* FIXME: Check the property exists on the demuxer */
+  g_object_set (demuxer,
+      "connection-speed", urisrc->connection_speed / 1000, NULL);
+
+  return demuxer;
+
+  /* ERRORS */
+no_demuxer:
+  {
+    /* FIXME: Fire the right error */
+    GST_ELEMENT_ERROR (urisrc, CORE, MISSING_PLUGIN, (NULL),
+        ("No demuxer element, check your installation"));
+    do_async_done (urisrc);
+    return NULL;
+  }
+}
+
+static void
+handle_new_pad (GstURISourceBin * urisrc, GstPad * srcpad, GstCaps * caps)
+{
+  gboolean is_raw;
+  GstStructure *s;
+  const gchar *media_type;
+  gboolean do_download = FALSE;
+
+  GST_URI_SOURCE_BIN_LOCK (urisrc);
+
+  /* if this is a pad with all raw caps, we can expose it */
+  if (is_all_raw_caps (caps, DEFAULT_CAPS, &is_raw) && is_raw) {
+    GstPad *pad;
+
+    GST_DEBUG_OBJECT (urisrc, "Found pad with raw caps %" GST_PTR_FORMAT
+        ", exposing", caps);
+    pad = create_output_pad (urisrc, srcpad);
+    GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+
+    expose_output_pad (urisrc, pad);
+    return;
+  }
+  GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+
+  s = gst_caps_get_structure (caps, 0);
+  media_type = gst_structure_get_name (s);
+
+  urisrc->is_adaptive = IS_ADAPTIVE_MEDIA (media_type);
+
+  if (urisrc->is_adaptive) {
+    GstElement *demux_elem;
+    GstPad *sinkpad;
+    GstPadLinkReturn link_res;
+
+    demux_elem = make_demuxer (urisrc, caps);
+    if (!demux_elem)
+      goto no_demuxer;
+    gst_bin_add (GST_BIN_CAST (urisrc), demux_elem);
+
+    sinkpad = gst_element_get_static_pad (demux_elem, "sink");
+    if (sinkpad == NULL)
+      goto no_demuxer_sink;
+
+    link_res = gst_pad_link (srcpad, sinkpad);
+
+    gst_object_unref (sinkpad);
+    if (link_res != GST_PAD_LINK_OK)
+      goto could_not_link;
+
+    gst_element_sync_state_with_parent (demux_elem);
+  } else {
+    OutputSlotInfo *slot;
+
+    /* only enable download buffering if the upstream duration is known */
+    if (urisrc->download) {
+      GstQuery *query = gst_query_new_duration (GST_FORMAT_BYTES);
+      if (gst_pad_query (srcpad, query)) {
+        gint64 dur;
+        gst_query_parse_duration (query, NULL, &dur);
+        do_download = (dur != -1);
+      }
+      gst_object_unref (query);
+    }
+
+    GST_DEBUG_OBJECT (urisrc, "check media-type %s, %d", media_type,
+        do_download);
+
+    GST_URI_SOURCE_BIN_LOCK (urisrc);
+    slot = get_output_slot (urisrc, do_download, FALSE, NULL);
+
+    if (slot == NULL || gst_pad_link (srcpad, slot->sinkpad) != GST_PAD_LINK_OK)
+      goto could_not_link;
+
+    expose_output_pad (urisrc, slot->srcpad);
+    GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+  }
+
+  return;
+
+  /* ERRORS */
+no_demuxer:
+  {
+    /* error was posted */
+    return;
+  }
+no_demuxer_sink:
+  {
+    GST_ELEMENT_ERROR (urisrc, CORE, NEGOTIATION,
+        (NULL), ("Adaptive demuxer element has no 'sink' pad"));
+    do_async_done (urisrc);
+    return;
+  }
+could_not_link:
+  {
+    GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+    GST_ELEMENT_ERROR (urisrc, CORE, NEGOTIATION,
+        (NULL), ("Can't link typefind to adaptive demuxer element"));
+    do_async_done (urisrc);
+    return;
+  }
+}
+
+/* signaled when we have a stream and we need to configure the download
+ * buffering or regular buffering */
+static void
+type_found (GstElement * typefind, guint probability,
+    GstCaps * caps, GstURISourceBin * urisrc)
+{
+  GstPad *srcpad = gst_element_get_static_pad (typefind, "src");
+
+  GST_DEBUG_OBJECT (urisrc, "typefind found caps %" GST_PTR_FORMAT
+      " on pad %" GST_PTR_FORMAT, caps, srcpad);
+  handle_new_pad (urisrc, srcpad, caps);
+
+  gst_object_unref (GST_OBJECT (srcpad));
+}
+
+/* setup a streaming source. This will first plug a typefind element to the
+ * source. After we find the type, we decide to whether to plug an adaptive
+ * demuxer, or just link through queue2 and expose the data. */
+static gboolean
+setup_streaming (GstURISourceBin * urisrc)
+{
+  GstElement *typefind;
+
+  /* now create the typefind element */
+  typefind = gst_element_factory_make ("typefind", NULL);
+  if (!typefind)
+    goto no_typefind;
+
+  gst_bin_add (GST_BIN_CAST (urisrc), typefind);
+
+  if (!gst_element_link_pads (urisrc->source, NULL, typefind, "sink"))
+    goto could_not_link;
+
+  urisrc->typefind = typefind;
+
+  /* connect a signal to find out when the typefind element found
+   * a type */
+  urisrc->have_type_id =
+      g_signal_connect (urisrc->typefind, "have-type",
+      G_CALLBACK (type_found), urisrc);
+
+  return TRUE;
+
+  /* ERRORS */
+no_typefind:
+  {
+    post_missing_plugin_error (GST_ELEMENT_CAST (urisrc), "typefind");
+    GST_ELEMENT_ERROR (urisrc, CORE, MISSING_PLUGIN, (NULL),
+        ("No typefind element, check your installation"));
+    do_async_done (urisrc);
+    return FALSE;
+  }
+could_not_link:
+  {
+    GST_ELEMENT_ERROR (urisrc, CORE, NEGOTIATION,
+        (NULL), ("Can't link source to typefind element"));
+    gst_bin_remove (GST_BIN_CAST (urisrc), typefind);
+    do_async_done (urisrc);
+    return FALSE;
+  }
+}
+
+static void
+free_output_slot (OutputSlotInfo * slot, GstURISourceBin * urisrc)
+{
+  GST_DEBUG_OBJECT (urisrc, "removing old queue element and freeing slot %p",
+      slot);
+  gst_element_set_locked_state (slot->queue, TRUE);
+  gst_element_set_state (slot->queue, GST_STATE_NULL);
+  gst_bin_remove (GST_BIN_CAST (urisrc), slot->queue);
+
+  gst_object_unref (slot->sinkpad);
+
+  remove_buffering_msgs (urisrc, GST_OBJECT_CAST (slot->queue));
+
+  /* deactivate and remove the srcpad */
+  gst_pad_set_active (slot->srcpad, FALSE);
+  gst_element_remove_pad (GST_ELEMENT_CAST (urisrc), slot->srcpad);
+
+  g_free (slot);
+}
+
+/* remove source and all related elements */
+static void
+remove_source (GstURISourceBin * urisrc)
+{
+  GstElement *source = urisrc->source;
+
+  if (source) {
+    GST_DEBUG_OBJECT (urisrc, "removing old src element");
+    gst_element_set_state (source, GST_STATE_NULL);
+
+    if (urisrc->src_np_sig_id) {
+      g_signal_handler_disconnect (source, urisrc->src_np_sig_id);
+      urisrc->src_np_sig_id = 0;
+    }
+    gst_bin_remove (GST_BIN_CAST (urisrc), source);
+    urisrc->source = NULL;
+  }
+  if (urisrc->typefind) {
+    GST_DEBUG_OBJECT (urisrc, "removing old typefind element");
+    gst_element_set_state (urisrc->typefind, GST_STATE_NULL);
+    gst_bin_remove (GST_BIN_CAST (urisrc), urisrc->typefind);
+    urisrc->typefind = NULL;
+  }
+
+  GST_URI_SOURCE_BIN_LOCK (urisrc);
+  g_slist_foreach (urisrc->out_slots, (GFunc) free_output_slot, urisrc);
+  g_slist_free (urisrc->out_slots);
+  urisrc->out_slots = NULL;
+  GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+
+  if (urisrc->demuxer) {
+    GST_DEBUG_OBJECT (urisrc, "removing old adaptive demux element");
+    gst_element_set_state (urisrc->demuxer, GST_STATE_NULL);
+    gst_bin_remove (GST_BIN_CAST (urisrc), urisrc->demuxer);
+    urisrc->demuxer = NULL;
+  }
+}
+
+/* is called when a dynamic source element created a new pad. */
+static void
+source_new_pad (GstElement * element, GstPad * pad, GstURISourceBin * urisrc)
+{
+  GstCaps *caps;
+
+  GST_DEBUG_OBJECT (urisrc, "Found new pad %s.%s in source element %s",
+      GST_DEBUG_PAD_NAME (pad), GST_ELEMENT_NAME (element));
+  caps = gst_pad_get_current_caps (pad);
+  if (caps == NULL)
+    caps = gst_pad_query_caps (pad, NULL);
+  handle_new_pad (urisrc, pad, caps);
+  gst_caps_unref (caps);
+}
+
+static gboolean
+is_live_source (GstElement * source)
+{
+  GObjectClass *source_class = NULL;
+  gboolean is_live = FALSE;
+  GParamSpec *pspec;
+
+  source_class = G_OBJECT_GET_CLASS (source);
+  pspec = g_object_class_find_property (source_class, "is-live");
+  if (!pspec || G_PARAM_SPEC_VALUE_TYPE (pspec) != G_TYPE_BOOLEAN)
+    return FALSE;
+
+  g_object_get (G_OBJECT (source), "is-live", &is_live, NULL);
+
+  return is_live;
+}
+
+/* construct and run the source and demuxer elements until we found
+ * all the streams or until a preroll queue has been filled.
+*/
+static gboolean
+setup_source (GstURISourceBin * urisrc)
+{
+  gboolean is_raw, have_out, is_dynamic;
+
+  GST_DEBUG_OBJECT (urisrc, "setup source");
+
+  /* delete old src */
+  remove_source (urisrc);
+
+  /* create and configure an element that can handle the uri */
+  if (!(urisrc->source = gen_source_element (urisrc)))
+    goto no_source;
+
+  /* state will be merged later - if file is not found, error will be
+   * handled by the application right after. */
+  gst_bin_add (GST_BIN_CAST (urisrc), urisrc->source);
+
+  /* notify of the new source used */
+  g_object_notify (G_OBJECT (urisrc), "source");
+
+  g_signal_emit (urisrc, gst_uri_source_bin_signals[SIGNAL_SOURCE_SETUP],
+      0, urisrc->source);
+
+  if (is_live_source (urisrc->source))
+    urisrc->is_stream = FALSE;
+
+  /* remove the old demuxer now, if any */
+  remove_demuxer (urisrc);
+
+  /* see if the source element emits raw audio/video all by itself,
+   * if so, we can create streams for the pads and be done with it.
+   * Also check that is has source pads, if not, we assume it will
+   * do everything itself.  */
+  if (!analyse_source (urisrc, &is_raw, &have_out, &is_dynamic,
+          urisrc->need_queue && urisrc->use_buffering))
+    goto invalid_source;
+
+  if (is_raw) {
+    GST_DEBUG_OBJECT (urisrc, "Source provides all raw data");
+    /* source provides raw data, we added the pads and we can now signal a
+     * no_more pads because we are done. */
+    gst_element_no_more_pads (GST_ELEMENT_CAST (urisrc));
+    do_async_done (urisrc);
+    return TRUE;
+  }
+  if (!have_out && !is_dynamic) {
+    GST_DEBUG_OBJECT (urisrc, "Source has no output pads");
+    return TRUE;
+  }
+  if (is_dynamic) {
+    GST_DEBUG_OBJECT (urisrc, "Source has dynamic output pads");
+    /* connect a handler for the new-pad signal */
+    urisrc->src_np_sig_id =
+        g_signal_connect (urisrc->source, "pad-added",
+        G_CALLBACK (source_new_pad), urisrc);
+  } else {
+    if (urisrc->is_stream) {
+      GST_DEBUG_OBJECT (urisrc, "Setting up streaming");
+      /* do the stream things here */
+      if (!setup_streaming (urisrc))
+        goto streaming_failed;
+    } else {
+      GstIterator *pads_iter;
+      gboolean done = FALSE;
+      pads_iter = gst_element_iterate_src_pads (urisrc->source);
+      while (!done) {
+        GValue item = { 0, };
+        GstPad *pad;
+
+        switch (gst_iterator_next (pads_iter, &item)) {
+          case GST_ITERATOR_ERROR:
+            GST_WARNING_OBJECT (urisrc,
+                "Error iterating pads on source element");
+            /* FALLTROUGH */
+          case GST_ITERATOR_DONE:
+            done = TRUE;
+            break;
+          case GST_ITERATOR_RESYNC:
+            /* reset results and resync */
+            gst_iterator_resync (pads_iter);
+            break;
+          case GST_ITERATOR_OK:
+            pad = g_value_get_object (&item);
+            /* no streaming source, expose pads directly */
+            GST_URI_SOURCE_BIN_LOCK (urisrc);
+            pad = create_output_pad (urisrc, pad);
+            GST_URI_SOURCE_BIN_UNLOCK (urisrc);
+            expose_output_pad (urisrc, pad);
+            g_value_reset (&item);
+            break;
+        }
+      }
+      gst_iterator_free (pads_iter);
+      gst_element_no_more_pads (GST_ELEMENT_CAST (urisrc));
+      do_async_done (urisrc);
+    }
+  }
+  return TRUE;
+
+  /* ERRORS */
+no_source:
+  {
+    /* error message was already posted */
+    return FALSE;
+  }
+invalid_source:
+  {
+    GST_ELEMENT_ERROR (urisrc, CORE, FAILED,
+        (_("Source element is invalid.")), (NULL));
+    return FALSE;
+  }
+streaming_failed:
+  {
+    /* message was posted */
+    return FALSE;
+  }
+}
+
+static void
+value_list_append_structure_list (GValue * list_val, GstStructure ** first,
+    GList * structure_list)
+{
+  GList *l;
+
+  for (l = structure_list; l != NULL; l = l->next) {
+    GValue val = { 0, };
+
+    if (*first == NULL)
+      *first = gst_structure_copy ((GstStructure *) l->data);
+
+    g_value_init (&val, GST_TYPE_STRUCTURE);
+    g_value_take_boxed (&val, gst_structure_copy ((GstStructure *) l->data));
+    gst_value_list_append_value (list_val, &val);
+    g_value_unset (&val);
+  }
+}
+
+/* if it's a redirect message with multiple redirect locations we might
+ * want to pick a different 'best' location depending on the required
+ * bitrates and the connection speed */
+static GstMessage *
+handle_redirect_message (GstURISourceBin * dec, GstMessage * msg)
+{
+  const GValue *locations_list, *location_val;
+  GstMessage *new_msg;
+  GstStructure *new_structure = NULL;
+  GList *l_good = NULL, *l_neutral = NULL, *l_bad = NULL;
+  GValue new_list = { 0, };
+  guint size, i;
+  const GstStructure *structure;
+
+  GST_DEBUG_OBJECT (dec, "redirect message: %" GST_PTR_FORMAT, msg);
+  GST_DEBUG_OBJECT (dec, "connection speed: %" G_GUINT64_FORMAT,
+      dec->connection_speed);
+
+  structure = gst_message_get_structure (msg);
+  if (dec->connection_speed == 0 || structure == NULL)
+    return msg;
+
+  locations_list = gst_structure_get_value (structure, "locations");
+  if (locations_list == NULL)
+    return msg;
+
+  size = gst_value_list_get_size (locations_list);
+  if (size < 2)
+    return msg;
+
+  /* maintain existing order as much as possible, just sort references
+   * with too high a bitrate to the end (the assumption being that if
+   * bitrates are given they are given for all interesting streams and
+   * that the you-need-at-least-version-xyz redirect has the same bitrate
+   * as the lowest referenced redirect alternative) */
+  for (i = 0; i < size; ++i) {
+    const GstStructure *s;
+    gint bitrate = 0;
+
+    location_val = gst_value_list_get_value (locations_list, i);
+    s = (const GstStructure *) g_value_get_boxed (location_val);
+    if (!gst_structure_get_int (s, "minimum-bitrate", &bitrate) || bitrate <= 0) {
+      GST_DEBUG_OBJECT (dec, "no bitrate: %" GST_PTR_FORMAT, s);
+      l_neutral = g_list_append (l_neutral, (gpointer) s);
+    } else if (bitrate > dec->connection_speed) {
+      GST_DEBUG_OBJECT (dec, "bitrate too high: %" GST_PTR_FORMAT, s);
+      l_bad = g_list_append (l_bad, (gpointer) s);
+    } else if (bitrate <= dec->connection_speed) {
+      GST_DEBUG_OBJECT (dec, "bitrate OK: %" GST_PTR_FORMAT, s);
+      l_good = g_list_append (l_good, (gpointer) s);
+    }
+  }
+
+  g_value_init (&new_list, GST_TYPE_LIST);
+  value_list_append_structure_list (&new_list, &new_structure, l_good);
+  value_list_append_structure_list (&new_list, &new_structure, l_neutral);
+  value_list_append_structure_list (&new_list, &new_structure, l_bad);
+  gst_structure_take_value (new_structure, "locations", &new_list);
+
+  g_list_free (l_good);
+  g_list_free (l_neutral);
+  g_list_free (l_bad);
+
+  new_msg = gst_message_new_element (msg->src, new_structure);
+  gst_message_unref (msg);
+
+  GST_DEBUG_OBJECT (dec, "new redirect message: %" GST_PTR_FORMAT, new_msg);
+  return new_msg;
+}
+
+static GstMessage *
+handle_buffering_message (GstURISourceBin * urisrc, GstMessage * msg)
+{
+  gint perc, msg_perc;
+  gint smaller_perc = 100;
+  GstMessage *smaller = NULL;
+  GList *found = NULL;
+  GList *iter;
+
+  /* buffering messages must be aggregated as there might be multiple
+   * multiqueue in the pipeline and their independent buffering messages
+   * will confuse the application
+   *
+   * urisourcebin keeps a list of messages received from elements that are
+   * buffering.
+   * Rules are:
+   * 0) Ignore buffering from elements that are draining (is_eos == TRUE)
+   * 1) Always post the smaller buffering %
+   * 2) If an element posts a 100% buffering message, remove it from the list
+   * 3) When there are no more messages on the list, post 100% message
+   * 4) When an element posts a new buffering message, update the one
+   *    on the list to this new value
+   */
+  gst_message_parse_buffering (msg, &msg_perc);
+  GST_LOG_OBJECT (urisrc, "Got buffering msg from %" GST_PTR_FORMAT
+      " with %d%%", GST_MESSAGE_SRC (msg), msg_perc);
+
+  GST_OBJECT_LOCK (urisrc);
+  /*
+   * Single loop for 2 things:
+   * 1) Look for a message with the same source
+   *   1.1) If the received message is 100%, remove it from the list
+   * 2) Find the minimum buffering from the list from elements that aren't EOS
+   */
+  for (iter = urisrc->buffering_status; iter;) {
+    GstMessage *bufstats = iter->data;
+    OutputSlotInfo *slot =
+        g_object_get_data (G_OBJECT (GST_MESSAGE_SRC (bufstats)),
+        "urisourcebin.slotinfo");
+    gboolean is_eos = FALSE;
+
+    if (slot)
+      is_eos = slot->is_eos;
+
+    if (GST_MESSAGE_SRC (bufstats) == GST_MESSAGE_SRC (msg)) {
+      found = iter;
+      if (msg_perc < 100) {
+        gst_message_unref (iter->data);
+        bufstats = iter->data = gst_message_ref (msg);
+      } else {
+        GList *current = iter;
+
+        /* remove the element here and avoid confusing the loop */
+        iter = g_list_next (iter);
+
+        gst_message_unref (current->data);
+        urisrc->buffering_status =
+            g_list_delete_link (urisrc->buffering_status, current);
+
+        continue;
+      }
+    }
+
+    /* only update minimum stat for non-EOS slots */
+    if (!is_eos) {
+      gst_message_parse_buffering (bufstats, &perc);
+      if (perc < smaller_perc) {
+        smaller_perc = perc;
+        smaller = bufstats;
+      }
+    } else {
+      GST_LOG_OBJECT (urisrc, "Ignoring buffering from EOS element");
+    }
+    iter = g_list_next (iter);
+  }
+
+  if (found == NULL && msg_perc < 100) {
+    if (msg_perc < smaller_perc) {
+      smaller_perc = msg_perc;
+      smaller = msg;
+    }
+    urisrc->buffering_status =
+        g_list_prepend (urisrc->buffering_status, gst_message_ref (msg));
+  }
+
+  if (smaller_perc == urisrc->last_buffering_pct) {
+    /* Don't repeat our last buffering status */
+    gst_message_replace (&msg, NULL);
+  } else {
+    urisrc->last_buffering_pct = smaller_perc;
+
+    /* now compute the buffering message that should be posted */
+    if (smaller_perc == 100) {
+      g_assert (urisrc->buffering_status == NULL);
+      /* we are posting the original received msg */
+    } else {
+      gst_message_replace (&msg, smaller);
+    }
+  }
+  GST_OBJECT_UNLOCK (urisrc);
+
+  if (msg) {
+    GST_LOG_OBJECT (urisrc, "Sending buffering msg from %" GST_PTR_FORMAT
+        " with %d%%", GST_MESSAGE_SRC (msg), smaller_perc);
+  } else {
+    GST_LOG_OBJECT (urisrc, "Dropped buffering msg as a repeat of %d%%",
+        smaller_perc);
+  }
+  return msg;
+}
+
+/* Remove any buffering message from the given source */
+static void
+remove_buffering_msgs (GstURISourceBin * urisrc, GstObject * src)
+{
+  GList *iter;
+
+  GST_OBJECT_LOCK (urisrc);
+  for (iter = urisrc->buffering_status; iter;) {
+    GstMessage *bufstats = iter->data;
+    if (GST_MESSAGE_SRC (bufstats) == src) {
+      gst_message_unref (bufstats);
+      urisrc->buffering_status =
+          g_list_delete_link (urisrc->buffering_status, iter);
+      break;
+    }
+    iter = g_list_next (iter);
+  }
+  GST_OBJECT_UNLOCK (urisrc);
+}
+
+static void
+handle_message (GstBin * bin, GstMessage * msg)
+{
+  GstURISourceBin *urisrc = GST_URI_SOURCE_BIN (bin);
+
+  switch (GST_MESSAGE_TYPE (msg)) {
+    case GST_MESSAGE_ELEMENT:{
+      if (gst_message_has_name (msg, "redirect")) {
+        /* sort redirect messages based on the connection speed. This simplifies
+         * the user of this element as it can in most cases just pick the first item
+         * of the sorted list as a good redirection candidate. It can of course
+         * choose something else from the list if it has a better way. */
+        msg = handle_redirect_message (urisrc, msg);
+      }
+      break;
+    }
+    case GST_MESSAGE_BUFFERING:
+      msg = handle_buffering_message (urisrc, msg);
+      break;
+    default:
+      break;
+  }
+
+  if (msg)
+    GST_BIN_CLASS (parent_class)->handle_message (bin, msg);
+}
+
+/* generic struct passed to all query fold methods
+ * FIXME, move to core.
+ */
+typedef struct
+{
+  GstQuery *query;
+  gint64 min;
+  gint64 max;
+  gboolean seekable;
+  gboolean live;
+} QueryFold;
+
+typedef void (*QueryInitFunction) (GstURISourceBin * urisrc, QueryFold * fold);
+typedef void (*QueryDoneFunction) (GstURISourceBin * urisrc, QueryFold * fold);
+
+/* for duration/position we collect all durations/positions and take
+ * the MAX of all valid results */
+static void
+decoder_query_init (GstURISourceBin * dec, QueryFold * fold)
+{
+  fold->min = 0;
+  fold->max = -1;
+  fold->seekable = TRUE;
+  fold->live = 0;
+}
+
+static gboolean
+decoder_query_duration_fold (const GValue * item, GValue * ret,
+    QueryFold * fold)
+{
+  GstPad *pad = g_value_get_object (item);
+
+  if (gst_pad_query (pad, fold->query)) {
+    gint64 duration;
+
+    g_value_set_boolean (ret, TRUE);
+
+    gst_query_parse_duration (fold->query, NULL, &duration);
+
+    GST_DEBUG_OBJECT (item, "got duration %" G_GINT64_FORMAT, duration);
+
+    if (duration > fold->max)
+      fold->max = duration;
+  }
+  return TRUE;
+}
+
+static void
+decoder_query_duration_done (GstURISourceBin * dec, QueryFold * fold)
+{
+  GstFormat format;
+
+  gst_query_parse_duration (fold->query, &format, NULL);
+  /* store max in query result */
+  gst_query_set_duration (fold->query, format, fold->max);
+
+  GST_DEBUG ("max duration %" G_GINT64_FORMAT, fold->max);
+}
+
+static gboolean
+decoder_query_position_fold (const GValue * item, GValue * ret,
+    QueryFold * fold)
+{
+  GstPad *pad = g_value_get_object (item);
+
+  if (gst_pad_query (pad, fold->query)) {
+    gint64 position;
+
+    g_value_set_boolean (ret, TRUE);
+
+    gst_query_parse_position (fold->query, NULL, &position);
+
+    GST_DEBUG_OBJECT (item, "got position %" G_GINT64_FORMAT, position);
+
+    if (position > fold->max)
+      fold->max = position;
+  }
+
+  return TRUE;
+}
+
+static void
+decoder_query_position_done (GstURISourceBin * dec, QueryFold * fold)
+{
+  GstFormat format;
+
+  gst_query_parse_position (fold->query, &format, NULL);
+  /* store max in query result */
+  gst_query_set_position (fold->query, format, fold->max);
+
+  GST_DEBUG_OBJECT (dec, "max position %" G_GINT64_FORMAT, fold->max);
+}
+
+static gboolean
+decoder_query_latency_fold (const GValue * item, GValue * ret, QueryFold * fold)
+{
+  GstPad *pad = g_value_get_object (item);
+
+  if (gst_pad_query (pad, fold->query)) {
+    GstClockTime min, max;
+    gboolean live;
+
+    gst_query_parse_latency (fold->query, &live, &min, &max);
+
+    GST_DEBUG_OBJECT (pad,
+        "got latency min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT
+        ", live %d", GST_TIME_ARGS (min), GST_TIME_ARGS (max), live);
+
+    if (live) {
+      /* for the combined latency we collect the MAX of all min latencies and
+       * the MIN of all max latencies */
+      if (min > fold->min)
+        fold->min = min;
+      if (fold->max == -1)
+        fold->max = max;
+      else if (max < fold->max)
+        fold->max = max;
+
+      fold->live = TRUE;
+    }
+  } else {
+    GST_LOG_OBJECT (pad, "latency query failed");
+    g_value_set_boolean (ret, FALSE);
+  }
+
+  return TRUE;
+}
+
+static void
+decoder_query_latency_done (GstURISourceBin * dec, QueryFold * fold)
+{
+  /* store max in query result */
+  gst_query_set_latency (fold->query, fold->live, fold->min, fold->max);
+
+  GST_DEBUG_OBJECT (dec,
+      "latency min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT
+      ", live %d", GST_TIME_ARGS (fold->min), GST_TIME_ARGS (fold->max),
+      fold->live);
+}
+
+/* we are seekable if all srcpads are seekable */
+static gboolean
+decoder_query_seeking_fold (const GValue * item, GValue * ret, QueryFold * fold)
+{
+  GstPad *pad = g_value_get_object (item);
+
+  if (gst_pad_query (pad, fold->query)) {
+    gboolean seekable;
+
+    g_value_set_boolean (ret, TRUE);
+    gst_query_parse_seeking (fold->query, NULL, &seekable, NULL, NULL);
+
+    GST_DEBUG_OBJECT (item, "got seekable %d", seekable);
+
+    if (fold->seekable)
+      fold->seekable = seekable;
+  }
+
+  return TRUE;
+}
+
+static void
+decoder_query_seeking_done (GstURISourceBin * dec, QueryFold * fold)
+{
+  GstFormat format;
+
+  gst_query_parse_seeking (fold->query, &format, NULL, NULL, NULL);
+  gst_query_set_seeking (fold->query, format, fold->seekable, 0, -1);
+
+  GST_DEBUG_OBJECT (dec, "seekable %d", fold->seekable);
+}
+
+/* generic fold, return first valid result */
+static gboolean
+decoder_query_generic_fold (const GValue * item, GValue * ret, QueryFold * fold)
+{
+  GstPad *pad = g_value_get_object (item);
+  gboolean res;
+
+  if ((res = gst_pad_query (pad, fold->query))) {
+    g_value_set_boolean (ret, TRUE);
+    GST_DEBUG_OBJECT (item, "answered query %p", fold->query);
+  }
+
+  /* and stop as soon as we have a valid result */
+  return !res;
+}
+
+/* we're a bin, the default query handler iterates sink elements, which we don't
+ * have normally. We should just query all source pads.
+ */
+static gboolean
+gst_uri_source_bin_query (GstElement * element, GstQuery * query)
+{
+  GstURISourceBin *decoder;
+  gboolean res = FALSE;
+  GstIterator *iter;
+  GstIteratorFoldFunction fold_func;
+  QueryInitFunction fold_init = NULL;
+  QueryDoneFunction fold_done = NULL;
+  QueryFold fold_data;
+  GValue ret = { 0 };
+  gboolean default_ret = FALSE;
+
+  decoder = GST_URI_SOURCE_BIN (element);
+
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_DURATION:
+      /* iterate and collect durations */
+      fold_func = (GstIteratorFoldFunction) decoder_query_duration_fold;
+      fold_init = decoder_query_init;
+      fold_done = decoder_query_duration_done;
+      break;
+    case GST_QUERY_POSITION:
+      /* iterate and collect durations */
+      fold_func = (GstIteratorFoldFunction) decoder_query_position_fold;
+      fold_init = decoder_query_init;
+      fold_done = decoder_query_position_done;
+      break;
+    case GST_QUERY_LATENCY:
+      /* iterate and collect durations */
+      fold_func = (GstIteratorFoldFunction) decoder_query_latency_fold;
+      fold_init = decoder_query_init;
+      fold_done = decoder_query_latency_done;
+      default_ret = TRUE;
+      break;
+    case GST_QUERY_SEEKING:
+      /* iterate and collect durations */
+      fold_func = (GstIteratorFoldFunction) decoder_query_seeking_fold;
+      fold_init = decoder_query_init;
+      fold_done = decoder_query_seeking_done;
+      break;
+    default:
+      fold_func = (GstIteratorFoldFunction) decoder_query_generic_fold;
+      break;
+  }
+
+  fold_data.query = query;
+
+  g_value_init (&ret, G_TYPE_BOOLEAN);
+  g_value_set_boolean (&ret, default_ret);
+
+  iter = gst_element_iterate_src_pads (element);
+  GST_DEBUG_OBJECT (element, "Sending query %p (type %d) to src pads",
+      query, GST_QUERY_TYPE (query));
+
+  if (fold_init)
+    fold_init (decoder, &fold_data);
+
+  while (TRUE) {
+    GstIteratorResult ires;
+
+    ires = gst_iterator_fold (iter, fold_func, &ret, &fold_data);
+
+    switch (ires) {
+      case GST_ITERATOR_RESYNC:
+        gst_iterator_resync (iter);
+        if (fold_init)
+          fold_init (decoder, &fold_data);
+        g_value_set_boolean (&ret, default_ret);
+        break;
+      case GST_ITERATOR_OK:
+      case GST_ITERATOR_DONE:
+        res = g_value_get_boolean (&ret);
+        if (fold_done != NULL && res)
+          fold_done (decoder, &fold_data);
+        goto done;
+      default:
+        res = FALSE;
+        goto done;
+    }
+  }
+done:
+  gst_iterator_free (iter);
+
+  return res;
+}
+
+static void
+sync_slot_queue (OutputSlotInfo * slot)
+{
+  gst_element_sync_state_with_parent (slot->queue);
+}
+
+static GstStateChangeReturn
+gst_uri_source_bin_change_state (GstElement * element,
+    GstStateChange transition)
+{
+  GstStateChangeReturn ret;
+  GstURISourceBin *urisrc = GST_URI_SOURCE_BIN (element);
+
+  switch (transition) {
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+      do_async_start (urisrc);
+      break;
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+  if (ret == GST_STATE_CHANGE_FAILURE)
+    goto setup_failed;
+  else if (ret == GST_STATE_CHANGE_NO_PREROLL)
+    do_async_done (urisrc);
+
+  switch (transition) {
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+      GST_DEBUG ("ready to paused");
+      if (!setup_source (urisrc))
+        goto source_failed;
+
+      ret = GST_STATE_CHANGE_ASYNC;
+
+      /* And now sync the states of everything we added */
+      g_slist_foreach (urisrc->out_slots, (GFunc) sync_slot_queue, NULL);
+      if (urisrc->typefind)
+        ret = gst_element_set_state (urisrc->typefind, GST_STATE_PAUSED);
+      if (ret == GST_STATE_CHANGE_FAILURE)
+        goto setup_failed;
+      if (urisrc->source)
+        ret = gst_element_set_state (urisrc->source, GST_STATE_PAUSED);
+      if (ret == GST_STATE_CHANGE_FAILURE)
+        goto setup_failed;
+      if (ret == GST_STATE_CHANGE_SUCCESS)
+        ret = GST_STATE_CHANGE_ASYNC;
+
+      break;
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+      GST_DEBUG ("paused to ready");
+      remove_demuxer (urisrc);
+      remove_source (urisrc);
+      do_async_done (urisrc);
+      g_list_free_full (urisrc->buffering_status,
+          (GDestroyNotify) gst_message_unref);
+      urisrc->buffering_status = NULL;
+      urisrc->last_buffering_pct = -1;
+      break;
+    case GST_STATE_CHANGE_READY_TO_NULL:
+      GST_DEBUG ("ready to null");
+      remove_demuxer (urisrc);
+      remove_source (urisrc);
+      break;
+    default:
+      break;
+  }
+  return ret;
+
+  /* ERRORS */
+source_failed:
+  {
+    do_async_done (urisrc);
+    return GST_STATE_CHANGE_FAILURE;
+  }
+setup_failed:
+  {
+    /* clean up leftover groups */
+    do_async_done (urisrc);
+    return GST_STATE_CHANGE_FAILURE;
+  }
+}
+
+gboolean
+gst_uri_source_bin_plugin_init (GstPlugin * plugin)
+{
+  GST_DEBUG_CATEGORY_INIT (gst_uri_source_bin_debug, "urisourcebin", 0,
+      "URI source element");
+
+  return gst_element_register (plugin, "urisourcebin", GST_RANK_NONE,
+      GST_TYPE_URI_DECODE_BIN);
+}
diff --git a/gst/subparse/Makefile.in b/gst/subparse/Makefile.in
index a1aa6ba..130d5d7 100644
--- a/gst/subparse/Makefile.in
+++ b/gst/subparse/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -436,6 +437,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -449,6 +453,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -486,6 +493,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst/subparse/gstssaparse.c b/gst/subparse/gstssaparse.c
index 06ecef9..536ce0d 100644
--- a/gst/subparse/gstssaparse.c
+++ b/gst/subparse/gstssaparse.c
@@ -97,10 +97,8 @@
 
   object_class->dispose = gst_ssa_parse_dispose;
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_templ));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
+  gst_element_class_add_static_pad_template (element_class, &sink_templ);
+  gst_element_class_add_static_pad_template (element_class, &src_templ);
   gst_element_class_set_static_metadata (element_class,
       "SSA Subtitle Parser", "Codec/Parser/Subtitle",
       "Parses SSA subtitle streams",
diff --git a/gst/subparse/gstsubparse.c b/gst/subparse/gstsubparse.c
index e306939..f61c6d4 100644
--- a/gst/subparse/gstsubparse.c
+++ b/gst/subparse/gstsubparse.c
@@ -2,6 +2,8 @@
  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
  * Copyright (C) 2004 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
  * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
+ * Copyright (C) 2016 Philippe Normand <pnormand@igalia.com>
+ * Copyright (C) 2016 Jan Schmidt <jan@centricular.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -39,6 +41,10 @@
 GST_DEBUG_CATEGORY (sub_parse_debug);
 
 #define DEFAULT_ENCODING   NULL
+#define ATTRIBUTE_REGEX "\\s?[a-zA-Z0-9\\. \t\\(\\)]*"
+static const gchar *allowed_srt_tags[] = { "i", "b", "u", NULL };
+static const gchar *allowed_vtt_tags[] =
+    { "i", "b", "c", "u", "v", "ruby", "rt", NULL };
 
 enum
 {
@@ -61,7 +67,7 @@
     GST_STATIC_CAPS ("application/x-subtitle; application/x-subtitle-sami; "
         "application/x-subtitle-tmplayer; application/x-subtitle-mpl2; "
         "application/x-subtitle-dks; application/x-subtitle-qttext;"
-        "application/x-subtitle-lrc;")
+        "application/x-subtitle-lrc; application/x-subtitle-vtt")
     );
 
 static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
@@ -127,10 +133,8 @@
   object_class->set_property = gst_sub_parse_set_property;
   object_class->get_property = gst_sub_parse_get_property;
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_templ));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
+  gst_element_class_add_static_pad_template (element_class, &sink_templ);
+  gst_element_class_add_static_pad_template (element_class, &src_templ);
   gst_element_class_set_static_metadata (element_class,
       "Subtitle parser", "Codec/Parser/Subtitle",
       "Parses subtitle (.sub) files into text streams",
@@ -372,6 +376,8 @@
       return "SubViewer";
     case GST_SUB_PARSE_FORMAT_DKS:
       return "DKS";
+    case GST_SUB_PARSE_FORMAT_VTT:
+      return "WebVTT";
     case GST_SUB_PARSE_FORMAT_QTTEXT:
       return "QTtext";
     case GST_SUB_PARSE_FORMAT_LRC:
@@ -665,45 +671,44 @@
  * escaping everything (the text between these simple markers isn't
  * necessarily escaped, so it seems best to do it like this) */
 static void
-subrip_unescape_formatting (gchar * txt)
+subrip_unescape_formatting (gchar * txt, gconstpointer allowed_tags_ptr,
+    gboolean allows_tag_attributes)
 {
-  gchar *pos;
+  gchar *res;
+  GRegex *tag_regex;
+  gchar *allowed_tags_pattern, *search_pattern;
+  const gchar *replace_pattern;
 
-  for (pos = txt; pos != NULL && *pos != '\0'; ++pos) {
-    if (g_ascii_strncasecmp (pos, "&lt;u&gt;", 9) == 0 ||
-        g_ascii_strncasecmp (pos, "&lt;i&gt;", 9) == 0 ||
-        g_ascii_strncasecmp (pos, "&lt;b&gt;", 9) == 0) {
-      pos[0] = '<';
-      pos[1] = g_ascii_tolower (pos[4]);
-      pos[2] = '>';
-      /* move NUL terminator as well */
-      memmove (pos + 3, pos + 9, strlen (pos + 9) + 1);
-      pos += 2;
-    }
+  /* No processing needed if no escaped tag marker found in the string. */
+  if (strstr (txt, "&lt;") == NULL)
+    return;
+
+  /* Build a list of alternates for our regexp.
+   * FIXME: Could be built once and stored */
+  allowed_tags_pattern = g_strjoinv ("|", (gchar **) allowed_tags_ptr);
+  /* Look for starting/ending escaped tags with optional attributes. */
+  search_pattern = g_strdup_printf ("&lt;(/)?\\ *(%s)(%s)&gt;",
+      allowed_tags_pattern, ATTRIBUTE_REGEX);
+  /* And unescape appropriately */
+  if (allows_tag_attributes) {
+    replace_pattern = "<\\1\\2\\3>";
+  } else {
+    replace_pattern = "<\\1\\2>";
   }
 
-  for (pos = txt; pos != NULL && *pos != '\0'; ++pos) {
-    gchar *tag;
+  tag_regex = g_regex_new (search_pattern, 0, 0, NULL);
+  res = g_regex_replace (tag_regex, txt, strlen (txt), 0,
+      replace_pattern, 0, NULL);
 
-    /* look for start of an escaped closing tag */
-    if (g_ascii_strncasecmp (pos, "&lt;/", 5) != 0)
-      continue;
-    tag = pos + 5;
-    while (*tag == ' ')
-      ++tag;
-    if ((*tag == 'u' || *tag == 'i' || *tag == 'b') &&
-        g_ascii_strncasecmp (tag + 1, "&gt;", 4) == 0) {
-      gsize tag_len = (guintptr) (tag + 1 + 4 - pos);
+  /* res will always be shorter than the input or identical, so this
+   * copy is OK */
+  strcpy (txt, res);
 
-      pos[0] = '<';
-      pos[1] = '/';
-      pos[2] = g_ascii_tolower (*tag);
-      pos[3] = '>';
-      /* move NUL terminator as well */
-      memmove (pos + 4, pos + tag_len, strlen (pos + tag_len) + 1);
-      pos += 3;
-    }
-  }
+  g_free (res);
+  g_free (search_pattern);
+  g_free (allowed_tags_pattern);
+
+  g_regex_unref (tag_regex);
 }
 
 
@@ -742,16 +747,25 @@
   }
 }
 
-/* we only allow <i>, <u> and <b>, so let's take a simple approach. This code
- * assumes the input has been escaped and subrip_unescape_formatting() has then
- * been run over the input! This function adds missing closing markup tags and
- * removes broken closing tags for tags that have never been opened. */
+/* we only allow a fixed set of tags like <i>, <u> and <b>, so let's
+ * take a simple approach. This code assumes the input has been
+ * escaped and subrip_unescape_formatting() has then been run over the
+ * input! This function adds missing closing markup tags and removes
+ * broken closing tags for tags that have never been opened. */
 static void
-subrip_fix_up_markup (gchar ** p_txt)
+subrip_fix_up_markup (gchar ** p_txt, gconstpointer allowed_tags_ptr)
 {
   gchar *cur, *next_tag;
-  gchar open_tags[32];
+  gchar *open_tags[32];
   guint num_open_tags = 0;
+  const gchar *iter_tag;
+  guint offset = 0;
+  guint index;
+  gchar *cur_tag;
+  gchar *end_tag;
+  GRegex *tag_regex;
+  GMatchInfo *match_info;
+  gchar **allowed_tags = (gchar **) allowed_tags_ptr;
 
   g_assert (*p_txt != NULL);
 
@@ -760,33 +774,58 @@
     next_tag = strchr (cur, '<');
     if (next_tag == NULL)
       break;
-    ++next_tag;
-    switch (*next_tag) {
-      case '/':{
-        ++next_tag;
-        if (num_open_tags == 0 || open_tags[num_open_tags - 1] != *next_tag) {
-          GST_LOG ("broken input, closing tag '%c' is not open", *next_tag);
-          memmove (next_tag - 2, next_tag + 2, strlen (next_tag + 2) + 1);
-          next_tag -= 2;
-        } else {
-          /* it's all good, closing tag which is open */
-          --num_open_tags;
+    offset = 0;
+    index = 0;
+    while (index < g_strv_length (allowed_tags)) {
+      iter_tag = allowed_tags[index];
+      /* Look for a white listed tag */
+      cur_tag = g_strconcat ("<", iter_tag, ATTRIBUTE_REGEX, ">", NULL);
+      tag_regex = g_regex_new (cur_tag, 0, 0, NULL);
+      (void) g_regex_match (tag_regex, next_tag, 0, &match_info);
+
+      if (g_match_info_matches (match_info)) {
+        gint start_pos, end_pos;
+        gchar *word = g_match_info_fetch (match_info, 0);
+        g_match_info_fetch_pos (match_info, 0, &start_pos, &end_pos);
+        if (start_pos == 0) {
+          offset = strlen (word);
         }
-        break;
+        g_free (word);
       }
-      case 'i':
-      case 'b':
-      case 'u':
-        if (num_open_tags == G_N_ELEMENTS (open_tags))
-          return;               /* something dodgy is going on, stop parsing */
-        open_tags[num_open_tags] = *next_tag;
+      g_match_info_free (match_info);
+      g_regex_unref (tag_regex);
+      g_free (cur_tag);
+      index++;
+      if (offset) {
+        /* OK we found a tag, let's keep track of it */
+        open_tags[num_open_tags] = g_strdup (iter_tag);
         ++num_open_tags;
         break;
-      default:
-        GST_ERROR ("unexpected tag '%c' (%s)", *next_tag, next_tag);
-        g_assert_not_reached ();
-        break;
+      }
     }
+
+    if (offset) {
+      next_tag += offset;
+      cur = next_tag;
+      continue;
+    }
+
+    if (*next_tag == '<' && *(next_tag + 1) == '/') {
+      end_tag = strchr (cur, '>');
+      if (end_tag) {
+        if (num_open_tags == 0
+            || g_ascii_strncasecmp (end_tag - 1, open_tags[num_open_tags - 1],
+                strlen (open_tags[num_open_tags - 1]))) {
+          GST_LOG ("broken input, closing tag '%s' is not open", next_tag);
+          memmove (next_tag, end_tag + 1, strlen (end_tag) + 1);
+          next_tag -= strlen (end_tag);
+        } else {
+          --num_open_tags;
+          g_free (open_tags[num_open_tags]);
+        }
+      }
+    }
+    ++next_tag;
     cur = next_tag;
   }
 
@@ -795,11 +834,12 @@
 
     s = g_string_new (*p_txt);
     while (num_open_tags > 0) {
-      GST_LOG ("adding missing closing tag '%c'", open_tags[num_open_tags - 1]);
+      GST_LOG ("adding missing closing tag '%s'", open_tags[num_open_tags - 1]);
       g_string_append_c (s, '<');
       g_string_append_c (s, '/');
-      g_string_append_c (s, open_tags[num_open_tags - 1]);
+      g_string_append (s, open_tags[num_open_tags - 1]);
       g_string_append_c (s, '>');
+      g_free (open_tags[num_open_tags - 1]);
       --num_open_tags;
     }
     g_free (*p_txt);
@@ -859,18 +899,111 @@
   return TRUE;
 }
 
+/* cue settings are part of the WebVTT specification. They are
+ * declared after the time interval in the first line of the
+ * cue. Example: 00:00:01,000 --> 00:00:02,000 D:vertical-lr A:start
+ * See also http://www.whatwg.org/specs/web-apps/current-work/webvtt.html
+ */
+static void
+parse_webvtt_cue_settings (ParserState * state, const gchar * settings)
+{
+  gchar **splitted_settings = g_strsplit_set (settings, " \t", -1);
+  gint i = 0;
+  gint16 text_position, text_size;
+  gint16 line_position;
+  gboolean vertical_found = FALSE;
+  gboolean alignment_found = FALSE;
+
+  while (i < g_strv_length (splitted_settings)) {
+    gboolean valid_tag = FALSE;
+    switch (splitted_settings[i][0]) {
+      case 'T':
+        if (sscanf (splitted_settings[i], "T:%" G_GINT16_FORMAT "%%",
+                &text_position) > 0) {
+          state->text_position = (guint8) text_position;
+          valid_tag = TRUE;
+        }
+        break;
+      case 'D':
+        if (strlen (splitted_settings[i]) > 2) {
+          vertical_found = TRUE;
+          g_free (state->vertical);
+          state->vertical = g_strdup (splitted_settings[i] + 2);
+          valid_tag = TRUE;
+        }
+        break;
+      case 'L':
+        if (g_str_has_suffix (splitted_settings[i], "%")) {
+          if (sscanf (splitted_settings[i], "L:%" G_GINT16_FORMAT "%%",
+                  &line_position) > 0) {
+            state->line_position = line_position;
+            valid_tag = TRUE;
+          }
+        } else {
+          if (sscanf (splitted_settings[i], "L:%" G_GINT16_FORMAT,
+                  &line_position) > 0) {
+            state->line_number = line_position;
+            valid_tag = TRUE;
+          }
+        }
+        break;
+      case 'S':
+        if (sscanf (splitted_settings[i], "S:%" G_GINT16_FORMAT "%%",
+                &text_size) > 0) {
+          state->text_size = (guint8) text_size;
+          valid_tag = TRUE;
+        }
+        break;
+      case 'A':
+        if (strlen (splitted_settings[i]) > 2) {
+          g_free (state->alignment);
+          state->alignment = g_strdup (splitted_settings[i] + 2);
+          alignment_found = TRUE;
+          valid_tag = TRUE;
+        }
+        break;
+      default:
+        break;
+    }
+    if (!valid_tag) {
+      GST_LOG ("Invalid or unrecognised setting found: %s",
+          splitted_settings[i]);
+    }
+    i++;
+  }
+  g_strfreev (splitted_settings);
+  if (!vertical_found) {
+    g_free (state->vertical);
+    state->vertical = g_strdup ("");
+  }
+  if (!alignment_found) {
+    g_free (state->alignment);
+    state->alignment = g_strdup ("");
+  }
+}
+
 static gchar *
 parse_subrip (ParserState * state, const gchar * line)
 {
-  int subnum;
   gchar *ret;
 
   switch (state->state) {
-    case 0:
-      /* looking for a single integer */
-      if (sscanf (line, "%u", &subnum) == 1)
+    case 0:{
+      char *endptr;
+      guint64 id;
+
+      /* looking for a single integer as a Cue ID, but we
+       * don't actually use it */
+      errno = 0;
+      id = g_ascii_strtoull (line, &endptr, 10);
+      if (id == G_MAXUINT64 && errno == ERANGE)
+        state->state = 1;
+      else if (id == 0 && errno == EINVAL)
+        state->state = 1;
+      else if (endptr != line && *endptr == '\0')
         state->state = 1;
       return NULL;
+    }
     case 1:
     {
       GstClockTime ts_start, ts_end;
@@ -917,10 +1050,11 @@
         ret = g_markup_escape_text (state->buf->str, state->buf->len);
         g_string_truncate (state->buf, 0);
         state->state = 0;
-        subrip_unescape_formatting (ret);
+        subrip_unescape_formatting (ret, state->allowed_tags,
+            state->allows_tag_attributes);
         subrip_remove_unhandled_tags (ret);
         strip_trailing_newlines (ret);
-        subrip_fix_up_markup (&ret);
+        subrip_fix_up_markup (&ret, state->allowed_tags);
         return ret;
       }
       return NULL;
@@ -957,6 +1091,56 @@
   return g_strdup (start + 1);
 }
 
+/* WebVTT is a new subtitle format for the upcoming HTML5 video track
+ * element. This format is similar to Subrip, the biggest differences
+ * are that there can be cue settings detailing how to display the cue
+ * text and more markup tags are allowed.
+ * See also http://www.whatwg.org/specs/web-apps/current-work/webvtt.html
+ */
+static gchar *
+parse_webvtt (ParserState * state, const gchar * line)
+{
+  /* Cue IDs are optional in WebVTT, but not in subrip,
+   * so when in state 0 (cue ID), also check if we're
+   * already at the start --> end time marker */
+  if (state->state == 0 || state->state == 1) {
+    GstClockTime ts_start, ts_end;
+    gchar *end_time;
+    gchar *cue_settings = NULL;
+
+    /* looking for start_time --> end_time */
+    if ((end_time = strstr (line, " --> ")) &&
+        parse_subrip_time (line, &ts_start) &&
+        parse_subrip_time (end_time + strlen (" --> "), &ts_end) &&
+        state->start_time <= ts_end) {
+      state->state = 2;
+      state->start_time = ts_start;
+      state->duration = ts_end - ts_start;
+      cue_settings = strstr (end_time + strlen (" --> "), " ");
+    } else {
+      GST_DEBUG ("error parsing subrip time line '%s'", line);
+      state->state = 0;
+    }
+
+    state->text_position = 0;
+    state->text_size = 0;
+    state->line_position = 0;
+    state->line_number = 0;
+
+    if (cue_settings)
+      parse_webvtt_cue_settings (state, cue_settings + 1);
+    else {
+      g_free (state->vertical);
+      state->vertical = g_strdup ("");
+      g_free (state->alignment);
+      state->alignment = g_strdup ("");
+    }
+
+    return NULL;
+  } else
+    return parse_subrip (state, line);
+}
+
 static void
 unescape_newlines_br (gchar * read)
 {
@@ -1188,6 +1372,12 @@
     g_string_free (state->buf, TRUE);
     state->buf = NULL;
   }
+
+  g_free (state->vertical);
+  state->vertical = NULL;
+  g_free (state->alignment);
+  state->alignment = NULL;
+
   if (state->user_data) {
     switch (self->parser_type) {
       case GST_SUB_PARSE_FORMAT_QTTEXT:
@@ -1200,6 +1390,7 @@
         break;
     }
   }
+  state->allowed_tags = NULL;
 }
 
 /* regex type enum */
@@ -1209,6 +1400,7 @@
   GST_SUB_PARSE_REGEX_MDVDSUB = 1,
   GST_SUB_PARSE_REGEX_SUBRIP = 2,
   GST_SUB_PARSE_REGEX_DKS = 3,
+  GST_SUB_PARSE_REGEX_VTT = 4,
 } GstSubParseRegex;
 
 static gpointer
@@ -1245,6 +1437,16 @@
         g_clear_error (&gerr);
       }
       break;
+    case GST_SUB_PARSE_REGEX_VTT:
+      result = (gpointer)
+          g_regex_new ("^(\\xef\\xbb\\xbf)?WEBVTT[\\xa\\xd\\x20\\x9]", 0, 0,
+          &gerr);
+      if (result == NULL) {
+        g_warning ("Compilation of vtt regex failed: %s", gerr->message);
+        g_error_free (gerr);
+      }
+      break;
+
     default:
       GST_WARNING ("Trying to allocate regex of unknown type %u", regtype);
   }
@@ -1265,10 +1467,12 @@
   static GOnce mdvd_rx_once = G_ONCE_INIT;
   static GOnce subrip_rx_once = G_ONCE_INIT;
   static GOnce dks_rx_once = G_ONCE_INIT;
+  static GOnce vtt_rx_once = G_ONCE_INIT;
 
   GRegex *mdvd_grx;
   GRegex *subrip_grx;
   GRegex *dks_grx;
+  GRegex *vtt_grx;
 
   g_once (&mdvd_rx_once,
       (GThreadFunc) gst_sub_parse_data_format_autodetect_regex_once,
@@ -1279,10 +1483,14 @@
   g_once (&dks_rx_once,
       (GThreadFunc) gst_sub_parse_data_format_autodetect_regex_once,
       (gpointer) GST_SUB_PARSE_REGEX_DKS);
+  g_once (&vtt_rx_once,
+      (GThreadFunc) gst_sub_parse_data_format_autodetect_regex_once,
+      (gpointer) GST_SUB_PARSE_REGEX_VTT);
 
   mdvd_grx = (GRegex *) mdvd_rx_once.retval;
   subrip_grx = (GRegex *) subrip_rx_once.retval;
   dks_grx = (GRegex *) dks_rx_once.retval;
+  vtt_grx = (GRegex *) vtt_rx_once.retval;
 
   if (g_regex_match (mdvd_grx, match_str, 0, NULL)) {
     GST_LOG ("MicroDVD (frame based) format detected");
@@ -1296,6 +1504,10 @@
     GST_LOG ("DKS (time based) format detected");
     return GST_SUB_PARSE_FORMAT_DKS;
   }
+  if (g_regex_match (vtt_grx, match_str, 0, NULL) == TRUE) {
+    GST_LOG ("WebVTT (time based) format detected");
+    return GST_SUB_PARSE_FORMAT_VTT;
+  }
 
   if (!strncmp (match_str, "FORMAT=TIME", 11)) {
     GST_LOG ("MPSub (time based) format detected");
@@ -1378,6 +1590,7 @@
   self->parser_type = format;
   self->subtitle_codec = gst_sub_parse_get_format_description (format);
   parser_state_init (&self->state);
+  self->state.allowed_tags = NULL;
 
   switch (format) {
     case GST_SUB_PARSE_FORMAT_MDVDSUB:
@@ -1385,6 +1598,8 @@
       return gst_caps_new_simple ("text/x-raw",
           "format", G_TYPE_STRING, "pango-markup", NULL);
     case GST_SUB_PARSE_FORMAT_SUBRIP:
+      self->state.allowed_tags = (gpointer) allowed_srt_tags;
+      self->state.allows_tag_attributes = FALSE;
       self->parse_line = parse_subrip;
       return gst_caps_new_simple ("text/x-raw",
           "format", G_TYPE_STRING, "pango-markup", NULL);
@@ -1410,6 +1625,12 @@
       self->parse_line = parse_dks;
       return gst_caps_new_simple ("text/x-raw",
           "format", G_TYPE_STRING, "utf8", NULL);
+    case GST_SUB_PARSE_FORMAT_VTT:
+      self->state.allowed_tags = (gpointer) allowed_vtt_tags;
+      self->state.allows_tag_attributes = TRUE;
+      self->parse_line = parse_webvtt;
+      return gst_caps_new_simple ("text/x-raw",
+          "format", G_TYPE_STRING, "pango-markup", NULL);
     case GST_SUB_PARSE_FORMAT_SUBVIEWER:
       self->parse_line = parse_subviewer;
       return gst_caps_new_simple ("text/x-raw",
@@ -1541,7 +1762,8 @@
     /* Set segment on our parser state machine */
     self->state.segment = &self->segment;
     /* Now parse the line, out of segment lines will just return NULL */
-    GST_LOG_OBJECT (self, "Parsing line '%s'", line + offset);
+    GST_LOG_OBJECT (self, "State %d. Parsing line '%s'", self->state.state,
+        line + offset);
     subtitle = self->parse_line (&self->state, line + offset);
     g_free (line);
 
@@ -1574,6 +1796,11 @@
           GST_TIME_FORMAT, subtitle, GST_TIME_ARGS (self->state.start_time),
           GST_TIME_ARGS (self->state.duration));
 
+      g_free (self->state.vertical);
+      self->state.vertical = NULL;
+      g_free (self->state.alignment);
+      self->state.alignment = NULL;
+
       ret = gst_pad_push (self->srcpad, buf);
 
       /* move this forward (the tmplayer parser needs this) */
@@ -1740,6 +1967,9 @@
 static GstStaticCaps dks_caps = GST_STATIC_CAPS ("application/x-subtitle-dks");
 #define DKS_CAPS (gst_static_caps_get (&dks_caps))
 
+static GstStaticCaps vtt_caps = GST_STATIC_CAPS ("application/x-subtitle-vtt");
+#define VTT_CAPS (gst_static_caps_get (&vtt_caps))
+
 static GstStaticCaps qttext_caps =
 GST_STATIC_CAPS ("application/x-subtitle-qttext");
 #define QTTEXT_CAPS (gst_static_caps_get (&qttext_caps))
@@ -1851,6 +2081,10 @@
       GST_DEBUG ("LRC format detected");
       caps = LRC_CAPS;
       break;
+    case GST_SUB_PARSE_FORMAT_VTT:
+      GST_DEBUG ("WebVTT format detected");
+      caps = VTT_CAPS;
+      break;
     default:
     case GST_SUB_PARSE_FORMAT_UNKNOWN:
       GST_DEBUG ("no subtitle format detected");
@@ -1867,8 +2101,8 @@
   GST_DEBUG_CATEGORY_INIT (sub_parse_debug, "subparse", 0, ".sub parser");
 
   if (!gst_type_find_register (plugin, "subparse_typefind", GST_RANK_MARGINAL,
-          gst_subparse_type_find, "srt,sub,mpsub,mdvd,smi,txt,dks", SUB_CAPS,
-          NULL, NULL))
+          gst_subparse_type_find, "srt,sub,mpsub,mdvd,smi,txt,dks,vtt",
+          SUB_CAPS, NULL, NULL))
     return FALSE;
 
   if (!gst_element_register (plugin, "subparse",
diff --git a/gst/subparse/gstsubparse.h b/gst/subparse/gstsubparse.h
index 012aee6..64aab34 100644
--- a/gst/subparse/gstsubparse.h
+++ b/gst/subparse/gstsubparse.h
@@ -56,7 +56,8 @@
   GST_SUB_PARSE_FORMAT_SUBVIEWER = 7,
   GST_SUB_PARSE_FORMAT_DKS = 8,
   GST_SUB_PARSE_FORMAT_QTTEXT = 9,
-  GST_SUB_PARSE_FORMAT_LRC = 10
+  GST_SUB_PARSE_FORMAT_LRC = 10,
+  GST_SUB_PARSE_FORMAT_VTT = 11
 } GstSubParseFormat;
 
 typedef struct {
@@ -69,6 +70,14 @@
   gpointer user_data;
   gboolean have_internal_fps; /* If TRUE don't overwrite fps by property */
   gint fps_n, fps_d;     /* used by frame based parsers */
+  guint8 line_position;          /* percent value */
+  gint line_number;              /* line number, can be positive or negative */
+  guint8 text_position;          /* percent value */
+  guint8 text_size;          /* percent value */
+  gchar *vertical;        /* "", "vertical", "vertical-lr" */
+  gchar *alignment;       /* "", "start", "middle", "end" */
+  gconstpointer allowed_tags; /* list of markup tags allowed in the cue text. */
+  gboolean allows_tag_attributes;
 } ParserState;
 
 typedef gchar* (*Parser) (ParserState *state, const gchar *line);
diff --git a/gst/tcp/Makefile.in b/gst/tcp/Makefile.in
index 2051645..c470f1f 100644
--- a/gst/tcp/Makefile.in
+++ b/gst/tcp/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -444,6 +445,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -457,6 +461,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -494,6 +501,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst/tcp/gstmultihandlesink.c b/gst/tcp/gstmultihandlesink.c
index 8a99e00..f060f0e 100644
--- a/gst/tcp/gstmultihandlesink.c
+++ b/gst/tcp/gstmultihandlesink.c
@@ -456,8 +456,7 @@
       G_STRUCT_OFFSET (GstMultiHandleSinkClass, clear), NULL, NULL,
       g_cclosure_marshal_generic, G_TYPE_NONE, 0);
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sinktemplate));
+  gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate);
 
   gst_element_class_set_static_metadata (gstelement_class,
       "Multi socket sink", "Sink/Network",
@@ -2222,9 +2221,16 @@
   sink = GST_MULTI_HANDLE_SINK (element);
 
   /* we disallow changing the state from the streaming thread */
-  if (g_thread_self () == sink->thread)
-    return GST_STATE_CHANGE_FAILURE;
+  if (g_thread_self () == sink->thread) {
+    g_warning
+        ("\nTrying to change %s's state from its streaming thread would deadlock.\n"
+        "You cannot change the state of an element from its streaming\n"
+        "thread. Use g_idle_add() or post a GstMessage on the bus to\n"
+        "schedule the state change from the main thread.\n",
+        GST_ELEMENT_NAME (sink));
 
+    return GST_STATE_CHANGE_FAILURE;
+  }
 
   switch (transition) {
     case GST_STATE_CHANGE_NULL_TO_READY:
diff --git a/gst/tcp/gstsocketsrc.c b/gst/tcp/gstsocketsrc.c
index bb85402..e22c071 100644
--- a/gst/tcp/gstsocketsrc.c
+++ b/gst/tcp/gstsocketsrc.c
@@ -153,8 +153,7 @@
       G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstSocketSrcClass,
           connection_closed_by_peer), NULL, NULL, NULL, G_TYPE_NONE, 0);
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
+  gst_element_class_add_static_pad_template (gstelement_class, &srctemplate);
 
   gst_element_class_set_static_metadata (gstelement_class,
       "socket source", "Source/Network",
diff --git a/gst/tcp/gsttcpclientsink.c b/gst/tcp/gsttcpclientsink.c
index d23ded4..5e96e76 100644
--- a/gst/tcp/gsttcpclientsink.c
+++ b/gst/tcp/gsttcpclientsink.c
@@ -114,8 +114,7 @@
           0, TCP_HIGHEST_PORT, TCP_DEFAULT_PORT,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sinktemplate));
+  gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate);
 
   gst_element_class_set_static_metadata (gstelement_class,
       "TCP client sink", "Sink/Network",
diff --git a/gst/tcp/gsttcpclientsrc.c b/gst/tcp/gsttcpclientsrc.c
index 776ff42..7ebe75a 100644
--- a/gst/tcp/gsttcpclientsrc.c
+++ b/gst/tcp/gsttcpclientsrc.c
@@ -109,8 +109,7 @@
           TCP_HIGHEST_PORT, TCP_DEFAULT_PORT,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
+  gst_element_class_add_static_pad_template (gstelement_class, &srctemplate);
 
   gst_element_class_set_static_metadata (gstelement_class,
       "TCP client source", "Source/Network",
diff --git a/gst/tcp/gsttcpserversrc.c b/gst/tcp/gsttcpserversrc.c
index 72efb86..6ac29a7 100644
--- a/gst/tcp/gsttcpserversrc.c
+++ b/gst/tcp/gsttcpserversrc.c
@@ -122,8 +122,7 @@
           "The port number the socket is currently bound to", 0,
           TCP_HIGHEST_PORT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
+  gst_element_class_add_static_pad_template (gstelement_class, &srctemplate);
 
   gst_element_class_set_static_metadata (gstelement_class,
       "TCP server source", "Source/Network",
diff --git a/gst/typefind/Makefile.in b/gst/typefind/Makefile.in
index da8c847..3a8b0cb 100644
--- a/gst/typefind/Makefile.in
+++ b/gst/typefind/Makefile.in
@@ -97,6 +97,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -432,6 +433,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -445,6 +449,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -482,6 +489,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c
index 63e1de9..353525a 100644
--- a/gst/typefind/gsttypefindfunctions.c
+++ b/gst/typefind/gsttypefindfunctions.c
@@ -4615,6 +4615,41 @@
   }
 }
 
+/*** WEBVTTT subtitles ***/
+static GstStaticCaps webvtt_caps =
+GST_STATIC_CAPS ("application/x-subtitle-vtt, parsed=(boolean)false");
+#define WEBVTT_CAPS (gst_static_caps_get(&webvtt_caps))
+
+static void
+webvtt_type_find (GstTypeFind * tf, gpointer private)
+{
+  const guint8 *data;
+
+  data = gst_type_find_peek (tf, 0, 9);
+
+  if (data == NULL)
+    return;
+
+  /* there might be a UTF-8 BOM at the beginning */
+  if (memcmp (data, "WEBVTT", 6) != 0 && memcmp (data + 3, "WEBVTT", 6) != 0) {
+    return;
+  }
+
+  if (data[0] != 'W') {
+    if (data[0] != 0xef || data[1] != 0xbb || data[2] != 0xbf)
+      return;                   /* Not a UTF-8 BOM */
+    data += 3;
+  }
+
+  /* After the WEBVTT magic must be one of these chars:
+   *   0x20 (space), 0x9 (tab), 0xa (LF) or 0xd (CR) */
+  if (data[6] != 0x20 && data[6] != 0x9 && data[6] != 0xa && data[6] != 0xd) {
+    return;
+  }
+
+  gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, WEBVTT_CAPS);
+}
+
 /*** application/x-ogm-video or audio***/
 
 static GstStaticCaps ogmvideo_caps =
@@ -5737,6 +5772,8 @@
       GST_RANK_SECONDARY, "Z", "\037\235", 2, GST_TYPE_FIND_LIKELY);
   TYPE_FIND_REGISTER (plugin, "subtitle/x-kate", GST_RANK_MARGINAL,
       kate_type_find, NULL, NULL, NULL, NULL);
+  TYPE_FIND_REGISTER (plugin, "application/x-subtitle-vtt", GST_RANK_MARGINAL,
+      webvtt_type_find, "vtt", WEBVTT_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "audio/x-flac", GST_RANK_PRIMARY, flac_type_find,
       "flac", FLAC_CAPS, NULL, NULL);
   TYPE_FIND_REGISTER (plugin, "audio/x-vorbis", GST_RANK_PRIMARY,
diff --git a/gst/videoconvert/Makefile.in b/gst/videoconvert/Makefile.in
index 7b6b795..8ec0701 100644
--- a/gst/videoconvert/Makefile.in
+++ b/gst/videoconvert/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -436,6 +437,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -449,6 +453,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -486,6 +493,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst/videoconvert/gstvideoconvert.c b/gst/videoconvert/gstvideoconvert.c
index 66e388c..b69cd07 100644
--- a/gst/videoconvert/gstvideoconvert.c
+++ b/gst/videoconvert/gstvideoconvert.c
@@ -511,10 +511,10 @@
   gobject_class->get_property = gst_video_convert_get_property;
   gobject_class->finalize = gst_video_convert_finalize;
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_video_convert_src_template));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_video_convert_sink_template));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_video_convert_src_template);
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_video_convert_sink_template);
 
   gst_element_class_set_static_metadata (gstelement_class,
       "Colorspace converter", "Filter/Converter/Video",
diff --git a/gst/videorate/Makefile.in b/gst/videorate/Makefile.in
index 812f729..ca27914 100644
--- a/gst/videorate/Makefile.in
+++ b/gst/videorate/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -431,6 +432,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -444,6 +448,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -481,6 +488,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst/videorate/gstvideorate.c b/gst/videorate/gstvideorate.c
index 4a815d5..eb3cc8c 100644
--- a/gst/videorate/gstvideorate.c
+++ b/gst/videorate/gstvideorate.c
@@ -255,10 +255,10 @@
       "Drops/duplicates/adjusts timestamps on video frames to make a perfect stream",
       "Wim Taymans <wim@fluendo.com>");
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_video_rate_sink_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_video_rate_src_template));
+  gst_element_class_add_static_pad_template (element_class,
+      &gst_video_rate_sink_template);
+  gst_element_class_add_static_pad_template (element_class,
+      &gst_video_rate_src_template);
 }
 
 static void
@@ -599,7 +599,8 @@
 
 /* flush the oldest buffer */
 static GstFlowReturn
-gst_video_rate_flush_prev (GstVideoRate * videorate, gboolean duplicate)
+gst_video_rate_flush_prev (GstVideoRate * videorate, gboolean duplicate,
+    GstClockTime next_intime)
 {
   GstFlowReturn res;
   GstBuffer *outbuf;
@@ -608,8 +609,12 @@
   if (!videorate->prevbuf)
     goto eos_before_buffers;
 
+  outbuf = gst_buffer_ref (videorate->prevbuf);
+  if (videorate->drop_only)
+    gst_buffer_replace (&videorate->prevbuf, NULL);
+
   /* make sure we can write to the metadata */
-  outbuf = gst_buffer_make_writable (gst_buffer_ref (videorate->prevbuf));
+  outbuf = gst_buffer_make_writable (outbuf);
 
   GST_BUFFER_OFFSET (outbuf) = videorate->out;
   GST_BUFFER_OFFSET_END (outbuf) = videorate->out + 1;
@@ -630,16 +635,40 @@
 
   videorate->out++;
   videorate->out_frame_count++;
-  if (videorate->to_rate_numerator) {
-    /* interpolate next expected timestamp in the segment */
-    videorate->next_ts =
-        videorate->segment.base + videorate->segment.start +
-        videorate->base_ts + gst_util_uint64_scale (videorate->out_frame_count,
-        videorate->to_rate_denominator * GST_SECOND,
-        videorate->to_rate_numerator);
-    GST_BUFFER_DURATION (outbuf) = videorate->next_ts - push_ts;
-  } else if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DURATION (outbuf))) {
-    videorate->next_ts = GST_BUFFER_PTS (outbuf) + GST_BUFFER_DURATION (outbuf);
+  if (videorate->segment.rate < 0.0) {
+    if (videorate->to_rate_numerator) {
+      /* interpolate next expected timestamp in the segment */
+
+      videorate->next_ts =
+          videorate->segment.base + videorate->segment.stop -
+          videorate->base_ts -
+          gst_util_uint64_scale (videorate->out_frame_count,
+          videorate->to_rate_denominator * GST_SECOND,
+          videorate->to_rate_numerator);
+      GST_BUFFER_DURATION (outbuf) = push_ts - videorate->next_ts;
+    } else if (next_intime != GST_CLOCK_TIME_NONE) {
+      videorate->next_ts = next_intime;
+    } else {
+      GST_FIXME_OBJECT (videorate, "No next intime for reverse playback");
+    }
+  } else {
+    if (videorate->to_rate_numerator) {
+      /* interpolate next expected timestamp in the segment */
+      videorate->next_ts =
+          videorate->segment.base + videorate->segment.start +
+          videorate->base_ts +
+          gst_util_uint64_scale (videorate->out_frame_count,
+          videorate->to_rate_denominator * GST_SECOND,
+          videorate->to_rate_numerator);
+      GST_BUFFER_DURATION (outbuf) = videorate->next_ts - push_ts;
+    } else if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DURATION (outbuf))) {
+      videorate->next_ts =
+          GST_BUFFER_PTS (outbuf) + GST_BUFFER_DURATION (outbuf);
+    } else {
+      /* There must always be a valid duration on prevbuf if rate > 0,
+       * it is ensured in the transform_ip function */
+      GST_FIXME_OBJECT (videorate, "No buffer duration known");
+    }
   }
 
   /* We do not need to update time in VFR (variable frame rate) mode */
@@ -716,12 +745,21 @@
         /* fill up to the end of current segment,
          * or only send out the stored buffer if there is no specific stop.
          * regardless, prevent going loopy in strange cases */
-        while (res == GST_FLOW_OK && count <= MAGIC_LIMIT &&
-            ((GST_CLOCK_TIME_IS_VALID (videorate->segment.stop) &&
-                    videorate->next_ts - videorate->segment.base
-                    < videorate->segment.stop)
+        while (res == GST_FLOW_OK && count <= MAGIC_LIMIT
+            && !videorate->drop_only
+            && ((videorate->segment.rate > 0.0
+                    && GST_CLOCK_TIME_IS_VALID (videorate->segment.stop)
+                    && GST_CLOCK_TIME_IS_VALID (videorate->next_ts)
+                    && videorate->next_ts - videorate->segment.base <
+                    videorate->segment.stop) || (videorate->segment.rate < 0.0
+                    && GST_CLOCK_TIME_IS_VALID (videorate->segment.start)
+                    && GST_CLOCK_TIME_IS_VALID (videorate->next_ts)
+                    && videorate->next_ts - videorate->segment.base >=
+                    videorate->segment.start)
                 || count < 1)) {
-          res = gst_video_rate_flush_prev (videorate, count > 0);
+          res =
+              gst_video_rate_flush_prev (videorate, count > 0,
+              GST_CLOCK_TIME_NONE);
           count++;
         }
         if (count > 1) {
@@ -755,14 +793,24 @@
         /* fill up to the end of current segment,
          * or only send out the stored buffer if there is no specific stop.
          * regardless, prevent going loopy in strange cases */
-        while (res == GST_FLOW_OK && count <= MAGIC_LIMIT &&
-            ((videorate->next_ts - videorate->segment.base <
-                    videorate->segment.stop)
+        while (res == GST_FLOW_OK && count <= MAGIC_LIMIT
+            && !videorate->drop_only
+            && ((videorate->segment.rate > 0.0
+                    && GST_CLOCK_TIME_IS_VALID (videorate->segment.stop)
+                    && GST_CLOCK_TIME_IS_VALID (videorate->next_ts)
+                    && videorate->next_ts - videorate->segment.base <
+                    videorate->segment.stop) || (videorate->segment.rate < 0.0
+                    && GST_CLOCK_TIME_IS_VALID (videorate->segment.start)
+                    && GST_CLOCK_TIME_IS_VALID (videorate->next_ts)
+                    && videorate->next_ts - videorate->segment.base >=
+                    videorate->segment.start)
                 || count < 1)) {
-          res = gst_video_rate_flush_prev (videorate, count > 0);
+          res =
+              gst_video_rate_flush_prev (videorate, count > 0,
+              GST_CLOCK_TIME_NONE);
           count++;
         }
-      } else if (videorate->prevbuf) {
+      } else if (!videorate->drop_only && videorate->prevbuf) {
         /* Output at least one frame but if the buffer duration is valid, output
          * enough frames to use the complete buffer duration */
         if (GST_BUFFER_DURATION_IS_VALID (videorate->prevbuf)) {
@@ -770,13 +818,19 @@
               videorate->next_ts + GST_BUFFER_DURATION (videorate->prevbuf);
 
           while (res == GST_FLOW_OK && count <= MAGIC_LIMIT &&
-              ((videorate->next_ts - videorate->segment.base < end_ts)
+              ((videorate->segment.rate > 0.0
+                      && GST_CLOCK_TIME_IS_VALID (videorate->segment.stop)
+                      && GST_CLOCK_TIME_IS_VALID (videorate->next_ts)
+                      && videorate->next_ts - videorate->segment.base < end_ts)
                   || count < 1)) {
-            res = gst_video_rate_flush_prev (videorate, count > 0);
+            res =
+                gst_video_rate_flush_prev (videorate, count > 0,
+                GST_CLOCK_TIME_NONE);
             count++;
           }
         } else {
-          res = gst_video_rate_flush_prev (videorate, FALSE);
+          res =
+              gst_video_rate_flush_prev (videorate, FALSE, GST_CLOCK_TIME_NONE);
           count = 1;
         }
       }
@@ -959,7 +1013,9 @@
 
   /* drop frames if they exceed our output rate */
   if (GST_CLOCK_TIME_IS_VALID (videorate->last_ts)) {
-    GstClockTimeDiff diff = ts - videorate->last_ts;
+    GstClockTimeDiff diff =
+        videorate->segment.rate <
+        0 ? videorate->last_ts - ts : ts - videorate->last_ts;
 
     /* Drop buffer if its early compared to the desired frame rate and
      * the current average is higher than the desired average
@@ -1057,7 +1113,7 @@
 {
   GstVideoRate *videorate;
   GstFlowReturn res = GST_BASE_TRANSFORM_FLOW_DROPPED;
-  GstClockTime intime, in_ts, in_dur;
+  GstClockTime intime, in_ts, in_dur, last_ts;
   GstClockTime avg_period;
   gboolean skip = FALSE;
 
@@ -1108,6 +1164,11 @@
   in_dur = GST_BUFFER_DURATION (buffer);
 
   if (G_UNLIKELY (in_ts == GST_CLOCK_TIME_NONE)) {
+    /* For reverse playback, we need all input timestamps as we can't
+     * guess from the previous buffers timestamp and duration */
+    if (G_UNLIKELY (in_ts == GST_CLOCK_TIME_NONE
+            && videorate->segment.rate < 0.0))
+      goto invalid_buffer;
     in_ts = videorate->last_ts;
     if (G_UNLIKELY (in_ts == GST_CLOCK_TIME_NONE))
       goto invalid_buffer;
@@ -1115,8 +1176,9 @@
 
   /* get the time of the next expected buffer timestamp, we use this when the
    * next buffer has -1 as a timestamp */
+  last_ts = videorate->last_ts;
   videorate->last_ts = in_ts;
-  if (in_dur != GST_CLOCK_TIME_NONE)
+  if (in_dur != GST_CLOCK_TIME_NONE && videorate->segment.rate > 0.0)
     videorate->last_ts += in_dur;
 
   GST_DEBUG_OBJECT (videorate, "got buffer with timestamp %" GST_TIME_FORMAT,
@@ -1128,6 +1190,17 @@
 
   /* we need to have two buffers to compare */
   if (videorate->prevbuf == NULL || videorate->drop_only) {
+    /* We can calculate the duration of the buffer here if not given for
+     * reverse playback. We need this later */
+    if (videorate->segment.rate < 0.0 && !GST_BUFFER_DURATION_IS_VALID (buffer)) {
+      /* As we require valid timestamps all the time for reverse playback, we either
+       * have a valid last_ts or we're at the very first buffer. */
+      if (!GST_CLOCK_TIME_IS_VALID (last_ts))
+        GST_BUFFER_DURATION (buffer) = videorate->segment.stop - in_ts;
+      else
+        GST_BUFFER_DURATION (buffer) = last_ts - in_ts;
+    }
+
     gst_video_rate_swap_prev (videorate, buffer, intime);
     videorate->in++;
     if (!GST_CLOCK_TIME_IS_VALID (videorate->next_ts)) {
@@ -1135,10 +1208,18 @@
        * timestamp in the segment */
       if (videorate->skip_to_first || skip) {
         videorate->next_ts = intime;
-        videorate->base_ts = in_ts - videorate->segment.start;
+        if (videorate->segment.rate < 0.0)
+          videorate->base_ts = videorate->segment.stop - in_ts;
+        else
+          videorate->base_ts = in_ts - videorate->segment.start;
         videorate->out_frame_count = 0;
       } else {
-        videorate->next_ts = videorate->segment.start + videorate->segment.base;
+        if (videorate->segment.rate < 0.0)
+          videorate->next_ts =
+              videorate->segment.stop + videorate->segment.base;
+        else
+          videorate->next_ts =
+              videorate->segment.start + videorate->segment.base;
       }
     }
 
@@ -1147,11 +1228,13 @@
      * allowed frame period. This also keeps latency down to 0 frames
      */
     if (videorate->drop_only) {
-      if (intime >= videorate->next_ts) {
+      if ((videorate->segment.rate > 0.0 && intime >= videorate->next_ts) ||
+          (videorate->segment.rate < 0.0 && intime <= videorate->next_ts)) {
         GstFlowReturn r;
 
         /* on error the _flush function posted a warning already */
-        if ((r = gst_video_rate_flush_prev (videorate, FALSE)) != GST_FLOW_OK) {
+        if ((r = gst_video_rate_flush_prev (videorate, FALSE,
+                    GST_CLOCK_TIME_NONE)) != GST_FLOW_OK) {
           res = r;
           goto done;
         }
@@ -1174,7 +1257,8 @@
     videorate->in++;
 
     /* drop new buffer if it's before previous one */
-    if (intime < prevtime) {
+    if ((videorate->segment.rate > 0.0 && intime < prevtime) ||
+        (videorate->segment.rate < 0.0 && intime > prevtime)) {
       GST_DEBUG_OBJECT (videorate,
           "The new buffer (%" GST_TIME_FORMAT
           ") is before the previous buffer (%"
@@ -1189,14 +1273,16 @@
     /* got 2 buffers, see which one is the best */
     do {
 
-      diff1 = prevtime - videorate->next_ts;
-      diff2 = intime - videorate->next_ts;
-
       /* take absolute values, beware: abs and ABS don't work for gint64 */
-      if (diff1 < 0)
-        diff1 = -diff1;
-      if (diff2 < 0)
-        diff2 = -diff2;
+      if (prevtime > videorate->next_ts)
+        diff1 = prevtime - videorate->next_ts;
+      else
+        diff1 = videorate->next_ts - prevtime;
+
+      if (intime > videorate->next_ts)
+        diff2 = intime - videorate->next_ts;
+      else
+        diff2 = videorate->next_ts - intime;
 
       GST_LOG_OBJECT (videorate,
           "diff with prev %" GST_TIME_FORMAT " diff with new %"
@@ -1204,10 +1290,18 @@
           GST_TIME_ARGS (diff1), GST_TIME_ARGS (diff2),
           GST_TIME_ARGS (videorate->next_ts));
 
-      if (!GST_BUFFER_DURATION_IS_VALID (videorate->prevbuf) &&
-          intime > prevtime) {
+      if (videorate->segment.rate < 0.0) {
+        /* Make sure that we have a duration for this buffer. The previous
+         * buffer already has a duration given by either exactly this code,
+         * or the code above for the very first buffer */
+        g_assert (GST_BUFFER_DURATION_IS_VALID (videorate->prevbuf));
+        if (!GST_BUFFER_DURATION_IS_VALID (buffer) && prevtime > intime)
+          GST_BUFFER_DURATION (buffer) = prevtime - intime;
+      } else {
         /* Make sure that we have a duration for previous buffer */
-        GST_BUFFER_DURATION (videorate->prevbuf) = intime - prevtime;
+        if (!GST_BUFFER_DURATION_IS_VALID (videorate->prevbuf)
+            && intime > prevtime)
+          GST_BUFFER_DURATION (videorate->prevbuf) = intime - prevtime;
       }
 
       /* output first one when its the best */
@@ -1217,15 +1311,12 @@
 
         /* on error the _flush function posted a warning already */
         if ((r = gst_video_rate_flush_prev (videorate,
-                    count > 1)) != GST_FLOW_OK) {
+                    count > 1, intime)) != GST_FLOW_OK) {
           res = r;
           goto done;
         }
       }
 
-      /* Do not produce any dups. We can exit loop now */
-      if (videorate->drop_only)
-        break;
       /* continue while the first one was the best, if they were equal avoid
        * going into an infinite loop */
     }
diff --git a/gst/videoscale/Makefile.in b/gst/videoscale/Makefile.in
index b705165..6887500 100644
--- a/gst/videoscale/Makefile.in
+++ b/gst/videoscale/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -432,6 +433,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -445,6 +449,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -482,6 +489,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst/videotestsrc/Makefile.in b/gst/videotestsrc/Makefile.in
index cf68eb4..14403bf 100644
--- a/gst/videotestsrc/Makefile.in
+++ b/gst/videotestsrc/Makefile.in
@@ -121,6 +121,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -473,6 +474,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -486,6 +490,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -523,6 +530,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst/videotestsrc/gstvideotestsrc.c b/gst/videotestsrc/gstvideotestsrc.c
index a1620f9..3d5c1e4 100644
--- a/gst/videotestsrc/gstvideotestsrc.c
+++ b/gst/videotestsrc/gstvideotestsrc.c
@@ -279,8 +279,8 @@
       "Video test source", "Source/Video",
       "Creates a test video stream", "David A. Schleef <ds@schleef.org>");
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_video_test_src_template));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_video_test_src_template);
 
   gstbasesrc_class->set_caps = gst_video_test_src_setcaps;
   gstbasesrc_class->fixate = gst_video_test_src_src_fixate;
diff --git a/gst/volume/Makefile.in b/gst/volume/Makefile.in
index 7f57b23..ce39f4d 100644
--- a/gst/volume/Makefile.in
+++ b/gst/volume/Makefile.in
@@ -120,6 +120,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -458,6 +459,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -471,6 +475,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -508,6 +515,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/gst/volume/gstvolumeorc-dist.c b/gst/volume/gstvolumeorc-dist.c
index 4b6ee6d..d4ccde8 100644
--- a/gst/volume/gstvolumeorc-dist.c
+++ b/gst/volume/gstvolumeorc-dist.c
@@ -258,7 +258,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 32, 118, 111, 108, 117, 109, 101, 95, 111, 114, 99, 95, 115, 99,
         97, 108, 97, 114, 109, 117, 108, 116, 105, 112, 108, 121, 95, 102, 54,
-        52,
+            52,
         95, 110, 115, 11, 8, 8, 18, 8, 214, 0, 0, 24, 2, 0,
       };
       p = orc_program_new_from_static_bytecode (bc);
@@ -388,7 +388,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 32, 118, 111, 108, 117, 109, 101, 95, 111, 114, 99, 95, 115, 99,
         97, 108, 97, 114, 109, 117, 108, 116, 105, 112, 108, 121, 95, 102, 51,
-        50,
+            50,
         95, 110, 115, 11, 4, 4, 17, 4, 202, 0, 0, 24, 2, 0,
       };
       p = orc_program_new_from_static_bytecode (bc);
@@ -1142,7 +1142,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 29, 118, 111, 108, 117, 109, 101, 95, 111, 114, 99, 95, 112, 114,
         111, 99, 101, 115, 115, 95, 105, 110, 116, 56, 95, 99, 108, 97, 109,
-        112,
+            112,
         11, 1, 1, 14, 2, 3, 0, 0, 0, 16, 1, 20, 2, 174, 32, 0,
         24, 94, 32, 32, 16, 159, 0, 32, 2, 0,
       };
@@ -1564,7 +1564,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 37, 118, 111, 108, 117, 109, 101, 95, 111, 114, 99, 95, 112, 114,
         111, 99, 101, 115, 115, 95, 99, 111, 110, 116, 114, 111, 108, 108, 101,
-        100,
+            100,
         95, 102, 54, 52, 95, 49, 99, 104, 11, 8, 8, 12, 8, 8, 214, 0,
         0, 4, 2, 0,
       };
@@ -1714,7 +1714,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 37, 118, 111, 108, 117, 109, 101, 95, 111, 114, 99, 95, 112, 114,
         111, 99, 101, 115, 115, 95, 99, 111, 110, 116, 114, 111, 108, 108, 101,
-        100,
+            100,
         95, 102, 51, 50, 95, 49, 99, 104, 11, 4, 4, 12, 8, 8, 20, 4,
         225, 32, 4, 202, 0, 0, 32, 2, 0,
       };
@@ -1901,7 +1901,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 37, 118, 111, 108, 117, 109, 101, 95, 111, 114, 99, 95, 112, 114,
         111, 99, 101, 115, 115, 95, 99, 111, 110, 116, 114, 111, 108, 108, 101,
-        100,
+            100,
         95, 102, 51, 50, 95, 50, 99, 104, 11, 8, 8, 12, 8, 8, 20, 4,
         20, 8, 225, 32, 4, 194, 33, 32, 32, 21, 1, 202, 0, 0, 33, 2,
         0,
@@ -2064,7 +2064,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 39, 118, 111, 108, 117, 109, 101, 95, 111, 114, 99, 95, 112, 114,
         111, 99, 101, 115, 115, 95, 99, 111, 110, 116, 114, 111, 108, 108, 101,
-        100,
+            100,
         95, 105, 110, 116, 51, 50, 95, 49, 99, 104, 11, 4, 4, 12, 8, 8,
         20, 8, 223, 32, 0, 214, 32, 32, 4, 222, 0, 32, 2, 0,
       };
@@ -2255,7 +2255,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 39, 118, 111, 108, 117, 109, 101, 95, 111, 114, 99, 95, 112, 114,
         111, 99, 101, 115, 115, 95, 99, 111, 110, 116, 114, 111, 108, 108, 101,
-        100,
+            100,
         95, 105, 110, 116, 49, 54, 95, 49, 99, 104, 11, 2, 2, 12, 8, 8,
         20, 4, 20, 4, 153, 32, 0, 211, 32, 32, 225, 33, 4, 202, 32, 32,
         33, 210, 32, 32, 165, 0, 32, 2, 0,
@@ -2508,7 +2508,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 39, 118, 111, 108, 117, 109, 101, 95, 111, 114, 99, 95, 112, 114,
         111, 99, 101, 115, 115, 95, 99, 111, 110, 116, 114, 111, 108, 108, 101,
-        100,
+            100,
         95, 105, 110, 116, 49, 54, 95, 50, 99, 104, 11, 4, 4, 12, 8, 8,
         20, 8, 20, 4, 20, 8, 21, 1, 153, 32, 0, 21, 1, 211, 32, 32,
         225, 33, 4, 194, 34, 33, 33, 21, 1, 202, 34, 34, 32, 21, 1, 210,
@@ -2723,7 +2723,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 38, 118, 111, 108, 117, 109, 101, 95, 111, 114, 99, 95, 112, 114,
         111, 99, 101, 115, 115, 95, 99, 111, 110, 116, 114, 111, 108, 108, 101,
-        100,
+            100,
         95, 105, 110, 116, 56, 95, 49, 99, 104, 11, 1, 1, 12, 8, 8, 20,
         2, 20, 4, 20, 4, 149, 32, 0, 153, 33, 32, 211, 33, 33, 225, 34,
         4, 202, 33, 33, 34, 210, 33, 33, 163, 32, 33, 159, 0, 32, 2, 0,
@@ -2998,7 +2998,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 38, 118, 111, 108, 117, 109, 101, 95, 111, 114, 99, 95, 112, 114,
         111, 99, 101, 115, 115, 95, 99, 111, 110, 116, 114, 111, 108, 108, 101,
-        100,
+            100,
         95, 105, 110, 116, 56, 95, 50, 99, 104, 11, 2, 2, 12, 8, 8, 20,
         4, 20, 8, 20, 8, 21, 1, 149, 32, 0, 21, 1, 153, 33, 32, 21,
         1, 211, 33, 33, 225, 32, 4, 194, 34, 32, 32, 21, 1, 202, 33, 33,
diff --git a/ltmain.sh b/ltmain.sh
index 2ad8be8..a736cf9 100644
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -31,7 +31,7 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION="2.4.6 Debian-2.4.6-1"
+VERSION="2.4.6 Debian-2.4.6-2"
 package_revision=2.4.6
 
 
@@ -1977,7 +1977,7 @@
 # End:
 
 # Set a version string.
-scriptversion='(GNU libtool) 2.4.6 Debian-2.4.6-1'
+scriptversion='(GNU libtool) 2.4.6'
 
 
 # func_echo ARG...
@@ -2068,7 +2068,7 @@
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname $scriptversion
+       version:        $progname $scriptversion Debian-2.4.6-2
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
diff --git a/m4/Makefile.in b/m4/Makefile.in
index 1471101..456736e 100644
--- a/m4/Makefile.in
+++ b/m4/Makefile.in
@@ -96,6 +96,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -345,6 +346,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -358,6 +362,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -395,6 +402,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/pkgconfig/Makefile.in b/pkgconfig/Makefile.in
index 6967bc7..a67536e 100644
--- a/pkgconfig/Makefile.in
+++ b/pkgconfig/Makefile.in
@@ -97,6 +97,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -411,6 +412,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -424,6 +428,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -461,6 +468,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/po/POTFILES.in b/po/POTFILES.in
index ac00380..98690d9 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -4,11 +4,14 @@
 ext/ogg/gstoggdemux.c
 gst/encoding/gstencodebin.c
 gst/playback/gstdecodebin2.c
+gst/playback/gstparsebin.c
 gst/playback/gstplaybin2.c
+gst/playback/gstplaybin3.c
 gst/playback/gstplaysink.c
 gst/playback/gstplaysinkconvertbin.c
 gst/playback/gstsubtitleoverlay.c
 gst/playback/gsturidecodebin.c
+gst/playback/gsturisourcebin.c
 gst/tcp/gsttcpclientsink.c
 gst/tcp/gsttcpclientsrc.c
 gst-libs/gst/audio/gstaudiobasesrc.c
diff --git a/po/af.gmo b/po/af.gmo
index 5e12fa3..bec559f 100644
--- a/po/af.gmo
+++ b/po/af.gmo
Binary files differ
diff --git a/po/af.po b/po/af.po
index fb631ed..25a2aaa 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: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\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"
@@ -76,9 +76,6 @@
 msgid "Could not read CD."
 msgstr "Kon nie skryf na toestel \"%s\" nie."
 
-msgid "Internal data stream error."
-msgstr ""
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr ""
@@ -94,6 +91,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Kon nie skryf na lêer \"%s\" nie."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Kon nie skryf na lêer \"%s\" nie."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Kon nie skryf na lêer \"%s\" nie."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr ""
@@ -227,6 +232,9 @@
 msgid "Kate subtitle format"
 msgstr ""
 
+msgid "WebVTT subtitle format"
+msgstr ""
+
 msgid "Uncompressed video"
 msgstr ""
 
@@ -393,6 +401,13 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr ""
 
+msgid "capturing 35 mm equivalent focal length"
+msgstr ""
+
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr ""
+
 msgid "capturing digital zoom ratio"
 msgstr ""
 
diff --git a/po/az.gmo b/po/az.gmo
index 5fd9415..d170cc4 100644
--- a/po/az.gmo
+++ b/po/az.gmo
Binary files differ
diff --git a/po/az.po b/po/az.po
index 83d6bd3..0fbc991 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: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\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"
@@ -77,9 +77,6 @@
 msgid "Could not read CD."
 msgstr "\"%s\" avadanlığına yazıla bilmədi."
 
-msgid "Internal data stream error."
-msgstr ""
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr ""
@@ -95,6 +92,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "\"%s\" faylına yazıla bilmədi."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "\"%s\" faylına yazıla bilmədi."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "\"%s\" faylına yazıla bilmədi."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr ""
@@ -228,6 +233,9 @@
 msgid "Kate subtitle format"
 msgstr ""
 
+msgid "WebVTT subtitle format"
+msgstr ""
+
 msgid "Uncompressed video"
 msgstr ""
 
@@ -394,6 +402,13 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr ""
 
+msgid "capturing 35 mm equivalent focal length"
+msgstr ""
+
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr ""
+
 msgid "capturing digital zoom ratio"
 msgstr ""
 
diff --git a/po/bg.gmo b/po/bg.gmo
index e773fae..fa5f76c 100644
--- a/po/bg.gmo
+++ b/po/bg.gmo
Binary files differ
diff --git a/po/bg.po b/po/bg.po
index bad77c6..afeba45 100644
--- a/po/bg.po
+++ b/po/bg.po
@@ -10,7 +10,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.7.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2016-02-21 21:03+0200\n"
 "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
 "Language-Team: Bulgarian <dict@ludost.net>\n"
@@ -75,9 +75,6 @@
 msgid "Could not read CD."
 msgstr "CD-то не може да бъде прочетено."
 
-msgid "Internal data stream error."
-msgstr "Вътрешна грешка на потока от данни."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Елементът „%s“ липсва — проверете инсталацията на GStreamer."
@@ -91,6 +88,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Не може да се създаде елемент „uridecodebin“."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Не може да се създаде елемент „uridecodebin“."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Не може да се създаде елемент „uridecodebin“."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Едновременно липсват елементите-приемници „autovideosink“ и „%s“."
@@ -224,6 +229,10 @@
 msgid "Kate subtitle format"
 msgstr "Субтитри, формат Kate"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Субтитри, формат Kate"
+
 msgid "Uncompressed video"
 msgstr "Некомпресирано видео"
 
@@ -390,6 +399,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Фокусно разстояние на обектива при заснемане в милиметри"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "фокусно разстояние"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Фокусно разстояние на обектива при заснемане в милиметри"
+
 msgid "capturing digital zoom ratio"
 msgstr "цифрово увеличение"
 
@@ -654,3 +672,6 @@
 
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "Натиснете „k“, за да видите списъка с клавишни комбинации.\n"
+
+#~ msgid "Internal data stream error."
+#~ msgstr "Вътрешна грешка на потока от данни."
diff --git a/po/ca.gmo b/po/ca.gmo
index e755ca1..9fbc299 100644
--- a/po/ca.gmo
+++ b/po/ca.gmo
Binary files differ
diff --git a/po/ca.po b/po/ca.po
index 25963fd..2aeb57a 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 0.10.32.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\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"
@@ -78,9 +78,6 @@
 msgid "Could not read CD."
 msgstr "No s'ha pogut llegir el CD."
 
-msgid "Internal data stream error."
-msgstr "S'ha produït un error intern de flux de dades."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Manca l'element «%s» - comproveu la vostra instaŀlació del GStreamer."
@@ -95,6 +92,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "No s'ha pogut crear l'element «decodebin»."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "No s'ha pogut crear l'element «decodebin»."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "No s'ha pogut crear l'element «decodebin»."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Manquen els elements autovideosink i %s."
@@ -232,6 +237,10 @@
 msgstr "Format de subtítols Kate"
 
 #, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Format de subtítols Kate"
+
+#, fuzzy
 msgid "Uncompressed video"
 msgstr "YUV sense comprimir"
 
@@ -400,6 +409,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Longitud focal de la lent utilitzada en capturar la imatge, en mm"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "longitud focal de la captura"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Longitud focal de la lent utilitzada en capturar la imatge, en mm"
+
 msgid "capturing digital zoom ratio"
 msgstr "relació de zoom digital de la captura"
 
@@ -671,6 +689,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr ""
 
+#~ msgid "Internal data stream error."
+#~ msgstr "S'ha produït un error intern de flux de dades."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "Es requereix un connector %s per a reproduir aquest flux, però no és "
diff --git a/po/cs.gmo b/po/cs.gmo
index d0f4fe1..917e03a 100644
--- a/po/cs.gmo
+++ b/po/cs.gmo
Binary files differ
diff --git a/po/cs.po b/po/cs.po
index c3806a5..2d9ff72 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -10,7 +10,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base-1.7.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2016-03-03 15:35+0100\n"
 "Last-Translator: Marek Černocký <marek@manet.cz>\n"
 "Language-Team: Czech <translation-team-cs@lists.sourceforge.net>\n"
@@ -76,9 +76,6 @@
 msgid "Could not read CD."
 msgstr "Nezdařilo čtení z CD."
 
-msgid "Internal data stream error."
-msgstr "Vnitřní chyba datového proudu."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Schází prvek „%s“ – zkontrolujte prosím instalaci systému GStreamer."
@@ -92,6 +89,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Nelze vytvořit prvek „uridecodebin“."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Nelze vytvořit prvek „uridecodebin“."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Nelze vytvořit prvek „uridecodebin“."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Schází jak prvek autovideosink, tak %s."
@@ -225,6 +230,10 @@
 msgid "Kate subtitle format"
 msgstr "Formát titulků Kate"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Formát titulků Kate"
+
 msgid "Uncompressed video"
 msgstr "Nekomprimované video"
 
@@ -391,6 +400,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Ohnisková vzdálenost čoček použitá při záchytávání obrazu, v mm"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "ohnisková vzdálenost při zachytávání"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Ohnisková vzdálenost čoček použitá při záchytávání obrazu, v mm"
+
 msgid "capturing digital zoom ratio"
 msgstr "stupeň digitálního přiblížení při zachytávání"
 
@@ -657,3 +675,6 @@
 
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "Zmáčknutím „k“ si zobrazíte seznam klávesových zkratek.\n"
+
+#~ msgid "Internal data stream error."
+#~ msgstr "Vnitřní chyba datového proudu."
diff --git a/po/da.gmo b/po/da.gmo
index cc75f27..0c034fc 100644
--- a/po/da.gmo
+++ b/po/da.gmo
Binary files differ
diff --git a/po/da.po b/po/da.po
index cf32a48..85f4451 100644
--- a/po/da.po
+++ b/po/da.po
@@ -33,7 +33,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.7.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2016-03-27 16:38+0100\n"
 "Last-Translator: Joe Hansen <joedalton2@yahoo.dk>\n"
 "Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
@@ -96,9 +96,6 @@
 msgid "Could not read CD."
 msgstr "Kunne ikke læse cd."
 
-msgid "Internal data stream error."
-msgstr "Intern datastrømsfejl."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Elementet »%s« mangler - kontroller din GStreamer-installation."
@@ -112,6 +109,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Kunne ikke oprette elementet »uridecodebin«."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Kunne ikke oprette elementet »uridecodebin«."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Kunne ikke oprette elementet »uridecodebin«."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Både autovideosink og %s elementer mangler."
@@ -246,6 +251,10 @@
 msgid "Kate subtitle format"
 msgstr "Kate-undertekstformat"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Kate-undertekstformat"
+
 msgid "Uncompressed video"
 msgstr "Ukomprimeret video"
 
@@ -418,6 +427,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Brændvidde på linse brugt under optagelse af billedet, i mm"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "brændvidde for optager"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Brændvidde på linse brugt under optagelse af billedet, i mm"
+
 msgid "capturing digital zoom ratio"
 msgstr "digitalt zoomforhold for optager"
 
@@ -693,3 +711,6 @@
 
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "Tryk »k« for at se en liste over genvejstaster.\n"
+
+#~ msgid "Internal data stream error."
+#~ msgstr "Intern datastrømsfejl."
diff --git a/po/de.gmo b/po/de.gmo
index d4ebfff..f2ba9c4 100644
--- a/po/de.gmo
+++ b/po/de.gmo
Binary files differ
diff --git a/po/de.po b/po/de.po
index 596f281..c992920 100644
--- a/po/de.po
+++ b/po/de.po
@@ -1,24 +1,25 @@
-# German messages for gst-plugins-base 1.4.0
+# German messages for gst-plugins-base 1.7.90
 # Copyright © 2006 Karl Eichwalder
 # This file is distributed under the same license as the gst-plugins-base package.
 # Karl Eichwalder <ke@suse.de>, 2006.
 # Mario Blättermann <mariobl@gnome.org>, 2010.
-# Christian Kirbach <christian.kirbach@gmail.com>, 2009, 2010, 2011, 2012, 2013.
+# Christian Kirbach <christian.kirbach@gmail.com>, 2009, 2010, 2011, 2012, 2013, 2016.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: gst-plugins-base 1.7.2\n"
+"Project-Id-Version: gst-plugins-base 1.7.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
-"PO-Revision-Date: 2016-02-22 23:44+0100\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
+"PO-Revision-Date: 2016-09-28 21:08+0200\n"
 "Last-Translator: Christian Kirbach <christian.kirbach@gmail.com>\n"
 "Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
 "Language: de\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 1.8.7\n"
+"X-Generator: Poedit 1.8.9\n"
 
 msgid "Could not open device for playback in mono mode."
 msgstr "Gerät konnte nicht zur Wiedergabe in Mono geöffnet werden."
@@ -75,9 +76,6 @@
 msgid "Could not read CD."
 msgstr "CD konnte nicht gelesen werden."
 
-msgid "Internal data stream error."
-msgstr "Interner Fehler im Datenstrom."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr ""
@@ -92,6 +90,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Das Element »uridecodebin« konnte nicht erstellt werden."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Das Element »decodebin2« konnte nicht erstellt werden."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Das Element »uridecodebin« konnte nicht erstellt werden."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Beide Elemente »autovideosink« und »%s« fehlen."
@@ -226,6 +232,10 @@
 msgid "Kate subtitle format"
 msgstr "Untertitel-Format Kate"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Untertitel-Format Kate"
+
 msgid "Uncompressed video"
 msgstr "Unkomprimiertes Video"
 
@@ -393,6 +403,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Die verwendete Brennweite des Objektivs bei Bildaufnahme in mm"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "Brennweite"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Die verwendete Brennweite des Objektivs bei Bildaufnahme in mm"
+
 msgid "capturing digital zoom ratio"
 msgstr "Digitale Vergrößerung"
 
@@ -567,13 +586,13 @@
 msgstr "Beenden"
 
 msgid "> or n"
-msgstr ""
+msgstr "> oder n"
 
 msgid "play next"
 msgstr "Nächsten wiedergeben"
 
 msgid "< or b"
-msgstr ""
+msgstr "< oder b"
 
 msgid "play previous"
 msgstr "Vorherigen wiedergeben"
@@ -662,6 +681,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "Geben Sie »k« ein, um die Liste der Tastenkombinationen zu sehen.\n"
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Interner Fehler im Datenstrom."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "Ein Plugin »%s« wird zum Abspielen dieses Datenstroms benötigt, ist aber "
@@ -820,9 +842,6 @@
 #~ msgid "Internal data flow error."
 #~ msgstr "Interner Fehler im Datenstrom."
 
-#~ msgid "Could not create \"decodebin2\" element."
-#~ msgstr "Das Element »decodebin2« konnte nicht erstellt werden."
-
 #~ msgid "Could not create \"queue2\" element."
 #~ msgstr "Das Element »queue2« konnte nicht erstellt werden."
 
diff --git a/po/el.gmo b/po/el.gmo
index 9d2d54f..8173292 100644
--- a/po/el.gmo
+++ b/po/el.gmo
Binary files differ
diff --git a/po/el.po b/po/el.po
index a456bc1..b34ec13 100644
--- a/po/el.po
+++ b/po/el.po
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 0.10.32.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2012-05-05 19:13+0100\n"
 "Last-Translator: Savvas Radevic <vicedar@gmail.com>\n"
 "Language-Team: Greek <team@lists.gnome.gr>\n"
@@ -76,9 +76,6 @@
 msgid "Could not read CD."
 msgstr "Αδυναμία ανάγνωσης CD."
 
-msgid "Internal data stream error."
-msgstr "Σφάλμα εσωτερικής ροής δεδομένων."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Λείπει το στοιχείο '%s' - ελέγξτε την εγκατάσταση του GStreamer."
@@ -93,6 +90,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Αδυναμία δημιουργία στοιχείου «decodebin»."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Αδυναμία δημιουργία στοιχείου «decodebin»."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Αδυναμία δημιουργία στοιχείου «decodebin»."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Λείπουν και τα δύο στοιχεία autoaudiosink και %s."
@@ -230,6 +235,10 @@
 msgstr "Μορφή υποτίτλων Kate"
 
 #, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Μορφή υποτίτλων Kate"
+
+#, fuzzy
 msgid "Uncompressed video"
 msgstr "Ασυμπίεστο YUV"
 
@@ -402,6 +411,17 @@
 "Το εστιακό μήκος του φακού που χρησιμοποιήθηκε κατά τη λήψη της εικόνας, σε "
 "mm"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "εστιακό μήκος λήψης"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr ""
+"Το εστιακό μήκος του φακού που χρησιμοποιήθηκε κατά τη λήψη της εικόνας, σε "
+"mm"
+
 msgid "capturing digital zoom ratio"
 msgstr "λόγος ψηφιακού ζουμ λήψης"
 
@@ -676,6 +696,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr ""
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Σφάλμα εσωτερικής ροής δεδομένων."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "Απαιτείται μια πρόσθετη λειτουργία %s για την αναπαραγωγή αυτής της ροής, "
diff --git a/po/en_GB.gmo b/po/en_GB.gmo
index 5937759..8475bd7 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 bedaeb8..fa6c580 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: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\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"
@@ -75,9 +75,6 @@
 msgid "Could not read CD."
 msgstr "Could not write to device \"%s\"."
 
-msgid "Internal data stream error."
-msgstr ""
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr ""
@@ -93,6 +90,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Could not write to file \"%s\"."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Could not write to file \"%s\"."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Could not write to file \"%s\"."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr ""
@@ -226,6 +231,9 @@
 msgid "Kate subtitle format"
 msgstr ""
 
+msgid "WebVTT subtitle format"
+msgstr ""
+
 msgid "Uncompressed video"
 msgstr ""
 
@@ -392,6 +400,13 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr ""
 
+msgid "capturing 35 mm equivalent focal length"
+msgstr ""
+
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr ""
+
 msgid "capturing digital zoom ratio"
 msgstr ""
 
diff --git a/po/eo.gmo b/po/eo.gmo
index 58ff20f..314e141 100644
--- a/po/eo.gmo
+++ b/po/eo.gmo
Binary files differ
diff --git a/po/eo.po b/po/eo.po
index c9e027b..7fc6425 100644
--- a/po/eo.po
+++ b/po/eo.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 0.10.32.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2011-06-04 21:11+0100\n"
 "Last-Translator: Kristjan SCHMIDT <kristjan.schmidt@googlemail.com>\n"
 "Language-Team: Esperanto <translation-team-eo@lists.sourceforge.net>\n"
@@ -72,9 +72,6 @@
 msgid "Could not read CD."
 msgstr "Ne eblis legi la KD-n."
 
-msgid "Internal data stream error."
-msgstr "Interna datumflu-eraro."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr ""
@@ -89,6 +86,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Ne eblis krei \"decodebin\"-elementon."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Ne eblis krei \"decodebin\"-elementon."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Ne eblis krei \"decodebin\"-elementon."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr ""
@@ -222,6 +227,9 @@
 msgid "Kate subtitle format"
 msgstr ""
 
+msgid "WebVTT subtitle format"
+msgstr ""
+
 msgid "Uncompressed video"
 msgstr ""
 
@@ -388,6 +396,13 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr ""
 
+msgid "capturing 35 mm equivalent focal length"
+msgstr ""
+
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr ""
+
 msgid "capturing digital zoom ratio"
 msgstr ""
 
@@ -649,6 +664,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr ""
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Interna datumflu-eraro."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr "%s-kromprogramo bezonatas, sed tia ne estas instalite."
 
diff --git a/po/es.gmo b/po/es.gmo
index 33a3788..418aa25 100644
--- a/po/es.gmo
+++ b/po/es.gmo
Binary files differ
diff --git a/po/es.po b/po/es.po
index f127bae..3f21cb7 100644
--- a/po/es.po
+++ b/po/es.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 0.10.32.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2011-10-02 15:46+0200\n"
 "Last-Translator: Jorge González González <aloriel@gmail.com>\n"
 "Language-Team: Spanish <es@li.org>\n"
@@ -72,9 +72,6 @@
 msgid "Could not read CD."
 msgstr "No se pudo leer del D."
 
-msgid "Internal data stream error."
-msgstr "Error interno de flujo de datos."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Falta el elemento «%s»; compruebe su instalación de GStreamer."
@@ -89,6 +86,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "No se pudo crear el elemento «decodebin»."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "No se pudo crear el elemento «decodebin2»."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "No se pudo crear el elemento «decodebin»."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Tanto el elemento autovideosink como %s faltan."
@@ -227,6 +232,10 @@
 msgstr "Formato de subtítulos kate"
 
 #, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Formato de subtítulos kate"
+
+#, fuzzy
 msgid "Uncompressed video"
 msgstr "YUV sin comprimir"
 
@@ -395,6 +404,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Longitud focal de la lente usada al tomar la imagen, en mm"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "longitud focal de la toma"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Longitud focal de la lente usada al tomar la imagen, en mm"
+
 msgid "capturing digital zoom ratio"
 msgstr "tasa de ampliación digital de la toma"
 
@@ -659,6 +677,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr ""
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Error interno de flujo de datos."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "Se requiere un complemento de %s para reproducir este medio, pero no está "
@@ -816,9 +837,6 @@
 #~ msgid "Internal data flow error."
 #~ msgstr "Error en el flujo de datos interno."
 
-#~ msgid "Could not create \"decodebin2\" element."
-#~ msgstr "No se pudo crear el elemento «decodebin2»."
-
 #~ msgid "Could not create \"queue2\" element."
 #~ msgstr "No se pudo crear el elemento «queue2»."
 
diff --git a/po/eu.gmo b/po/eu.gmo
index 774a721..a3c1d91 100644
--- a/po/eu.gmo
+++ b/po/eu.gmo
Binary files differ
diff --git a/po/eu.po b/po/eu.po
index 320c57f..c58786d 100644
--- a/po/eu.po
+++ b/po/eu.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base-0.10.26.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2010-03-25 12:32+0100\n"
 "Last-Translator: Mikel Olasagasti Uranga <hey_neken@mundurat.net>\n"
 "Language-Team: Basque <translation-team-eu@lists.sourceforge.net>\n"
@@ -74,9 +74,6 @@
 msgid "Could not read CD."
 msgstr "Ezin izan da CDa irakurri."
 
-msgid "Internal data stream error."
-msgstr "Datu-korrontearen barne-errorea."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "'%s' elementua falta da. Begiratu GStreamer ondo instalatua dagoen."
@@ -91,6 +88,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Ezin izan da sortu \"decodebin\" elementua."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Ezin izan da sortu \"decodebin\" elementua."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Ezin izan da sortu \"decodebin\" elementua."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Autovideosink eta %s elementuak, biak, falta dira."
@@ -230,6 +235,10 @@
 msgstr "'Kate' azpititulu-formatua"
 
 #, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "'Kate' azpititulu-formatua"
+
+#, fuzzy
 msgid "Uncompressed video"
 msgstr "Konprimitu gabeko YUV"
 
@@ -398,6 +407,13 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr ""
 
+msgid "capturing 35 mm equivalent focal length"
+msgstr ""
+
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr ""
+
 msgid "capturing digital zoom ratio"
 msgstr ""
 
@@ -661,6 +677,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr ""
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Datu-korrontearen barne-errorea."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "%s plugina behar da korronte hori erreproduzitzeko, baina ez dago "
diff --git a/po/fi.gmo b/po/fi.gmo
index 00ff3f0..feab351 100644
--- a/po/fi.gmo
+++ b/po/fi.gmo
Binary files differ
diff --git a/po/fi.po b/po/fi.po
index 2d7fe9e..99db27c 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -12,7 +12,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 0.10.30.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2010-12-31 23:21+0200\n"
 "Last-Translator: Tommi Vainikainen <Tommi.Vainikainen@iki.fi>\n"
 "Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n"
@@ -76,9 +76,6 @@
 msgid "Could not read CD."
 msgstr "CD-levyä ei voitu lukea."
 
-msgid "Internal data stream error."
-msgstr "Sisäisen tietovirran virhe."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Puuttuva elementti \"%s\" - tarkista GStreamer-asennuksesi."
@@ -93,6 +90,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Elementtiä \"decodebin\" ei voitu luoda."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Elementtiä \"decodebin2\" ei voitu luoda."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Elementtiä \"decodebin\" ei voitu luoda."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Sekä autovideosink- ja %s-elementit puuttuvat."
@@ -230,6 +235,10 @@
 msgstr "Kate-tekstitysmuoto"
 
 #, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Kate-tekstitysmuoto"
+
+#, fuzzy
 msgid "Uncompressed video"
 msgstr "Pakkaamaton YUV"
 
@@ -398,6 +407,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Linssin polttoväli kuvattaessa, millimetriä"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "kuvaamisen polttoväli"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Linssin polttoväli kuvattaessa, millimetriä"
+
 msgid "capturing digital zoom ratio"
 msgstr "kuvaamisen digitaalinen zoomaus"
 
@@ -663,6 +681,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr ""
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Sisäisen tietovirran virhe."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "Virran toistamiseen tarvitaan %s-liitännäinen, mutta se ei ole asennettu."
@@ -818,9 +839,6 @@
 #~ msgid "Internal data flow error."
 #~ msgstr "Sisäisen tietovirran virhe."
 
-#~ msgid "Could not create \"decodebin2\" element."
-#~ msgstr "Elementtiä \"decodebin2\" ei voitu luoda."
-
 #~ msgid "Could not create \"queue2\" element."
 #~ msgstr "Elementtiä \"queue2\" ei voitu luoda."
 
diff --git a/po/fr.gmo b/po/fr.gmo
index 7b1fb8c..eabc8f2 100644
--- a/po/fr.gmo
+++ b/po/fr.gmo
Binary files differ
diff --git a/po/fr.po b/po/fr.po
index 660d2f7..ffd37dd 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -10,7 +10,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.7.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2016-03-04 13:08+0100\n"
 "Last-Translator: Stéphane Aulery <lkppo@free.fr>\n"
 "Language-Team: French <traduc@traduc.org>\n"
@@ -84,9 +84,6 @@
 msgid "Could not read CD."
 msgstr "Impossible de lire le CD."
 
-msgid "Internal data stream error."
-msgstr "Erreur du flux de données interne."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Élément « %s » manquant — Vérifiez votre installation de GStreamer."
@@ -100,6 +97,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Impossible de créer un élément « uridecodebin »."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Impossible de créer un élément « uridecodebin »."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Impossible de créer un élément « uridecodebin »."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Les éléments autovideosink et %s sont tous deux manquants."
@@ -234,6 +239,10 @@
 msgid "Kate subtitle format"
 msgstr "Format de sous-titres Kate"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Format de sous-titres Kate"
+
 msgid "Uncompressed video"
 msgstr "Video non compressée"
 
@@ -402,6 +411,16 @@
 msgstr ""
 "Distance focale de l’optique utilisée pour la capture de l’image (en mm)"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "distance focale de la capture"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr ""
+"Distance focale de l’optique utilisée pour la capture de l’image (en mm)"
+
 msgid "capturing digital zoom ratio"
 msgstr "valeur du zoom numérique de la capture"
 
@@ -677,3 +696,6 @@
 
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "Pressez k pour voir la liste des raccourcis clavier.\n"
+
+#~ msgid "Internal data stream error."
+#~ msgstr "Erreur du flux de données interne."
diff --git a/po/gl.gmo b/po/gl.gmo
index 51b383d..5a5b274 100644
--- a/po/gl.gmo
+++ b/po/gl.gmo
Binary files differ
diff --git a/po/gl.po b/po/gl.po
index 30e5d33..a757242 100644
--- a/po/gl.po
+++ b/po/gl.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.0.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2012-12-15 03:40+0200\n"
 "Last-Translator: Fran Dieguez <frandieguez@ubuntu.com>\n"
 "Language-Team: Galician <proxecto@trasno.net>\n"
@@ -77,9 +77,6 @@
 msgid "Could not read CD."
 msgstr "Non foi posíbel ler o CD."
 
-msgid "Internal data stream error."
-msgstr "Produciuse un erro no fluxo de datos internos."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Falta o elemento «%s» - comprobe a instalación do GStreamer."
@@ -94,6 +91,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Non foi posíbel crear o elemento \"decodebin\" ."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Non foi posíbel crear o elemento \"decodebin\" ."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Non foi posíbel crear o elemento \"decodebin\" ."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Faltan os elementos autivideosink e %s."
@@ -228,6 +233,10 @@
 msgid "Kate subtitle format"
 msgstr "Formato de subtítulos Kate"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Formato de subtítulos Kate"
+
 msgid "Uncompressed video"
 msgstr "Vídeo sen comprimir"
 
@@ -394,6 +403,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Lonxitude focal da lente usada ao tomar a imaxe, en mm"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "lonxitude focal da toma"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Lonxitude focal da lente usada ao tomar a imaxe, en mm"
+
 msgid "capturing digital zoom ratio"
 msgstr "taxa de ampliación dixital da toma"
 
@@ -659,6 +677,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr ""
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Produciuse un erro no fluxo de datos internos."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "Precísase un engadido %s que non está instalado para reproducir este "
diff --git a/po/gst-plugins-base-1.0.pot b/po/gst-plugins-base-1.0.pot
index 322fcb2..daf9488 100644
--- a/po/gst-plugins-base-1.0.pot
+++ b/po/gst-plugins-base-1.0.pot
@@ -5,9 +5,9 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: gst-plugins-base 1.8.3\n"
+"Project-Id-Version: gst-plugins-base 1.9.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\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"
@@ -39,7 +39,7 @@
 msgid "Could not open audio device for playback."
 msgstr ""
 
-#: ext/alsa/gstalsasink.c:1082
+#: ext/alsa/gstalsasink.c:1074
 msgid "Error outputting to audio device. The device has been disconnected."
 msgstr ""
 
@@ -66,7 +66,7 @@
 msgid "Could not open audio device for recording."
 msgstr ""
 
-#: ext/alsa/gstalsasrc.c:996
+#: ext/alsa/gstalsasrc.c:988
 msgid "Error recording from audio device. The device has been disconnected."
 msgstr ""
 
@@ -82,123 +82,128 @@
 msgid "Could not read CD."
 msgstr ""
 
-#: ext/ogg/gstoggdemux.c:4848
-msgid "Internal data stream error."
-msgstr ""
-
-#: gst/encoding/gstencodebin.c:1591 gst/playback/gstplaybin2.c:3363
-#: gst/playback/gstplaysink.c:1483 gst/playback/gstplaysink.c:1496
-#: gst/playback/gstplaysink.c:1833 gst/playback/gstplaysink.c:1865
-#: gst/playback/gstplaysink.c:2445 gst/playback/gstplaysink.c:2494
-#: gst/playback/gstplaysink.c:2509 gst/playback/gstplaysink.c:2534
-#: gst/playback/gstplaysink.c:2566 gst/playback/gstplaysink.c:2714
-#: gst/playback/gstplaysink.c:2745 gst/playback/gstplaysink.c:3123
-#: gst/playback/gstplaysink.c:3132 gst/playback/gstplaysink.c:3141
-#: gst/playback/gstplaysink.c:3150 gst/playback/gstplaysink.c:3553
-#: gst/playback/gstplaysink.c:4427 gst/playback/gstplaysinkconvertbin.c:97
-#: gst/playback/gstplaysinkconvertbin.c:117 gst/playback/gsturidecodebin.c:1490
+#: gst/encoding/gstencodebin.c:1590 gst/playback/gstplaybin2.c:3401
+#: gst/playback/gstplaysink.c:1480 gst/playback/gstplaysink.c:1493
+#: gst/playback/gstplaysink.c:1830 gst/playback/gstplaysink.c:1862
+#: gst/playback/gstplaysink.c:2442 gst/playback/gstplaysink.c:2491
+#: gst/playback/gstplaysink.c:2506 gst/playback/gstplaysink.c:2531
+#: gst/playback/gstplaysink.c:2563 gst/playback/gstplaysink.c:2711
+#: gst/playback/gstplaysink.c:2742 gst/playback/gstplaysink.c:3120
+#: gst/playback/gstplaysink.c:3129 gst/playback/gstplaysink.c:3138
+#: gst/playback/gstplaysink.c:3147 gst/playback/gstplaysink.c:3550
+#: gst/playback/gstplaysink.c:4424 gst/playback/gstplaysinkconvertbin.c:97
+#: gst/playback/gstplaysinkconvertbin.c:117 gst/playback/gsturidecodebin.c:1489
+#: gst/playback/gsturisourcebin.c:1620
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr ""
 
-#: gst/playback/gstdecodebin2.c:1883
+#: gst/playback/gstdecodebin2.c:1865 gst/playback/gstparsebin.c:1572
 msgid "Could not determine type of stream"
 msgstr ""
 
-#: gst/playback/gstdecodebin2.c:2839
+#: gst/playback/gstdecodebin2.c:2841 gst/playback/gstparsebin.c:2405
 msgid "This appears to be a text file"
 msgstr ""
 
-#: gst/playback/gstplaybin2.c:5408
+#: gst/playback/gstplaybin2.c:5446
 msgid "Could not create \"uridecodebin\" element."
 msgstr ""
 
-#: gst/playback/gstplaysink.c:1964
+#: gst/playback/gstplaybin3.c:4643
+msgid "Could not create \"decodebin3\" element."
+msgstr ""
+
+#: gst/playback/gstplaybin3.c:4889
+msgid "Could not create \"urisourcebin\" element."
+msgstr ""
+
+#: gst/playback/gstplaysink.c:1961
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr ""
 
-#: gst/playback/gstplaysink.c:1968
+#: gst/playback/gstplaysink.c:1965
 msgid "The autovideosink element is missing."
 msgstr ""
 
-#: gst/playback/gstplaysink.c:1973
+#: gst/playback/gstplaysink.c:1970
 #, c-format
 msgid "Configured videosink %s is not working."
 msgstr ""
 
-#: gst/playback/gstplaysink.c:1977
+#: gst/playback/gstplaysink.c:1974
 #, c-format
 msgid "Both autovideosink and %s elements are not working."
 msgstr ""
 
-#: gst/playback/gstplaysink.c:1981
+#: gst/playback/gstplaysink.c:1978
 msgid "The autovideosink element is not working."
 msgstr ""
 
-#: gst/playback/gstplaysink.c:2482
+#: gst/playback/gstplaysink.c:2479
 msgid "Custom text sink element is not usable."
 msgstr ""
 
-#: gst/playback/gstplaysink.c:2860
+#: gst/playback/gstplaysink.c:2857
 msgid "No volume control found"
 msgstr ""
 
-#: gst/playback/gstplaysink.c:2890
+#: gst/playback/gstplaysink.c:2887
 #, c-format
 msgid "Both autoaudiosink and %s elements are missing."
 msgstr ""
 
-#: gst/playback/gstplaysink.c:2894
+#: gst/playback/gstplaysink.c:2891
 msgid "The autoaudiosink element is missing."
 msgstr ""
 
-#: gst/playback/gstplaysink.c:2899
+#: gst/playback/gstplaysink.c:2896
 #, c-format
 msgid "Configured audiosink %s is not working."
 msgstr ""
 
-#: gst/playback/gstplaysink.c:2903
+#: gst/playback/gstplaysink.c:2900
 #, c-format
 msgid "Both autoaudiosink and %s elements are not working."
 msgstr ""
 
-#: gst/playback/gstplaysink.c:2907
+#: gst/playback/gstplaysink.c:2904
 msgid "The autoaudiosink element is not working."
 msgstr ""
 
-#: gst/playback/gstplaysink.c:3226 gst/playback/gstplaysink.c:3231
+#: gst/playback/gstplaysink.c:3223 gst/playback/gstplaysink.c:3228
 msgid "Can't play a text file without video or visualizations."
 msgstr ""
 
-#: gst/playback/gsturidecodebin.c:939
+#: gst/playback/gsturidecodebin.c:938
 #, c-format
 msgid "No decoder available for type '%s'."
 msgstr ""
 
-#: gst/playback/gsturidecodebin.c:1396
+#: gst/playback/gsturidecodebin.c:1395 gst/playback/gsturisourcebin.c:1514
 msgid "No URI specified to play from."
 msgstr ""
 
-#: gst/playback/gsturidecodebin.c:1402
+#: gst/playback/gsturidecodebin.c:1401 gst/playback/gsturisourcebin.c:1520
 #, c-format
 msgid "Invalid URI \"%s\"."
 msgstr ""
 
-#: gst/playback/gsturidecodebin.c:1409
+#: gst/playback/gsturidecodebin.c:1408 gst/playback/gsturisourcebin.c:1527
 msgid "This stream type cannot be played yet."
 msgstr ""
 
-#: gst/playback/gsturidecodebin.c:1427
+#: gst/playback/gsturidecodebin.c:1426 gst/playback/gsturisourcebin.c:1545
 #, c-format
 msgid "No URI handler implemented for \"%s\"."
 msgstr ""
 
-#: gst/playback/gsturidecodebin.c:2300
+#: gst/playback/gsturidecodebin.c:2292 gst/playback/gsturisourcebin.c:2200
 msgid "Source element is invalid."
 msgstr ""
 
-#: gst/tcp/gsttcpclientsink.c:215
+#: gst/tcp/gsttcpclientsink.c:214
 #, c-format
 msgid "Error while sending data to \"%s:%d\"."
 msgstr ""
@@ -289,127 +294,131 @@
 msgid "Kate subtitle format"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:452
-#: gst-libs/gst/pbutils/descriptions.c:455
-#: gst-libs/gst/pbutils/descriptions.c:505
+#: gst-libs/gst/pbutils/descriptions.c:290
+msgid "WebVTT subtitle format"
+msgstr ""
+
+#: gst-libs/gst/pbutils/descriptions.c:453
+#: gst-libs/gst/pbutils/descriptions.c:456
+#: gst-libs/gst/pbutils/descriptions.c:506
 msgid "Uncompressed video"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:460
+#: gst-libs/gst/pbutils/descriptions.c:461
 msgid "Uncompressed gray"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:483
+#: gst-libs/gst/pbutils/descriptions.c:484
 #, c-format
 msgid "Uncompressed packed YUV %s"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:485
+#: gst-libs/gst/pbutils/descriptions.c:486
 #, c-format
 msgid "Uncompressed semi-planar YUV %s"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:487
+#: gst-libs/gst/pbutils/descriptions.c:488
 #, c-format
 msgid "Uncompressed planar YUV %s"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:498
+#: gst-libs/gst/pbutils/descriptions.c:499
 #, c-format
 msgid "Uncompressed palettized %d-bit %s"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:501
+#: gst-libs/gst/pbutils/descriptions.c:502
 #, c-format
 msgid "Uncompressed %d-bit %s"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:583
+#: gst-libs/gst/pbutils/descriptions.c:584
 #, c-format
 msgid "DivX MPEG-4 Version %d"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:830
+#: gst-libs/gst/pbutils/descriptions.c:831
 msgid "Uncompressed audio"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:836
+#: gst-libs/gst/pbutils/descriptions.c:837
 #, c-format
 msgid "Raw %d-bit %s audio"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:936
+#: gst-libs/gst/pbutils/descriptions.c:937
 msgid "Audio CD source"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:939
+#: gst-libs/gst/pbutils/descriptions.c:940
 msgid "DVD source"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:942
+#: gst-libs/gst/pbutils/descriptions.c:943
 msgid "Real Time Streaming Protocol (RTSP) source"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:946
+#: gst-libs/gst/pbutils/descriptions.c:947
 msgid "Microsoft Media Server (MMS) protocol source"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:954
+#: gst-libs/gst/pbutils/descriptions.c:955
 #, c-format
 msgid "%s protocol source"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:1026
+#: gst-libs/gst/pbutils/descriptions.c:1027
 #, c-format
 msgid "%s video RTP depayloader"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:1028
+#: gst-libs/gst/pbutils/descriptions.c:1029
 #, c-format
 msgid "%s audio RTP depayloader"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:1030
+#: gst-libs/gst/pbutils/descriptions.c:1031
 #, c-format
 msgid "%s RTP depayloader"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:1037
+#: gst-libs/gst/pbutils/descriptions.c:1038
 #, c-format
 msgid "%s demuxer"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:1039
+#: gst-libs/gst/pbutils/descriptions.c:1040
 #, c-format
 msgid "%s decoder"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:1077
+#: gst-libs/gst/pbutils/descriptions.c:1078
 #, c-format
 msgid "%s video RTP payloader"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:1079
+#: gst-libs/gst/pbutils/descriptions.c:1080
 #, c-format
 msgid "%s audio RTP payloader"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:1081
+#: gst-libs/gst/pbutils/descriptions.c:1082
 #, c-format
 msgid "%s RTP payloader"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:1088
+#: gst-libs/gst/pbutils/descriptions.c:1089
 #, c-format
 msgid "%s muxer"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:1090
+#: gst-libs/gst/pbutils/descriptions.c:1091
 #, c-format
 msgid "%s encoder"
 msgstr ""
 
-#: gst-libs/gst/pbutils/descriptions.c:1122
+#: gst-libs/gst/pbutils/descriptions.c:1123
 #, c-format
 msgid "GStreamer element %s"
 msgstr ""
@@ -438,7 +447,7 @@
 msgid "Plugin or element of unknown type"
 msgstr ""
 
-#: gst-libs/gst/tag/gsttagdemux.c:1268
+#: gst-libs/gst/tag/gsttagdemux.c:1271
 msgid "Failed to read tag: not enough data"
 msgstr ""
 
@@ -506,164 +515,173 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:122
+#: gst-libs/gst/tag/tags.c:123
+msgid "capturing 35 mm equivalent focal length"
+msgstr ""
+
+#: gst-libs/gst/tag/tags.c:124
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr ""
+
+#: gst-libs/gst/tag/tags.c:128
 msgid "capturing digital zoom ratio"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:123
+#: gst-libs/gst/tag/tags.c:129
 msgid "Digital zoom ratio used when capturing an image"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:126
+#: gst-libs/gst/tag/tags.c:132
 msgid "capturing iso speed"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:127
+#: gst-libs/gst/tag/tags.c:133
 msgid "The ISO speed used when capturing an image"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:130
+#: gst-libs/gst/tag/tags.c:136
 msgid "capturing exposure program"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:131
+#: gst-libs/gst/tag/tags.c:137
 msgid "The exposure program used when capturing an image"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:134
+#: gst-libs/gst/tag/tags.c:140
 msgid "capturing exposure mode"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:135
+#: gst-libs/gst/tag/tags.c:141
 msgid "The exposure mode used when capturing an image"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:138
+#: gst-libs/gst/tag/tags.c:144
 msgid "capturing exposure compensation"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:139
+#: gst-libs/gst/tag/tags.c:145
 msgid "The exposure compensation used when capturing an image"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:142
+#: gst-libs/gst/tag/tags.c:148
 msgid "capturing scene capture type"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:143
+#: gst-libs/gst/tag/tags.c:149
 msgid "The scene capture mode used when capturing an image"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:146
+#: gst-libs/gst/tag/tags.c:152
 msgid "capturing gain adjustment"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:147
+#: gst-libs/gst/tag/tags.c:153
 msgid "The overall gain adjustment applied on an image"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:150
+#: gst-libs/gst/tag/tags.c:156
 msgid "capturing white balance"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:151
+#: gst-libs/gst/tag/tags.c:157
 msgid "The white balance mode set when capturing an image"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:154
+#: gst-libs/gst/tag/tags.c:160
 msgid "capturing contrast"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:155
+#: gst-libs/gst/tag/tags.c:161
 msgid "The direction of contrast processing applied when capturing an image"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:159
+#: gst-libs/gst/tag/tags.c:165
 msgid "capturing saturation"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:160
+#: gst-libs/gst/tag/tags.c:166
 msgid "The direction of saturation processing applied when capturing an image"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:164
+#: gst-libs/gst/tag/tags.c:170
 msgid "capturing sharpness"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:165
+#: gst-libs/gst/tag/tags.c:171
 msgid "The direction of sharpness processing applied when capturing an image"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:169
+#: gst-libs/gst/tag/tags.c:175
 msgid "capturing flash fired"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:170
+#: gst-libs/gst/tag/tags.c:176
 msgid "If the flash fired while capturing an image"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:173
+#: gst-libs/gst/tag/tags.c:179
 msgid "capturing flash mode"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:174
+#: gst-libs/gst/tag/tags.c:180
 msgid "The selected flash mode while capturing an image"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:177
+#: gst-libs/gst/tag/tags.c:183
 msgid "capturing metering mode"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:178
+#: gst-libs/gst/tag/tags.c:184
 msgid ""
 "The metering mode used while determining exposure for capturing an image"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:182
+#: gst-libs/gst/tag/tags.c:188
 msgid "capturing source"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:183
+#: gst-libs/gst/tag/tags.c:189
 msgid "The source or type of device used for the capture"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:186
+#: gst-libs/gst/tag/tags.c:192
 msgid "image horizontal ppi"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:187
+#: gst-libs/gst/tag/tags.c:193
 msgid "Media (image/video) intended horizontal pixel density in ppi"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:190
+#: gst-libs/gst/tag/tags.c:196
 msgid "image vertical ppi"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:191
+#: gst-libs/gst/tag/tags.c:197
 msgid "Media (image/video) intended vertical pixel density in ppi"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:194
+#: gst-libs/gst/tag/tags.c:200
 msgid "ID3v2 frame"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:194
+#: gst-libs/gst/tag/tags.c:200
 msgid "unparsed id3v2 tag frame"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:198
+#: gst-libs/gst/tag/tags.c:204
 msgid "musical-key"
 msgstr ""
 
-#: gst-libs/gst/tag/tags.c:198
+#: gst-libs/gst/tag/tags.c:204
 msgid "Initial key in which the sound starts"
 msgstr ""
 
-#: tools/gst-device-monitor.c:154 tools/gst-play.c:1143
+#: tools/gst-device-monitor.c:156 tools/gst-play.c:1166
 msgid "Print version information and exit"
 msgstr ""
 
-#: tools/gst-device-monitor.c:156
+#: tools/gst-device-monitor.c:158
 msgid ""
 "Don't exit after showing the initial device list, but wait for devices to "
 "added/removed."
@@ -683,7 +701,7 @@
 msgstr ""
 
 #: tools/gst-play.c:365 tools/gst-play.c:411 tools/gst-play.c:763
-#: tools/gst-play.c:1047
+#: tools/gst-play.c:1070
 msgid "Reached end of play list."
 msgstr ""
 
@@ -711,143 +729,143 @@
 msgid "Could not change playback rate to %.2f"
 msgstr ""
 
-#: tools/gst-play.c:987
+#: tools/gst-play.c:1010
 msgid "space"
 msgstr ""
 
-#: tools/gst-play.c:987
+#: tools/gst-play.c:1010
 msgid "pause/unpause"
 msgstr ""
 
-#: tools/gst-play.c:988
+#: tools/gst-play.c:1011
 msgid "q or ESC"
 msgstr ""
 
-#: tools/gst-play.c:988
+#: tools/gst-play.c:1011
 msgid "quit"
 msgstr ""
 
-#: tools/gst-play.c:989
+#: tools/gst-play.c:1012
 msgid "> or n"
 msgstr ""
 
-#: tools/gst-play.c:989
+#: tools/gst-play.c:1012
 msgid "play next"
 msgstr ""
 
-#: tools/gst-play.c:990
+#: tools/gst-play.c:1013
 msgid "< or b"
 msgstr ""
 
-#: tools/gst-play.c:990
+#: tools/gst-play.c:1013
 msgid "play previous"
 msgstr ""
 
-#: tools/gst-play.c:991
+#: tools/gst-play.c:1014
 msgid "seek forward"
 msgstr ""
 
-#: tools/gst-play.c:992
+#: tools/gst-play.c:1015
 msgid "seek backward"
 msgstr ""
 
-#: tools/gst-play.c:993
+#: tools/gst-play.c:1016
 msgid "volume up"
 msgstr ""
 
-#: tools/gst-play.c:994
+#: tools/gst-play.c:1017
 msgid "volume down"
 msgstr ""
 
-#: tools/gst-play.c:995
+#: tools/gst-play.c:1018
 msgid "increase playback rate"
 msgstr ""
 
-#: tools/gst-play.c:996
+#: tools/gst-play.c:1019
 msgid "decrease playback rate"
 msgstr ""
 
-#: tools/gst-play.c:997
+#: tools/gst-play.c:1020
 msgid "change playback direction"
 msgstr ""
 
-#: tools/gst-play.c:998
+#: tools/gst-play.c:1021
 msgid "enable/disable trick modes"
 msgstr ""
 
-#: tools/gst-play.c:999
+#: tools/gst-play.c:1022
 msgid "change audio track"
 msgstr ""
 
-#: tools/gst-play.c:1000
+#: tools/gst-play.c:1023
 msgid "change video track"
 msgstr ""
 
-#: tools/gst-play.c:1001
+#: tools/gst-play.c:1024
 msgid "change subtitle track"
 msgstr ""
 
-#: tools/gst-play.c:1002
+#: tools/gst-play.c:1025
 msgid "seek to beginning"
 msgstr ""
 
-#: tools/gst-play.c:1003
+#: tools/gst-play.c:1026
 msgid "show keyboard shortcuts"
 msgstr ""
 
-#: tools/gst-play.c:1006
+#: tools/gst-play.c:1029
 msgid "Interactive mode - keyboard controls:"
 msgstr ""
 
-#: tools/gst-play.c:1138
+#: tools/gst-play.c:1161
 msgid "Output status information and property notifications"
 msgstr ""
 
-#: tools/gst-play.c:1140
+#: tools/gst-play.c:1163
 msgid "Control playback behaviour setting playbin 'flags' property"
 msgstr ""
 
-#: tools/gst-play.c:1145
+#: tools/gst-play.c:1168
 msgid "Video sink to use (default is autovideosink)"
 msgstr ""
 
-#: tools/gst-play.c:1147
+#: tools/gst-play.c:1170
 msgid "Audio sink to use (default is autoaudiosink)"
 msgstr ""
 
-#: tools/gst-play.c:1149
+#: tools/gst-play.c:1172
 msgid "Enable gapless playback"
 msgstr ""
 
-#: tools/gst-play.c:1151
+#: tools/gst-play.c:1174
 msgid "Shuffle playlist"
 msgstr ""
 
-#: tools/gst-play.c:1154
+#: tools/gst-play.c:1177
 msgid "Disable interactive control via the keyboard"
 msgstr ""
 
-#: tools/gst-play.c:1156
+#: tools/gst-play.c:1179
 msgid "Volume"
 msgstr ""
 
-#: tools/gst-play.c:1158
+#: tools/gst-play.c:1181
 msgid "Playlist file containing input media files"
 msgstr ""
 
-#: tools/gst-play.c:1160
+#: tools/gst-play.c:1183
 msgid "Do not print any output (apart from errors)"
 msgstr ""
 
-#: tools/gst-play.c:1231
+#: tools/gst-play.c:1254
 #, c-format
 msgid "Usage: %s FILE1|URI1 [FILE2|URI2] [FILE3|URI3] ..."
 msgstr ""
 
-#: tools/gst-play.c:1235
+#: tools/gst-play.c:1258
 msgid "You must provide at least one filename or URI to play."
 msgstr ""
 
-#: tools/gst-play.c:1275
+#: tools/gst-play.c:1298
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr ""
diff --git a/po/hr.gmo b/po/hr.gmo
index 8cfb6ee..b056894 100644
--- a/po/hr.gmo
+++ b/po/hr.gmo
Binary files differ
diff --git a/po/hr.po b/po/hr.po
index 99fada0..f2e39ae 100644
--- a/po/hr.po
+++ b/po/hr.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.7.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2016-05-27 12:47-0700\n"
 "Last-Translator: Božidar Putanec <bozidarp@yahoo.com>\n"
 "Language-Team: Croatian <lokalizacija@linux.hr>\n"
@@ -74,9 +74,6 @@
 msgid "Could not read CD."
 msgstr "CD nije moguće čitati."
 
-msgid "Internal data stream error."
-msgstr "Interna greška toka (stream) podataka."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Nedostaje element ‘%s’ - provjerite vašu GStreamer instalaciju."
@@ -90,6 +87,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Element „uridecodebin“ nije moguće napraviti (kreirati)."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Element „uridecodebin“ nije moguće napraviti (kreirati)."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Element „uridecodebin“ nije moguće napraviti (kreirati)."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Oba elementa, autoaudiosink i %s nedostaju."
@@ -225,6 +230,10 @@
 msgid "Kate subtitle format"
 msgstr "Format naslova Kate"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Format naslova Kate"
+
 msgid "Uncompressed video"
 msgstr "Nesažeti video"
 
@@ -394,6 +403,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Primijenjena žarišna duljina leće pri snimanju slike u mm"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "žarišna duljina"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Primijenjena žarišna duljina leće pri snimanju slike u mm"
+
 msgid "capturing digital zoom ratio"
 msgstr "digitalno povećanje"
 
@@ -660,6 +678,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "Pritisnite ‘k’ da pogledate listu tipkovničkih prečaca.\n"
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Interna greška toka (stream) podataka."
+
 #~ msgid "Master"
 #~ msgstr "Glavni"
 
diff --git a/po/hu.gmo b/po/hu.gmo
index 4d9cdbb..27db305 100644
--- a/po/hu.gmo
+++ b/po/hu.gmo
Binary files differ
diff --git a/po/hu.po b/po/hu.po
index 4b5cd88..bcfb214 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.7.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2016-03-14 19:14+0100\n"
 "Last-Translator: Gabor Kelemen <kelemeng@gnome.hu>\n"
 "Language-Team: Hungarian <translation-team-hu@lists.sourceforge.net>\n"
@@ -76,9 +76,6 @@
 msgid "Could not read CD."
 msgstr "Nem olvasható a CD."
 
-msgid "Internal data stream error."
-msgstr "Belső adatfolyam-hiba."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "A(z) „%s” elem hiányzik - ellenőrizze a Gstreamer telepítését."
@@ -92,6 +89,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Nem hozható létre „uridecodebin” elem."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Nem hozható létre „uridecodebin” elem."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Nem hozható létre „uridecodebin” elem."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Az autovideosink és a(z) %s elem is hiányzik."
@@ -225,6 +230,10 @@
 msgid "Kate subtitle format"
 msgstr "Kate feliratformátum"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Kate feliratformátum"
+
 msgid "Uncompressed video"
 msgstr "Tömörítetlen videó"
 
@@ -391,6 +400,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "A kép felvételéhez használt lencse fókusztávolsága mm-ben"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "felvétel fókusztávolsága"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "A kép felvételéhez használt lencse fókusztávolsága mm-ben"
+
 msgid "capturing digital zoom ratio"
 msgstr "felvétel digitális nagyítási aránya"
 
@@ -657,6 +675,9 @@
 msgstr ""
 "Nyomja meg a „k” billentyűt a gyorsbillentyűk listájának megtekintéséhez.\n"
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Belső adatfolyam-hiba."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "Az adatfolyam lejátszásához egy %s bővítmény szükséges, de az nincs "
diff --git a/po/id.gmo b/po/id.gmo
index 963403f..dbe5e2c 100644
--- a/po/id.gmo
+++ b/po/id.gmo
Binary files differ
diff --git a/po/id.po b/po/id.po
index 93c8169..97dd1ce 100644
--- a/po/id.po
+++ b/po/id.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.4.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2014-07-30 09:19+0700\n"
 "Last-Translator: Andhika Padmawan <andhika.padmawan@gmail.com>\n"
 "Language-Team: Indonesian <translation-team-id@lists.sourceforge.net>\n"
@@ -71,9 +71,6 @@
 msgid "Could not read CD."
 msgstr "Tak dapat membaca CD."
 
-msgid "Internal data stream error."
-msgstr "Galat arus data internal."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Elemen '%s' hilang - cek instalasi GStreamer anda."
@@ -87,6 +84,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Tak dapat membuat elemen \"uridecodebin\"."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Tak dapat membuat elemen \"uridecodebin\"."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Tak dapat membuat elemen \"uridecodebin\"."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Baik elemen autovideosink maupun %s hilang."
@@ -220,6 +225,10 @@
 msgid "Kate subtitle format"
 msgstr "Format subjudul Kate"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Format subjudul Kate"
+
 msgid "Uncompressed video"
 msgstr "Video tak dikompresi"
 
@@ -386,6 +395,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Panjang fokal dari lensa digunakan ketika menangkap gambar, dalam mm"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "menangkap panjang fokal"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Panjang fokal dari lensa digunakan ketika menangkap gambar, dalam mm"
+
 msgid "capturing digital zoom ratio"
 msgstr "menangkap rasio pembesaran digital"
 
@@ -657,5 +675,8 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr ""
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Galat arus data internal."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr "Plugin %s dibutuhkan untuk memutar arus ini, tapi tidak diinstal."
diff --git a/po/it.gmo b/po/it.gmo
index ccec88f..f03b5e9 100644
--- a/po/it.gmo
+++ b/po/it.gmo
Binary files differ
diff --git a/po/it.po b/po/it.po
index dbc0c40..b4016b3 100644
--- a/po/it.po
+++ b/po/it.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 0.10.28.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2010-04-28 14:27+0200\n"
 "Last-Translator: Luca Ferretti <elle.uca@infinito.it>\n"
 "Language-Team: Italian <tp@lists.linux.it>\n"
@@ -74,9 +74,6 @@
 msgid "Could not read CD."
 msgstr "Impossibile leggere il CD."
 
-msgid "Internal data stream error."
-msgstr "Errore interno nel flusso di dati."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr ""
@@ -93,6 +90,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Impossibile creare l'elemento «decodebin»."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Impossibile creare l'elemento «decodebin»."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Impossibile creare l'elemento «decodebin»."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Risultano mancanti entrambi gli elementi «autovideosink» e «%s»."
@@ -234,6 +239,10 @@
 msgstr "Sottotitoli formato Kate"
 
 #, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Sottotitoli formato Kate"
+
+#, fuzzy
 msgid "Uncompressed video"
 msgstr "YUV non compresso"
 
@@ -427,6 +436,13 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr ""
 
+msgid "capturing 35 mm equivalent focal length"
+msgstr ""
+
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr ""
+
 msgid "capturing digital zoom ratio"
 msgstr ""
 
@@ -690,6 +706,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr ""
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Errore interno nel flusso di dati."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "Per riprodurre questo stream è richiesto un plugin %s, che però non "
diff --git a/po/ja.gmo b/po/ja.gmo
index cd14078..1e4499c 100644
--- a/po/ja.gmo
+++ b/po/ja.gmo
Binary files differ
diff --git a/po/ja.po b/po/ja.po
index 7b2dfb9..9bc7afc 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 0.10.30.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2010-10-25 10:27+0900\n"
 "Last-Translator: Makoto Kato <makoto.kt@gmail.com>\n"
 "Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n"
@@ -72,9 +72,6 @@
 msgid "Could not read CD."
 msgstr "CD を読むことができませんでした"
 
-msgid "Internal data stream error."
-msgstr "内部データストリームエラー"
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr ""
@@ -91,6 +88,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "\"decodebin\" エレメントを作成できません。"
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "\"decodebin2\" エレメントを作成できませんでした"
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "\"decodebin\" エレメントを作成できません。"
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "autovideosinkと%sエレメントの両方が見つかりません。"
@@ -228,6 +233,10 @@
 msgstr "Kate 字幕形式"
 
 #, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Kate 字幕形式"
+
+#, fuzzy
 msgid "Uncompressed video"
 msgstr "非圧縮 YUV"
 
@@ -396,6 +405,13 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr ""
 
+msgid "capturing 35 mm equivalent focal length"
+msgstr ""
+
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr ""
+
 msgid "capturing digital zoom ratio"
 msgstr ""
 
@@ -661,6 +677,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr ""
 
+#~ msgid "Internal data stream error."
+#~ msgstr "内部データストリームエラー"
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "%s プラグインはこのストリームを再生するのに必要ですが、インストールされて"
@@ -809,8 +828,5 @@
 #~ msgid "Could not open file \"%s\" for reading."
 #~ msgstr "読み込み用にファイル \"%s\" を開くことができませんでした"
 
-#~ msgid "Could not create \"decodebin2\" element."
-#~ msgstr "\"decodebin2\" エレメントを作成できませんでした"
-
 #~ msgid "Could not create \"queue2\" element."
 #~ msgstr "\"queue2\" エレメントを作成できませんでした"
diff --git a/po/lt.gmo b/po/lt.gmo
index 2750850..1e2e745 100644
--- a/po/lt.gmo
+++ b/po/lt.gmo
Binary files differ
diff --git a/po/lt.po b/po/lt.po
index 1fe80c1..b823e7f 100644
--- a/po/lt.po
+++ b/po/lt.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base-0.10.15.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2008-03-07 23:43+0200\n"
 "Last-Translator: Gintautas Miliauskas <gintas@akl.lt>\n"
 "Language-Team: Lithuanian <komp_lt@konferencijos.lt>\n"
@@ -74,9 +74,6 @@
 msgid "Could not read CD."
 msgstr "Nepavyko perskaityti CD."
 
-msgid "Internal data stream error."
-msgstr "Vidinė duomenų srauto klaida."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Trūksta elemento „%s“ - patikrinkite GStreamer įdiegimą."
@@ -92,6 +89,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Nepavyko sukurti „decodebin“ elemento."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Nepavyko sukurti „decodebin2“ elemento."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Nepavyko sukurti „decodebin“ elemento."
+
 #, fuzzy, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Trūksta ir autovideosink, ir xvimagesink elementų."
@@ -234,6 +239,10 @@
 msgstr "Sami titrų formatas"
 
 #, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Sami titrų formatas"
+
+#, fuzzy
 msgid "Uncompressed video"
 msgstr "Nekompresuotas YUV"
 
@@ -402,6 +411,13 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr ""
 
+msgid "capturing 35 mm equivalent focal length"
+msgstr ""
+
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr ""
+
 msgid "capturing digital zoom ratio"
 msgstr ""
 
@@ -665,6 +681,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr ""
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Vidinė duomenų srauto klaida."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr "Šiam srautui groti reikalingas %s įskiepis, bet jis nėra įdiegtas."
 
@@ -804,9 +823,6 @@
 #~ msgid "Error while sending gdp payload data to \"%s:%d\"."
 #~ msgstr "Klaida siunčiant gdp duomenis į „%s:%d“."
 
-#~ msgid "Could not create \"decodebin2\" element."
-#~ msgstr "Nepavyko sukurti „decodebin2“ elemento."
-
 #~ msgid "Could not create \"queue2\" element."
 #~ msgstr "Nepavyko sukurti „queue2“ elemento."
 
diff --git a/po/lv.gmo b/po/lv.gmo
index 37ff6f4..59e8353 100644
--- a/po/lv.gmo
+++ b/po/lv.gmo
Binary files differ
diff --git a/po/lv.po b/po/lv.po
index 0dfb991..e925ed6 100644
--- a/po/lv.po
+++ b/po/lv.po
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.2.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2014-04-20 16:15+0300\n"
 "Last-Translator: Rihards Prieditis <rprieditis@gmail.com>\n"
 "Language-Team: Latvian <translation-team-lv@lists.sourceforge.net>\n"
@@ -78,9 +78,6 @@
 msgid "Could not read CD."
 msgstr "Nevarēja nolasīt CD."
 
-msgid "Internal data stream error."
-msgstr "Iekšējās datu plūsmas kļūda."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Trūkst elements “%s” - pārbaudiet savu GStreamer instalāciju."
@@ -94,6 +91,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Nevarēja izveidot “uridecodebin” elementu."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Nav iespējams izveidot \"decodebin2\" elementu."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Nevarēja izveidot “uridecodebin” elementu."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Trūkst gan autovideosink, gan %s elementi."
@@ -227,6 +232,10 @@
 msgid "Kate subtitle format"
 msgstr "Kate subtitru formāts"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Kate subtitru formāts"
+
 msgid "Uncompressed video"
 msgstr "Nesaspiests video"
 
@@ -393,6 +402,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Attēla tveršanā izmantotā lēcas fokusa attālums milimetros"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "tveršanas fokusa attālums"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Attēla tveršanā izmantotā lēcas fokusa attālums milimetros"
+
 msgid "capturing digital zoom ratio"
 msgstr "tveršanas digitālais mērogs"
 
@@ -656,6 +674,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr ""
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Iekšējās datu plūsmas kļūda."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "Nepieciešamas %s spraudnis, lai atskaņotu šo plūsmu, bet tas nav "
@@ -793,9 +814,6 @@
 #~ msgid "Could not open device \"%s\" for reading and writing."
 #~ msgstr "Nevarēja atvērt ierīci \"%s\" lasīšanai vai rakstīšanai."
 
-#~ msgid "Could not create \"decodebin2\" element."
-#~ msgstr "Nav iespējams izveidot \"decodebin2\" elementu."
-
 #~ msgid "Could not create \"queue2\" element."
 #~ msgstr "Nav iespējams izveidot  \"queue2\" elementu."
 
diff --git a/po/nb.gmo b/po/nb.gmo
index 25172eb..0fffd24 100644
--- a/po/nb.gmo
+++ b/po/nb.gmo
Binary files differ
diff --git a/po/nb.po b/po/nb.po
index 2a83939..032f151 100644
--- a/po/nb.po
+++ b/po/nb.po
@@ -2,14 +2,14 @@
 # This file is put in the public domain.
 #
 # Kjartan Maraas <kmaraas@gnome.org>, 2004-2010.
-# Johnny A. Solbu <johnny@solbu.net>, 2012-2015
+# Johnny A. Solbu <johnny@solbu.net>, 2012-2016
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: gst-plugins-base 1.7.1\n"
+"Project-Id-Version: gst-plugins-base 1.7.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
-"PO-Revision-Date: 2015-12-24 23:08+0100\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
+"PO-Revision-Date: 2016-08-05 23:45+0200\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"
@@ -17,7 +17,7 @@
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 1.5.7\n"
+"X-Generator: Poedit 1.8.7.1\n"
 
 msgid "Could not open device for playback in mono mode."
 msgstr "Kunne ikke åpne enheten for avspilling i mono-modus."
@@ -73,9 +73,6 @@
 msgid "Could not read CD."
 msgstr "Kunne ikke lese CD."
 
-msgid "Internal data stream error."
-msgstr "Intern feil i datastrøm."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Mangler elementet «%s» - kontroller GStreamer-installasjonen."
@@ -89,6 +86,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Kunne ikke opprette elementet «uridecodebin»"
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Kunne ikke opprette elementet «uridecodebin»"
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Kunne ikke opprette elementet «uridecodebin»"
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Både autobildesluk- og %s-elementer mangler."
@@ -222,6 +227,10 @@
 msgid "Kate subtitle format"
 msgstr "Kate undertekstformat"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Kate undertekstformat"
+
 msgid "Uncompressed video"
 msgstr "Ukomprimert video"
 
@@ -388,6 +397,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Brennvidden til objektivet som brukes når du tar bildet, i mm"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "opptaksbrennvidde"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Brennvidden til objektivet som brukes når du tar bildet, i mm"
+
 msgid "capturing digital zoom ratio"
 msgstr "fanger digitalt zoomforhold"
 
@@ -559,13 +577,13 @@
 msgstr "Avslutt"
 
 msgid "> or n"
-msgstr ""
+msgstr "> eller n"
 
 msgid "play next"
 msgstr "spill neste"
 
 msgid "< or b"
-msgstr ""
+msgstr "< eller b"
 
 msgid "play previous"
 msgstr "spill forige"
@@ -613,10 +631,10 @@
 msgstr "Interaktiv modus - tastaturkontroller:"
 
 msgid "Output status information and property notifications"
-msgstr ""
+msgstr "Utdata-statusinformasjon og egenskapsvarslinger"
 
 msgid "Control playback behaviour setting playbin 'flags' property"
-msgstr ""
+msgstr "Kontroller avspillingsoppførsel ved å sette playbin «flagg»-egenskap"
 
 msgid "Video sink to use (default is autovideosink)"
 msgstr "Video-sink som skal brukes (standard er autovideosink)"
@@ -652,6 +670,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "Trykk «k» for å se en liste over hurtigtaster.\n"
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Intern feil i datastrøm."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "Et %s-tillegg kreves for å spille av denne strømmen, men det er ikke "
diff --git a/po/nl.gmo b/po/nl.gmo
index 385860c..04e52c2 100644
--- a/po/nl.gmo
+++ b/po/nl.gmo
Binary files differ
diff --git a/po/nl.po b/po/nl.po
index 0e44496..b7f4ed2 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.7.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2016-02-20 16:39+0100\n"
 "Last-Translator: Freek de Kruijf <f.de.kruijf@gmail.com>\n"
 "Language-Team: Dutch <vertaling@vrijschrift.org>\n"
@@ -74,9 +74,6 @@
 msgid "Could not read CD."
 msgstr "Kan niet lezen van CD."
 
-msgid "Internal data stream error."
-msgstr "Interne fout in gegevensstroom."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Ontbrekend element '%s' - controleer de instalatie van uw GStreamer."
@@ -90,6 +87,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Kon element \"uridecodebin\" niet aanmaken."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Kon element \"uridecodebin\" niet aanmaken."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Kon element \"uridecodebin\" niet aanmaken."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "De elementen 'autovideosink' en '%s' ontbreken beide."
@@ -223,6 +228,10 @@
 msgid "Kate subtitle format"
 msgstr "Kate ondertitelformaat"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Kate ondertitelformaat"
+
 msgid "Uncompressed video"
 msgstr "Niet-gecomprimeerde video"
 
@@ -390,6 +399,16 @@
 msgstr ""
 "Ge bruikte brandpuntsafstand van de lens bij het maken van de foto, in mm"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "brandpuntsafstand bij maken"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr ""
+"Ge bruikte brandpuntsafstand van de lens bij het maken van de foto, in mm"
+
 msgid "capturing digital zoom ratio"
 msgstr "digitale zoom-verhouding bij het maken"
 
@@ -662,6 +681,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "Druk op 'k' om een lijst met sneltoetsen te zien.\n"
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Interne fout in gegevensstroom."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "Een %s plugin is vereist voor het afspelen van deze gegevens, echter deze "
diff --git a/po/or.gmo b/po/or.gmo
index dbfe3bc..a45aa9a 100644
--- a/po/or.gmo
+++ b/po/or.gmo
Binary files differ
diff --git a/po/or.po b/po/or.po
index 8485bbd..5a5510f 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: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\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"
@@ -77,9 +77,6 @@
 msgid "Could not read CD."
 msgstr "\"%s\" ଯନ୍ତ୍ରରେ ଲେଖିହେଲା ନାହିଁ."
 
-msgid "Internal data stream error."
-msgstr ""
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr ""
@@ -95,6 +92,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "\"%s\" ଫାଇଲ ଲେଖିହେଲା ନାହିଁ."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "\"%s\" ଫାଇଲ ଲେଖିହେଲା ନାହିଁ."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "\"%s\" ଫାଇଲ ଲେଖିହେଲା ନାହିଁ."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr ""
@@ -228,6 +233,9 @@
 msgid "Kate subtitle format"
 msgstr ""
 
+msgid "WebVTT subtitle format"
+msgstr ""
+
 msgid "Uncompressed video"
 msgstr ""
 
@@ -394,6 +402,13 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr ""
 
+msgid "capturing 35 mm equivalent focal length"
+msgstr ""
+
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr ""
+
 msgid "capturing digital zoom ratio"
 msgstr ""
 
diff --git a/po/pl.gmo b/po/pl.gmo
index d78bb8d..5d58c98 100644
--- a/po/pl.gmo
+++ b/po/pl.gmo
Binary files differ
diff --git a/po/pl.po b/po/pl.po
index a9df0ca..5e8e273 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.7.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2016-03-02 22:08+0100\n"
 "Last-Translator: Jakub Bogusz <qboosh@pld-linux.org>\n"
 "Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"
@@ -81,9 +81,6 @@
 msgid "Could not read CD."
 msgstr "Nie udał się odczyt CD."
 
-msgid "Internal data stream error."
-msgstr "Błąd wewnętrzny strumienia danych."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Brak elementu '%s' - proszę sprawdzić instalację GStreamera."
@@ -97,6 +94,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Nie udało się utworzyć elementu \"uridecodebin\"."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Nie udało się utworzyć elementu \"uridecodebin\"."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Nie udało się utworzyć elementu \"uridecodebin\"."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Nie ma żadnego z elementów autovideosink i %s."
@@ -230,6 +235,10 @@
 msgid "Kate subtitle format"
 msgstr "Format podpisów Kate"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Format podpisów Kate"
+
 msgid "Uncompressed video"
 msgstr "Nieskompresowany obraz"
 
@@ -396,6 +405,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Długość ogniskowej obiektywu użyta przy robieniu zdjęcia, w mm"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "ogniskowa obiektywu"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Długość ogniskowej obiektywu użyta przy robieniu zdjęcia, w mm"
+
 msgid "capturing digital zoom ratio"
 msgstr "współczynnik powiększenia cyfrowego"
 
@@ -660,3 +678,6 @@
 
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "Klawisz 'k' wyświetla listę skrótów klawiatury.\n"
+
+#~ msgid "Internal data stream error."
+#~ msgstr "Błąd wewnętrzny strumienia danych."
diff --git a/po/pt_BR.gmo b/po/pt_BR.gmo
index 44b8595..f1f4304 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 bf6974f..321b9c5 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -11,7 +11,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base-1.7.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2016-05-06 16:47-0300\n"
 "Last-Translator: Fabrício Godoy <skarllot@gmail.com>\n"
 "Language-Team: Brazilian Portuguese <ldpbr-translation@lists.sourceforge."
@@ -79,9 +79,6 @@
 msgid "Could not read CD."
 msgstr "Não foi possível ler o CD."
 
-msgid "Internal data stream error."
-msgstr "Erro interno no fluxo de dados."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr ""
@@ -96,6 +93,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Não foi possível criar o elemento \"uridecodebin\"."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Não foi possível criar o elemento \"decodebin2\"."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Não foi possível criar o elemento \"uridecodebin\"."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Os elementos autovideosink e %s estão faltando."
@@ -230,6 +235,10 @@
 msgid "Kate subtitle format"
 msgstr "Formato de legendas Kate"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Formato de legendas Kate"
+
 msgid "Uncompressed video"
 msgstr "Vídeo sem compressão"
 
@@ -396,6 +405,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Distância focal das lentes utilizada ao capturar a imagem, em mm"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "distância focal ao capturar"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Distância focal das lentes utilizada ao capturar a imagem, em mm"
+
 msgid "capturing digital zoom ratio"
 msgstr "taxa de zoom digital ao capturar"
 
@@ -678,6 +696,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "Pressione \"k\" para ver a lista de atalhos do teclado.\n"
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Erro interno no fluxo de dados."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "O plug-in %s é necessário para reproduzir este fluxo, mas não está "
@@ -819,9 +840,6 @@
 #~ msgid "Could not open device \"%s\" for reading and writing."
 #~ msgstr "Não foi possível abrir o dispositivo \"%s\" para leitura e escrita."
 
-#~ msgid "Could not create \"decodebin2\" element."
-#~ msgstr "Não foi possível criar o elemento \"decodebin2\"."
-
 #~ msgid "Could not create \"queue2\" element."
 #~ msgstr "Não foi possível criar o elemento \"queue2\"."
 
diff --git a/po/ro.gmo b/po/ro.gmo
index 52e883b..ec54480 100644
--- a/po/ro.gmo
+++ b/po/ro.gmo
Binary files differ
diff --git a/po/ro.po b/po/ro.po
index 5f74462..d911230 100644
--- a/po/ro.po
+++ b/po/ro.po
@@ -5,7 +5,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 0.10.29.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2010-08-16 01:21+0300\n"
 "Last-Translator: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>\n"
 "Language-Team: Romanian <translation-team-ro@lists.sourceforge.net>\n"
@@ -73,9 +73,6 @@
 msgid "Could not read CD."
 msgstr "Nu s-a putut citi CD-ul."
 
-msgid "Internal data stream error."
-msgstr "Eroare internă a fluxului de date."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Element %s lipsă - verificați instalarea GStreamer."
@@ -90,6 +87,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Nu se poate crea elementul „decodebin”."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Nu se poate crea elementul „decodebin”."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Nu se poate crea elementul „decodebin”."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Lipsește atât elementul autovideosink cât și %s."
@@ -227,6 +232,10 @@
 msgstr "Format subtitrare Kate"
 
 #, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Format subtitrare Kate"
+
+#, fuzzy
 msgid "Uncompressed video"
 msgstr "YUV necomprimat"
 
@@ -395,6 +404,13 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr ""
 
+msgid "capturing 35 mm equivalent focal length"
+msgstr ""
+
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr ""
+
 msgid "capturing digital zoom ratio"
 msgstr ""
 
@@ -658,6 +674,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr ""
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Eroare internă a fluxului de date."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "Un modul de extensie %s este necesar pentru a reda acest flux, dar acesta "
diff --git a/po/ru.gmo b/po/ru.gmo
index 13aa57e..8250574 100644
--- a/po/ru.gmo
+++ b/po/ru.gmo
Binary files differ
diff --git a/po/ru.po b/po/ru.po
index f16b1c1..cf3884c 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.7.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2016-03-05 08:42+0300\n"
 "Last-Translator: Yuri Kozlov <yuray@komyakino.ru>\n"
 "Language-Team: Russian <gnu@d07.ru>\n"
@@ -76,9 +76,6 @@
 msgid "Could not read CD."
 msgstr "Не удалось прочитать CD."
 
-msgid "Internal data stream error."
-msgstr "Внутренняя ошибка потока данных."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Отсутствует элемент «%s» — проверьте правильность установки GStreamer."
@@ -92,6 +89,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Не удалось создать элемент «uridecodebin»."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Не удалось создать элемент «decodebin2»."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Не удалось создать элемент «uridecodebin»."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Отсутствуют элементы autovideosink и %s."
@@ -226,6 +231,10 @@
 msgid "Kate subtitle format"
 msgstr "Формат субтитров Kate"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Формат субтитров Kate"
+
 msgid "Uncompressed video"
 msgstr "Несжатое видео"
 
@@ -392,6 +401,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Фокусное расстояние зеркала при съёмке изображения, в мм"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "фокусное расстояние при съёмке"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Фокусное расстояние зеркала при съёмке изображения, в мм"
+
 msgid "capturing digital zoom ratio"
 msgstr "коэффициент цифрового трансфокатора при съёмке"
 
@@ -658,6 +676,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "Нажмите «k» для показа списка клавиатурных комбинаций.\n"
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Внутренняя ошибка потока данных."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "Для воспроизведения этого потока требуется модуль %s, но он не установлен."
@@ -803,8 +824,5 @@
 #~ msgid "Could not open file \"%s\" for reading."
 #~ msgstr "Не удалось открыть файл «%s» для чтения."
 
-#~ msgid "Could not create \"decodebin2\" element."
-#~ msgstr "Не удалось создать элемент «decodebin2»."
-
 #~ msgid "Could not create \"queue2\" element."
 #~ msgstr "Не удалось создать элемент «queue2»."
diff --git a/po/sk.gmo b/po/sk.gmo
index caa480c..75f9350 100644
--- a/po/sk.gmo
+++ b/po/sk.gmo
Binary files differ
diff --git a/po/sk.po b/po/sk.po
index b2d36b4..5317a69 100644
--- a/po/sk.po
+++ b/po/sk.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.7.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2016-05-20 12:24+0100\n"
 "Last-Translator: Peter Tuhársky <tuharsky@misbb.sk>\n"
 "Language-Team: Slovak <sk-i18n@lists.linux.sk>\n"
@@ -73,9 +73,6 @@
 msgid "Could not read CD."
 msgstr "Nepodarilo sa čítať CD."
 
-msgid "Internal data stream error."
-msgstr "Vnútorná chyba prúdu údajov."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Chýa prvok '%s' - skontrolujte svoju inštaláciu GStreamer."
@@ -89,6 +86,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Nepodarilo sa vytvoriť prvok \"uridecodebin\"."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Nepodarilo sa vytvoriť prvok \"decodebin2\"."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Nepodarilo sa vytvoriť prvok \"uridecodebin\"."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Chýbajú prvky autovideosink aj %s."
@@ -222,6 +227,10 @@
 msgid "Kate subtitle format"
 msgstr "Formát titulkov Kate"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Formát titulkov Kate"
+
 msgid "Uncompressed video"
 msgstr "Nekomprimované video"
 
@@ -388,6 +397,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Ohnisková vzdialenosť objektívu pri zachytávaní obrázku, v mm"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "ohnisková vzdialenosť"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Ohnisková vzdialenosť objektívu pri zachytávaní obrázku, v mm"
+
 msgid "capturing digital zoom ratio"
 msgstr "pomer digitálneho priblíženia"
 
@@ -651,6 +669,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "Stlačením 'k' zobrazíte zoznam klávesových skratiek.\n"
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Vnútorná chyba prúdu údajov."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "Na prehratie tohto prúdu údajov je vyžadovaný zásuvný modul %s, ktorý nie "
@@ -804,9 +825,6 @@
 #~ msgid "Internal data flow error."
 #~ msgstr "Vnútorná chyba prúdu údajov."
 
-#~ msgid "Could not create \"decodebin2\" element."
-#~ msgstr "Nepodarilo sa vytvoriť prvok \"decodebin2\"."
-
 #~ msgid "Could not create \"queue2\" element."
 #~ msgstr "Nepodarilo sa vytvoriť prvok \"queue2\"."
 
diff --git a/po/sl.gmo b/po/sl.gmo
index d51e181..96a200c 100644
--- a/po/sl.gmo
+++ b/po/sl.gmo
Binary files differ
diff --git a/po/sl.po b/po/sl.po
index 6b84d3c..ba445b0 100644
--- a/po/sl.po
+++ b/po/sl.po
@@ -10,7 +10,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base-1.0.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2013-01-05 10:10+0100\n"
 "Last-Translator: Klemen Košir <klemen913@gmail.com>\n"
 "Language-Team: Slovenian <translation-team-sl@lists.sourceforge.net>\n"
@@ -75,9 +75,6 @@
 msgid "Could not read CD."
 msgstr "CD-ja ni mogoče prebrati."
 
-msgid "Internal data stream error."
-msgstr "Notranja napaka pretoka podatkov."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Predmet '%s' manjka - preverite namestitev paketa GStreamer."
@@ -91,6 +88,12 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr ""
 
+msgid "Could not create \"decodebin3\" element."
+msgstr ""
+
+msgid "Could not create \"urisourcebin\" element."
+msgstr ""
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Predmeta autovideosink in %s manjkata."
@@ -224,6 +227,10 @@
 msgid "Kate subtitle format"
 msgstr "Oblika podnapisov Kate"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Oblika podnapisov Kate"
+
 msgid "Uncompressed video"
 msgstr "Nestisnjen video"
 
@@ -390,6 +397,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Goriščna razdalja leč, uporabljena med zajemanjem slike"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "goriščna razdalja med zajemanjem"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Goriščna razdalja leč, uporabljena med zajemanjem slike"
+
 msgid "capturing digital zoom ratio"
 msgstr "razmerje digitalnega približevanja med zajemanjem"
 
@@ -654,6 +670,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr ""
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Notranja napaka pretoka podatkov."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "Za predvajanje tega pretoka je potreben vstavek %s, ki pa ni nameščen."
diff --git a/po/sq.gmo b/po/sq.gmo
index a302eea..047d8b4 100644
--- a/po/sq.gmo
+++ b/po/sq.gmo
Binary files differ
diff --git a/po/sq.po b/po/sq.po
index fc35a0b..cd183e0 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: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\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"
@@ -75,9 +75,6 @@
 msgid "Could not read CD."
 msgstr "I pamundur shkrimi në dispozitivin \"%s\"."
 
-msgid "Internal data stream error."
-msgstr ""
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr ""
@@ -93,6 +90,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "I pamundur shkrimi tek file \"%s\"."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "I pamundur shkrimi tek file \"%s\"."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "I pamundur shkrimi tek file \"%s\"."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr ""
@@ -226,6 +231,9 @@
 msgid "Kate subtitle format"
 msgstr ""
 
+msgid "WebVTT subtitle format"
+msgstr ""
+
 msgid "Uncompressed video"
 msgstr ""
 
@@ -392,6 +400,13 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr ""
 
+msgid "capturing 35 mm equivalent focal length"
+msgstr ""
+
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr ""
+
 msgid "capturing digital zoom ratio"
 msgstr ""
 
diff --git a/po/sr.gmo b/po/sr.gmo
index 94fdd7e..c79a890 100644
--- a/po/sr.gmo
+++ b/po/sr.gmo
Binary files differ
diff --git a/po/sr.po b/po/sr.po
index 5ab0897..8dc61b4 100644
--- a/po/sr.po
+++ b/po/sr.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base-1.7.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2016-03-05 09:48+0200\n"
 "Last-Translator: Мирослав Николић <miroslavnikolic@rocketmail.com>\n"
 "Language-Team: Serbian <(nothing)>\n"
@@ -73,9 +73,6 @@
 msgid "Could not read CD."
 msgstr "Не могу да читам ЦД."
 
-msgid "Internal data stream error."
-msgstr "Унутрашња грешка тока података."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Недостаје елемент „%s“ — проверите вашу инсталацију Гстримера."
@@ -89,6 +86,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Не могу да направим „уридекодебин“ елемент."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Не могу да направим „уридекодебин“ елемент."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Не могу да направим „уридекодебин“ елемент."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Недостају и самоусклађивање снимка и „%s“."
@@ -222,6 +227,10 @@
 msgid "Kate subtitle format"
 msgstr "Кејт запис превода"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Кејт запис превода"
+
 msgid "Uncompressed video"
 msgstr "Несажети снимак"
 
@@ -388,6 +397,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Жижна даљина објектива коришћеног за снимање слика, у мииметрима"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "жижна даљина снимања"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Жижна даљина објектива коришћеног за снимање слика, у мииметрима"
+
 msgid "capturing digital zoom ratio"
 msgstr "однос дигиталног зума снимања"
 
@@ -653,6 +671,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "Притисните „k“ да видите списак пречица тастатуре.\n"
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Унутрашња грешка тока података."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "За пуштање овог тока потребан је прикључак „%s“, али није инсталиран."
diff --git a/po/sv.gmo b/po/sv.gmo
index 6264aff..4db36b8 100644
--- a/po/sv.gmo
+++ b/po/sv.gmo
Binary files differ
diff --git a/po/sv.po b/po/sv.po
index ccbbf86..b3e7716 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.7.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2016-03-02 22:20+0100\n"
 "Last-Translator: Sebastian Rasmussen <sebras@gmail.com>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
@@ -74,9 +74,6 @@
 msgid "Could not read CD."
 msgstr "Kunde inte läsa cd-skivan."
 
-msgid "Internal data stream error."
-msgstr "Internt dataströmningsfel."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Saknar elementet \"%s\" - kontrollera din GStreamer-installation."
@@ -90,6 +87,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Kunde inte skapa \"uridecodebin\"-element."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Kunde inte skapa \"uridecodebin\"-element."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Kunde inte skapa \"uridecodebin\"-element."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Både autovideosink- och %s-elementet saknas."
@@ -223,6 +228,10 @@
 msgid "Kate subtitle format"
 msgstr "Undertextformatet Kate"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Undertextformatet Kate"
+
 msgid "Uncompressed video"
 msgstr "Okomprimerad video"
 
@@ -389,6 +398,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Brännvidd för linsen i mm när bild infångas"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "brännvidd"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Brännvidd för linsen i mm när bild infångas"
+
 msgid "capturing digital zoom ratio"
 msgstr "digitalt zoom-förhållande"
 
@@ -653,6 +671,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "Tryck på 'k' för att se en lista över tangentbordsgenvägar.\n"
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Internt dataströmningsfel."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr ""
 #~ "En %s-insticksmodul krävs för att spela upp den här strömmen men är inte "
diff --git a/po/tr.gmo b/po/tr.gmo
index e3ac963..faf642f 100644
--- a/po/tr.gmo
+++ b/po/tr.gmo
Binary files differ
diff --git a/po/tr.po b/po/tr.po
index ff0f71e..0b22684 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.4.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\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"
@@ -73,9 +73,6 @@
 msgid "Could not read CD."
 msgstr "CD okunamıyor."
 
-msgid "Internal data stream error."
-msgstr "İç veri akışı hatası."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Kayıp öğe '%s' - GStreamer kurulumunu denetleyin."
@@ -89,6 +86,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "\"uridecodebin\" ögesi oluşturulamıyor."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Bir \"decodebin2\" öğesi oluşturamıyor."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "\"uridecodebin\" ögesi oluşturulamıyor."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Autovideosink ve xvimagesink %s öğelerininin ikisi de kayıp."
@@ -222,6 +227,10 @@
 msgid "Kate subtitle format"
 msgstr "Kate altyazı kipi"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Kate altyazı kipi"
+
 msgid "Uncompressed video"
 msgstr "Sıkıştırılmamış video"
 
@@ -388,6 +397,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Mm bazında, resim çekerken kullanılan odaksal uzunluk"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "odaksal uzunluğu yakalıyor"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Mm bazında, resim çekerken kullanılan odaksal uzunluk"
+
 msgid "capturing digital zoom ratio"
 msgstr "sayısal zum oranını yakalıyor"
 
@@ -656,6 +674,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr ""
 
+#~ msgid "Internal data stream error."
+#~ msgstr "İç veri akışı hatası."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr "Bir %s eklenti bu akışı çalmak için gerekli, fakat kurulu değil."
 
@@ -809,9 +830,6 @@
 #~ msgid "Internal data flow error."
 #~ msgstr "İç veri akışı hatası."
 
-#~ msgid "Could not create \"decodebin2\" element."
-#~ msgstr "Bir \"decodebin2\" öğesi oluşturamıyor."
-
 #~ msgid "Could not create \"queue2\" element."
 #~ msgstr "Bir \"queue2\" öğesi oluşturamıyor."
 
diff --git a/po/uk.gmo b/po/uk.gmo
index bfe5b05..7c7c387 100644
--- a/po/uk.gmo
+++ b/po/uk.gmo
Binary files differ
diff --git a/po/uk.po b/po/uk.po
index c4b0722..1381539 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.7.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2016-03-02 22:05+0200\n"
 "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
 "Language-Team: Ukrainian <translation-team-uk@lists.sourceforge.net>\n"
@@ -78,9 +78,6 @@
 msgid "Could not read CD."
 msgstr "Не вдалося прочитати CD."
 
-msgid "Internal data stream error."
-msgstr "Помилка внутрішнього потоку даних."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr ""
@@ -95,6 +92,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Не вдалося створити елемент \"uridecodebin\"."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Не вдається створити елемент \"decodebin2\"."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Не вдалося створити елемент \"uridecodebin\"."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Не вказано елементів autovideosink і %s."
@@ -229,6 +234,10 @@
 msgid "Kate subtitle format"
 msgstr "Формат субтитрів Kate"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Формат субтитрів Kate"
+
 msgid "Uncompressed video"
 msgstr "Нестиснене відео"
 
@@ -398,6 +407,16 @@
 msgstr ""
 "Фокальна відстань об’єктива, використаного при створенні зображення, у мм"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "фокальна відстань"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr ""
+"Фокальна відстань об’єктива, використаного при створенні зображення, у мм"
+
 msgid "capturing digital zoom ratio"
 msgstr "коефіцієнт цифрового збільшення"
 
@@ -671,6 +690,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "Натисніть «k», щоб переглянути список клавіатурних скорочень.\n"
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Помилка внутрішнього потоку даних."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr "Для відтворення потоку потрібен модуль %s, але він не встановлений."
 
@@ -816,9 +838,6 @@
 #~ msgid "Could not open file \"%s\" for reading."
 #~ msgstr "Не вдається відкрити файл \"%s\" для читання."
 
-#~ msgid "Could not create \"decodebin2\" element."
-#~ msgstr "Не вдається створити елемент \"decodebin2\"."
-
 #~ msgid "Could not create \"queue2\" element."
 #~ msgstr "Не вдається створити елемент \"queue2\"."
 
diff --git a/po/vi.gmo b/po/vi.gmo
index b139f63..65b6a38 100644
--- a/po/vi.gmo
+++ b/po/vi.gmo
Binary files differ
diff --git a/po/vi.po b/po/vi.po
index ab2a269..eb5a0d1 100644
--- a/po/vi.po
+++ b/po/vi.po
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.7.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2016-03-03 07:49+0700\n"
 "Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n"
 "Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n"
@@ -75,9 +75,6 @@
 msgid "Could not read CD."
 msgstr "Không thể đọc đĩa CD."
 
-msgid "Internal data stream error."
-msgstr "Lỗi luồng dữ liệu nội bộ."
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "Thiếu phần tử “%s” — hãy kiểm tra lại phần cài đặt GStreamer."
@@ -91,6 +88,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "Không thể tạo phần tử “uridecodebin”."
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "Không thể tạo phần tử “uridecodebin”."
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "Không thể tạo phần tử “uridecodebin”."
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "Thiếu phần tử autovideosink, cũng thiếu phần tử %s."
@@ -225,6 +230,10 @@
 msgid "Kate subtitle format"
 msgstr "Định dạng phụ đề Kate"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Định dạng phụ đề Kate"
+
 msgid "Uncompressed video"
 msgstr "Video không nén"
 
@@ -394,6 +403,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "Chiều dài tiêu cự ống kính được sử dụng khi chụp một ảnh, tính bằng mm"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "độ dài tiêu cự khi chụp"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "Chiều dài tiêu cự ống kính được sử dụng khi chụp một ảnh, tính bằng mm"
+
 msgid "capturing digital zoom ratio"
 msgstr "tỷ lệ phóng to kỹ thuật số khi chụp"
 
@@ -659,6 +677,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "Nhấn phím “k” để xem toàn bộ phím tắt.\n"
 
+#~ msgid "Internal data stream error."
+#~ msgstr "Lỗi luồng dữ liệu nội bộ."
+
 #~ msgid "A %s plugin is required to play this stream, but not installed."
 #~ msgstr "Cần phần bổ sung %s để phát luồng này nhưng chưa cài đặt."
 
diff --git a/po/zh_CN.gmo b/po/zh_CN.gmo
index 335babe..054d9d4 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 0655cb6..8ea9070 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-base 1.7.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2016-08-19 11:53+0300\n"
+"POT-Creation-Date: 2016-09-30 12:11+0300\n"
 "PO-Revision-Date: 2016-03-03 12:15+0800\n"
 "Last-Translator: Tianze Wang <zwpwjwtz@126.com>\n"
 "Language-Team: Chinese (simplified) <i18n-zh@googlegroups.com>\n"
@@ -68,9 +68,6 @@
 msgid "Could not read CD."
 msgstr "无法读取 CD。"
 
-msgid "Internal data stream error."
-msgstr "内部数据流错误。"
-
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr "未找到组件‘%s’-请检查您的 GStreamer 安装情况。"
@@ -84,6 +81,14 @@
 msgid "Could not create \"uridecodebin\" element."
 msgstr "无法创建“uridecodebin”组件。"
 
+#, fuzzy
+msgid "Could not create \"decodebin3\" element."
+msgstr "无法创建“decodebin”组件。"
+
+#, fuzzy
+msgid "Could not create \"urisourcebin\" element."
+msgstr "无法创建“uridecodebin”组件。"
+
 #, c-format
 msgid "Both autovideosink and %s elements are missing."
 msgstr "缺少 autovideosink 和 %s 组件。"
@@ -217,6 +222,10 @@
 msgid "Kate subtitle format"
 msgstr "Kate 字幕格式"
 
+#, fuzzy
+msgid "WebVTT subtitle format"
+msgstr "Kate 字幕格式"
+
 msgid "Uncompressed video"
 msgstr "未压缩的视频"
 
@@ -383,6 +392,15 @@
 msgid "Focal length of the lens used capturing the image, in mm"
 msgstr "(在mm中)捕捉图像时的焦距"
 
+#, fuzzy
+msgid "capturing 35 mm equivalent focal length"
+msgstr "捕捉焦距"
+
+#, fuzzy
+msgid ""
+"35 mm equivalent focal length of the lens used capturing the image, in mm"
+msgstr "(在mm中)捕捉图像时的焦距"
+
 msgid "capturing digital zoom ratio"
 msgstr "捕捉数码变焦比"
 
@@ -644,6 +662,9 @@
 msgid "Press 'k' to see a list of keyboard shortcuts.\n"
 msgstr "按“k”键来显示键盘快捷键列表。\n"
 
+#~ msgid "Internal data stream error."
+#~ msgstr "内部数据流错误。"
+
 #~ msgid "Master"
 #~ msgstr "主音量"
 
@@ -723,9 +744,6 @@
 #~ msgid "Could not open file \"%s\" for reading."
 #~ msgstr "无法打开文件“%s”读取。"
 
-#~ msgid "Could not create \"decodebin2\" element."
-#~ msgstr "无法创建“decodebin”组件。"
-
 #~ msgid "Could not create \"queue2\" element."
 #~ msgstr "无法创建“queue2”组件。"
 
diff --git a/sys/Makefile.in b/sys/Makefile.in
index 722e256..73962f0 100644
--- a/sys/Makefile.in
+++ b/sys/Makefile.in
@@ -101,6 +101,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -410,6 +411,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -423,6 +427,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -460,6 +467,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/sys/ximage/Makefile.in b/sys/ximage/Makefile.in
index 2d48cf3..373a975 100644
--- a/sys/ximage/Makefile.in
+++ b/sys/ximage/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -431,6 +432,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -444,6 +448,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -481,6 +488,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/sys/ximage/ximagesink.c b/sys/ximage/ximagesink.c
index d2c8c81..e625989 100644
--- a/sys/ximage/ximagesink.c
+++ b/sys/ximage/ximagesink.c
@@ -1585,7 +1585,6 @@
   XID xwindow_id = id;
   GstXImageSink *ximagesink = GST_X_IMAGE_SINK (overlay);
   GstXWindow *xwindow = NULL;
-  XWindowAttributes attr;
 
   /* We acquire the stream lock while setting this window in the element.
      We are basically cleaning tons of stuff replacing the old window, putting
@@ -1626,12 +1625,8 @@
 
     xwindow->win = xwindow_id;
 
-    /* We get window geometry, set the event we want to receive,
-       and create a GC */
+    /* We set the events we want to receive and create a GC. */
     g_mutex_lock (&ximagesink->x_lock);
-    XGetWindowAttributes (ximagesink->xcontext->disp, xwindow->win, &attr);
-    xwindow->width = attr.width;
-    xwindow->height = attr.height;
     xwindow->internal = FALSE;
     if (ximagesink->handle_events) {
       XSelectInput (ximagesink->xcontext->disp, xwindow->win, ExposureMask |
@@ -1643,8 +1638,11 @@
     g_mutex_unlock (&ximagesink->x_lock);
   }
 
-  if (xwindow)
+  if (xwindow) {
     ximagesink->xwindow = xwindow;
+    /* Update the window geometry, possibly generating a reconfigure event. */
+    gst_x_image_sink_xwindow_update_geometry(ximagesink);
+  }
 
   g_mutex_unlock (&ximagesink->flow_lock);
 }
@@ -1976,8 +1974,8 @@
       "Video sink", "Sink/Video",
       "A standard X based videosink", "Julien Moutte <julien@moutte.net>");
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_x_image_sink_sink_template_factory));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_x_image_sink_sink_template_factory);
 
   gstelement_class->change_state = gst_x_image_sink_change_state;
 
diff --git a/sys/xvimage/Makefile.in b/sys/xvimage/Makefile.in
index fd4590b..6517d39 100644
--- a/sys/xvimage/Makefile.in
+++ b/sys/xvimage/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -433,6 +434,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -446,6 +450,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -483,6 +490,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/sys/xvimage/xvimagesink.c b/sys/xvimage/xvimagesink.c
index c612076..e008d09 100644
--- a/sys/xvimage/xvimagesink.c
+++ b/sys/xvimage/xvimagesink.c
@@ -2013,8 +2013,8 @@
       "Video sink", "Sink/Video",
       "A Xv based videosink", "Julien Moutte <julien@moutte.net>");
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_xv_image_sink_sink_template_factory));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_xv_image_sink_sink_template_factory);
 
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_xv_image_sink_change_state);
diff --git a/tests/Makefile.in b/tests/Makefile.in
index f9793a2..3b50ba9 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -96,6 +96,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -404,6 +405,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -417,6 +421,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -454,6 +461,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am
index ed1d026..a70b3cf 100644
--- a/tests/check/Makefile.am
+++ b/tests/check/Makefile.am
@@ -75,7 +75,8 @@
 
 if USE_PLUGIN_PLAYBACK
 check_playback = elements/decodebin elements/playbin \
-    elements/playbin-complex elements/streamsynchronizer
+    elements/playbin-complex elements/streamsynchronizer \
+    elements/playsink
 else
 check_playback =
 endif
@@ -121,7 +122,9 @@
 endif
 
 if USE_PLUGIN_VIDEOSCALE
-check_videoscale = elements/videoscale
+check_videoscale = elements/videoscale elements/videoscale-1 \
+        elements/videoscale-2 elements/videoscale-3 elements/videoscale-4 \
+        elements/videoscale-5 elements/videoscale-6
 else
 check_videoscale =
 endif
@@ -216,6 +219,7 @@
 	libs/video \
 	libs/videodecoder \
 	libs/videoencoder \
+	libs/videotimecode \
 	libs/xmpwriter \
 	pipelines/simple-launch-lines \
 	pipelines/basetime \
@@ -268,12 +272,12 @@
 	$(GST_CFLAGS) $(GST_CHECK_CFLAGS) \
 	-DGST_TEST_FILES_PATH="\"$(TEST_FILES_DIRECTORY)\"" \
 	-DGST_CHECK_TEST_ENVIRONMENT_BEACON="\"GST_PLUGIN_LOADING_WHITELIST\"" \
-	-UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS
+	-UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS $(PTHREAD_CFLAGS)
 AM_CXXFLAGS = -I$(top_srcdir)/gst-libs -I$(top_builddir)/gst-libs \
 	$(GST_CXXFLAGS) $(GST_CHECK_CFLAGS) \
 	-DGST_TEST_FILES_PATH="\"$(TEST_FILES_DIRECTORY)\"" \
 	-DGST_CHECK_TEST_ENVIRONMENT_BEACON="\"GST_PLUGIN_LOADING_WHITELIST\"" \
-	-UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS
+	-UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS $(PTHREAD_CFLAGS)
 LDADD = $(GST_LIBS) $(GST_CHECK_LIBS)
 
 # valgrind testing
@@ -587,6 +591,25 @@
 	$(top_builddir)/gst-libs/gst/video/libgstvideo-@GST_API_VERSION@.la \
 	$(GST_BASE_LIBS) $(LDADD)
 
+elements_videoscale_1_SOURCES = elements/videoscale.c
+elements_videoscale_1_CFLAGS = $(elements_videoscale_CFLAGS) -DVSCALE_TEST_GROUP=1
+elements_videoscale_1_LDADD = $(elements_videoscale_LDADD)
+elements_videoscale_2_SOURCES = elements/videoscale.c
+elements_videoscale_2_CFLAGS = $(elements_videoscale_CFLAGS) -DVSCALE_TEST_GROUP=2
+elements_videoscale_2_LDADD = $(elements_videoscale_LDADD)
+elements_videoscale_3_SOURCES = elements/videoscale.c
+elements_videoscale_3_CFLAGS = $(elements_videoscale_CFLAGS) -DVSCALE_TEST_GROUP=3
+elements_videoscale_3_LDADD = $(elements_videoscale_LDADD)
+elements_videoscale_4_SOURCES = elements/videoscale.c
+elements_videoscale_4_CFLAGS = $(elements_videoscale_CFLAGS) -DVSCALE_TEST_GROUP=4
+elements_videoscale_4_LDADD = $(elements_videoscale_LDADD)
+elements_videoscale_5_SOURCES = elements/videoscale.c
+elements_videoscale_5_CFLAGS = $(elements_videoscale_CFLAGS) -DVSCALE_TEST_GROUP=5
+elements_videoscale_5_LDADD = $(elements_videoscale_LDADD)
+elements_videoscale_6_SOURCES = elements/videoscale.c
+elements_videoscale_6_CFLAGS = $(elements_videoscale_CFLAGS) -DVSCALE_TEST_GROUP=6
+elements_videoscale_6_LDADD = $(elements_videoscale_LDADD)
+
 gst_typefindfunctions_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS)
 gst_typefindfunctions_LDADD = $(GST_BASE_LIBS) $(LDADD)
 
@@ -620,6 +643,16 @@
 	$(GST_BASE_LIBS) \
 	$(LDADD)
 
+libs_videotimecode_CFLAGS = \
+	$(GST_PLUGINS_BASE_CFLAGS) \
+	$(GST_BASE_CFLAGS) \
+	$(AM_CFLAGS)
+
+libs_videotimecode_LDADD = \
+	$(top_builddir)/gst-libs/gst/video/libgstvideo-@GST_API_VERSION@.la \
+	$(GST_BASE_LIBS) \
+	$(LDADD)
+
 elements_multisocketsink_CFLAGS = $(GIO_CFLAGS) $(AM_CFLAGS)
 elements_multisocketsink_LDADD = $(GIO_LIBS) $(LDADD)
 
diff --git a/tests/check/Makefile.in b/tests/check/Makefile.in
index d9dab9c..e9cfddd 100644
--- a/tests/check/Makefile.in
+++ b/tests/check/Makefile.in
@@ -102,7 +102,8 @@
 	libs/rtsp$(EXEEXT) libs/rtspconnection$(EXEEXT) \
 	libs/sdp$(EXEEXT) libs/tag$(EXEEXT) libs/video$(EXEEXT) \
 	libs/videodecoder$(EXEEXT) libs/videoencoder$(EXEEXT) \
-	libs/xmpwriter$(EXEEXT) pipelines/simple-launch-lines$(EXEEXT) \
+	libs/videotimecode$(EXEEXT) libs/xmpwriter$(EXEEXT) \
+	pipelines/simple-launch-lines$(EXEEXT) \
 	pipelines/basetime$(EXEEXT) \
 	pipelines/capsfilter-renegotiation$(EXEEXT) \
 	pipelines/streamsynchronizer$(EXEEXT) $(am__EXEEXT_1) \
@@ -123,6 +124,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -175,7 +177,8 @@
 @USE_PLUGIN_PLAYBACK_TRUE@am__EXEEXT_12 = elements/decodebin$(EXEEXT) \
 @USE_PLUGIN_PLAYBACK_TRUE@	elements/playbin$(EXEEXT) \
 @USE_PLUGIN_PLAYBACK_TRUE@	elements/playbin-complex$(EXEEXT) \
-@USE_PLUGIN_PLAYBACK_TRUE@	elements/streamsynchronizer$(EXEEXT)
+@USE_PLUGIN_PLAYBACK_TRUE@	elements/streamsynchronizer$(EXEEXT) \
+@USE_PLUGIN_PLAYBACK_TRUE@	elements/playsink$(EXEEXT)
 @USE_PLUGIN_SUBPARSE_TRUE@am__EXEEXT_13 = elements/subparse$(EXEEXT)
 @USE_PLUGIN_APP_FALSE@@USE_PLUGIN_TCP_TRUE@am__EXEEXT_14 = elements/multifdsink$(EXEEXT) \
 @USE_PLUGIN_APP_FALSE@@USE_PLUGIN_TCP_TRUE@	elements/multisocketsink$(EXEEXT)
@@ -190,7 +193,13 @@
 @USE_PLUGIN_VIDEORATE_TRUE@am__EXEEXT_18 =  \
 @USE_PLUGIN_VIDEORATE_TRUE@	elements/videorate$(EXEEXT)
 @USE_PLUGIN_VIDEOSCALE_TRUE@am__EXEEXT_19 =  \
-@USE_PLUGIN_VIDEOSCALE_TRUE@	elements/videoscale$(EXEEXT)
+@USE_PLUGIN_VIDEOSCALE_TRUE@	elements/videoscale$(EXEEXT) \
+@USE_PLUGIN_VIDEOSCALE_TRUE@	elements/videoscale-1$(EXEEXT) \
+@USE_PLUGIN_VIDEOSCALE_TRUE@	elements/videoscale-2$(EXEEXT) \
+@USE_PLUGIN_VIDEOSCALE_TRUE@	elements/videoscale-3$(EXEEXT) \
+@USE_PLUGIN_VIDEOSCALE_TRUE@	elements/videoscale-4$(EXEEXT) \
+@USE_PLUGIN_VIDEOSCALE_TRUE@	elements/videoscale-5$(EXEEXT) \
+@USE_PLUGIN_VIDEOSCALE_TRUE@	elements/videoscale-6$(EXEEXT)
 @USE_PLUGIN_VIDEOTESTSRC_TRUE@am__EXEEXT_20 =  \
 @USE_PLUGIN_VIDEOTESTSRC_TRUE@	elements/videotestsrc$(EXEEXT)
 @USE_PLUGIN_VOLUME_TRUE@am__EXEEXT_21 = elements/volume$(EXEEXT)
@@ -333,6 +342,11 @@
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
 	$(elements_playbin_complex_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
 	$(LDFLAGS) -o $@
+elements_playsink_SOURCES = elements/playsink.c
+elements_playsink_OBJECTS = elements/playsink.$(OBJEXT)
+elements_playsink_LDADD = $(LDADD)
+elements_playsink_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
 elements_streamsynchronizer_SOURCES = elements/streamsynchronizer.c
 elements_streamsynchronizer_OBJECTS =  \
 	elements/streamsynchronizer.$(OBJEXT)
@@ -379,6 +393,56 @@
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
 	$(elements_videoscale_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
 	$(LDFLAGS) -o $@
+am_elements_videoscale_1_OBJECTS =  \
+	elements/elements_videoscale_1-videoscale.$(OBJEXT)
+elements_videoscale_1_OBJECTS = $(am_elements_videoscale_1_OBJECTS)
+am__DEPENDENCIES_3 = $(top_builddir)/gst-libs/gst/video/libgstvideo-@GST_API_VERSION@.la \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
+elements_videoscale_1_DEPENDENCIES = $(am__DEPENDENCIES_3)
+elements_videoscale_1_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(elements_videoscale_1_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+am_elements_videoscale_2_OBJECTS =  \
+	elements/elements_videoscale_2-videoscale.$(OBJEXT)
+elements_videoscale_2_OBJECTS = $(am_elements_videoscale_2_OBJECTS)
+elements_videoscale_2_DEPENDENCIES = $(am__DEPENDENCIES_3)
+elements_videoscale_2_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(elements_videoscale_2_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+am_elements_videoscale_3_OBJECTS =  \
+	elements/elements_videoscale_3-videoscale.$(OBJEXT)
+elements_videoscale_3_OBJECTS = $(am_elements_videoscale_3_OBJECTS)
+elements_videoscale_3_DEPENDENCIES = $(am__DEPENDENCIES_3)
+elements_videoscale_3_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(elements_videoscale_3_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+am_elements_videoscale_4_OBJECTS =  \
+	elements/elements_videoscale_4-videoscale.$(OBJEXT)
+elements_videoscale_4_OBJECTS = $(am_elements_videoscale_4_OBJECTS)
+elements_videoscale_4_DEPENDENCIES = $(am__DEPENDENCIES_3)
+elements_videoscale_4_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(elements_videoscale_4_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+am_elements_videoscale_5_OBJECTS =  \
+	elements/elements_videoscale_5-videoscale.$(OBJEXT)
+elements_videoscale_5_OBJECTS = $(am_elements_videoscale_5_OBJECTS)
+elements_videoscale_5_DEPENDENCIES = $(am__DEPENDENCIES_3)
+elements_videoscale_5_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(elements_videoscale_5_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+am_elements_videoscale_6_OBJECTS =  \
+	elements/elements_videoscale_6-videoscale.$(OBJEXT)
+elements_videoscale_6_OBJECTS = $(am_elements_videoscale_6_OBJECTS)
+elements_videoscale_6_DEPENDENCIES = $(am__DEPENDENCIES_3)
+elements_videoscale_6_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(elements_videoscale_6_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
 elements_videotestsrc_SOURCES = elements/videotestsrc.c
 elements_videotestsrc_OBJECTS = elements/videotestsrc.$(OBJEXT)
 elements_videotestsrc_LDADD = $(LDADD)
@@ -627,6 +691,15 @@
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
 	$(libs_videoencoder_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
 	-o $@
+libs_videotimecode_SOURCES = libs/videotimecode.c
+libs_videotimecode_OBJECTS =  \
+	libs/libs_videotimecode-videotimecode.$(OBJEXT)
+libs_videotimecode_DEPENDENCIES = $(top_builddir)/gst-libs/gst/video/libgstvideo-@GST_API_VERSION@.la \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
+libs_videotimecode_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(libs_videotimecode_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
 libs_xmpwriter_SOURCES = libs/xmpwriter.c
 libs_xmpwriter_OBJECTS = libs/libs_xmpwriter-xmpwriter.$(OBJEXT)
 libs_xmpwriter_DEPENDENCIES = $(top_builddir)/gst-libs/gst/tag/libgsttag-@GST_API_VERSION@.la \
@@ -806,20 +879,26 @@
 	elements/decodebin.c elements/encodebin.c elements/libvisual.c \
 	elements/multifdsink.c elements/multisocketsink.c \
 	elements/opus.c elements/playbin.c elements/playbin-complex.c \
-	elements/streamsynchronizer.c elements/subparse.c \
-	elements/textoverlay.c elements/videoconvert.c \
-	elements/videorate.c elements/videoscale.c \
-	elements/videotestsrc.c elements/volume.c elements/vorbisdec.c \
-	elements/vorbistag.c generic/clock-selection.c \
-	generic/states.c gst/typefindfunctions.c libs/allocators.c \
-	libs/audio.c libs/audiocdsrc.c libs/audiodecoder.c \
-	libs/audioencoder.c $(libs_baseaudiovisualizer_SOURCES) \
-	libs/discoverer.c libs/fft.c $(libs_gstlibscpp_SOURCES) \
-	libs/libsabi.c libs/mikey.c libs/navigation.c libs/pbutils.c \
-	libs/profile.c libs/rtp.c libs/rtpbasedepayload.c \
-	libs/rtpbasepayload.c libs/rtsp.c libs/rtspconnection.c \
-	libs/sdp.c libs/tag.c libs/video.c libs/videodecoder.c \
-	libs/videoencoder.c libs/xmpwriter.c \
+	elements/playsink.c elements/streamsynchronizer.c \
+	elements/subparse.c elements/textoverlay.c \
+	elements/videoconvert.c elements/videorate.c \
+	elements/videoscale.c $(elements_videoscale_1_SOURCES) \
+	$(elements_videoscale_2_SOURCES) \
+	$(elements_videoscale_3_SOURCES) \
+	$(elements_videoscale_4_SOURCES) \
+	$(elements_videoscale_5_SOURCES) \
+	$(elements_videoscale_6_SOURCES) elements/videotestsrc.c \
+	elements/volume.c elements/vorbisdec.c elements/vorbistag.c \
+	generic/clock-selection.c generic/states.c \
+	gst/typefindfunctions.c libs/allocators.c libs/audio.c \
+	libs/audiocdsrc.c libs/audiodecoder.c libs/audioencoder.c \
+	$(libs_baseaudiovisualizer_SOURCES) libs/discoverer.c \
+	libs/fft.c $(libs_gstlibscpp_SOURCES) libs/libsabi.c \
+	libs/mikey.c libs/navigation.c libs/pbutils.c libs/profile.c \
+	libs/rtp.c libs/rtpbasedepayload.c libs/rtpbasepayload.c \
+	libs/rtsp.c libs/rtspconnection.c libs/sdp.c libs/tag.c \
+	libs/video.c libs/videodecoder.c libs/videoencoder.c \
+	libs/videotimecode.c libs/xmpwriter.c \
 	$(nodist_orc_adder_SOURCES) $(nodist_orc_audio_SOURCES) \
 	$(nodist_orc_video_SOURCES) $(nodist_orc_videotestsrc_SOURCES) \
 	$(nodist_orc_volume_SOURCES) pipelines/basetime.c \
@@ -834,20 +913,26 @@
 	elements/decodebin.c elements/encodebin.c elements/libvisual.c \
 	elements/multifdsink.c elements/multisocketsink.c \
 	elements/opus.c elements/playbin.c elements/playbin-complex.c \
-	elements/streamsynchronizer.c elements/subparse.c \
-	elements/textoverlay.c elements/videoconvert.c \
-	elements/videorate.c elements/videoscale.c \
-	elements/videotestsrc.c elements/volume.c elements/vorbisdec.c \
-	elements/vorbistag.c generic/clock-selection.c \
-	generic/states.c gst/typefindfunctions.c libs/allocators.c \
-	libs/audio.c libs/audiocdsrc.c libs/audiodecoder.c \
-	libs/audioencoder.c $(libs_baseaudiovisualizer_SOURCES) \
-	libs/discoverer.c libs/fft.c $(libs_gstlibscpp_SOURCES) \
-	libs/libsabi.c libs/mikey.c libs/navigation.c libs/pbutils.c \
-	libs/profile.c libs/rtp.c libs/rtpbasedepayload.c \
-	libs/rtpbasepayload.c libs/rtsp.c libs/rtspconnection.c \
-	libs/sdp.c libs/tag.c libs/video.c libs/videodecoder.c \
-	libs/videoencoder.c libs/xmpwriter.c pipelines/basetime.c \
+	elements/playsink.c elements/streamsynchronizer.c \
+	elements/subparse.c elements/textoverlay.c \
+	elements/videoconvert.c elements/videorate.c \
+	elements/videoscale.c $(elements_videoscale_1_SOURCES) \
+	$(elements_videoscale_2_SOURCES) \
+	$(elements_videoscale_3_SOURCES) \
+	$(elements_videoscale_4_SOURCES) \
+	$(elements_videoscale_5_SOURCES) \
+	$(elements_videoscale_6_SOURCES) elements/videotestsrc.c \
+	elements/volume.c elements/vorbisdec.c elements/vorbistag.c \
+	generic/clock-selection.c generic/states.c \
+	gst/typefindfunctions.c libs/allocators.c libs/audio.c \
+	libs/audiocdsrc.c libs/audiodecoder.c libs/audioencoder.c \
+	$(libs_baseaudiovisualizer_SOURCES) libs/discoverer.c \
+	libs/fft.c $(libs_gstlibscpp_SOURCES) libs/libsabi.c \
+	libs/mikey.c libs/navigation.c libs/pbutils.c libs/profile.c \
+	libs/rtp.c libs/rtpbasedepayload.c libs/rtpbasepayload.c \
+	libs/rtsp.c libs/rtspconnection.c libs/sdp.c libs/tag.c \
+	libs/video.c libs/videodecoder.c libs/videoencoder.c \
+	libs/videotimecode.c libs/xmpwriter.c pipelines/basetime.c \
 	pipelines/capsfilter-renegotiation.c pipelines/gio.c \
 	pipelines/oggmux.c pipelines/simple-launch-lines.c \
 	pipelines/streamsynchronizer.c pipelines/tcp.c \
@@ -1279,6 +1364,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -1292,6 +1380,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -1329,6 +1420,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -1418,7 +1510,8 @@
 @USE_PLUGIN_AUDIOCONVERT_TRUE@check_audioconvert = elements/audioconvert
 @USE_PLUGIN_PLAYBACK_FALSE@check_playback = 
 @USE_PLUGIN_PLAYBACK_TRUE@check_playback = elements/decodebin elements/playbin \
-@USE_PLUGIN_PLAYBACK_TRUE@    elements/playbin-complex elements/streamsynchronizer
+@USE_PLUGIN_PLAYBACK_TRUE@    elements/playbin-complex elements/streamsynchronizer \
+@USE_PLUGIN_PLAYBACK_TRUE@    elements/playsink
 
 @USE_THEORA_FALSE@check_theora = 
 @USE_THEORA_TRUE@check_theora = pipelines/theoraenc
@@ -1434,7 +1527,10 @@
 @USE_PLUGIN_VIDEORATE_FALSE@check_videorate = 
 @USE_PLUGIN_VIDEORATE_TRUE@check_videorate = elements/videorate
 @USE_PLUGIN_VIDEOSCALE_FALSE@check_videoscale = 
-@USE_PLUGIN_VIDEOSCALE_TRUE@check_videoscale = elements/videoscale
+@USE_PLUGIN_VIDEOSCALE_TRUE@check_videoscale = elements/videoscale elements/videoscale-1 \
+@USE_PLUGIN_VIDEOSCALE_TRUE@        elements/videoscale-2 elements/videoscale-3 elements/videoscale-4 \
+@USE_PLUGIN_VIDEOSCALE_TRUE@        elements/videoscale-5 elements/videoscale-6
+
 @USE_PLUGIN_VIDEOTESTSRC_FALSE@check_videotestsrc = 
 @USE_PLUGIN_VIDEOTESTSRC_TRUE@check_videotestsrc = elements/videotestsrc
 @USE_PLUGIN_VOLUME_FALSE@check_volume = 
@@ -1476,13 +1572,13 @@
 	$(GST_CFLAGS) $(GST_CHECK_CFLAGS) \
 	-DGST_TEST_FILES_PATH="\"$(TEST_FILES_DIRECTORY)\"" \
 	-DGST_CHECK_TEST_ENVIRONMENT_BEACON="\"GST_PLUGIN_LOADING_WHITELIST\"" \
-	-UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS
+	-UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS $(PTHREAD_CFLAGS)
 
 AM_CXXFLAGS = -I$(top_srcdir)/gst-libs -I$(top_builddir)/gst-libs \
 	$(GST_CXXFLAGS) $(GST_CHECK_CFLAGS) \
 	-DGST_TEST_FILES_PATH="\"$(TEST_FILES_DIRECTORY)\"" \
 	-DGST_CHECK_TEST_ENVIRONMENT_BEACON="\"GST_PLUGIN_LOADING_WHITELIST\"" \
-	-UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS
+	-UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS $(PTHREAD_CFLAGS)
 
 LDADD = $(GST_LIBS) $(GST_CHECK_LIBS)
 
@@ -1799,6 +1895,24 @@
 	$(top_builddir)/gst-libs/gst/video/libgstvideo-@GST_API_VERSION@.la \
 	$(GST_BASE_LIBS) $(LDADD)
 
+elements_videoscale_1_SOURCES = elements/videoscale.c
+elements_videoscale_1_CFLAGS = $(elements_videoscale_CFLAGS) -DVSCALE_TEST_GROUP=1
+elements_videoscale_1_LDADD = $(elements_videoscale_LDADD)
+elements_videoscale_2_SOURCES = elements/videoscale.c
+elements_videoscale_2_CFLAGS = $(elements_videoscale_CFLAGS) -DVSCALE_TEST_GROUP=2
+elements_videoscale_2_LDADD = $(elements_videoscale_LDADD)
+elements_videoscale_3_SOURCES = elements/videoscale.c
+elements_videoscale_3_CFLAGS = $(elements_videoscale_CFLAGS) -DVSCALE_TEST_GROUP=3
+elements_videoscale_3_LDADD = $(elements_videoscale_LDADD)
+elements_videoscale_4_SOURCES = elements/videoscale.c
+elements_videoscale_4_CFLAGS = $(elements_videoscale_CFLAGS) -DVSCALE_TEST_GROUP=4
+elements_videoscale_4_LDADD = $(elements_videoscale_LDADD)
+elements_videoscale_5_SOURCES = elements/videoscale.c
+elements_videoscale_5_CFLAGS = $(elements_videoscale_CFLAGS) -DVSCALE_TEST_GROUP=5
+elements_videoscale_5_LDADD = $(elements_videoscale_LDADD)
+elements_videoscale_6_SOURCES = elements/videoscale.c
+elements_videoscale_6_CFLAGS = $(elements_videoscale_CFLAGS) -DVSCALE_TEST_GROUP=6
+elements_videoscale_6_LDADD = $(elements_videoscale_LDADD)
 gst_typefindfunctions_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS)
 gst_typefindfunctions_LDADD = $(GST_BASE_LIBS) $(LDADD)
 libs_video_CFLAGS = \
@@ -1831,6 +1945,16 @@
 	$(GST_BASE_LIBS) \
 	$(LDADD)
 
+libs_videotimecode_CFLAGS = \
+	$(GST_PLUGINS_BASE_CFLAGS) \
+	$(GST_BASE_CFLAGS) \
+	$(AM_CFLAGS)
+
+libs_videotimecode_LDADD = \
+	$(top_builddir)/gst-libs/gst/video/libgstvideo-@GST_API_VERSION@.la \
+	$(GST_BASE_LIBS) \
+	$(LDADD)
+
 elements_multisocketsink_CFLAGS = $(GIO_CFLAGS) $(AM_CFLAGS)
 elements_multisocketsink_LDADD = $(GIO_LIBS) $(LDADD)
 @USE_GIO_UNIX_2_0_TRUE@GIO_UNIX_2_0_DEFINED = -DHAVE_GIO_UNIX_2_0=1
@@ -2026,6 +2150,12 @@
 elements/playbin-complex$(EXEEXT): $(elements_playbin_complex_OBJECTS) $(elements_playbin_complex_DEPENDENCIES) $(EXTRA_elements_playbin_complex_DEPENDENCIES) elements/$(am__dirstamp)
 	@rm -f elements/playbin-complex$(EXEEXT)
 	$(AM_V_CCLD)$(elements_playbin_complex_LINK) $(elements_playbin_complex_OBJECTS) $(elements_playbin_complex_LDADD) $(LIBS)
+elements/playsink.$(OBJEXT): elements/$(am__dirstamp) \
+	elements/$(DEPDIR)/$(am__dirstamp)
+
+elements/playsink$(EXEEXT): $(elements_playsink_OBJECTS) $(elements_playsink_DEPENDENCIES) $(EXTRA_elements_playsink_DEPENDENCIES) elements/$(am__dirstamp)
+	@rm -f elements/playsink$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(elements_playsink_OBJECTS) $(elements_playsink_LDADD) $(LIBS)
 elements/streamsynchronizer.$(OBJEXT): elements/$(am__dirstamp) \
 	elements/$(DEPDIR)/$(am__dirstamp)
 
@@ -2062,6 +2192,42 @@
 elements/videoscale$(EXEEXT): $(elements_videoscale_OBJECTS) $(elements_videoscale_DEPENDENCIES) $(EXTRA_elements_videoscale_DEPENDENCIES) elements/$(am__dirstamp)
 	@rm -f elements/videoscale$(EXEEXT)
 	$(AM_V_CCLD)$(elements_videoscale_LINK) $(elements_videoscale_OBJECTS) $(elements_videoscale_LDADD) $(LIBS)
+elements/elements_videoscale_1-videoscale.$(OBJEXT):  \
+	elements/$(am__dirstamp) elements/$(DEPDIR)/$(am__dirstamp)
+
+elements/videoscale-1$(EXEEXT): $(elements_videoscale_1_OBJECTS) $(elements_videoscale_1_DEPENDENCIES) $(EXTRA_elements_videoscale_1_DEPENDENCIES) elements/$(am__dirstamp)
+	@rm -f elements/videoscale-1$(EXEEXT)
+	$(AM_V_CCLD)$(elements_videoscale_1_LINK) $(elements_videoscale_1_OBJECTS) $(elements_videoscale_1_LDADD) $(LIBS)
+elements/elements_videoscale_2-videoscale.$(OBJEXT):  \
+	elements/$(am__dirstamp) elements/$(DEPDIR)/$(am__dirstamp)
+
+elements/videoscale-2$(EXEEXT): $(elements_videoscale_2_OBJECTS) $(elements_videoscale_2_DEPENDENCIES) $(EXTRA_elements_videoscale_2_DEPENDENCIES) elements/$(am__dirstamp)
+	@rm -f elements/videoscale-2$(EXEEXT)
+	$(AM_V_CCLD)$(elements_videoscale_2_LINK) $(elements_videoscale_2_OBJECTS) $(elements_videoscale_2_LDADD) $(LIBS)
+elements/elements_videoscale_3-videoscale.$(OBJEXT):  \
+	elements/$(am__dirstamp) elements/$(DEPDIR)/$(am__dirstamp)
+
+elements/videoscale-3$(EXEEXT): $(elements_videoscale_3_OBJECTS) $(elements_videoscale_3_DEPENDENCIES) $(EXTRA_elements_videoscale_3_DEPENDENCIES) elements/$(am__dirstamp)
+	@rm -f elements/videoscale-3$(EXEEXT)
+	$(AM_V_CCLD)$(elements_videoscale_3_LINK) $(elements_videoscale_3_OBJECTS) $(elements_videoscale_3_LDADD) $(LIBS)
+elements/elements_videoscale_4-videoscale.$(OBJEXT):  \
+	elements/$(am__dirstamp) elements/$(DEPDIR)/$(am__dirstamp)
+
+elements/videoscale-4$(EXEEXT): $(elements_videoscale_4_OBJECTS) $(elements_videoscale_4_DEPENDENCIES) $(EXTRA_elements_videoscale_4_DEPENDENCIES) elements/$(am__dirstamp)
+	@rm -f elements/videoscale-4$(EXEEXT)
+	$(AM_V_CCLD)$(elements_videoscale_4_LINK) $(elements_videoscale_4_OBJECTS) $(elements_videoscale_4_LDADD) $(LIBS)
+elements/elements_videoscale_5-videoscale.$(OBJEXT):  \
+	elements/$(am__dirstamp) elements/$(DEPDIR)/$(am__dirstamp)
+
+elements/videoscale-5$(EXEEXT): $(elements_videoscale_5_OBJECTS) $(elements_videoscale_5_DEPENDENCIES) $(EXTRA_elements_videoscale_5_DEPENDENCIES) elements/$(am__dirstamp)
+	@rm -f elements/videoscale-5$(EXEEXT)
+	$(AM_V_CCLD)$(elements_videoscale_5_LINK) $(elements_videoscale_5_OBJECTS) $(elements_videoscale_5_LDADD) $(LIBS)
+elements/elements_videoscale_6-videoscale.$(OBJEXT):  \
+	elements/$(am__dirstamp) elements/$(DEPDIR)/$(am__dirstamp)
+
+elements/videoscale-6$(EXEEXT): $(elements_videoscale_6_OBJECTS) $(elements_videoscale_6_DEPENDENCIES) $(EXTRA_elements_videoscale_6_DEPENDENCIES) elements/$(am__dirstamp)
+	@rm -f elements/videoscale-6$(EXEEXT)
+	$(AM_V_CCLD)$(elements_videoscale_6_LINK) $(elements_videoscale_6_OBJECTS) $(elements_videoscale_6_LDADD) $(LIBS)
 elements/videotestsrc.$(OBJEXT): elements/$(am__dirstamp) \
 	elements/$(DEPDIR)/$(am__dirstamp)
 
@@ -2266,6 +2432,12 @@
 libs/videoencoder$(EXEEXT): $(libs_videoencoder_OBJECTS) $(libs_videoencoder_DEPENDENCIES) $(EXTRA_libs_videoencoder_DEPENDENCIES) libs/$(am__dirstamp)
 	@rm -f libs/videoencoder$(EXEEXT)
 	$(AM_V_CCLD)$(libs_videoencoder_LINK) $(libs_videoencoder_OBJECTS) $(libs_videoencoder_LDADD) $(LIBS)
+libs/libs_videotimecode-videotimecode.$(OBJEXT): libs/$(am__dirstamp) \
+	libs/$(DEPDIR)/$(am__dirstamp)
+
+libs/videotimecode$(EXEEXT): $(libs_videotimecode_OBJECTS) $(libs_videotimecode_DEPENDENCIES) $(EXTRA_libs_videotimecode_DEPENDENCIES) libs/$(am__dirstamp)
+	@rm -f libs/videotimecode$(EXEEXT)
+	$(AM_V_CCLD)$(libs_videotimecode_LINK) $(libs_videotimecode_OBJECTS) $(libs_videotimecode_LDADD) $(LIBS)
 libs/libs_xmpwriter-xmpwriter.$(OBJEXT): libs/$(am__dirstamp) \
 	libs/$(DEPDIR)/$(am__dirstamp)
 
@@ -2404,11 +2576,18 @@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_textoverlay-textoverlay.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_videoconvert-videoconvert.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_videoscale-videoscale.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_videoscale_1-videoscale.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_videoscale_2-videoscale.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_videoscale_3-videoscale.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_videoscale_4-videoscale.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_videoscale_5-videoscale.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_videoscale_6-videoscale.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_volume-volume.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_vorbisdec-vorbisdec.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/elements_vorbistag-vorbistag.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/multifdsink.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/opus.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/playsink.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/streamsynchronizer.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/videorate.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@elements/$(DEPDIR)/videotestsrc.Po@am__quote@
@@ -2439,6 +2618,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@libs/$(DEPDIR)/libs_video-video.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@libs/$(DEPDIR)/libs_videodecoder-videodecoder.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@libs/$(DEPDIR)/libs_videoencoder-videoencoder.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@libs/$(DEPDIR)/libs_videotimecode-videotimecode.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@libs/$(DEPDIR)/libs_xmpwriter-xmpwriter.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@orc/$(DEPDIR)/orc_adder-adder.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@orc/$(DEPDIR)/orc_audio-audio.Po@am__quote@
@@ -2704,6 +2884,90 @@
 @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_videoscale_CFLAGS) $(CFLAGS) -c -o elements/elements_videoscale-videoscale.obj `if test -f 'elements/videoscale.c'; then $(CYGPATH_W) 'elements/videoscale.c'; else $(CYGPATH_W) '$(srcdir)/elements/videoscale.c'; fi`
 
+elements/elements_videoscale_1-videoscale.o: elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_videoscale_1_CFLAGS) $(CFLAGS) -MT elements/elements_videoscale_1-videoscale.o -MD -MP -MF elements/$(DEPDIR)/elements_videoscale_1-videoscale.Tpo -c -o elements/elements_videoscale_1-videoscale.o `test -f 'elements/videoscale.c' || echo '$(srcdir)/'`elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) elements/$(DEPDIR)/elements_videoscale_1-videoscale.Tpo elements/$(DEPDIR)/elements_videoscale_1-videoscale.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='elements/videoscale.c' object='elements/elements_videoscale_1-videoscale.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_videoscale_1_CFLAGS) $(CFLAGS) -c -o elements/elements_videoscale_1-videoscale.o `test -f 'elements/videoscale.c' || echo '$(srcdir)/'`elements/videoscale.c
+
+elements/elements_videoscale_1-videoscale.obj: elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_videoscale_1_CFLAGS) $(CFLAGS) -MT elements/elements_videoscale_1-videoscale.obj -MD -MP -MF elements/$(DEPDIR)/elements_videoscale_1-videoscale.Tpo -c -o elements/elements_videoscale_1-videoscale.obj `if test -f 'elements/videoscale.c'; then $(CYGPATH_W) 'elements/videoscale.c'; else $(CYGPATH_W) '$(srcdir)/elements/videoscale.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) elements/$(DEPDIR)/elements_videoscale_1-videoscale.Tpo elements/$(DEPDIR)/elements_videoscale_1-videoscale.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='elements/videoscale.c' object='elements/elements_videoscale_1-videoscale.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_videoscale_1_CFLAGS) $(CFLAGS) -c -o elements/elements_videoscale_1-videoscale.obj `if test -f 'elements/videoscale.c'; then $(CYGPATH_W) 'elements/videoscale.c'; else $(CYGPATH_W) '$(srcdir)/elements/videoscale.c'; fi`
+
+elements/elements_videoscale_2-videoscale.o: elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_videoscale_2_CFLAGS) $(CFLAGS) -MT elements/elements_videoscale_2-videoscale.o -MD -MP -MF elements/$(DEPDIR)/elements_videoscale_2-videoscale.Tpo -c -o elements/elements_videoscale_2-videoscale.o `test -f 'elements/videoscale.c' || echo '$(srcdir)/'`elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) elements/$(DEPDIR)/elements_videoscale_2-videoscale.Tpo elements/$(DEPDIR)/elements_videoscale_2-videoscale.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='elements/videoscale.c' object='elements/elements_videoscale_2-videoscale.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_videoscale_2_CFLAGS) $(CFLAGS) -c -o elements/elements_videoscale_2-videoscale.o `test -f 'elements/videoscale.c' || echo '$(srcdir)/'`elements/videoscale.c
+
+elements/elements_videoscale_2-videoscale.obj: elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_videoscale_2_CFLAGS) $(CFLAGS) -MT elements/elements_videoscale_2-videoscale.obj -MD -MP -MF elements/$(DEPDIR)/elements_videoscale_2-videoscale.Tpo -c -o elements/elements_videoscale_2-videoscale.obj `if test -f 'elements/videoscale.c'; then $(CYGPATH_W) 'elements/videoscale.c'; else $(CYGPATH_W) '$(srcdir)/elements/videoscale.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) elements/$(DEPDIR)/elements_videoscale_2-videoscale.Tpo elements/$(DEPDIR)/elements_videoscale_2-videoscale.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='elements/videoscale.c' object='elements/elements_videoscale_2-videoscale.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_videoscale_2_CFLAGS) $(CFLAGS) -c -o elements/elements_videoscale_2-videoscale.obj `if test -f 'elements/videoscale.c'; then $(CYGPATH_W) 'elements/videoscale.c'; else $(CYGPATH_W) '$(srcdir)/elements/videoscale.c'; fi`
+
+elements/elements_videoscale_3-videoscale.o: elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_videoscale_3_CFLAGS) $(CFLAGS) -MT elements/elements_videoscale_3-videoscale.o -MD -MP -MF elements/$(DEPDIR)/elements_videoscale_3-videoscale.Tpo -c -o elements/elements_videoscale_3-videoscale.o `test -f 'elements/videoscale.c' || echo '$(srcdir)/'`elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) elements/$(DEPDIR)/elements_videoscale_3-videoscale.Tpo elements/$(DEPDIR)/elements_videoscale_3-videoscale.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='elements/videoscale.c' object='elements/elements_videoscale_3-videoscale.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_videoscale_3_CFLAGS) $(CFLAGS) -c -o elements/elements_videoscale_3-videoscale.o `test -f 'elements/videoscale.c' || echo '$(srcdir)/'`elements/videoscale.c
+
+elements/elements_videoscale_3-videoscale.obj: elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_videoscale_3_CFLAGS) $(CFLAGS) -MT elements/elements_videoscale_3-videoscale.obj -MD -MP -MF elements/$(DEPDIR)/elements_videoscale_3-videoscale.Tpo -c -o elements/elements_videoscale_3-videoscale.obj `if test -f 'elements/videoscale.c'; then $(CYGPATH_W) 'elements/videoscale.c'; else $(CYGPATH_W) '$(srcdir)/elements/videoscale.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) elements/$(DEPDIR)/elements_videoscale_3-videoscale.Tpo elements/$(DEPDIR)/elements_videoscale_3-videoscale.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='elements/videoscale.c' object='elements/elements_videoscale_3-videoscale.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_videoscale_3_CFLAGS) $(CFLAGS) -c -o elements/elements_videoscale_3-videoscale.obj `if test -f 'elements/videoscale.c'; then $(CYGPATH_W) 'elements/videoscale.c'; else $(CYGPATH_W) '$(srcdir)/elements/videoscale.c'; fi`
+
+elements/elements_videoscale_4-videoscale.o: elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_videoscale_4_CFLAGS) $(CFLAGS) -MT elements/elements_videoscale_4-videoscale.o -MD -MP -MF elements/$(DEPDIR)/elements_videoscale_4-videoscale.Tpo -c -o elements/elements_videoscale_4-videoscale.o `test -f 'elements/videoscale.c' || echo '$(srcdir)/'`elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) elements/$(DEPDIR)/elements_videoscale_4-videoscale.Tpo elements/$(DEPDIR)/elements_videoscale_4-videoscale.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='elements/videoscale.c' object='elements/elements_videoscale_4-videoscale.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_videoscale_4_CFLAGS) $(CFLAGS) -c -o elements/elements_videoscale_4-videoscale.o `test -f 'elements/videoscale.c' || echo '$(srcdir)/'`elements/videoscale.c
+
+elements/elements_videoscale_4-videoscale.obj: elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_videoscale_4_CFLAGS) $(CFLAGS) -MT elements/elements_videoscale_4-videoscale.obj -MD -MP -MF elements/$(DEPDIR)/elements_videoscale_4-videoscale.Tpo -c -o elements/elements_videoscale_4-videoscale.obj `if test -f 'elements/videoscale.c'; then $(CYGPATH_W) 'elements/videoscale.c'; else $(CYGPATH_W) '$(srcdir)/elements/videoscale.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) elements/$(DEPDIR)/elements_videoscale_4-videoscale.Tpo elements/$(DEPDIR)/elements_videoscale_4-videoscale.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='elements/videoscale.c' object='elements/elements_videoscale_4-videoscale.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_videoscale_4_CFLAGS) $(CFLAGS) -c -o elements/elements_videoscale_4-videoscale.obj `if test -f 'elements/videoscale.c'; then $(CYGPATH_W) 'elements/videoscale.c'; else $(CYGPATH_W) '$(srcdir)/elements/videoscale.c'; fi`
+
+elements/elements_videoscale_5-videoscale.o: elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_videoscale_5_CFLAGS) $(CFLAGS) -MT elements/elements_videoscale_5-videoscale.o -MD -MP -MF elements/$(DEPDIR)/elements_videoscale_5-videoscale.Tpo -c -o elements/elements_videoscale_5-videoscale.o `test -f 'elements/videoscale.c' || echo '$(srcdir)/'`elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) elements/$(DEPDIR)/elements_videoscale_5-videoscale.Tpo elements/$(DEPDIR)/elements_videoscale_5-videoscale.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='elements/videoscale.c' object='elements/elements_videoscale_5-videoscale.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_videoscale_5_CFLAGS) $(CFLAGS) -c -o elements/elements_videoscale_5-videoscale.o `test -f 'elements/videoscale.c' || echo '$(srcdir)/'`elements/videoscale.c
+
+elements/elements_videoscale_5-videoscale.obj: elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_videoscale_5_CFLAGS) $(CFLAGS) -MT elements/elements_videoscale_5-videoscale.obj -MD -MP -MF elements/$(DEPDIR)/elements_videoscale_5-videoscale.Tpo -c -o elements/elements_videoscale_5-videoscale.obj `if test -f 'elements/videoscale.c'; then $(CYGPATH_W) 'elements/videoscale.c'; else $(CYGPATH_W) '$(srcdir)/elements/videoscale.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) elements/$(DEPDIR)/elements_videoscale_5-videoscale.Tpo elements/$(DEPDIR)/elements_videoscale_5-videoscale.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='elements/videoscale.c' object='elements/elements_videoscale_5-videoscale.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_videoscale_5_CFLAGS) $(CFLAGS) -c -o elements/elements_videoscale_5-videoscale.obj `if test -f 'elements/videoscale.c'; then $(CYGPATH_W) 'elements/videoscale.c'; else $(CYGPATH_W) '$(srcdir)/elements/videoscale.c'; fi`
+
+elements/elements_videoscale_6-videoscale.o: elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_videoscale_6_CFLAGS) $(CFLAGS) -MT elements/elements_videoscale_6-videoscale.o -MD -MP -MF elements/$(DEPDIR)/elements_videoscale_6-videoscale.Tpo -c -o elements/elements_videoscale_6-videoscale.o `test -f 'elements/videoscale.c' || echo '$(srcdir)/'`elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) elements/$(DEPDIR)/elements_videoscale_6-videoscale.Tpo elements/$(DEPDIR)/elements_videoscale_6-videoscale.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='elements/videoscale.c' object='elements/elements_videoscale_6-videoscale.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_videoscale_6_CFLAGS) $(CFLAGS) -c -o elements/elements_videoscale_6-videoscale.o `test -f 'elements/videoscale.c' || echo '$(srcdir)/'`elements/videoscale.c
+
+elements/elements_videoscale_6-videoscale.obj: elements/videoscale.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_videoscale_6_CFLAGS) $(CFLAGS) -MT elements/elements_videoscale_6-videoscale.obj -MD -MP -MF elements/$(DEPDIR)/elements_videoscale_6-videoscale.Tpo -c -o elements/elements_videoscale_6-videoscale.obj `if test -f 'elements/videoscale.c'; then $(CYGPATH_W) 'elements/videoscale.c'; else $(CYGPATH_W) '$(srcdir)/elements/videoscale.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) elements/$(DEPDIR)/elements_videoscale_6-videoscale.Tpo elements/$(DEPDIR)/elements_videoscale_6-videoscale.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='elements/videoscale.c' object='elements/elements_videoscale_6-videoscale.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_videoscale_6_CFLAGS) $(CFLAGS) -c -o elements/elements_videoscale_6-videoscale.obj `if test -f 'elements/videoscale.c'; then $(CYGPATH_W) 'elements/videoscale.c'; else $(CYGPATH_W) '$(srcdir)/elements/videoscale.c'; fi`
+
 elements/elements_volume-volume.o: elements/volume.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(elements_volume_CFLAGS) $(CFLAGS) -MT elements/elements_volume-volume.o -MD -MP -MF elements/$(DEPDIR)/elements_volume-volume.Tpo -c -o elements/elements_volume-volume.o `test -f 'elements/volume.c' || echo '$(srcdir)/'`elements/volume.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) elements/$(DEPDIR)/elements_volume-volume.Tpo elements/$(DEPDIR)/elements_volume-volume.Po
@@ -3082,6 +3346,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) $(libs_videoencoder_CFLAGS) $(CFLAGS) -c -o libs/libs_videoencoder-videoencoder.obj `if test -f 'libs/videoencoder.c'; then $(CYGPATH_W) 'libs/videoencoder.c'; else $(CYGPATH_W) '$(srcdir)/libs/videoencoder.c'; fi`
 
+libs/libs_videotimecode-videotimecode.o: libs/videotimecode.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libs_videotimecode_CFLAGS) $(CFLAGS) -MT libs/libs_videotimecode-videotimecode.o -MD -MP -MF libs/$(DEPDIR)/libs_videotimecode-videotimecode.Tpo -c -o libs/libs_videotimecode-videotimecode.o `test -f 'libs/videotimecode.c' || echo '$(srcdir)/'`libs/videotimecode.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) libs/$(DEPDIR)/libs_videotimecode-videotimecode.Tpo libs/$(DEPDIR)/libs_videotimecode-videotimecode.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='libs/videotimecode.c' object='libs/libs_videotimecode-videotimecode.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) $(libs_videotimecode_CFLAGS) $(CFLAGS) -c -o libs/libs_videotimecode-videotimecode.o `test -f 'libs/videotimecode.c' || echo '$(srcdir)/'`libs/videotimecode.c
+
+libs/libs_videotimecode-videotimecode.obj: libs/videotimecode.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libs_videotimecode_CFLAGS) $(CFLAGS) -MT libs/libs_videotimecode-videotimecode.obj -MD -MP -MF libs/$(DEPDIR)/libs_videotimecode-videotimecode.Tpo -c -o libs/libs_videotimecode-videotimecode.obj `if test -f 'libs/videotimecode.c'; then $(CYGPATH_W) 'libs/videotimecode.c'; else $(CYGPATH_W) '$(srcdir)/libs/videotimecode.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) libs/$(DEPDIR)/libs_videotimecode-videotimecode.Tpo libs/$(DEPDIR)/libs_videotimecode-videotimecode.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='libs/videotimecode.c' object='libs/libs_videotimecode-videotimecode.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) $(libs_videotimecode_CFLAGS) $(CFLAGS) -c -o libs/libs_videotimecode-videotimecode.obj `if test -f 'libs/videotimecode.c'; then $(CYGPATH_W) 'libs/videotimecode.c'; else $(CYGPATH_W) '$(srcdir)/libs/videotimecode.c'; fi`
+
 libs/libs_xmpwriter-xmpwriter.o: libs/xmpwriter.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libs_xmpwriter_CFLAGS) $(CFLAGS) -MT libs/libs_xmpwriter-xmpwriter.o -MD -MP -MF libs/$(DEPDIR)/libs_xmpwriter-xmpwriter.Tpo -c -o libs/libs_xmpwriter-xmpwriter.o `test -f 'libs/xmpwriter.c' || echo '$(srcdir)/'`libs/xmpwriter.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) libs/$(DEPDIR)/libs_xmpwriter-xmpwriter.Tpo libs/$(DEPDIR)/libs_xmpwriter-xmpwriter.Po
@@ -3668,6 +3946,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)
+libs/videotimecode.log: libs/videotimecode$(EXEEXT)
+	@p='libs/videotimecode$(EXEEXT)'; \
+	b='libs/videotimecode'; \
+	$(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)
 libs/xmpwriter.log: libs/xmpwriter$(EXEEXT)
 	@p='libs/xmpwriter$(EXEEXT)'; \
 	b='libs/xmpwriter'; \
@@ -3815,6 +4100,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/playsink.log: elements/playsink$(EXEEXT)
+	@p='elements/playsink$(EXEEXT)'; \
+	b='elements/playsink'; \
+	$(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/subparse.log: elements/subparse$(EXEEXT)
 	@p='elements/subparse$(EXEEXT)'; \
 	b='elements/subparse'; \
@@ -3878,6 +4170,48 @@
 	--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/videoscale-1.log: elements/videoscale-1$(EXEEXT)
+	@p='elements/videoscale-1$(EXEEXT)'; \
+	b='elements/videoscale-1'; \
+	$(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/videoscale-2.log: elements/videoscale-2$(EXEEXT)
+	@p='elements/videoscale-2$(EXEEXT)'; \
+	b='elements/videoscale-2'; \
+	$(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/videoscale-3.log: elements/videoscale-3$(EXEEXT)
+	@p='elements/videoscale-3$(EXEEXT)'; \
+	b='elements/videoscale-3'; \
+	$(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/videoscale-4.log: elements/videoscale-4$(EXEEXT)
+	@p='elements/videoscale-4$(EXEEXT)'; \
+	b='elements/videoscale-4'; \
+	$(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/videoscale-5.log: elements/videoscale-5$(EXEEXT)
+	@p='elements/videoscale-5$(EXEEXT)'; \
+	b='elements/videoscale-5'; \
+	$(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/videoscale-6.log: elements/videoscale-6$(EXEEXT)
+	@p='elements/videoscale-6$(EXEEXT)'; \
+	b='elements/videoscale-6'; \
+	$(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/videotestsrc.log: elements/videotestsrc$(EXEEXT)
 	@p='elements/videotestsrc$(EXEEXT)'; \
 	b='elements/videotestsrc'; \
diff --git a/tests/check/elements/adder.c b/tests/check/elements/adder.c
index 3308a8e..3a9e3b6 100644
--- a/tests/check/elements/adder.c
+++ b/tests/check/elements/adder.c
@@ -1198,6 +1198,7 @@
 
 GST_END_TEST;
 
+#if 0
 GST_START_TEST (test_flush_start_flush_stop)
 {
   GstPadTemplate *sink_template;
@@ -1255,7 +1256,7 @@
 }
 
 GST_END_TEST;
-
+#endif
 
 static Suite *
 adder_suite (void)
@@ -1276,7 +1277,12 @@
   tcase_add_test (tc_chain, test_duration_is_max);
   tcase_add_test (tc_chain, test_duration_unknown_overrides);
   tcase_add_test (tc_chain, test_loop);
+  /* This test is racy and occasionally fails in interesting ways
+   * https://bugzilla.gnome.org/show_bug.cgi?id=708891
+   * It's unlikely that it will ever be fixed for adder, works with audiomixer */
+#if 0
   tcase_add_test (tc_chain, test_flush_start_flush_stop);
+#endif
 
   /* Use a longer timeout */
 #ifdef HAVE_VALGRIND
diff --git a/tests/check/elements/appsink.c b/tests/check/elements/appsink.c
index 1c9feed..aabeb00 100644
--- a/tests/check/elements/appsink.c
+++ b/tests/check/elements/appsink.c
@@ -348,6 +348,68 @@
 
 GST_END_TEST;
 
+GST_START_TEST (test_pull_with_timeout)
+{
+  GstElement *sink;
+  GstBuffer *buffer;
+  GstSample *s;
+  guint64 t1, tdiff;
+
+  sink = setup_appsink ();
+
+  ASSERT_SET_STATE (sink, GST_STATE_PLAYING, GST_STATE_CHANGE_ASYNC);
+
+  /* Check that it actually waits for a bit */
+  t1 = gst_util_get_timestamp ();
+  s = gst_app_sink_try_pull_preroll (GST_APP_SINK (sink), GST_SECOND / 20);
+  tdiff = gst_util_get_timestamp () - t1;
+  GST_LOG ("tdiff: %" GST_TIME_FORMAT, GST_TIME_ARGS (tdiff));
+  fail_unless (s == NULL);
+  fail_unless (tdiff > (GST_SECOND / (20 * 2)));
+
+  buffer = gst_buffer_new_and_alloc (4);
+  fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
+
+  s = gst_app_sink_try_pull_preroll (GST_APP_SINK (sink), GST_SECOND / 20);
+  fail_unless (s != NULL);
+  gst_sample_unref (s);
+
+  s = gst_app_sink_try_pull_sample (GST_APP_SINK (sink), 500 * GST_SECOND);
+  fail_unless (s != NULL);
+  gst_sample_unref (s);
+
+  /* No waiting */
+  s = gst_app_sink_try_pull_sample (GST_APP_SINK (sink), 0);
+  fail_unless (s == NULL);
+
+  /* Check that it actually waits for a bit */
+  t1 = gst_util_get_timestamp ();
+  s = gst_app_sink_try_pull_sample (GST_APP_SINK (sink), GST_SECOND / 20);
+  tdiff = gst_util_get_timestamp () - t1;
+  GST_LOG ("tdiff: %" GST_TIME_FORMAT, GST_TIME_ARGS (tdiff));
+  fail_unless (s == NULL);
+  fail_unless (tdiff > (GST_SECOND / (20 * 2)));
+
+  /* No waiting, with buffer pending */
+  buffer = gst_buffer_new_and_alloc (5);
+  fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
+  s = gst_app_sink_try_pull_sample (GST_APP_SINK (sink), 0);
+  fail_unless (s != NULL);
+  gst_sample_unref (s);
+
+  /* With timeout, with buffer pending */
+  buffer = gst_buffer_new_and_alloc (6);
+  fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK);
+  s = gst_app_sink_try_pull_sample (GST_APP_SINK (sink), GST_SECOND / 20);
+  fail_unless (s != NULL);
+  gst_sample_unref (s);
+
+  ASSERT_SET_STATE (sink, GST_STATE_NULL, GST_STATE_CHANGE_SUCCESS);
+  cleanup_appsink (sink);
+}
+
+GST_END_TEST;
+
 static Suite *
 appsink_suite (void)
 {
@@ -362,6 +424,7 @@
   tcase_add_test (tc_chain, test_buffer_list_fallback);
   tcase_add_test (tc_chain, test_buffer_list_fallback_signal);
   tcase_add_test (tc_chain, test_segment);
+  tcase_add_test (tc_chain, test_pull_with_timeout);
 
   return s;
 }
diff --git a/tests/check/elements/appsrc.c b/tests/check/elements/appsrc.c
index f7f1a13..56fe0f7 100644
--- a/tests/check/elements/appsrc.c
+++ b/tests/check/elements/appsrc.c
@@ -60,6 +60,7 @@
 {
   GST_DEBUG ("cleanup_appsrc");
 
+  gst_check_drop_buffers ();
   gst_check_teardown_sink_pad (appsrc);
   gst_check_teardown_element (appsrc);
 }
@@ -147,14 +148,14 @@
 }
 
 /*
- * appsink => appsrc pipelines executed 100 times: 
+ * appsink => appsrc pipelines executed 100 times:
  * - appsink pipeline has sync=false
  * - appsrc pipeline has sync=true
  * - appsrc has block=true
  * after 1 second an error message is posted on appsink pipeline bus
  * when the error is received the appsrc pipeline is set to NULL
  * and then the appsink pipeline is
- * set to NULL too, this must not deadlock 
+ * set to NULL too, this must not deadlock
  */
 
 GST_START_TEST (test_appsrc_block_deadlock)
diff --git a/tests/check/elements/audiorate.c b/tests/check/elements/audiorate.c
index f7bfc58..7664cb0 100644
--- a/tests/check/elements/audiorate.c
+++ b/tests/check/elements/audiorate.c
@@ -58,10 +58,8 @@
 {
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_template));
+  gst_element_class_add_static_pad_template (element_class, &src_template);
+  gst_element_class_add_static_pad_template (element_class, &sink_template);
 }
 
 static GstFlowReturn
@@ -444,6 +442,7 @@
   gst_element_set_state (audiorate, GST_STATE_NULL);
   gst_caps_unref (caps);
 
+  gst_check_drop_buffers ();
   gst_check_teardown_sink_pad (audiorate);
   gst_check_teardown_src_pad (audiorate);
 
diff --git a/tests/check/elements/decodebin.c b/tests/check/elements/decodebin.c
index fba0b1c..457cb36 100644
--- a/tests/check/elements/decodebin.c
+++ b/tests/check/elements/decodebin.c
@@ -230,10 +230,8 @@
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
   GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_template));
+  gst_element_class_add_static_pad_template (element_class, &sink_template);
+  gst_element_class_add_static_pad_template (element_class, &src_template);
 
   gst_element_class_set_metadata (element_class, "MPEG1 Audio Parser",
       "Codec/Parser/Audio", "Pretends to parse mpeg1 audio stream",
@@ -383,10 +381,8 @@
           "stream-format=(string) { avc, byte-stream }"));
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_templ));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
+  gst_element_class_add_static_pad_template (element_class, &sink_templ);
+  gst_element_class_add_static_pad_template (element_class, &src_templ);
   gst_element_class_set_metadata (element_class,
       "FakeH264Parser", "Codec/Parser/Converter/Video", "yep", "me");
 }
@@ -486,10 +482,8 @@
       GST_STATIC_CAPS ("video/x-raw"));
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_templ));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
+  gst_element_class_add_static_pad_template (element_class, &sink_templ);
+  gst_element_class_add_static_pad_template (element_class, &src_templ);
   gst_element_class_set_metadata (element_class,
       "FakeH264Decoder", "Codec/Decoder/Video", "yep", "me");
 }
diff --git a/tests/check/elements/opus.c b/tests/check/elements/opus.c
index 5b04bb2..3678ed1 100644
--- a/tests/check/elements/opus.c
+++ b/tests/check/elements/opus.c
@@ -23,6 +23,7 @@
 #include <unistd.h>
 
 #include <gst/check/gstcheck.h>
+#include <gst/check/gstharness.h>
 
 #if G_BYTE_ORDER == G_BIG_ENDIAN
 #define AFORMAT "S16BE"
@@ -420,6 +421,68 @@
 
 GST_END_TEST;
 
+GST_START_TEST (test_opus_decode_plc_timestamps_with_fec)
+{
+  GstBuffer *buf;
+  GstHarness *h =
+      gst_harness_new_parse ("opusdec use-inband-fec=TRUE plc=TRUE");
+  GstClockTime dur0 = GST_MSECOND * 35 / 10;    /* because of lookahead */
+  GstClockTime dur = GST_MSECOND * 10;
+
+  gst_harness_add_src_parse (h,
+      "audiotestsrc samplesperbuffer=480 is-live=TRUE ! "
+      "opusenc frame-size=10 inband-fec=TRUE", TRUE);
+
+  /* Push first buffer from encoder to decoder. It will not be decoded yet
+   * because of the delay introduced by FEC */
+  gst_harness_src_crank_and_push_many (h, 1, 1);
+  fail_unless_equals_int (0, gst_harness_buffers_received (h));
+
+  /* Drop second buffer from encoder and send a GAP event to decoder
+   * instead with 2x duration */
+  gst_harness_src_crank_and_push_many (h, 1, 0);
+  fail_unless (buf = gst_harness_pull (h->src_harness));
+  fail_unless (gst_harness_push_event (h,
+          gst_event_new_gap (GST_BUFFER_PTS (buf),
+              GST_BUFFER_DURATION (buf) * 2)));
+  gst_buffer_unref (buf);
+
+  /* Extract first buffer from decoder and verify timstamps */
+  fail_unless (buf = gst_harness_pull (h));
+  fail_unless_equals_int64 (0, GST_BUFFER_PTS (buf));
+  fail_unless_equals_int64 (dur0, GST_BUFFER_DURATION (buf));
+  fail_unless (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
+  gst_buffer_unref (buf);
+
+  /* Third buffer is pushed from encoder to decoder with DISCONT set */
+  gst_harness_src_crank_and_push_many (h, 1, 0);
+  fail_unless (buf = gst_harness_pull (h->src_harness));
+  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
+  gst_harness_push (h, buf);
+
+  /* Extract second (concealed) buffer from decoder and verify timestamp
+     and the 2x duration */
+  fail_unless (buf = gst_harness_pull (h));
+  fail_unless_equals_int64 (dur0, GST_BUFFER_PTS (buf));
+  fail_unless_equals_int64 (dur * 2, GST_BUFFER_DURATION (buf));
+  fail_if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
+  gst_buffer_unref (buf);
+
+  /* Push fourth buffer from encoder to decoder as normal */
+  gst_harness_src_crank_and_push_many (h, 1, 1);
+
+  /* Extract third buffer from decoder and verify timestamps */
+  fail_unless (buf = gst_harness_pull (h));
+  fail_unless_equals_int64 (dur0 + 1 * dur, GST_BUFFER_PTS (buf));
+  fail_unless_equals_int64 (dur, GST_BUFFER_DURATION (buf));
+  fail_if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
+  gst_buffer_unref (buf);
+
+  gst_harness_teardown (h);
+}
+
+GST_END_TEST;
+
 static Suite *
 opus_suite (void)
 {
@@ -433,6 +496,7 @@
   tcase_add_test (tc_chain, test_opus_encode_samples);
   tcase_add_test (tc_chain, test_opus_encode_properties);
   tcase_add_test (tc_chain, test_opusdec_getcaps);
+  tcase_add_test (tc_chain, test_opus_decode_plc_timestamps_with_fec);
 
   return s;
 }
diff --git a/tests/check/elements/playbin-complex.c b/tests/check/elements/playbin-complex.c
index 377bd83..ebe5bbd 100644
--- a/tests/check/elements/playbin-complex.c
+++ b/tests/check/elements/playbin-complex.c
@@ -170,8 +170,7 @@
       GST_PAD_SRC, GST_PAD_ALWAYS,
       GST_STATIC_CAPS_ANY);
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
+  gst_element_class_add_static_pad_template (element_class, &src_templ);
   gst_element_class_set_metadata (element_class,
       "CapsSource", "Source/Generic", "yep", "me");
 
@@ -321,8 +320,7 @@
       g_param_spec_boolean ("mute", "Mute",
           "Mute", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_templ));
+  gst_element_class_add_static_pad_template (element_class, &sink_templ);
   gst_element_class_set_metadata (element_class,
       "AudioCodecSink", "Sink/Audio", "yep", "me");
 
@@ -372,8 +370,7 @@
       );
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_templ));
+  gst_element_class_add_static_pad_template (element_class, &sink_templ);
   gst_element_class_set_metadata (element_class,
       "VideoCodecSink", "Sink/Video", "yep", "me");
 
@@ -441,10 +438,8 @@
 
   gobject_class->finalize = gst_codec_demuxer_finalize;
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&cd_sink_templ));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&cd_src_templ));
+  gst_element_class_add_static_pad_template (element_class, &cd_sink_templ);
+  gst_element_class_add_static_pad_template (element_class, &cd_src_templ);
   gst_element_class_set_metadata (element_class,
       "CodecDemuxer", "Codec/Demuxer", "yep", "me");
 }
@@ -647,8 +642,7 @@
           GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL))
       );
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_templ));
+  gst_element_class_add_static_pad_template (element_class, &sink_templ);
 
   gst_element_class_set_static_metadata (element_class,
       "Fake Video Sink1", "Sink/Video",
@@ -669,8 +663,7 @@
       GST_PAD_SINK, GST_PAD_ALWAYS,
       GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL)));
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_templ));
+  gst_element_class_add_static_pad_template (element_class, &sink_templ);
 
   gst_element_class_set_static_metadata (element_class,
       "Fake Video Sink2", "Sink/Video",
@@ -710,10 +703,8 @@
               GST_VIDEO_FORMATS_ALL) ";"
           GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL)));
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_templ));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
+  gst_element_class_add_static_pad_template (element_class, &sink_templ);
+  gst_element_class_add_static_pad_template (element_class, &src_templ);
   gst_element_class_set_static_metadata (element_class,
       "Fake theora video decoder1", "Codec/Decoder/Video",
       "decode theora stream",
@@ -741,10 +732,8 @@
       GST_PAD_SRC, GST_PAD_ALWAYS,
       GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_VIDEO_FORMATS_ALL)));
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_templ));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
+  gst_element_class_add_static_pad_template (element_class, &sink_templ);
+  gst_element_class_add_static_pad_template (element_class, &src_templ);
   gst_element_class_set_static_metadata (element_class,
       "Fake theora video decoder2", "Codec/Decoder/Video",
       "decode theora stream",
diff --git a/tests/check/elements/playbin.c b/tests/check/elements/playbin.c
index cdc737e..170ddce 100644
--- a/tests/check/elements/playbin.c
+++ b/tests/check/elements/playbin.c
@@ -523,7 +523,7 @@
   GstElement *src = NULL;
 
   if (!gst_registry_check_feature_version (gst_registry_get (), "redvideosrc",
-          0, 10, 0)) {
+          GST_VERSION_MAJOR, GST_VERSION_MINOR, 0)) {
     fail_unless (gst_element_register (NULL, "redvideosrc", GST_RANK_PRIMARY,
             gst_red_video_src_get_type ()));
   }
@@ -553,6 +553,59 @@
 
 GST_END_TEST;
 
+static void
+element_setup (GstElement * playbin, GstElement * element, GQueue * elts)
+{
+  GstElementFactory *f = gst_element_get_factory (element);
+
+  g_queue_push_tail (elts, f ? GST_OBJECT_NAME (f) : GST_OBJECT_NAME (element));
+}
+
+GST_START_TEST (test_element_setup)
+{
+  GstElement *playbin, *videosink;
+  GQueue elts = G_QUEUE_INIT;
+
+  if (!gst_registry_check_feature_version (gst_registry_get (), "redvideosrc",
+          GST_VERSION_MAJOR, GST_VERSION_MINOR, 0)) {
+    fail_unless (gst_element_register (NULL, "redvideosrc", GST_RANK_PRIMARY,
+            gst_red_video_src_get_type ()));
+  }
+
+  playbin = gst_element_factory_make ("playbin", NULL);
+  g_object_set (playbin, "uri", "redvideo://", NULL);
+
+  videosink = gst_element_factory_make ("fakesink", "myvideosink");
+  g_object_set (playbin, "video-sink", videosink, NULL);
+
+  g_signal_connect (playbin, "element-setup", G_CALLBACK (element_setup),
+      &elts);
+
+  fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_PAUSED),
+      GST_STATE_CHANGE_ASYNC);
+  fail_unless_equals_int (gst_element_get_state (playbin, NULL, NULL,
+          GST_CLOCK_TIME_NONE), GST_STATE_CHANGE_SUCCESS);
+
+#define seen_element(e) g_queue_find_custom(&elts, e, (GCompareFunc) strcmp)
+
+  fail_unless (seen_element ("redvideosrc"));
+  fail_unless (seen_element ("uridecodebin"));
+  fail_unless (seen_element ("videoconvert"));
+  fail_unless (seen_element ("videoscale"));
+  fail_unless (seen_element ("fakesink"));
+
+#undef seen_element
+
+  g_queue_clear (&elts);
+
+  fail_unless_equals_int (gst_element_set_state (playbin, GST_STATE_NULL),
+      GST_STATE_CHANGE_SUCCESS);
+
+  gst_object_unref (playbin);
+}
+
+GST_END_TEST;
+
 /*** redvideo:// source ***/
 
 static GstURIType
@@ -649,8 +702,7 @@
       );
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
+  gst_element_class_add_static_pad_template (element_class, &src_templ);
   gst_element_class_set_metadata (element_class,
       "Red Video Src", "Source/Video", "yep", "me");
 
@@ -751,8 +803,7 @@
       );
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
+  gst_element_class_add_static_pad_template (element_class, &src_templ);
   gst_element_class_set_metadata (element_class,
       "Codec Src", "Source/Video", "yep", "me");
 
@@ -851,6 +902,7 @@
   tcase_add_test (tc_chain, test_missing_primary_decoder);
   tcase_add_test (tc_chain, test_refcount);
   tcase_add_test (tc_chain, test_source_setup);
+  tcase_add_test (tc_chain, test_element_setup);
 
 #if 0
   {
diff --git a/tests/check/elements/playsink.c b/tests/check/elements/playsink.c
new file mode 100644
index 0000000..c0e629c
--- /dev/null
+++ b/tests/check/elements/playsink.c
@@ -0,0 +1,88 @@
+/* GStreamer unit tests for playsink
+ * 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_volume_in_sink)
+{
+  GstElement *pipe, *audiosink, *playsink, *fakesink, *volume, *src;
+  GstPad *sinkpad;
+  GstMessage *msg;
+
+  pipe = gst_pipeline_new (NULL);
+  playsink = gst_element_factory_make ("playsink", NULL);
+
+  audiosink = gst_bin_new ("audiosink");
+  volume = gst_element_factory_make ("volume", NULL);
+  fakesink = gst_element_factory_make ("fakesink", NULL);
+  gst_bin_add_many (GST_BIN (audiosink), volume, fakesink, NULL);
+  gst_element_link_many (volume, fakesink, NULL);
+  sinkpad = gst_element_get_static_pad (volume, "sink");
+  gst_element_add_pad (audiosink, gst_ghost_pad_new ("sink", sinkpad));
+  gst_object_unref (sinkpad);
+
+  g_object_set (playsink, "audio-sink", audiosink, NULL);
+
+  src = gst_element_factory_make ("audiotestsrc", NULL);
+  g_object_set (src, "num-buffers", 5, NULL);
+
+
+  gst_bin_add (GST_BIN (pipe), src);
+  gst_bin_add (GST_BIN (pipe), playsink);
+
+  if (!gst_element_link (src, playsink))
+    g_error ("oops");
+
+  fail_unless_equals_int (gst_element_set_state (pipe, GST_STATE_PLAYING),
+      GST_STATE_CHANGE_ASYNC);
+
+  /* wait for eos */
+  msg = gst_bus_timed_pop_filtered (GST_ELEMENT_BUS (pipe), GST_CLOCK_TIME_NONE,
+      GST_MESSAGE_EOS | GST_MESSAGE_ERROR);
+  fail_if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR);
+  gst_message_unref (msg);
+
+  fail_unless_equals_int (gst_element_set_state (pipe, GST_STATE_NULL),
+      GST_STATE_CHANGE_SUCCESS);
+
+  gst_object_unref (pipe);
+}
+
+GST_END_TEST;
+
+
+static Suite *
+playsink_suite (void)
+{
+  Suite *s = suite_create ("playsink");
+  TCase *tc_chain = tcase_create ("general");
+
+  suite_add_tcase (s, tc_chain);
+
+  tcase_add_test (tc_chain, test_volume_in_sink);
+
+  return s;
+}
+
+GST_CHECK_MAIN (playsink);
diff --git a/tests/check/elements/subparse.c b/tests/check/elements/subparse.c
index 306b7f8..8c827f0 100644
--- a/tests/check/elements/subparse.c
+++ b/tests/check/elements/subparse.c
@@ -160,6 +160,25 @@
       3090 * GST_MSECOND, 4000 * GST_MSECOND, "Three"}
 };
 
+/* Some WebVTT chunks, this format is similar to SRT but should be
+ * parsed differently nonetheless, the WebVTT tags should be stripped
+ * off. */
+static SubParseInputChunk srt_input4[] = {
+  {
+        "1\n00:00:01,000 --> 00:00:02,000\n<v>some text\n\n",
+      1 * GST_SECOND, 2 * GST_SECOND, "some text"}
+  ,
+  {
+        "1\n00:00:01,000 --> 00:00:02,000\n<b.loud>some text\n\n",
+      1 * GST_SECOND, 2 * GST_SECOND, "<b>some text</b>"}
+  ,
+  {
+        "1\n00:00:01,000 --> 00:00:02,000\n<ruby>base text<rt>annotation</rt></ruby>\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND,
+      "base textannotation"}
+  ,
+};
+
 static void
 setup_subparse (void)
 {
@@ -260,6 +279,71 @@
   teardown_subparse ();
 }
 
+static void
+test_vtt_do_test (SubParseInputChunk * input, guint start_idx, guint num)
+{
+  guint n;
+
+  GST_LOG ("vtt test: start_idx = %u, num = %u", start_idx, num);
+
+  setup_subparse ();
+
+  for (n = start_idx; n < start_idx + num; ++n) {
+    GstBuffer *buf;
+    gchar *data = g_strconcat ("WEBVTT FILE\n", input[n].in, NULL);
+    buf = buffer_from_static_string (data);
+    fail_unless_equals_int (gst_pad_push (mysrcpad, buf), GST_FLOW_OK);
+    g_free (data);
+  }
+
+  gst_pad_push_event (mysrcpad, gst_event_new_eos ());
+
+  fail_unless_equals_int (g_list_length (buffers), num);
+
+  for (n = start_idx; n < start_idx + num; ++n) {
+    const GstStructure *buffer_caps_struct;
+    GstMapInfo map;
+    GstBuffer *buf;
+    GstCaps *outcaps;
+    gchar *out;
+    guint out_size;
+
+    buf = g_list_nth_data (buffers, n - start_idx);
+    fail_unless (buf != NULL);
+    fail_unless (GST_BUFFER_TIMESTAMP_IS_VALID (buf), NULL);
+    fail_unless (GST_BUFFER_DURATION_IS_VALID (buf), NULL);
+    fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buf), input[n].from_ts);
+    fail_unless_equals_uint64 (GST_BUFFER_DURATION (buf),
+        input[n].to_ts - input[n].from_ts);
+    fail_unless (gst_buffer_map (buf, &map, GST_MAP_READ));
+    out = (gchar *) map.data;
+
+    out_size = gst_buffer_get_size (buf);
+    /* shouldn't have trailing newline characters */
+    fail_if (out_size > 0 && out[out_size - 1] == '\n');
+    /* shouldn't include NUL-terminator in data size */
+    fail_if (out_size > 0 && out[out_size - 1] == '\0');
+    /* but should still have a  NUL-terminator behind the declared data */
+    fail_unless_equals_int (out[out_size], '\0');
+    /* make sure out string matches expected string */
+    fail_unless_equals_string (out, input[n].out);
+
+    gst_buffer_unmap (buf, &map);
+
+    /* check caps */
+    outcaps = gst_pad_get_current_caps (mysinkpad);
+    fail_unless (outcaps != NULL);
+    buffer_caps_struct = gst_caps_get_structure (outcaps, 0);
+    fail_unless_equals_string (gst_structure_get_name (buffer_caps_struct),
+        "text/x-raw");
+    fail_unless_equals_string (gst_structure_get_string (buffer_caps_struct,
+            "format"), "pango-markup");
+    gst_caps_unref (outcaps);
+  }
+
+  teardown_subparse ();
+}
+
 GST_START_TEST (test_srt)
 {
   test_srt_do_test (srt_input, 0, G_N_ELEMENTS (srt_input));
@@ -284,6 +368,96 @@
 
   /* try with fewer than three post-comma digits, and some extra spaces */
   test_srt_do_test (srt_input3, 0, G_N_ELEMENTS (srt_input3));
+
+  /* try with some WebVTT chunks */
+  test_srt_do_test (srt_input4, 0, G_N_ELEMENTS (srt_input4));
+}
+
+GST_END_TEST;
+
+
+GST_START_TEST (test_webvtt)
+{
+  SubParseInputChunk webvtt_input[] = {
+    {
+          "1\n00:00:01.000 --> 00:00:02.000 D:vertical T:50%\nOne\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND, "One"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:02.000 D:vertical   T:50%\nOne\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND, "One"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:02.000 D:vertical\tT:50%\nOne\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND, "One"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:02.000 D:vertical-lr\nOne\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND, "One"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:02.000 L:-123\nOne\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND, "One"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:02.000 L:123\nOne\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND, "One"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:02.000 L:12%\nOne\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND, "One"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:02.000 L:12% S:35% A:start\nOne\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND, "One"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:02.000 A:middle\nOne\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND, "One"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:02.000 A:end\nOne\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND, "One"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:02.000\nOne & Two\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND, "One &amp; Two"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:02.000\nOne < Two\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND, "One &lt; Two"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:02.000\n<v Spoke>Live long and prosper\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND, "<v Spoke>Live long and prosper</v>"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:02.000\n<v The Joker>HAHAHA\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND, "<v The Joker>HAHAHA</v>"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:02.000\n<c.someclass>some text\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND, "<c.someclass>some text</c>"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:02.000\n<b.loud>some text\n\n",
+        1 * GST_SECOND, 2 * GST_SECOND, "<b.loud>some text</b>"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:02.000\n<ruby>base text<rt>annotation</rt></ruby>\n\n",
+          1 * GST_SECOND, 2 * GST_SECOND,
+        "<ruby>base text<rt>annotation</rt></ruby>"}
+    ,
+    {
+          "1\n00:00:01.000 --> 00:00:03.000\nOne... <00:00:00,200>Two... <00:00:00,500>Three...\n\n",
+          1 * GST_SECOND, 3 * GST_SECOND,
+        "One... &lt;00:00:00,200&gt;Two... &lt;00:00:00,500&gt;Three..."}
+    ,
+    {"1\n00:00:02.000 --> 00:00:03.000\nHello\nWorld\n\n",
+        2 * GST_SECOND, 3 * GST_SECOND, "Hello\nWorld"}
+    ,
+  };
+  test_vtt_do_test (webvtt_input, 0, G_N_ELEMENTS (webvtt_input));
 }
 
 GST_END_TEST;
@@ -836,6 +1010,7 @@
   suite_add_tcase (s, tc_chain);
 
   tcase_add_test (tc_chain, test_srt);
+  tcase_add_test (tc_chain, test_webvtt);
   tcase_add_test (tc_chain, test_tmplayer_multiline);
   tcase_add_test (tc_chain, test_tmplayer_multiline_with_bogus_lines);
   tcase_add_test (tc_chain, test_tmplayer_style1);
diff --git a/tests/check/elements/videoscale.c b/tests/check/elements/videoscale.c
index 369df32..c158061 100644
--- a/tests/check/elements/videoscale.c
+++ b/tests/check/elements/videoscale.c
@@ -29,6 +29,8 @@
 /* kids, don't do this at home, skipping checks is *BAD* */
 #define LINK_CHECK_FLAGS GST_PAD_LINK_CHECK_NOTHING
 
+#ifndef VSCALE_TEST_GROUP
+
 static guint
 get_num_formats (void)
 {
@@ -157,6 +159,8 @@
 
 GST_END_TEST;
 
+#endif /* !defined(VSCALE_TEST_GROUP) */
+
 static GstCaps **
 videoscale_get_allowed_caps_for_method (int method)
 {
@@ -307,6 +311,8 @@
   gst_object_unref (bus);
 }
 
+#ifndef VSCALE_TEST_GROUP
+
 static void
 on_sink_handoff_passthrough (GstElement * element, GstBuffer * buffer,
     GstPad * pad, gpointer user_data)
@@ -409,6 +415,7 @@
 }
 
 GST_END_TEST;
+#endif /* !defined(VSCALE_TEST_GROUP) */
 
 #define CREATE_TEST(name,method,src_width,src_height,dest_width,dest_height) \
 GST_START_TEST (name) \
@@ -434,6 +441,7 @@
 \
 GST_END_TEST;
 
+#if defined(VSCALE_TEST_GROUP) && VSCALE_TEST_GROUP == 1
 CREATE_TEST (test_downscale_640x480_320x240_method_0, 0, 640, 480, 320, 240);
 CREATE_TEST (test_downscale_640x480_320x240_method_1, 1, 640, 480, 320, 240);
 CREATE_TEST (test_downscale_640x480_320x240_method_2, 2, 640, 480, 320, 240);
@@ -442,6 +450,7 @@
 CREATE_TEST (test_upscale_320x240_640x480_method_1, 1, 320, 240, 640, 480);
 CREATE_TEST (test_upscale_320x240_640x480_method_2, 2, 320, 240, 640, 480);
 CREATE_TEST (test_upscale_320x240_640x480_method_3, 3, 320, 240, 640, 480);
+#elif defined(VSCALE_TEST_GROUP) && VSCALE_TEST_GROUP == 2
 CREATE_TEST (test_downscale_640x480_1x1_method_0, 0, 640, 480, 1, 1);
 CREATE_TEST (test_downscale_640x480_1x1_method_1, 1, 640, 480, 1, 1);
 CREATE_TEST (test_downscale_640x480_1x1_method_2, 2, 640, 480, 1, 1);
@@ -450,6 +459,7 @@
 CREATE_TEST (test_upscale_1x1_640x480_method_1, 1, 1, 1, 640, 480);
 CREATE_TEST (test_upscale_1x1_640x480_method_2, 2, 1, 1, 640, 480);
 CREATE_TEST (test_upscale_1x1_640x480_method_3, 3, 1, 1, 640, 480);
+#elif defined(VSCALE_TEST_GROUP) && VSCALE_TEST_GROUP == 3
 CREATE_TEST (test_downscale_641x481_111x30_method_0, 0, 641, 481, 111, 30);
 CREATE_TEST (test_downscale_641x481_111x30_method_1, 1, 641, 481, 111, 30);
 CREATE_TEST (test_downscale_641x481_111x30_method_2, 2, 641, 481, 111, 30);
@@ -458,6 +468,7 @@
 CREATE_TEST (test_upscale_111x30_641x481_method_1, 1, 111, 30, 641, 481);
 CREATE_TEST (test_upscale_111x30_641x481_method_2, 2, 111, 30, 641, 481);
 CREATE_TEST (test_upscale_111x30_641x481_method_3, 2, 111, 30, 641, 481);
+#elif defined(VSCALE_TEST_GROUP) && VSCALE_TEST_GROUP == 4
 CREATE_TEST (test_downscale_641x481_30x111_method_0, 0, 641, 481, 30, 111);
 CREATE_TEST (test_downscale_641x481_30x111_method_1, 1, 641, 481, 30, 111);
 CREATE_TEST (test_downscale_641x481_30x111_method_2, 2, 641, 481, 30, 111);
@@ -466,6 +477,7 @@
 CREATE_TEST (test_upscale_30x111_641x481_method_1, 1, 30, 111, 641, 481);
 CREATE_TEST (test_upscale_30x111_641x481_method_2, 2, 30, 111, 641, 481);
 CREATE_TEST (test_upscale_30x111_641x481_method_3, 3, 30, 111, 641, 481);
+#elif defined(VSCALE_TEST_GROUP) && VSCALE_TEST_GROUP == 5
 CREATE_TEST (test_downscale_640x480_320x1_method_0, 0, 640, 480, 320, 1);
 CREATE_TEST (test_downscale_640x480_320x1_method_1, 1, 640, 480, 320, 1);
 CREATE_TEST (test_downscale_640x480_320x1_method_2, 2, 640, 480, 320, 1);
@@ -474,6 +486,7 @@
 CREATE_TEST (test_upscale_320x1_640x480_method_1, 1, 320, 1, 640, 480);
 CREATE_TEST (test_upscale_320x1_640x480_method_2, 2, 320, 1, 640, 480);
 CREATE_TEST (test_upscale_320x1_640x480_method_3, 3, 320, 1, 640, 480);
+#elif defined(VSCALE_TEST_GROUP) && VSCALE_TEST_GROUP == 6
 CREATE_TEST (test_downscale_640x480_1x240_method_0, 0, 640, 480, 1, 240);
 CREATE_TEST (test_downscale_640x480_1x240_method_1, 1, 640, 480, 1, 240);
 CREATE_TEST (test_downscale_640x480_1x240_method_2, 2, 640, 480, 1, 240);
@@ -482,6 +495,9 @@
 CREATE_TEST (test_upscale_1x240_640x480_method_1, 1, 1, 240, 640, 480);
 CREATE_TEST (test_upscale_1x240_640x480_method_2, 2, 1, 240, 640, 480);
 CREATE_TEST (test_upscale_1x240_640x480_method_3, 3, 1, 240, 640, 480);
+#endif
+
+#ifndef VSCALE_TEST_GROUP
 
 typedef struct
 {
@@ -633,6 +649,7 @@
   g_signal_connect (bus, "message", G_CALLBACK (_test_negotiation_message),
       &data);
 
+  gst_bus_remove_signal_watch (bus);
   gst_object_unref (bus);
 
   fail_unless (gst_element_set_state (pipeline,
@@ -809,8 +826,7 @@
       "Test Reverse Negotiation Sink",
       "Sink",
       "Some test sink", "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sinktemplate));
+  gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate);
 
 #if 0
   gstbase_sink_class->buffer_alloc =
@@ -973,6 +989,8 @@
 
 GST_END_TEST;
 
+#endif /* !defined(VSCALE_TEST_GROUP) */
+
 static Suite *
 videoscale_suite (void)
 {
@@ -981,11 +999,18 @@
 
   suite_add_tcase (s, tc_chain);
   tcase_set_timeout (tc_chain, 180);
+#ifndef VSCALE_TEST_GROUP
   tcase_add_test (tc_chain, test_template_formats);
   tcase_add_test (tc_chain, test_passthrough_method_0);
   tcase_add_test (tc_chain, test_passthrough_method_1);
   tcase_add_test (tc_chain, test_passthrough_method_2);
   tcase_add_test (tc_chain, test_passthrough_method_3);
+  tcase_add_test (tc_chain, test_negotiation);
+#if 0
+  tcase_add_test (tc_chain, test_reverse_negotiation);
+#endif
+  tcase_add_test (tc_chain, test_basetransform_negotiation);
+#elif VSCALE_TEST_GROUP == 1
   tcase_add_test (tc_chain, test_downscale_640x480_320x240_method_0);
   tcase_add_test (tc_chain, test_downscale_640x480_320x240_method_1);
   tcase_add_test (tc_chain, test_downscale_640x480_320x240_method_2);
@@ -994,6 +1019,7 @@
   tcase_add_test (tc_chain, test_upscale_320x240_640x480_method_1);
   tcase_add_test (tc_chain, test_upscale_320x240_640x480_method_2);
   tcase_add_test (tc_chain, test_upscale_320x240_640x480_method_3);
+#elif VSCALE_TEST_GROUP == 2
   tcase_add_test (tc_chain, test_downscale_640x480_1x1_method_0);
   tcase_add_test (tc_chain, test_downscale_640x480_1x1_method_1);
   tcase_add_test (tc_chain, test_downscale_640x480_1x1_method_2);
@@ -1002,6 +1028,7 @@
   tcase_add_test (tc_chain, test_upscale_1x1_640x480_method_1);
   tcase_add_test (tc_chain, test_upscale_1x1_640x480_method_2);
   tcase_add_test (tc_chain, test_upscale_1x1_640x480_method_3);
+#elif VSCALE_TEST_GROUP == 3
   tcase_add_test (tc_chain, test_downscale_641x481_111x30_method_0);
   tcase_add_test (tc_chain, test_downscale_641x481_111x30_method_1);
   tcase_add_test (tc_chain, test_downscale_641x481_111x30_method_2);
@@ -1010,6 +1037,7 @@
   tcase_add_test (tc_chain, test_upscale_111x30_641x481_method_1);
   tcase_add_test (tc_chain, test_upscale_111x30_641x481_method_2);
   tcase_add_test (tc_chain, test_upscale_111x30_641x481_method_3);
+#elif VSCALE_TEST_GROUP == 4
   tcase_add_test (tc_chain, test_downscale_641x481_30x111_method_0);
   tcase_add_test (tc_chain, test_downscale_641x481_30x111_method_1);
   tcase_add_test (tc_chain, test_downscale_641x481_30x111_method_2);
@@ -1018,6 +1046,7 @@
   tcase_add_test (tc_chain, test_upscale_30x111_641x481_method_1);
   tcase_add_test (tc_chain, test_upscale_30x111_641x481_method_2);
   tcase_add_test (tc_chain, test_upscale_30x111_641x481_method_3);
+#elif VSCALE_TEST_GROUP == 5
   tcase_add_test (tc_chain, test_downscale_640x480_320x1_method_0);
   tcase_add_test (tc_chain, test_downscale_640x480_320x1_method_1);
   tcase_add_test (tc_chain, test_downscale_640x480_320x1_method_2);
@@ -1026,6 +1055,7 @@
   tcase_add_test (tc_chain, test_upscale_320x1_640x480_method_1);
   tcase_add_test (tc_chain, test_upscale_320x1_640x480_method_2);
   tcase_skip_broken_test (tc_chain, test_upscale_320x1_640x480_method_3);
+#elif VSCALE_TEST_GROUP == 6
   tcase_add_test (tc_chain, test_downscale_640x480_1x240_method_0);
   tcase_add_test (tc_chain, test_downscale_640x480_1x240_method_1);
   tcase_add_test (tc_chain, test_downscale_640x480_1x240_method_2);
@@ -1034,11 +1064,7 @@
   tcase_add_test (tc_chain, test_upscale_1x240_640x480_method_1);
   tcase_add_test (tc_chain, test_upscale_1x240_640x480_method_2);
   tcase_add_test (tc_chain, test_upscale_1x240_640x480_method_3);
-  tcase_add_test (tc_chain, test_negotiation);
-#if 0
-  tcase_add_test (tc_chain, test_reverse_negotiation);
 #endif
-  tcase_add_test (tc_chain, test_basetransform_negotiation);
 
   return s;
 }
diff --git a/tests/check/elements/vorbistag.c b/tests/check/elements/vorbistag.c
index 74a7075..0ffa102 100644
--- a/tests/check/elements/vorbistag.c
+++ b/tests/check/elements/vorbistag.c
@@ -118,6 +118,7 @@
 
   gst_pad_set_active (mysrcpad, FALSE);
   gst_pad_set_active (mysinkpad, FALSE);
+  gst_check_drop_buffers ();
   gst_check_teardown_src_pad (vorbistag);
   gst_check_teardown_sink_pad (vorbistag);
   gst_check_teardown_element (vorbistag);
diff --git a/tests/check/libs/audiodecoder.c b/tests/check/libs/audiodecoder.c
index 5b92caf..cba7a35 100644
--- a/tests/check/libs/audiodecoder.c
+++ b/tests/check/libs/audiodecoder.c
@@ -73,6 +73,8 @@
 
   gboolean setoutputformat_on_decoding;
   gboolean output_too_many_frames;
+  gboolean delay_decoding;
+  GstBuffer *prev_buf;
 };
 
 struct _GstAudioDecoderTesterClass
@@ -92,6 +94,11 @@
 static gboolean
 gst_audio_decoder_tester_stop (GstAudioDecoder * dec)
 {
+  GstAudioDecoderTester *tester = (GstAudioDecoderTester *)dec;
+  if (tester->prev_buf) {
+    gst_buffer_unref (tester->prev_buf);
+    tester->prev_buf = NULL;
+  }
   return TRUE;
 }
 
@@ -127,10 +134,14 @@
   gint size;
   GstMapInfo map;
   GstBuffer *output_buffer;
+  GstFlowReturn ret = GST_FLOW_OK;
+  gboolean do_plc = gst_audio_decoder_get_plc (dec) &&
+      gst_audio_decoder_get_plc_aware (dec);
 
-  if (buffer == NULL)
+  if (buffer == NULL || (!do_plc && gst_buffer_get_size (buffer) == 0))
     return GST_FLOW_OK;
 
+  gst_buffer_ref (buffer);
   if (tester->setoutputformat_on_decoding) {
     GstCaps *caps;
     GstAudioInfo info;
@@ -143,25 +154,46 @@
 
     gst_audio_decoder_set_output_format (dec, &info);
   }
+  if ((tester->delay_decoding && tester->prev_buf != NULL) ||
+      !tester->delay_decoding) {
+    gsize buf_num = tester->delay_decoding ? 2 : 1;
+    for (gint i = 0; i != buf_num; ++i) {
+      GstBuffer *cur_buf = buf_num == 1 || i != 0 ? buffer : tester->prev_buf;
+      gst_buffer_map (cur_buf, &map, GST_MAP_READ);
 
-  gst_buffer_map (buffer, &map, GST_MAP_READ);
+      /* the output is SE32LE stereo 44100 Hz */
+      size = 2 * 4;
+      g_assert (size == sizeof (guint64));
+      data = g_malloc0 (size);
 
-  /* the output is SE32LE stereo 44100 Hz */
-  size = 2 * 4;
-  g_assert (size == sizeof (guint64));
-  data = g_malloc0 (size);
+      if (map.size) {
+        g_assert_cmpint (map.size, >=, sizeof (guint64));
+        memcpy (data, map.data, sizeof (guint64));
+      }
 
-  memcpy (data, map.data, sizeof (guint64));
+      output_buffer = gst_buffer_new_wrapped (data, size);
 
-  output_buffer = gst_buffer_new_wrapped (data, size);
+      gst_buffer_unmap (cur_buf, &map);
 
-  gst_buffer_unmap (buffer, &map);
-
-  if (tester->output_too_many_frames) {
-    return gst_audio_decoder_finish_frame (dec, output_buffer, 2);
-  } else {
-    return gst_audio_decoder_finish_frame (dec, output_buffer, 1);
+      if (tester->output_too_many_frames) {
+        ret = gst_audio_decoder_finish_frame (dec, output_buffer, 2);
+      } else {
+        ret = gst_audio_decoder_finish_frame (dec, output_buffer, 1);
+      }
+      if (ret != GST_FLOW_OK)
+        break;
+    }
+    tester->delay_decoding = FALSE;
   }
+
+  if (tester->prev_buf)
+    gst_buffer_unref (tester->prev_buf);
+  tester->prev_buf = NULL;
+  if (tester->delay_decoding)
+    tester->prev_buf = buffer;
+  else
+    gst_buffer_unref (buffer);
+  return ret;
 }
 
 static void
@@ -178,10 +210,8 @@
       GST_PAD_SRC, GST_PAD_ALWAYS,
       GST_STATIC_CAPS ("audio/x-raw"));
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_templ));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
+  gst_element_class_add_static_pad_template (element_class, &sink_templ);
+  gst_element_class_add_static_pad_template (element_class, &src_templ);
 
   gst_element_class_set_metadata (element_class,
       "AudioDecoderTester", "Decoder/Audio", "yep", "me");
@@ -1012,6 +1042,92 @@
 
 GST_END_TEST;
 
+GST_START_TEST (audiodecoder_plc_on_gap_event)
+{
+  /* GstAudioDecoder should not mark the stream DISCOUNT flag when
+  concealed audio eliminate discontinuity. More important it should not
+  mess with the timestamps */
+
+  GstClockTime pts;
+  GstClockTime dur = gst_util_uint64_scale_round (1, GST_SECOND, TEST_MSECS_PER_SAMPLE);
+  GstBuffer *buf;
+  GstHarness *h = setup_audiodecodertester (NULL, NULL);
+  gst_audio_decoder_set_plc_aware (GST_AUDIO_DECODER (h->element), TRUE);
+  gst_audio_decoder_set_plc (GST_AUDIO_DECODER (h->element), TRUE);
+
+  pts = gst_util_uint64_scale_round (0, GST_SECOND, TEST_MSECS_PER_SAMPLE);
+  gst_harness_push (h, create_test_buffer(0));
+  buf = gst_harness_pull (h);
+  fail_unless_equals_int (pts, GST_BUFFER_PTS (buf));
+  fail_unless_equals_int (dur, GST_BUFFER_DURATION (buf));
+  fail_unless (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
+  gst_buffer_unref (buf);
+
+  pts = gst_util_uint64_scale_round (1, GST_SECOND, TEST_MSECS_PER_SAMPLE);
+  gst_harness_push_event (h, gst_event_new_gap (pts, dur));
+  buf = gst_harness_pull (h);
+  fail_unless_equals_int (pts, GST_BUFFER_PTS (buf));
+  fail_unless_equals_int (dur, GST_BUFFER_DURATION (buf));
+  fail_unless (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
+  gst_buffer_unref (buf);
+
+  pts = gst_util_uint64_scale_round (2, GST_SECOND, TEST_MSECS_PER_SAMPLE);
+  buf = create_test_buffer(2);
+  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
+  gst_harness_push (h, buf);
+  buf = gst_harness_pull (h);
+  fail_unless_equals_int (pts, GST_BUFFER_PTS (buf));
+  fail_unless_equals_int (dur, GST_BUFFER_DURATION (buf));
+  fail_unless (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
+  gst_buffer_unref (buf);
+  gst_harness_teardown (h);
+}
+GST_END_TEST;
+
+GST_START_TEST (audiodecoder_plc_on_gap_event_with_delay)
+{
+  /* The same thing as in audiodecoder_plc_on_gap_event, but GstAudioDecoder
+  subclass delays the decoding
+  */
+  GstClockTime pts0, pts1;
+  GstClockTime dur = gst_util_uint64_scale_round (1, GST_SECOND, TEST_MSECS_PER_SAMPLE);
+  GstBuffer *buf;
+  GstHarness *h = setup_audiodecodertester (NULL, NULL);
+  gst_audio_decoder_set_plc_aware (GST_AUDIO_DECODER (h->element), TRUE);
+  gst_audio_decoder_set_plc (GST_AUDIO_DECODER (h->element), TRUE);
+
+  pts0 = gst_util_uint64_scale_round (0, GST_SECOND, TEST_MSECS_PER_SAMPLE);;
+  gst_harness_push (h, create_test_buffer(0));
+  buf = gst_harness_pull (h);
+  fail_unless_equals_int (pts0, GST_BUFFER_PTS (buf));
+  fail_unless_equals_int (dur, GST_BUFFER_DURATION (buf));
+  fail_unless (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
+  gst_buffer_unref (buf);
+
+  ((GstAudioDecoderTester *)h->element)->delay_decoding = TRUE;
+  pts0 = gst_util_uint64_scale_round (1, GST_SECOND, TEST_MSECS_PER_SAMPLE);
+  gst_harness_push_event (h, gst_event_new_gap (pts0, dur));
+  fail_unless_equals_int (0, gst_harness_buffers_in_queue (h));
+
+  pts1 = gst_util_uint64_scale_round (2, GST_SECOND, TEST_MSECS_PER_SAMPLE);
+  buf = create_test_buffer(2);
+  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
+  gst_harness_push (h, buf);
+  buf = gst_harness_pull (h);
+  fail_unless_equals_int (pts0, GST_BUFFER_PTS (buf));
+  fail_unless_equals_int (dur, GST_BUFFER_DURATION (buf));
+  fail_unless (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
+  gst_buffer_unref (buf);
+
+  buf = gst_harness_pull (h);
+  fail_unless_equals_int (pts1, GST_BUFFER_PTS (buf));
+  fail_unless_equals_int (dur, GST_BUFFER_DURATION (buf));
+  fail_unless (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT));
+  gst_buffer_unref (buf);
+  gst_harness_teardown (h);
+}
+GST_END_TEST;
+
 static Suite *
 gst_audiodecoder_suite (void)
 {
@@ -1039,6 +1155,9 @@
 
   tcase_add_test (tc, audiodecoder_tag_handling);
 
+  tcase_add_test (tc, audiodecoder_plc_on_gap_event);
+  tcase_add_test (tc, audiodecoder_plc_on_gap_event_with_delay);
+
   return s;
 }
 
diff --git a/tests/check/libs/audioencoder.c b/tests/check/libs/audioencoder.c
index 614440d..bcaf8d9 100644
--- a/tests/check/libs/audioencoder.c
+++ b/tests/check/libs/audioencoder.c
@@ -116,10 +116,8 @@
       GST_PAD_SRC, GST_PAD_ALWAYS,
       GST_STATIC_CAPS ("audio/x-test-custom"));
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_templ));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
+  gst_element_class_add_static_pad_template (element_class, &sink_templ);
+  gst_element_class_add_static_pad_template (element_class, &src_templ);
 
   gst_element_class_set_metadata (element_class,
       "AudioEncoderTester", "Encoder/Audio", "yep", "me");
diff --git a/tests/check/libs/baseaudiovisualizer.c b/tests/check/libs/baseaudiovisualizer.c
index 70d7264..3e26de5 100644
--- a/tests/check/libs/baseaudiovisualizer.c
+++ b/tests/check/libs/baseaudiovisualizer.c
@@ -74,10 +74,10 @@
       "Visualization",
       "Dummy test scope", "Stefan Kost <ensonic@users.sf.net>");
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_test_scope_src_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_test_scope_sink_template));
+  gst_element_class_add_static_pad_template (element_class,
+      &gst_test_scope_src_template);
+  gst_element_class_add_static_pad_template (element_class,
+      &gst_test_scope_sink_template);
 }
 
 static void
diff --git a/tests/check/libs/discoverer.c b/tests/check/libs/discoverer.c
index aa2b9a9..bbee562 100644
--- a/tests/check/libs/discoverer.c
+++ b/tests/check/libs/discoverer.c
@@ -29,6 +29,7 @@
 #include <glib/gstdio.h>
 #include <glib/gprintf.h>
 
+static gboolean have_theora, have_ogg;
 
 GST_START_TEST (test_disco_init)
 {
@@ -66,8 +67,15 @@
 
   info = gst_discoverer_discover_uri (dc, uri, &err);
   fail_unless (info);
-  fail_unless_equals_int (gst_discoverer_info_get_result (info),
-      GST_DISCOVERER_OK);
+  if (have_theora && have_ogg) {
+    fail_unless_equals_int (gst_discoverer_info_get_result (info),
+        GST_DISCOVERER_OK);
+  } else {
+    fail_unless_equals_int (gst_discoverer_info_get_result (info),
+        GST_DISCOVERER_MISSING_PLUGINS);
+    g_clear_error (&err);
+    goto missing_plugins;
+  }
   serialized =
       gst_discoverer_info_to_variant (info, GST_DISCOVERER_SERIALIZE_ALL);
 
@@ -85,13 +93,15 @@
 
   fail_unless (g_variant_equal (serialized, reserialized));
 
-  gst_discoverer_info_unref (info);
   gst_discoverer_info_unref (dinfo);
-  g_free (uri);
   g_variant_unref (serialized);
   g_variant_unref (reserialized);
 
+missing_plugins:
+
+  gst_discoverer_info_unref (info);
   g_object_unref (dc);
+  g_free (uri);
 }
 
 GST_END_TEST;
@@ -239,6 +249,11 @@
   Suite *s = suite_create ("discoverer");
   TCase *tc_chain = tcase_create ("general");
 
+  have_theora = gst_registry_check_feature_version (gst_registry_get (),
+      "theoradec", GST_VERSION_MAJOR, GST_VERSION_MINOR, 0);
+  have_ogg = gst_registry_check_feature_version (gst_registry_get (),
+      "oggdemux", GST_VERSION_MAJOR, GST_VERSION_MINOR, 0);
+
   suite_add_tcase (s, tc_chain);
   tcase_add_test (tc_chain, test_disco_init);
   tcase_add_test (tc_chain, test_disco_sync);
diff --git a/tests/check/libs/gstlibscpp.cc b/tests/check/libs/gstlibscpp.cc
index eaf7dbb..049cac8 100644
--- a/tests/check/libs/gstlibscpp.cc
+++ b/tests/check/libs/gstlibscpp.cc
@@ -89,6 +89,7 @@
 #include <gst/video/video.h>
 #include <gst/video/colorbalancechannel.h>
 #include <gst/video/colorbalance.h>
+#include <gst/video/videodirection.h>
 #include <gst/video/videoorientation.h>
 #include <gst/video/videooverlay.h>
 #include <gst/video/navigation.h>
@@ -102,6 +103,17 @@
 
 GST_END_TEST;
 
+GST_START_TEST (test_init_macros)
+{
+  GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
+  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
+
+  fail_unless_equals_int (rtp.size[0], 0)
+  fail_unless_equals_int (rtcp.map.size, 0);
+}
+
+GST_END_TEST;
+
 static Suite *
 libscpp_suite (void)
 {
@@ -110,6 +122,7 @@
 
   suite_add_tcase (s, tc_chain);
   tcase_add_test (tc_chain, test_nothing);
+  tcase_add_test (tc_chain, test_init_macros);
 
   return s;
 }
diff --git a/tests/check/libs/libsabi.c b/tests/check/libs/libsabi.c
index 508406a..316826e 100644
--- a/tests/check/libs/libsabi.c
+++ b/tests/check/libs/libsabi.c
@@ -62,6 +62,7 @@
 #include <gst/video/gstvideofilter.h>
 #include <gst/video/gstvideosink.h>
 #include <gst/video/colorbalance.h>
+#include <gst/video/videodirection.h>
 #include <gst/video/videoorientation.h>
 #include <gst/video/videooverlay.h>
 #include <gst/video/navigation.h>
diff --git a/tests/check/libs/rtp.c b/tests/check/libs/rtp.c
index d69357a..20c01ab 100644
--- a/tests/check/libs/rtp.c
+++ b/tests/check/libs/rtp.c
@@ -991,6 +991,152 @@
 
 GST_END_TEST;
 
+GST_START_TEST (test_rtcp_buffer_profile_specific_extension)
+{
+  GstBuffer *buf;
+  GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
+  GstRTCPPacket packet;
+  const guint8 pse[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
+  const guint8 pse2[] = { 0x01, 0x23, 0x45, 0x67 };
+
+  fail_unless ((buf = gst_rtcp_buffer_new (1400)) != NULL);
+  gst_rtcp_buffer_map (buf, GST_MAP_READWRITE, &rtcp);
+
+  fail_unless (gst_rtcp_buffer_validate (buf) == FALSE);
+  fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &packet) == FALSE);
+  fail_unless (gst_rtcp_buffer_get_packet_count (&rtcp) == 0);
+
+  /* add an SR packet with sender info */
+  fail_unless (gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_SR, &packet));
+  gst_rtcp_packet_sr_set_sender_info (&packet, 0x44556677,
+      G_GUINT64_CONSTANT (1), 0x11111111, 101, 123456);
+  fail_unless_equals_int (0,
+      gst_rtcp_packet_get_profile_specific_ext_length (&packet));
+  fail_unless_equals_int (6, gst_rtcp_packet_get_length (&packet));
+
+  /* add profile-specific extension */
+  fail_unless (gst_rtcp_packet_add_profile_specific_ext (&packet,
+          pse, sizeof (pse)));
+  {
+    guint8 *data = NULL;
+    guint len = 0;
+
+    fail_unless_equals_int (8, gst_rtcp_packet_get_length (&packet));
+    fail_unless_equals_int (sizeof (pse) / 4,
+        gst_rtcp_packet_get_profile_specific_ext_length (&packet));
+
+    /* gst_rtcp_packet_get_profile_specific_ext */
+    fail_unless (gst_rtcp_packet_get_profile_specific_ext (&packet, &data,
+            &len));
+    fail_unless_equals_int (sizeof (pse), len);
+    fail_unless (data != NULL);
+    fail_unless_equals_int (0, memcmp (pse, data, sizeof (pse)));
+
+    /* gst_rtcp_packet_copy_profile_specific_ext */
+    fail_unless (gst_rtcp_packet_copy_profile_specific_ext (&packet, &data,
+            &len));
+    fail_unless_equals_int (sizeof (pse), len);
+    fail_unless (data != NULL);
+    fail_unless_equals_int (0, memcmp (pse, data, sizeof (pse)));
+    g_free (data);
+  }
+
+  /* append more profile-specific extension */
+  fail_unless (gst_rtcp_packet_add_profile_specific_ext (&packet,
+          pse2, sizeof (pse2)));
+  {
+    guint8 *data = NULL;
+    guint len = 0;
+    guint concat_len;
+    guint8 *concat_pse;
+
+    /* Expect the second extension to be appended to the first */
+    concat_len = sizeof (pse) + sizeof (pse2);
+    concat_pse = g_malloc (concat_len);
+    memcpy (concat_pse, pse, sizeof (pse));
+    memcpy (concat_pse + sizeof (pse), pse2, sizeof (pse2));
+
+    fail_unless_equals_int (9, gst_rtcp_packet_get_length (&packet));
+    fail_unless_equals_int (concat_len / 4,
+        gst_rtcp_packet_get_profile_specific_ext_length (&packet));
+
+    /* gst_rtcp_packet_get_profile_specific_ext */
+    fail_unless (gst_rtcp_packet_get_profile_specific_ext (&packet, &data,
+            &len));
+    fail_unless_equals_int (concat_len, len);
+    fail_unless (data != NULL);
+    fail_unless_equals_int (0, memcmp (concat_pse, data, len));
+
+    /* gst_rtcp_packet_copy_profile_specific_ext */
+    fail_unless (gst_rtcp_packet_copy_profile_specific_ext (&packet, &data,
+            &len));
+    fail_unless_equals_int (concat_len, len);
+    fail_unless (data != NULL);
+    fail_unless_equals_int (0, memcmp (concat_pse, data, len));
+    g_free (data);
+    g_free (concat_pse);
+  }
+
+  /* close and validate */
+  gst_rtcp_buffer_unmap (&rtcp);
+  fail_unless (gst_rtcp_buffer_validate (buf) == TRUE);
+  gst_buffer_unref (buf);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_rtcp_buffer_app)
+{
+  GstBuffer *buf;
+  GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
+  GstRTCPPacket packet;
+  guint mtu = 1000;
+  const guint8 data[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
+  guint max_data_length = (mtu - 12) / 4;
+  guint8 *data_ptr;
+
+  fail_unless ((buf = gst_rtcp_buffer_new (mtu)) != NULL);
+  gst_rtcp_buffer_map (buf, GST_MAP_READWRITE, &rtcp);
+
+  /* Not a valid packet yet */
+  fail_if (gst_rtcp_buffer_validate (buf));
+  fail_if (gst_rtcp_buffer_get_first_packet (&rtcp, &packet));
+  fail_unless_equals_int (gst_rtcp_buffer_get_packet_count (&rtcp), 0);
+
+  /* Add APP packet  */
+  fail_unless (gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_APP, &packet));
+  gst_rtcp_packet_app_set_subtype (&packet, 0x15);
+  gst_rtcp_packet_app_set_ssrc (&packet, 0x01234567);
+  gst_rtcp_packet_app_set_name (&packet, "Test");
+
+  /* Check maximum allowed data */
+  fail_if (gst_rtcp_packet_app_set_data_length (&packet, max_data_length + 1));
+  fail_unless (gst_rtcp_packet_app_set_data_length (&packet, max_data_length));
+
+  /* Add data */
+  fail_unless (gst_rtcp_packet_app_set_data_length (&packet,
+          (sizeof (data) + 3) / 4));
+  fail_unless_equals_int (gst_rtcp_packet_app_get_data_length (&packet), 2);
+  fail_unless ((data_ptr = gst_rtcp_packet_app_get_data (&packet)));
+  memcpy (data_ptr, data, sizeof (data));
+
+  gst_rtcp_buffer_unmap (&rtcp);
+
+  /* Map again with only the READ flag and check fields */
+  gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp);
+  fail_unless_equals_int (gst_rtcp_packet_app_get_subtype (&packet), 0x15);
+  fail_unless_equals_int (gst_rtcp_packet_app_get_ssrc (&packet), 0x01234567);
+  fail_unless (memcmp (gst_rtcp_packet_app_get_name (&packet), "Test", 4) == 0);
+  fail_unless_equals_int (gst_rtcp_packet_app_get_data_length (&packet), 2);
+  fail_unless ((data_ptr = gst_rtcp_packet_app_get_data (&packet)));
+  fail_unless (memcmp (data_ptr, data, sizeof (data)) == 0);
+  gst_rtcp_buffer_unmap (&rtcp);
+
+  gst_buffer_unref (buf);
+}
+
+GST_END_TEST;
+
 GST_START_TEST (test_rtp_ntp64_extension)
 {
   GstBuffer *buf;
@@ -1231,6 +1377,9 @@
       test_rtcp_validate_with_padding_set_in_first_packet);
   tcase_add_test (tc_chain, test_rtcp_validate_reduced_without_padding);
   tcase_add_test (tc_chain, test_rtcp_validate_reduced_with_padding);
+  tcase_add_test (tc_chain, test_rtcp_buffer_profile_specific_extension);
+  tcase_add_test (tc_chain, test_rtcp_buffer_app);
+
   tcase_add_test (tc_chain, test_rtp_ntp64_extension);
   tcase_add_test (tc_chain, test_rtp_ntp56_extension);
 
diff --git a/tests/check/libs/rtpbasedepayload.c b/tests/check/libs/rtpbasedepayload.c
index 003f2f0..63cbc87 100644
--- a/tests/check/libs/rtpbasedepayload.c
+++ b/tests/check/libs/rtpbasedepayload.c
@@ -83,10 +83,10 @@
   gstelement_class = GST_ELEMENT_CLASS (klass);
   gstrtpbasedepayload_class = GST_RTP_BASE_DEPAYLOAD_CLASS (klass);
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_rtp_dummy_depay_sink_template));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_rtp_dummy_depay_src_template));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_rtp_dummy_depay_sink_template);
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_rtp_dummy_depay_src_template);
 
   gstrtpbasedepayload_class->process = gst_rtp_dummy_depay_process;
   gstrtpbasedepayload_class->set_caps = gst_rtp_dummy_depay_set_caps;
@@ -730,6 +730,50 @@
 }
 
 GST_END_TEST
+/* The same scenario as in rtp_base_depayload_reversed_test
+ * except that SSRC is changed for the 2nd packet that is why
+ * it should not be discarded.
+ */
+GST_START_TEST (rtp_base_depayload_ssrc_changed_test)
+{
+  State *state;
+
+  state = create_depayloader ("application/x-rtp", NULL);
+
+  set_state (state, GST_STATE_PLAYING);
+
+  push_rtp_buffer (state,
+      "pts", 0 * GST_SECOND,
+      "rtptime", G_GUINT64_CONSTANT (0x43214321),
+      "seq", 0x4242, "ssrc", 0xabe2b0b, NULL);
+
+  push_rtp_buffer (state,
+      "pts", 1 * GST_SECOND,
+      "rtptime", G_GUINT64_CONSTANT (0x43214321) + 1 * DEFAULT_CLOCK_RATE,
+      "seq", 0x4242 - 1, "ssrc", 0xcafebabe, NULL);
+
+  set_state (state, GST_STATE_NULL);
+
+  validate_buffers_received (2);
+
+  validate_buffer (0, "pts", 0 * GST_SECOND, "discont", FALSE, NULL);
+
+  validate_buffer (1, "pts", 1 * GST_SECOND, "discont", TRUE, NULL);
+
+  validate_events_received (3);
+
+  validate_event (0, "stream-start", NULL);
+
+  validate_event (1, "caps", "media-type", "application/x-rtp", NULL);
+
+  validate_event (2, "segment",
+      "time", G_GUINT64_CONSTANT (0),
+      "start", G_GUINT64_CONSTANT (0), "stop", G_MAXUINT64, NULL);
+
+  destroy_depayloader (state);
+}
+
+GST_END_TEST
 /* the intent of this test is to push two RTP packets that have reverse sequence
  * numbers that differ significantly. the depayloader will consider RTP packets
  * where the sequence numbers differ by more than 1000 to indicate that the
@@ -1198,6 +1242,7 @@
   tcase_add_test (tc_chain, rtp_base_depayload_invalid_rtp_packet_test);
   tcase_add_test (tc_chain, rtp_base_depayload_with_gap_test);
   tcase_add_test (tc_chain, rtp_base_depayload_reversed_test);
+  tcase_add_test (tc_chain, rtp_base_depayload_ssrc_changed_test);
   tcase_add_test (tc_chain, rtp_base_depayload_old_reversed_test);
 
   tcase_add_test (tc_chain, rtp_base_depayload_without_negotiation_test);
diff --git a/tests/check/libs/rtpbasepayload.c b/tests/check/libs/rtpbasepayload.c
index 09f5ca0..3cc6e41 100644
--- a/tests/check/libs/rtpbasepayload.c
+++ b/tests/check/libs/rtpbasepayload.c
@@ -80,10 +80,10 @@
   gstelement_class = GST_ELEMENT_CLASS (klass);
   gstrtpbasepayload_class = GST_RTP_BASE_PAYLOAD_CLASS (klass);
 
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_rtp_dummy_pay_sink_template));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&gst_rtp_dummy_pay_src_template));
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_rtp_dummy_pay_sink_template);
+  gst_element_class_add_static_pad_template (gstelement_class,
+      &gst_rtp_dummy_pay_src_template);
 
   gstrtpbasepayload_class->handle_buffer = gst_rtp_dummy_pay_handle_buffer;
 }
diff --git a/tests/check/libs/tag.c b/tests/check/libs/tag.c
index e8244bf..992b198 100644
--- a/tests/check/libs/tag.c
+++ b/tests/check/libs/tag.c
@@ -1676,10 +1676,11 @@
   g_value_unset (&value);
 
   g_value_init (&value, G_TYPE_DOUBLE);
-  g_value_set_double (&value, 30.5);
+  g_value_set_double (&value, 40.3456784);
   do_simple_exif_tag_serialization_deserialization
       (GST_TAG_GEO_LOCATION_LATITUDE, &value);
-  g_value_set_double (&value, -12.125);
+  g_value_set_double (&value, -12.1250865);
+
   do_simple_exif_tag_serialization_deserialization
       (GST_TAG_GEO_LOCATION_LATITUDE, &value);
   g_value_set_double (&value, 0);
@@ -1775,6 +1776,10 @@
   g_value_set_double (&value, -2.5);
   do_simple_exif_tag_serialization_deserialization
       (GST_TAG_CAPTURING_EXPOSURE_COMPENSATION, &value);
+
+  g_value_set_double (&value, 50.0);
+  do_simple_exif_tag_serialization_deserialization
+      (GST_TAG_CAPTURING_FOCAL_LENGTH_35_MM, &value);
   g_value_unset (&value);
 
   g_value_init (&value, G_TYPE_INT);
diff --git a/tests/check/libs/video.c b/tests/check/libs/video.c
index 86c565f..d37c0b5 100644
--- a/tests/check/libs/video.c
+++ b/tests/check/libs/video.c
@@ -343,6 +343,7 @@
     case GST_VIDEO_FORMAT_YVU9:
       return FALSE;
     case GST_VIDEO_FORMAT_IYU1:
+    case GST_VIDEO_FORMAT_IYU2:
     case GST_VIDEO_FORMAT_YUY2:
     case GST_VIDEO_FORMAT_YVYU:
     case GST_VIDEO_FORMAT_UYVY:
@@ -872,7 +873,7 @@
         _16_235, SMPTE240M, SMPTE240M, SMPTE240M),
     MAKE_COLORIMETRY_TEST ("sRGB", "sRGB", "sRGB",
         _0_255, RGB, SRGB, BT709),
-    MAKE_COLORIMETRY_TEST ("bt2020" , "bt2020", "bt2020",
+    MAKE_COLORIMETRY_TEST ("bt2020", "bt2020", "bt2020",
         _16_235, BT2020, BT2020_12, BT2020),
     MAKE_COLORIMETRY_TEST ("1:4:0:0", "1:4:0:0", NULL,
         _0_255, BT601, UNKNOWN, UNKNOWN),
diff --git a/tests/check/libs/videodecoder.c b/tests/check/libs/videodecoder.c
index 1fc9f36..b780079 100644
--- a/tests/check/libs/videodecoder.c
+++ b/tests/check/libs/videodecoder.c
@@ -185,10 +185,8 @@
       GST_PAD_SRC, GST_PAD_ALWAYS,
       GST_STATIC_CAPS ("video/x-raw"));
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_templ));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
+  gst_element_class_add_static_pad_template (element_class, &sink_templ);
+  gst_element_class_add_static_pad_template (element_class, &src_templ);
 
   gst_element_class_set_metadata (element_class,
       "VideoDecoderTester", "Decoder/Video", "yep", "me");
diff --git a/tests/check/libs/videoencoder.c b/tests/check/libs/videoencoder.c
index 1844ab6..e1c180d 100644
--- a/tests/check/libs/videoencoder.c
+++ b/tests/check/libs/videoencoder.c
@@ -128,10 +128,8 @@
       GST_PAD_SRC, GST_PAD_ALWAYS,
       GST_STATIC_CAPS ("video/x-test-custom"));
 
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_templ));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_templ));
+  gst_element_class_add_static_pad_template (element_class, &sink_templ);
+  gst_element_class_add_static_pad_template (element_class, &src_templ);
 
   gst_element_class_set_metadata (element_class,
       "VideoEncoderTester", "Encoder/Video", "yep", "me");
diff --git a/tests/check/libs/videotimecode.c b/tests/check/libs/videotimecode.c
new file mode 100644
index 0000000..23d6b50
--- /dev/null
+++ b/tests/check/libs/videotimecode.c
@@ -0,0 +1,401 @@
+/* GStreamer
+ *
+ * Copyright (C) 2016 Vivia Nikolaidou <vivia@toolsonair.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/gst.h>
+#include <gst/check/gstcheck.h>
+#include <gst/video/video.h>
+
+
+GST_START_TEST (videotimecode_compare_equal)
+{
+  GstVideoTimeCode *tc1, *tc2;
+
+  tc2 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
+  tc1 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
+  fail_unless (gst_video_time_code_compare (tc1, tc2) == 0);
+  gst_video_time_code_free (tc1);
+  gst_video_time_code_free (tc2);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_compare_fps_n)
+{
+  GstVideoTimeCode *tc1, *tc2;
+
+  tc1 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
+  tc2 = gst_video_time_code_new (25, 1, NULL, 0, 10, 10, 10, 10, 0);
+  fail_unless (gst_video_time_code_compare (tc1, tc2) == 1);
+  fail_unless (gst_video_time_code_compare (tc2, tc1) == -1);
+  gst_video_time_code_free (tc1);
+  gst_video_time_code_free (tc2);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_compare_fps_d)
+{
+  GstVideoTimeCode *tc1, *tc2;
+
+  tc1 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
+  tc2 = gst_video_time_code_new (50, 2, NULL, 0, 10, 10, 10, 10, 0);
+  fail_unless (gst_video_time_code_compare (tc1, tc2) == 1);
+  fail_unless (gst_video_time_code_compare (tc2, tc1) == -1);
+  gst_video_time_code_free (tc1);
+  gst_video_time_code_free (tc2);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_compare_frames)
+{
+  GstVideoTimeCode *tc1, *tc2;
+
+  tc1 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
+  tc2 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 9, 0);
+  fail_unless (gst_video_time_code_compare (tc1, tc2) == 1);
+  fail_unless (gst_video_time_code_compare (tc2, tc1) == -1);
+  gst_video_time_code_free (tc1);
+  gst_video_time_code_free (tc2);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_compare_seconds)
+{
+  GstVideoTimeCode *tc1, *tc2;
+
+  tc1 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
+  tc2 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 9, 10, 0);
+  fail_unless (gst_video_time_code_compare (tc1, tc2) == 1);
+  fail_unless (gst_video_time_code_compare (tc2, tc1) == -1);
+  gst_video_time_code_free (tc1);
+  gst_video_time_code_free (tc2);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_compare_minutes)
+{
+  GstVideoTimeCode *tc1, *tc2;
+
+  tc1 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
+  tc2 = gst_video_time_code_new (50, 1, NULL, 0, 10, 9, 10, 10, 0);
+  fail_unless (gst_video_time_code_compare (tc1, tc2) == 1);
+  fail_unless (gst_video_time_code_compare (tc2, tc1) == -1);
+  gst_video_time_code_free (tc1);
+  gst_video_time_code_free (tc2);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_compare_hours)
+{
+  GstVideoTimeCode *tc1, *tc2;
+
+  tc1 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
+  tc2 = gst_video_time_code_new (50, 1, NULL, 0, 9, 10, 10, 10, 0);
+  fail_unless (gst_video_time_code_compare (tc1, tc2) == 1);
+  fail_unless (gst_video_time_code_compare (tc2, tc1) == -1);
+  gst_video_time_code_free (tc1);
+  gst_video_time_code_free (tc2);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_compare_fieldcounts)
+{
+  GstVideoTimeCode *tc1, *tc2;
+
+  tc1 =
+      gst_video_time_code_new (50, 1, NULL,
+      GST_VIDEO_TIME_CODE_FLAGS_INTERLACED, 10, 10, 10, 10, 2);
+  tc2 =
+      gst_video_time_code_new (50, 1, NULL,
+      GST_VIDEO_TIME_CODE_FLAGS_INTERLACED, 10, 10, 10, 10, 1);
+  fail_unless (gst_video_time_code_compare (tc1, tc2) == 1);
+  fail_unless (gst_video_time_code_compare (tc2, tc1) == -1);
+  gst_video_time_code_free (tc1);
+  gst_video_time_code_free (tc2);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_addframe_10)
+{
+  GstVideoTimeCode *tc1;
+
+  tc1 = gst_video_time_code_new (50, 1, NULL, 0, 10, 10, 10, 10, 0);
+  gst_video_time_code_increment_frame (tc1);
+  fail_unless (tc1->hours == 10);
+  fail_unless (tc1->minutes == 10);
+  fail_unless (tc1->seconds == 10);
+  fail_unless (tc1->frames == 11);
+  gst_video_time_code_free (tc1);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_addframe_0)
+{
+  GstVideoTimeCode *tc1;
+
+  tc1 = gst_video_time_code_new (50, 1, NULL, 0, 0, 0, 0, 0, 0);
+  gst_video_time_code_increment_frame (tc1);
+  fail_unless (tc1->hours == 0);
+  fail_unless (tc1->minutes == 0);
+  fail_unless (tc1->seconds == 0);
+  fail_unless (tc1->frames == 1);
+  gst_video_time_code_free (tc1);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_addframe_high)
+{
+  GstVideoTimeCode *tc1;
+  /* Make sure nothing overflows */
+
+  tc1 = gst_video_time_code_new (60, 1, NULL, 0, 23, 59, 59, 58, 0);
+  gst_video_time_code_increment_frame (tc1);
+  fail_unless (tc1->hours == 23);
+  fail_unless (tc1->minutes == 59);
+  fail_unless (tc1->seconds == 59);
+  fail_unless (tc1->frames == 59);
+  gst_video_time_code_free (tc1);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_addframe_dropframe)
+{
+  GstVideoTimeCode *tc1;
+
+  tc1 =
+      gst_video_time_code_new (30000, 1001, NULL,
+      GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 10, 10, 10, 10, 0);
+  gst_video_time_code_increment_frame (tc1);
+  fail_unless (tc1->hours == 10);
+  fail_unless (tc1->minutes == 10);
+  fail_unless (tc1->seconds == 10);
+  fail_unless (tc1->frames == 11);
+  gst_video_time_code_free (tc1);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_addframe_framedropped)
+{
+  GstVideoTimeCode *tc1;
+
+  tc1 =
+      gst_video_time_code_new (30000, 1001, NULL,
+      GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 10, 10, 59, 29, 0);
+  gst_video_time_code_increment_frame (tc1);
+  fail_unless (tc1->hours == 10);
+  fail_unless (tc1->minutes == 11);
+  fail_unless (tc1->seconds == 0);
+  fail_unless (tc1->frames == 2);
+  gst_video_time_code_free (tc1);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_addframe_wrapover)
+{
+  GstVideoTimeCode *tc1;
+
+  tc1 =
+      gst_video_time_code_new (30000, 1001, NULL,
+      GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 23, 59, 59, 29, 0);
+  gst_video_time_code_increment_frame (tc1);
+  fail_unless (tc1->hours == 0);
+  fail_unless (tc1->minutes == 0);
+  fail_unless (tc1->seconds == 0);
+  fail_unless (tc1->frames == 0);
+  gst_video_time_code_free (tc1);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_addframe_60drop_dropframe)
+{
+  GstVideoTimeCode *tc1;
+
+  tc1 =
+      gst_video_time_code_new (60000, 1001, NULL,
+      GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 10, 10, 10, 10, 0);
+  gst_video_time_code_increment_frame (tc1);
+  fail_unless (tc1->hours == 10);
+  fail_unless (tc1->minutes == 10);
+  fail_unless (tc1->seconds == 10);
+  fail_unless (tc1->frames == 11);
+  gst_video_time_code_free (tc1);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_addframe_60drop_framedropped)
+{
+  GstVideoTimeCode *tc1;
+
+  tc1 =
+      gst_video_time_code_new (60000, 1001, NULL,
+      GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 10, 10, 59, 59, 0);
+  gst_video_time_code_increment_frame (tc1);
+  fail_unless (tc1->hours == 10);
+  fail_unless (tc1->minutes == 11);
+  fail_unless (tc1->seconds == 0);
+  fail_unless (tc1->frames == 4);
+  gst_video_time_code_free (tc1);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_addframe_60drop_wrapover)
+{
+  GstVideoTimeCode *tc1;
+  /* Make sure nothing overflows here either */
+
+  tc1 =
+      gst_video_time_code_new (60000, 1001, NULL,
+      GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 23, 59, 59, 59, 0);
+  gst_video_time_code_increment_frame (tc1);
+  fail_unless (tc1->hours == 0);
+  fail_unless (tc1->minutes == 0);
+  fail_unless (tc1->seconds == 0);
+  fail_unless (tc1->frames == 0);
+  gst_video_time_code_free (tc1);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_addframe_loop)
+{
+  GstVideoTimeCode *tc1;
+  guint64 i;
+  /* Loop for an hour and a bit, make sure no assertions explode */
+
+  tc1 =
+      gst_video_time_code_new (60000, 1001, NULL,
+      GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 12, 12, 12, 12, 0);
+  for (i = 0; i < 220000; i++)
+    gst_video_time_code_increment_frame (tc1);
+  gst_video_time_code_init (tc1, 60, 1, NULL, 0, 12, 12, 12, 12, 0);
+  for (i = 0; i < 220000; i++)
+    gst_video_time_code_increment_frame (tc1);
+  gst_video_time_code_free (tc1);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_dailyjam_todatetime)
+{
+  GstVideoTimeCode *tc1;
+  GDateTime *dt1, *dt2;
+
+  dt1 = g_date_time_new_utc (2016, 7, 29, 10, 32, 50);
+
+  tc1 =
+      gst_video_time_code_new (50, 1, dt1,
+      GST_VIDEO_TIME_CODE_FLAGS_NONE, 0, 0, 0, 0, 0);
+  /* 1 hour, 4 minutes, 3 seconds, and 2 frames */
+  gst_video_time_code_add_frames (tc1, 192152);
+  fail_unless (tc1->hours == 1);
+  fail_unless (tc1->minutes == 4);
+  fail_unless (tc1->seconds == 3);
+  fail_unless (tc1->frames == 2);
+
+  dt2 = gst_video_time_code_to_date_time (tc1);
+  fail_unless (g_date_time_get_year (dt2) == 2016);
+  fail_unless (g_date_time_get_month (dt2) == 7);
+  fail_unless (g_date_time_get_day_of_month (dt2) == 29);
+  fail_unless (g_date_time_get_hour (dt2) == 11);
+  fail_unless (g_date_time_get_minute (dt2) == 36);
+  fail_unless_equals_float (g_date_time_get_seconds (dt2), 53.04);
+
+  gst_video_time_code_free (tc1);
+  g_date_time_unref (dt2);
+  g_date_time_unref (dt1);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (videotimecode_dailyjam_compare)
+{
+  GstVideoTimeCode *tc1, *tc2;
+  GDateTime *dt1;
+
+  dt1 = g_date_time_new_utc (2016, 7, 29, 10, 32, 50);
+
+  tc1 =
+      gst_video_time_code_new (50, 1, dt1,
+      GST_VIDEO_TIME_CODE_FLAGS_NONE, 0, 0, 0, 0, 0);
+  tc2 = gst_video_time_code_copy (tc1);
+  fail_unless (gst_video_time_code_compare (tc1, tc2) == 0);
+  gst_video_time_code_increment_frame (tc1);
+  fail_unless (gst_video_time_code_compare (tc1, tc2) == 1);
+  gst_video_time_code_add_frames (tc2, 2);
+  fail_unless (gst_video_time_code_compare (tc1, tc2) == -1);
+
+  gst_video_time_code_free (tc1);
+  gst_video_time_code_free (tc2);
+  g_date_time_unref (dt1);
+}
+
+GST_END_TEST;
+
+static Suite *
+gst_videotimecode_suite (void)
+{
+  Suite *s = suite_create ("GstVideoTimeCode");
+  TCase *tc = tcase_create ("general");
+
+  suite_add_tcase (s, tc);
+
+  tcase_add_test (tc, videotimecode_compare_equal);
+  tcase_add_test (tc, videotimecode_compare_fps_n);
+  tcase_add_test (tc, videotimecode_compare_fps_d);
+  tcase_add_test (tc, videotimecode_compare_frames);
+  tcase_add_test (tc, videotimecode_compare_seconds);
+  tcase_add_test (tc, videotimecode_compare_minutes);
+  tcase_add_test (tc, videotimecode_compare_hours);
+  tcase_add_test (tc, videotimecode_compare_fieldcounts);
+
+  tcase_add_test (tc, videotimecode_addframe_10);
+  tcase_add_test (tc, videotimecode_addframe_0);
+  tcase_add_test (tc, videotimecode_addframe_high);
+  tcase_add_test (tc, videotimecode_addframe_dropframe);
+  tcase_add_test (tc, videotimecode_addframe_framedropped);
+  tcase_add_test (tc, videotimecode_addframe_wrapover);
+  tcase_add_test (tc, videotimecode_addframe_60drop_dropframe);
+  tcase_add_test (tc, videotimecode_addframe_60drop_framedropped);
+  tcase_add_test (tc, videotimecode_addframe_60drop_wrapover);
+  tcase_add_test (tc, videotimecode_addframe_loop);
+
+  tcase_add_test (tc, videotimecode_dailyjam_todatetime);
+  tcase_add_test (tc, videotimecode_dailyjam_compare);
+  return s;
+}
+
+GST_CHECK_MAIN (gst_videotimecode);
diff --git a/tests/check/pipelines/vorbisenc.c b/tests/check/pipelines/vorbisenc.c
index 246c903..6eeefcc 100644
--- a/tests/check/pipelines/vorbisenc.c
+++ b/tests/check/pipelines/vorbisenc.c
@@ -96,7 +96,7 @@
 
   pipe_str = g_strdup_printf ("audiotestsrc timestamp-offset=%" G_GUINT64_FORMAT
       " ! audio/x-raw,rate=44100"
-      " ! audioconvert ! vorbisenc ! fakesink", TIMESTAMP_OFFSET);
+      " ! audioconvert ! vorbisenc ! fakesink name=sink", TIMESTAMP_OFFSET);
 
   bin = gst_parse_launch (pipe_str, &error);
   fail_unless (bin != NULL, "Error parsing pipeline: %s",
@@ -105,7 +105,7 @@
 
   /* get the pad */
   {
-    GstElement *sink = gst_bin_get_by_name (GST_BIN (bin), "fakesink0");
+    GstElement *sink = gst_bin_get_by_name (GST_BIN (bin), "sink");
 
     fail_unless (sink != NULL, "Could not get fakesink out of bin");
     pad = gst_element_get_static_pad (sink, "sink");
@@ -187,7 +187,8 @@
   GError *error = NULL;
 
   pipe_str = g_strdup_printf ("audiotestsrc"
-      " ! audio/x-raw,rate=44100 ! audioconvert ! vorbisenc ! fakesink");
+      " ! audio/x-raw,rate=44100 ! audioconvert ! vorbisenc "
+      " ! fakesink name=sink");
 
   bin = gst_parse_launch (pipe_str, &error);
   fail_unless (bin != NULL, "Error parsing pipeline: %s",
@@ -196,7 +197,7 @@
 
   /* get the pad */
   {
-    GstElement *sink = gst_bin_get_by_name (GST_BIN (bin), "fakesink0");
+    GstElement *sink = gst_bin_get_by_name (GST_BIN (bin), "sink");
 
     fail_unless (sink != NULL, "Could not get fakesink out of bin");
     pad = gst_element_get_static_pad (sink, "sink");
@@ -287,8 +288,8 @@
 
   /* make audioencoder act sufficiently pedantic */
   pipe_str = g_strdup_printf ("audiotestsrc samplesperbuffer=1024"
-      " ! audio/x-raw,rate=44100" " ! audioconvert "
-      " ! vorbisenc tolerance=10000000 ! fakesink");
+      " ! audio/x-raw,rate=44100 ! audioconvert "
+      " ! vorbisenc tolerance=10000000 name=enc ! fakesink name=sink");
 
   bin = gst_parse_launch (pipe_str, &error);
   fail_unless (bin != NULL, "Error parsing pipeline: %s",
@@ -300,7 +301,7 @@
 
   /* get the pad to use to drop buffers */
   {
-    GstElement *sink = gst_bin_get_by_name (GST_BIN (bin), "vorbisenc0");
+    GstElement *sink = gst_bin_get_by_name (GST_BIN (bin), "enc");
 
     fail_unless (sink != NULL, "Could not get vorbisenc out of bin");
     droppad = gst_element_get_static_pad (sink, "sink");
@@ -310,7 +311,7 @@
 
   /* get the pad */
   {
-    GstElement *sink = gst_bin_get_by_name (GST_BIN (bin), "fakesink0");
+    GstElement *sink = gst_bin_get_by_name (GST_BIN (bin), "sink");
 
     fail_unless (sink != NULL, "Could not get fakesink out of bin");
     pad = gst_element_get_static_pad (sink, "sink");
diff --git a/tests/examples/Makefile.am b/tests/examples/Makefile.am
index 90171e9..330ea8f 100644
--- a/tests/examples/Makefile.am
+++ b/tests/examples/Makefile.am
@@ -2,8 +2,8 @@
 GTK_SUBDIRS = playback seek snapshot
 endif
 
-SUBDIRS = app audio dynamic fft $(GTK_SUBDIRS) gio overlay playrec encoding
-DIST_SUBDIRS = app audio dynamic fft gio playback overlay seek snapshot playrec encoding
+SUBDIRS = app audio decodebin_next dynamic fft $(GTK_SUBDIRS) gio overlay playrec encoding
+DIST_SUBDIRS = app audio dynamic decodebin_next fft gio playback overlay seek snapshot playrec encoding
 
 include $(top_srcdir)/common/parallel-subdirs.mak
 
diff --git a/tests/examples/Makefile.in b/tests/examples/Makefile.in
index bd90000..58be066 100644
--- a/tests/examples/Makefile.in
+++ b/tests/examples/Makefile.in
@@ -101,6 +101,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -410,6 +411,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -423,6 +427,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -460,6 +467,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -511,8 +519,8 @@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 @HAVE_GTK_TRUE@GTK_SUBDIRS = playback seek snapshot
-SUBDIRS = app audio dynamic fft $(GTK_SUBDIRS) gio overlay playrec encoding
-DIST_SUBDIRS = app audio dynamic fft gio playback overlay seek snapshot playrec encoding
+SUBDIRS = app audio decodebin_next dynamic fft $(GTK_SUBDIRS) gio overlay playrec encoding
+DIST_SUBDIRS = app audio dynamic decodebin_next fft gio playback overlay seek snapshot playrec encoding
 all: all-recursive
 
 .SUFFIXES:
diff --git a/tests/examples/app/Makefile.in b/tests/examples/app/Makefile.in
index ae18eb3..1b2413a 100644
--- a/tests/examples/app/Makefile.in
+++ b/tests/examples/app/Makefile.in
@@ -101,6 +101,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -453,6 +454,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -466,6 +470,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -503,6 +510,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/tests/examples/audio/Makefile.in b/tests/examples/audio/Makefile.in
index a015ed2..8f24af6 100644
--- a/tests/examples/audio/Makefile.in
+++ b/tests/examples/audio/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -410,6 +411,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -423,6 +427,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -460,6 +467,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/tests/examples/decodebin_next/Makefile.am b/tests/examples/decodebin_next/Makefile.am
new file mode 100644
index 0000000..5270bec
--- /dev/null
+++ b/tests/examples/decodebin_next/Makefile.am
@@ -0,0 +1,5 @@
+noinst_PROGRAMS = decodebin3 playbin-test
+
+LDADD = $(GST_LIBS)
+
+AM_CFLAGS = -I$(top_builddir)/gst-libs $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
diff --git a/tests/examples/decodebin_next/Makefile.in b/tests/examples/decodebin_next/Makefile.in
new file mode 100644
index 0000000..bae3fc7
--- /dev/null
+++ b/tests/examples/decodebin_next/Makefile.in
@@ -0,0 +1,812 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+noinst_PROGRAMS = decodebin3$(EXEEXT) playbin-test$(EXEEXT)
+subdir = tests/examples/decodebin_next
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/common/m4/as-ac-expand.m4 \
+	$(top_srcdir)/common/m4/as-auto-alt.m4 \
+	$(top_srcdir)/common/m4/as-compiler-flag.m4 \
+	$(top_srcdir)/common/m4/as-libtool.m4 \
+	$(top_srcdir)/common/m4/as-version.m4 \
+	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
+	$(top_srcdir)/common/m4/gst-arch.m4 \
+	$(top_srcdir)/common/m4/gst-args.m4 \
+	$(top_srcdir)/common/m4/gst-check.m4 \
+	$(top_srcdir)/common/m4/gst-default.m4 \
+	$(top_srcdir)/common/m4/gst-error.m4 \
+	$(top_srcdir)/common/m4/gst-feature.m4 \
+	$(top_srcdir)/common/m4/gst-function.m4 \
+	$(top_srcdir)/common/m4/gst-gettext.m4 \
+	$(top_srcdir)/common/m4/gst-glib2.m4 \
+	$(top_srcdir)/common/m4/gst-package-release-datetime.m4 \
+	$(top_srcdir)/common/m4/gst-platform.m4 \
+	$(top_srcdir)/common/m4/gst-plugin-docs.m4 \
+	$(top_srcdir)/common/m4/gst-plugindir.m4 \
+	$(top_srcdir)/common/m4/gst.m4 \
+	$(top_srcdir)/common/m4/gtk-doc.m4 \
+	$(top_srcdir)/common/m4/introspection.m4 \
+	$(top_srcdir)/common/m4/orc.m4 $(top_srcdir)/common/m4/pkg.m4 \
+	$(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gst-alsa.m4 \
+	$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+	$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+	$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
+	$(top_srcdir)/m4/lrint.m4 $(top_srcdir)/m4/lrintf.m4 \
+	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+	$(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+decodebin3_SOURCES = decodebin3.c
+decodebin3_OBJECTS = decodebin3.$(OBJEXT)
+decodebin3_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+decodebin3_DEPENDENCIES = $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+playbin_test_SOURCES = playbin-test.c
+playbin_test_OBJECTS = playbin-test.$(OBJEXT)
+playbin_test_LDADD = $(LDADD)
+playbin_test_DEPENDENCIES = $(am__DEPENDENCIES_1)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+SOURCES = decodebin3.c playbin-test.c
+DIST_SOURCES = decodebin3.c playbin-test.c
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+ALSA_CFLAGS = @ALSA_CFLAGS@
+ALSA_LIBS = @ALSA_LIBS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUDIORESAMPLE_FORMAT_AUTO = @AUDIORESAMPLE_FORMAT_AUTO@
+AUDIORESAMPLE_FORMAT_FLOAT = @AUDIORESAMPLE_FORMAT_FLOAT@
+AUDIORESAMPLE_FORMAT_INT = @AUDIORESAMPLE_FORMAT_INT@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CDPARANOIA_CFLAGS = @CDPARANOIA_CFLAGS@
+CDPARANOIA_LIBS = @CDPARANOIA_LIBS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFAULT_AUDIOSINK = @DEFAULT_AUDIOSINK@
+DEFAULT_AUDIOSRC = @DEFAULT_AUDIOSRC@
+DEFAULT_VIDEOSINK = @DEFAULT_VIDEOSINK@
+DEFAULT_VIDEOSRC = @DEFAULT_VIDEOSRC@
+DEFAULT_VISUALIZER = @DEFAULT_VISUALIZER@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DEPRECATED_CFLAGS = @DEPRECATED_CFLAGS@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ERROR_CFLAGS = @ERROR_CFLAGS@
+ERROR_CXXFLAGS = @ERROR_CXXFLAGS@
+EXEEXT = @EXEEXT@
+FFLAGS = @FFLAGS@
+FGREP = @FGREP@
+GCOV = @GCOV@
+GCOV_CFLAGS = @GCOV_CFLAGS@
+GCOV_LIBS = @GCOV_LIBS@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LDFLAGS = @GIO_LDFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GIO_UNIX_2_0_CFLAGS = @GIO_UNIX_2_0_CFLAGS@
+GIO_UNIX_2_0_LIBS = @GIO_UNIX_2_0_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_EXTRA_CFLAGS = @GLIB_EXTRA_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GLIB_MKENUMS = @GLIB_MKENUMS@
+GLIB_PREFIX = @GLIB_PREFIX@
+GLIB_REQ = @GLIB_REQ@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+GST_AGE = @GST_AGE@
+GST_ALL_LDFLAGS = @GST_ALL_LDFLAGS@
+GST_API_VERSION = @GST_API_VERSION@
+GST_BASE_CFLAGS = @GST_BASE_CFLAGS@
+GST_BASE_LIBS = @GST_BASE_LIBS@
+GST_CFLAGS = @GST_CFLAGS@
+GST_CHECK_CFLAGS = @GST_CHECK_CFLAGS@
+GST_CHECK_LIBS = @GST_CHECK_LIBS@
+GST_CONTROLLER_CFLAGS = @GST_CONTROLLER_CFLAGS@
+GST_CONTROLLER_LIBS = @GST_CONTROLLER_LIBS@
+GST_CURRENT = @GST_CURRENT@
+GST_CXXFLAGS = @GST_CXXFLAGS@
+GST_INSTALL_PLUGINS_HELPER = @GST_INSTALL_PLUGINS_HELPER@
+GST_LEVEL_DEFAULT = @GST_LEVEL_DEFAULT@
+GST_LIBS = @GST_LIBS@
+GST_LIBVERSION = @GST_LIBVERSION@
+GST_LIB_LDFLAGS = @GST_LIB_LDFLAGS@
+GST_LICENSE = @GST_LICENSE@
+GST_LT_LDFLAGS = @GST_LT_LDFLAGS@
+GST_NET_CFLAGS = @GST_NET_CFLAGS@
+GST_NET_LIBS = @GST_NET_LIBS@
+GST_OPTION_CFLAGS = @GST_OPTION_CFLAGS@
+GST_OPTION_CXXFLAGS = @GST_OPTION_CXXFLAGS@
+GST_PACKAGE_NAME = @GST_PACKAGE_NAME@
+GST_PACKAGE_ORIGIN = @GST_PACKAGE_ORIGIN@
+GST_PKG_CONFIG_PATH = @GST_PKG_CONFIG_PATH@
+GST_PLUGINS_ALL = @GST_PLUGINS_ALL@
+GST_PLUGINS_BASE_CFLAGS = @GST_PLUGINS_BASE_CFLAGS@
+GST_PLUGINS_DIR = @GST_PLUGINS_DIR@
+GST_PLUGINS_NONPORTED = @GST_PLUGINS_NONPORTED@
+GST_PLUGINS_SELECTED = @GST_PLUGINS_SELECTED@
+GST_PLUGIN_LDFLAGS = @GST_PLUGIN_LDFLAGS@
+GST_PLUGIN_LIBTOOLFLAGS = @GST_PLUGIN_LIBTOOLFLAGS@
+GST_PREFIX = @GST_PREFIX@
+GST_REVISION = @GST_REVISION@
+GST_TOOLS_DIR = @GST_TOOLS_DIR@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+GTK_QUARTZ_CFLAGS = @GTK_QUARTZ_CFLAGS@
+GTK_QUARTZ_LIBS = @GTK_QUARTZ_LIBS@
+GTK_X11_CFLAGS = @GTK_X11_CFLAGS@
+GTK_X11_LIBS = @GTK_X11_LIBS@
+HAVE_CDPARANOIA = @HAVE_CDPARANOIA@
+HAVE_XSHM = @HAVE_XSHM@
+HAVE_ZLIB = @HAVE_ZLIB@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_INIT = @INTROSPECTION_INIT@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+IVORBIS_CFLAGS = @IVORBIS_CFLAGS@
+IVORBIS_LIBS = @IVORBIS_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBVISUAL_CFLAGS = @LIBVISUAL_CFLAGS@
+LIBVISUAL_LIBS = @LIBVISUAL_LIBS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOCALEDIR = @LOCALEDIR@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OGG_CFLAGS = @OGG_CFLAGS@
+OGG_LIBS = @OGG_LIBS@
+OPUS_CFLAGS = @OPUS_CFLAGS@
+OPUS_LIBS = @OPUS_LIBS@
+ORCC = @ORCC@
+ORCC_FLAGS = @ORCC_FLAGS@
+ORC_CFLAGS = @ORC_CFLAGS@
+ORC_LIBS = @ORC_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MICRO = @PACKAGE_VERSION_MICRO@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_NANO = @PACKAGE_VERSION_NANO@
+PACKAGE_VERSION_RELEASE = @PACKAGE_VERSION_RELEASE@
+PANGO_CFLAGS = @PANGO_CFLAGS@
+PANGO_LIBS = @PANGO_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PLUGINDIR = @PLUGINDIR@
+POSUB = @POSUB@
+PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+QTCHOOSER = @QTCHOOSER@
+QT_CFLAGS = @QT_CFLAGS@
+QT_LIBS = @QT_LIBS@
+QT_MOC = @QT_MOC@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
+STRIP = @STRIP@
+THEORA_CFLAGS = @THEORA_CFLAGS@
+THEORA_LIBS = @THEORA_LIBS@
+USE_NLS = @USE_NLS@
+VALGRIND_CFLAGS = @VALGRIND_CFLAGS@
+VALGRIND_LIBS = @VALGRIND_LIBS@
+VALGRIND_PATH = @VALGRIND_PATH@
+VERSION = @VERSION@
+VORBIS_CFLAGS = @VORBIS_CFLAGS@
+VORBIS_LIBS = @VORBIS_LIBS@
+WARNING_CFLAGS = @WARNING_CFLAGS@
+WARNING_CXXFLAGS = @WARNING_CXXFLAGS@
+WIN32_LIBS = @WIN32_LIBS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XSHM_CFLAGS = @XSHM_CFLAGS@
+XSHM_LIBS = @XSHM_LIBS@
+XVIDEO_CFLAGS = @XVIDEO_CFLAGS@
+XVIDEO_LIBS = @XVIDEO_LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+ZLIB_CFLAGS = @ZLIB_CFLAGS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+LDADD = $(GST_LIBS)
+AM_CFLAGS = -I$(top_builddir)/gst-libs $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/examples/decodebin_next/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu tests/examples/decodebin_next/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+
+decodebin3$(EXEEXT): $(decodebin3_OBJECTS) $(decodebin3_DEPENDENCIES) $(EXTRA_decodebin3_DEPENDENCIES) 
+	@rm -f decodebin3$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(decodebin3_OBJECTS) $(decodebin3_LDADD) $(LIBS)
+
+playbin-test$(EXEEXT): $(playbin_test_OBJECTS) $(playbin_test_DEPENDENCIES) $(EXTRA_playbin_test_DEPENDENCIES) 
+	@rm -f playbin-test$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(playbin_test_OBJECTS) $(playbin_test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decodebin3.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/playbin-test.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \
+	ctags-am distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tests/examples/decodebin_next/decodebin3.c b/tests/examples/decodebin_next/decodebin3.c
new file mode 100644
index 0000000..2b36239
--- /dev/null
+++ b/tests/examples/decodebin_next/decodebin3.c
@@ -0,0 +1,356 @@
+/* sample application for testing decodebin3
+ *
+ * Copyright (C) 2015 Centricular Ltd
+ *  @author:  Edward Hervey <edward@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 <glib.h>
+#include <glib-object.h>
+#include <glib/gprintf.h>
+#include <gst/gst.h>
+
+/* Global structure */
+
+typedef struct _MyDataStruct
+{
+  GMainLoop *mainloop;
+  GstElement *pipeline;
+  GstBus *demux_bus;
+
+  GstElement *decodebin;
+
+  GstElement *src;
+  GList *other_src;
+  GstElement *playsink;
+
+  /* Current collection */
+  GstStreamCollection *collection;
+  guint notify_id;
+
+  guint current_audio;
+  guint current_video;
+  guint current_text;
+
+  glong timeout_id;
+} MyDataStruct;
+
+static void
+print_tag_foreach (const GstTagList * tags, const gchar * tag,
+    gpointer user_data)
+{
+  GValue val = { 0, };
+  gchar *str;
+  gint depth = GPOINTER_TO_INT (user_data);
+
+  if (!gst_tag_list_copy_value (&val, tags, tag))
+    return;
+
+  if (G_VALUE_HOLDS_STRING (&val))
+    str = g_value_dup_string (&val);
+  else
+    str = gst_value_serialize (&val);
+
+  g_print ("%*s%s: %s\n", 2 * depth, " ", gst_tag_get_nick (tag), str);
+  g_free (str);
+
+  g_value_unset (&val);
+}
+
+static void
+dump_collection (GstStreamCollection * collection)
+{
+  guint i;
+  GstTagList *tags;
+  GstCaps *caps;
+
+  for (i = 0; i < gst_stream_collection_get_size (collection); i++) {
+    GstStream *stream = gst_stream_collection_get_stream (collection, i);
+    g_print (" Stream %u type %s flags 0x%x\n", i,
+        gst_stream_type_get_name (gst_stream_get_stream_type (stream)),
+        gst_stream_get_stream_flags (stream));
+    g_print ("  ID: %s\n", gst_stream_get_stream_id (stream));
+
+    caps = gst_stream_get_caps (stream);
+    if (caps) {
+      gchar *caps_str = gst_caps_to_string (caps);
+      g_print ("  caps: %s\n", caps_str);
+      g_free (caps_str);
+      gst_caps_unref (caps);
+    }
+
+    tags = gst_stream_get_tags (stream);
+    if (tags) {
+      g_print ("  tags:\n");
+      gst_tag_list_foreach (tags, print_tag_foreach, GUINT_TO_POINTER (3));
+      gst_tag_list_unref (tags);
+    }
+  }
+}
+
+static gboolean
+switch_streams (MyDataStruct * data)
+{
+  guint i, nb_streams;
+  gint nb_video = 0, nb_audio = 0, nb_text = 0;
+  GstStream *videos[256], *audios[256], *texts[256];
+  GList *streams = NULL;
+  GstEvent *ev;
+
+  g_print ("Switching Streams...\n");
+
+  /* Calculate the number of streams of each type */
+  nb_streams = gst_stream_collection_get_size (data->collection);
+  for (i = 0; i < nb_streams; i++) {
+    GstStream *stream = gst_stream_collection_get_stream (data->collection, i);
+    GstStreamType stype = gst_stream_get_stream_type (stream);
+    if (stype == GST_STREAM_TYPE_VIDEO) {
+      videos[nb_video] = stream;
+      nb_video += 1;
+    } else if (stype == GST_STREAM_TYPE_AUDIO) {
+      audios[nb_audio] = stream;
+      nb_audio += 1;
+    } else if (stype == GST_STREAM_TYPE_TEXT) {
+      texts[nb_text] = stream;
+      nb_text += 1;
+    }
+  }
+
+  if (nb_video) {
+    data->current_video = (data->current_video + 1) % nb_video;
+    streams =
+        g_list_append (streams,
+        (gchar *) gst_stream_get_stream_id (videos[data->current_video]));
+    g_print ("  Selecting video channel #%d : %s\n", data->current_video,
+        gst_stream_get_stream_id (videos[data->current_video]));
+  }
+  if (nb_audio) {
+    data->current_audio = (data->current_audio + 1) % nb_audio;
+    streams =
+        g_list_append (streams,
+        (gchar *) gst_stream_get_stream_id (audios[data->current_audio]));
+    g_print ("  Selecting audio channel #%d : %s\n", data->current_audio,
+        gst_stream_get_stream_id (audios[data->current_audio]));
+  }
+  if (nb_text) {
+    data->current_text = (data->current_text + 1) % nb_text;
+    streams =
+        g_list_append (streams,
+        (gchar *) gst_stream_get_stream_id (texts[data->current_text]));
+    g_print ("  Selecting text channel #%d : %s\n", data->current_text,
+        gst_stream_get_stream_id (texts[data->current_text]));
+  }
+
+  ev = gst_event_new_select_streams (streams);
+  gst_element_send_event (data->pipeline, ev);
+
+  return G_SOURCE_CONTINUE;
+}
+
+static void
+stream_notify_cb (GstStreamCollection * collection, GstStream * stream,
+    GParamSpec * pspec, guint * val)
+{
+  g_print ("Got stream-notify from stream %s for %s (collection %p)\n",
+      stream->stream_id, pspec->name, collection);
+  if (g_str_equal (pspec->name, "caps")) {
+    GstCaps *caps = gst_stream_get_caps (stream);
+    gchar *caps_str = gst_caps_to_string (caps);
+    g_print (" New caps: %s\n", caps_str);
+    g_free (caps_str);
+    gst_caps_unref (caps);
+  }
+}
+
+static GstBusSyncReply
+_on_bus_message (GstBus * bus, GstMessage * message, MyDataStruct * data)
+{
+  GstObject *src = GST_MESSAGE_SRC (message);
+  switch (GST_MESSAGE_TYPE (message)) {
+    case GST_MESSAGE_ERROR:{
+      GError *err = NULL;
+      gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (message));
+      gst_message_parse_error (message, &err, NULL);
+
+      g_printerr ("ERROR: from element %s: %s\n", name, err->message);
+      g_error_free (err);
+      g_free (name);
+
+      g_printf ("Stopping\n");
+      g_main_loop_quit (data->mainloop);
+      break;
+    }
+    case GST_MESSAGE_EOS:
+      g_printf ("EOS ! Stopping \n");
+      g_main_loop_quit (data->mainloop);
+      break;
+    case GST_MESSAGE_STREAM_COLLECTION:
+    {
+      GstStreamCollection *collection = NULL;
+      gst_message_parse_stream_collection (message, &collection);
+      if (collection) {
+        g_printf ("Got a collection from %s:\n",
+            src ? GST_OBJECT_NAME (src) : "Unknown");
+        dump_collection (collection);
+        if (data->collection && data->notify_id) {
+          g_signal_handler_disconnect (data->collection, data->notify_id);
+          data->notify_id = 0;
+        }
+        gst_object_replace ((GstObject **) & data->collection,
+            (GstObject *) collection);
+        if (data->collection) {
+          data->notify_id =
+              g_signal_connect (data->collection, "stream-notify",
+              (GCallback) stream_notify_cb, data);
+        }
+        if (data->timeout_id == 0)
+          /* In 5s try to change streams */
+          data->timeout_id =
+              g_timeout_add_seconds (5, (GSourceFunc) switch_streams, data);
+        gst_object_unref (collection);
+      }
+      break;
+    }
+    default:
+      break;
+  }
+
+  return GST_BUS_PASS;
+}
+
+static void
+decodebin_pad_added_cb (GstElement * dbin, GstPad * pad, MyDataStruct * data)
+{
+  gchar *pad_name = gst_pad_get_name (pad);
+  const gchar *sink_pad = NULL;
+
+  GST_DEBUG_OBJECT (pad, "New pad ! Link to playsink !");
+  if (!g_ascii_strncasecmp (pad_name, "video_", 6))
+    sink_pad = "video_sink";
+  else if (!g_ascii_strncasecmp (pad_name, "audio_", 6))
+    sink_pad = "audio_sink";
+  else if (!g_ascii_strncasecmp (pad_name, "text_", 5))
+    sink_pad = "text_sink";
+  else
+    GST_WARNING_OBJECT (pad, "non audio/video/text pad");
+
+  g_free (pad_name);
+
+  if (sink_pad) {
+    GstPad *playsink_pad;
+
+    playsink_pad = gst_element_get_request_pad (data->playsink, sink_pad);
+    if (playsink_pad)
+      gst_pad_link (pad, playsink_pad);
+  }
+}
+
+int
+main (int argc, gchar ** argv)
+{
+  GError *error = NULL;
+  GstBus *bus;
+  MyDataStruct *data;
+  int i;
+
+  gst_init (&argc, &argv);
+
+  data = g_new0 (MyDataStruct, 1);
+
+  if (argc < 2) {
+    g_print ("Usage: decodebin3 URI\n");
+    return 1;
+  }
+
+  data->pipeline = gst_pipeline_new ("pipeline");
+  data->decodebin = gst_element_factory_make ("decodebin3", NULL);
+
+  data->src =
+      gst_element_make_from_uri (GST_URI_SRC, argv[1], "source", &error);
+  if (error) {
+    g_printf ("pipeline could not be constructed: %s\n", error->message);
+    g_error_free (error);
+    return 1;
+  }
+  data->playsink = gst_element_factory_make ("playsink", NULL);
+
+#if 0
+  {
+    GstElement *sink = gst_element_factory_make ("fakesink", NULL);
+    g_object_set (sink, "sync", FALSE, NULL);
+    g_object_set (data->playsink, "video-sink", sink, NULL);
+
+    sink = gst_element_factory_make ("fakesink", NULL);
+    g_object_set (sink, "sync", FALSE, NULL);
+    g_object_set (data->playsink, "audio-sink", sink, NULL);
+  }
+#endif
+
+  gst_bin_add_many ((GstBin *) data->pipeline, data->src, data->decodebin,
+      data->playsink, NULL);
+  if (!gst_element_link (data->src, (GstElement *) data->decodebin)) {
+    g_printf ("Could not link source to demuxer\n");
+    return 1;
+  }
+
+  /* Handle other inputs if specified */
+  if (argc > 2) {
+    for (i = 2; i < argc; i++) {
+      GstElement *new_src =
+          gst_element_make_from_uri (GST_URI_SRC, argv[i], NULL, &error);
+      GstPad *src_pad, *sink_pad;
+      if (error) {
+        g_printf ("pipeline could not be constructed: %s\n", error->message);
+        g_error_free (error);
+        return 1;
+      }
+      data->other_src = g_list_append (data->other_src, new_src);
+      gst_bin_add ((GstBin *) data->pipeline, new_src);
+      src_pad = gst_element_get_static_pad (new_src, "src");
+      sink_pad = gst_element_get_request_pad (data->decodebin, "sink_%u");
+      if (gst_pad_link (src_pad, sink_pad) != GST_PAD_LINK_OK) {
+        g_printf ("Could not link new source to decodebin : %s\n", argv[i]);
+        return 1;
+      }
+    }
+  }
+
+
+  g_signal_connect (data->decodebin, "pad-added",
+      (GCallback) decodebin_pad_added_cb, data);
+  data->mainloop = g_main_loop_new (NULL, FALSE);
+
+  /* Put a bus handler */
+  bus = gst_pipeline_get_bus (GST_PIPELINE (data->pipeline));
+  gst_bus_set_sync_handler (bus, (GstBusSyncHandler) _on_bus_message, data,
+      NULL);
+
+  /* Start pipeline */
+  gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
+  g_main_loop_run (data->mainloop);
+
+  gst_element_set_state (data->pipeline, GST_STATE_NULL);
+
+  gst_object_unref (data->pipeline);
+  gst_object_unref (bus);
+
+  return 0;
+}
diff --git a/tests/examples/decodebin_next/playbin-test.c b/tests/examples/decodebin_next/playbin-test.c
new file mode 100644
index 0000000..f51b1fc
--- /dev/null
+++ b/tests/examples/decodebin_next/playbin-test.c
@@ -0,0 +1,329 @@
+/* sample application for testing decodebin3 w/ playbin
+ *
+ * Copyright (C) 2015 Centricular Ltd
+ *  @author:  Edward Hervey <edward@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 <glib.h>
+#include <glib-object.h>
+#include <glib/gprintf.h>
+#include <gst/gst.h>
+
+/* Global structure */
+
+typedef struct _MyDataStruct
+{
+  GMainLoop *mainloop;
+  GstElement *pipeline;
+  GstBus *bus;
+
+  /* Current collection */
+  GstStreamCollection *collection;
+  guint notify_id;
+
+  guint current_audio;
+  guint current_video;
+  guint current_text;
+
+  glong timeout_id;
+} MyDataStruct;
+
+static void
+print_tag_foreach (const GstTagList * tags, const gchar * tag,
+    gpointer user_data)
+{
+  GValue val = { 0, };
+  gchar *str;
+  gint depth = GPOINTER_TO_INT (user_data);
+
+  if (!gst_tag_list_copy_value (&val, tags, tag))
+    return;
+
+  if (G_VALUE_HOLDS_STRING (&val))
+    str = g_value_dup_string (&val);
+  else
+    str = gst_value_serialize (&val);
+
+  g_print ("%*s%s: %s\n", 2 * depth, " ", gst_tag_get_nick (tag), str);
+  g_free (str);
+
+  g_value_unset (&val);
+}
+
+static void
+dump_collection (GstStreamCollection * collection)
+{
+  guint i;
+  GstTagList *tags;
+  GstCaps *caps;
+
+  for (i = 0; i < gst_stream_collection_get_size (collection); i++) {
+    GstStream *stream = gst_stream_collection_get_stream (collection, i);
+    g_print (" Stream %u type %s flags 0x%x\n", i,
+        gst_stream_type_get_name (gst_stream_get_stream_type (stream)),
+        gst_stream_get_stream_flags (stream));
+    g_print ("  ID: %s\n", gst_stream_get_stream_id (stream));
+
+    caps = gst_stream_get_caps (stream);
+    if (caps) {
+      gchar *caps_str = gst_caps_to_string (caps);
+      g_print ("  caps: %s\n", caps_str);
+      g_free (caps_str);
+      gst_caps_unref (caps);
+    }
+
+    tags = gst_stream_get_tags (stream);
+    if (tags) {
+      g_print ("  tags:\n");
+      gst_tag_list_foreach (tags, print_tag_foreach, GUINT_TO_POINTER (3));
+      gst_tag_list_unref (tags);
+    }
+  }
+}
+
+static gboolean
+switch_streams (MyDataStruct * data)
+{
+  guint i, nb_streams;
+  gint nb_video = 0, nb_audio = 0, nb_text = 0;
+  GstStream *videos[256], *audios[256], *texts[256];
+  GList *streams = NULL;
+  GstEvent *ev;
+
+  g_print ("Switching Streams...\n");
+
+  /* Calculate the number of streams of each type */
+  nb_streams = gst_stream_collection_get_size (data->collection);
+  for (i = 0; i < nb_streams; i++) {
+    GstStream *stream = gst_stream_collection_get_stream (data->collection, i);
+    GstStreamType stype = gst_stream_get_stream_type (stream);
+    if (stype == GST_STREAM_TYPE_VIDEO) {
+      videos[nb_video] = stream;
+      nb_video += 1;
+    } else if (stype == GST_STREAM_TYPE_AUDIO) {
+      audios[nb_audio] = stream;
+      nb_audio += 1;
+    } else if (stype == GST_STREAM_TYPE_TEXT) {
+      texts[nb_text] = stream;
+      nb_text += 1;
+    }
+  }
+
+  if (nb_video) {
+    data->current_video = (data->current_video + 1) % nb_video;
+    streams =
+        g_list_append (streams,
+        (gchar *) gst_stream_get_stream_id (videos[data->current_video]));
+    g_print ("  Selecting video channel #%d : %s\n", data->current_video,
+        gst_stream_get_stream_id (videos[data->current_video]));
+  }
+  if (nb_audio) {
+    data->current_audio = (data->current_audio + 1) % nb_audio;
+    streams =
+        g_list_append (streams,
+        (gchar *) gst_stream_get_stream_id (audios[data->current_audio]));
+    g_print ("  Selecting audio channel #%d : %s\n", data->current_audio,
+        gst_stream_get_stream_id (audios[data->current_audio]));
+  }
+  if (nb_text) {
+    data->current_text = (data->current_text + 1) % nb_text;
+    streams =
+        g_list_append (streams,
+        (gchar *) gst_stream_get_stream_id (texts[data->current_text]));
+    g_print ("  Selecting text channel #%d : %s\n", data->current_text,
+        gst_stream_get_stream_id (texts[data->current_text]));
+  }
+
+  ev = gst_event_new_select_streams (streams);
+  gst_element_send_event (data->pipeline, ev);
+
+  return G_SOURCE_CONTINUE;
+}
+
+static void
+stream_notify_cb (GstStreamCollection * collection, GstStream * stream,
+    GParamSpec * pspec, guint * val)
+{
+  g_print ("Got stream-notify from stream %s for %s (collection %p)\n",
+      stream->stream_id, pspec->name, collection);
+  if (g_str_equal (pspec->name, "caps")) {
+    GstCaps *caps = gst_stream_get_caps (stream);
+    gchar *caps_str = gst_caps_to_string (caps);
+    g_print (" New caps: %s\n", caps_str);
+    g_free (caps_str);
+    gst_caps_unref (caps);
+  }
+}
+
+static GstBusSyncReply
+_on_bus_message (GstBus * bus, GstMessage * message, MyDataStruct * data)
+{
+  GstObject *src = GST_MESSAGE_SRC (message);
+  switch (GST_MESSAGE_TYPE (message)) {
+    case GST_MESSAGE_ERROR:{
+      GError *err = NULL;
+      gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (message));
+      gst_message_parse_error (message, &err, NULL);
+
+      g_printerr ("ERROR: from element %s: %s\n", name, err->message);
+      g_error_free (err);
+      g_free (name);
+
+      g_printf ("Stopping\n");
+      g_main_loop_quit (data->mainloop);
+      break;
+    }
+    case GST_MESSAGE_EOS:
+      g_printf ("EOS ! Stopping \n");
+      g_main_loop_quit (data->mainloop);
+      break;
+    case GST_MESSAGE_STREAM_COLLECTION:
+    {
+      GstStreamCollection *collection = NULL;
+      gst_message_parse_stream_collection (message, &collection);
+      if (collection) {
+        g_printf ("Got a collection from %s:\n",
+            src ? GST_OBJECT_NAME (src) : "Unknown");
+        dump_collection (collection);
+        if (data->collection && data->notify_id) {
+          g_signal_handler_disconnect (data->collection, data->notify_id);
+          data->notify_id = 0;
+        }
+        gst_object_replace ((GstObject **) & data->collection,
+            (GstObject *) collection);
+        if (data->collection) {
+          data->notify_id =
+              g_signal_connect (data->collection, "stream-notify",
+              (GCallback) stream_notify_cb, data);
+        }
+        if (data->timeout_id == 0)
+          /* In 5s try to change streams */
+          data->timeout_id =
+              g_timeout_add_seconds (5, (GSourceFunc) switch_streams, data);
+        gst_object_unref (collection);
+      }
+      break;
+    }
+    case GST_MESSAGE_STREAMS_SELECTED:
+    {
+      GstStreamCollection *collection = NULL;
+      gst_message_parse_streams_selected (message, &collection);
+      if (collection) {
+        guint i, len;
+        g_printf ("Got a STREAMS_SELECTED message from %s (seqnum:%"
+            G_GUINT32_FORMAT "):\n", src ? GST_OBJECT_NAME (src) : "unknown",
+            GST_MESSAGE_SEQNUM (message));
+        len = gst_message_streams_selected_get_size (message);
+        for (i = 0; i < len; i++) {
+          GstStream *stream =
+              gst_message_streams_selected_get_stream (message, i);
+          g_printf ("  Stream #%d : %s\n", i,
+              gst_stream_get_stream_id (stream));
+          gst_object_unref (stream);
+        }
+        gst_object_unref (collection);
+      }
+    }
+    default:
+      break;
+  }
+
+  return GST_BUS_PASS;
+}
+
+static gchar *
+cmdline_to_uri (const gchar * arg)
+{
+  if (gst_uri_is_valid (arg))
+    return g_strdup (arg);
+
+  return gst_filename_to_uri (arg, NULL);
+}
+
+int
+main (int argc, gchar ** argv)
+{
+  GstBus *bus;
+  MyDataStruct *data;
+  gchar *uri;
+
+  gst_init (&argc, &argv);
+
+  data = g_new0 (MyDataStruct, 1);
+
+  uri = cmdline_to_uri (argv[1]);
+
+  if (argc < 2 || uri == NULL) {
+    g_print ("Usage: %s URI\n", argv[0]);
+    return 1;
+  }
+
+  data->pipeline = gst_element_factory_make ("playbin3", NULL);
+  if (data->pipeline == NULL) {
+    g_printerr ("Failed to create playbin element. Aborting");
+    return 1;
+  }
+
+  g_object_set (data->pipeline, "uri", uri, "auto-select-streams", FALSE, NULL);
+  g_free (uri);
+
+#if 0
+  {
+    GstElement *sink = gst_element_factory_make ("fakesink", NULL);
+    g_object_set (sink, "sync", FALSE, NULL);
+    g_object_set (data->pipeline, "video-sink", sink, NULL);
+
+    sink = gst_element_factory_make ("fakesink", NULL);
+    g_object_set (sink, "sync", FALSE, NULL);
+    g_object_set (data->pipeline, "audio-sink", sink, NULL);
+  }
+#endif
+
+  /* Handle other input if specified */
+  if (argc > 2) {
+    uri = cmdline_to_uri (argv[2]);
+    if (uri != NULL) {
+      g_object_set (data->pipeline, "suburi", uri, NULL);
+      g_free (uri);
+    } else {
+      g_warning ("Could not parse auxilliary file argument. Ignoring");
+    }
+  }
+
+  data->mainloop = g_main_loop_new (NULL, FALSE);
+
+  /* Put a bus handler */
+  bus = gst_pipeline_get_bus (GST_PIPELINE (data->pipeline));
+  gst_bus_set_sync_handler (bus, (GstBusSyncHandler) _on_bus_message, data,
+      NULL);
+
+  /* Start pipeline */
+  gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
+  g_main_loop_run (data->mainloop);
+
+  gst_element_set_state (data->pipeline, GST_STATE_NULL);
+
+  gst_object_unref (data->pipeline);
+  gst_object_unref (bus);
+
+  return 0;
+}
diff --git a/tests/examples/dynamic/Makefile.in b/tests/examples/dynamic/Makefile.in
index 0d0a77e..2d0dd61 100644
--- a/tests/examples/dynamic/Makefile.in
+++ b/tests/examples/dynamic/Makefile.in
@@ -99,6 +99,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -426,6 +427,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -439,6 +443,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -476,6 +483,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/tests/examples/encoding/Makefile.in b/tests/examples/encoding/Makefile.in
index 4788a62..d4f8a81 100644
--- a/tests/examples/encoding/Makefile.in
+++ b/tests/examples/encoding/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -402,6 +403,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -415,6 +419,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -452,6 +459,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/tests/examples/fft/Makefile.in b/tests/examples/fft/Makefile.in
index 187cc3d..5eb8966 100644
--- a/tests/examples/fft/Makefile.in
+++ b/tests/examples/fft/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -400,6 +401,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -413,6 +417,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -450,6 +457,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/tests/examples/gio/Makefile.in b/tests/examples/gio/Makefile.in
index a1739b9..8e3fe23 100644
--- a/tests/examples/gio/Makefile.in
+++ b/tests/examples/gio/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -403,6 +404,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -416,6 +420,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -453,6 +460,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/tests/examples/overlay/Makefile.in b/tests/examples/overlay/Makefile.in
index 7973f6d..973cfff 100644
--- a/tests/examples/overlay/Makefile.in
+++ b/tests/examples/overlay/Makefile.in
@@ -101,6 +101,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -463,6 +464,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -476,6 +480,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -513,6 +520,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/tests/examples/playback/Makefile.in b/tests/examples/playback/Makefile.in
index c70dd52..de0818e 100644
--- a/tests/examples/playback/Makefile.in
+++ b/tests/examples/playback/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -399,6 +400,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -412,6 +416,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -449,6 +456,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/tests/examples/playback/playback-test.c b/tests/examples/playback/playback-test.c
index a238003..18b5b54 100644
--- a/tests/examples/playback/playback-test.c
+++ b/tests/examples/playback/playback-test.c
@@ -2210,7 +2210,8 @@
       app->embed_xid);
 #elif defined (GDK_WINDOWING_QUARTZ)
   app->embed_xid = (guintptr) gdk_quartz_window_get_nsview (window);
-  g_print ("Window realize: video window NSView = %p\n", app->embed_xid);
+  g_print ("Window realize: video window NSView = %" G_GUINTPTR_FORMAT "\n",
+      app->embed_xid);
 #elif defined (GDK_WINDOWING_X11)
   app->embed_xid = GDK_WINDOW_XID (window);
   g_print ("Window realize: video window XID = %" G_GUINTPTR_FORMAT "\n",
diff --git a/tests/examples/playrec/Makefile.in b/tests/examples/playrec/Makefile.in
index 15fd7f1..469e6ee 100644
--- a/tests/examples/playrec/Makefile.in
+++ b/tests/examples/playrec/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -399,6 +400,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -412,6 +416,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -449,6 +456,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/tests/examples/seek/Makefile.in b/tests/examples/seek/Makefile.in
index df94fe8..3eea09d 100644
--- a/tests/examples/seek/Makefile.in
+++ b/tests/examples/seek/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -421,6 +422,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -434,6 +438,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -471,6 +478,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/tests/examples/seek/stepping.c b/tests/examples/seek/stepping.c
index 44bc033..31656af 100644
--- a/tests/examples/seek/stepping.c
+++ b/tests/examples/seek/stepping.c
@@ -36,7 +36,7 @@
 
   length = sin (period);
 
-  period += M_PI / 40;
+  period += G_PI / 40;
 
   length += 1.1;
   length *= 100 * GST_MSECOND;
diff --git a/tests/examples/seek/stepping2.c b/tests/examples/seek/stepping2.c
index 70d297d..34922a9 100644
--- a/tests/examples/seek/stepping2.c
+++ b/tests/examples/seek/stepping2.c
@@ -36,7 +36,7 @@
 
   rate = sin (period);
 
-  period += M_PI / 150;
+  period += G_PI / 150;
 
   rate += 1.2;
 
diff --git a/tests/examples/snapshot/Makefile.in b/tests/examples/snapshot/Makefile.in
index 7f2e144..4ca6c3e 100644
--- a/tests/examples/snapshot/Makefile.in
+++ b/tests/examples/snapshot/Makefile.in
@@ -98,6 +98,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -397,6 +398,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -410,6 +414,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -447,6 +454,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/tests/files/Makefile.in b/tests/files/Makefile.in
index 48bdeee..57a9a74 100644
--- a/tests/files/Makefile.in
+++ b/tests/files/Makefile.in
@@ -96,6 +96,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -345,6 +346,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -358,6 +362,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -395,6 +402,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/tests/icles/Makefile.am b/tests/icles/Makefile.am
index f479bb7..f489cd4 100644
--- a/tests/icles/Makefile.am
+++ b/tests/icles/Makefile.am
@@ -88,6 +88,10 @@
 test_scale_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
 test_scale_LDADD = $(GST_LIBS) $(LIBM)
 
+test_resample_SOURCES = test-resample.c
+test_resample_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
+test_resample_LDADD = $(GST_LIBS) $(LIBM)
+
 test_box_SOURCES = test-box.c
 test_box_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
 test_box_LDADD = $(GST_LIBS) $(LIBM)
@@ -98,4 +102,5 @@
 
 noinst_PROGRAMS = $(X_TESTS) $(PANGO_TESTS) \
 	audio-trickplay playbin-text position-formats stress-playbin \
-	test-scale test-box test-effect-switch test-overlay-blending test-reverseplay
+	test-scale test-box test-effect-switch test-overlay-blending test-reverseplay \
+	test-resample
diff --git a/tests/icles/Makefile.in b/tests/icles/Makefile.in
index 6aef428..007e8fd 100644
--- a/tests/icles/Makefile.in
+++ b/tests/icles/Makefile.in
@@ -95,7 +95,7 @@
 	position-formats$(EXEEXT) stress-playbin$(EXEEXT) \
 	test-scale$(EXEEXT) test-box$(EXEEXT) \
 	test-effect-switch$(EXEEXT) test-overlay-blending$(EXEEXT) \
-	test-reverseplay$(EXEEXT)
+	test-reverseplay$(EXEEXT) test-resample$(EXEEXT)
 subdir = tests/icles
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/common/m4/as-ac-expand.m4 \
@@ -104,6 +104,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -245,6 +246,13 @@
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
 	$(test_overlay_blending_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
 	$(LDFLAGS) -o $@
+am_test_resample_OBJECTS = test_resample-test-resample.$(OBJEXT)
+test_resample_OBJECTS = $(am_test_resample_OBJECTS)
+test_resample_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
+test_resample_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_resample_CFLAGS) \
+	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
 am_test_reverseplay_OBJECTS =  \
 	test_reverseplay-test-reverseplay.$(OBJEXT)
 test_reverseplay_OBJECTS = $(am_test_reverseplay_OBJECTS)
@@ -321,9 +329,9 @@
 	$(position_formats_SOURCES) $(stress_playbin_SOURCES) \
 	$(stress_videooverlay_SOURCES) $(test_box_SOURCES) \
 	$(test_colorkey_SOURCES) $(test_effect_switch_SOURCES) \
-	$(test_overlay_blending_SOURCES) $(test_reverseplay_SOURCES) \
-	$(test_scale_SOURCES) $(test_textoverlay_SOURCES) \
-	$(test_videooverlay_SOURCES)
+	$(test_overlay_blending_SOURCES) $(test_resample_SOURCES) \
+	$(test_reverseplay_SOURCES) $(test_scale_SOURCES) \
+	$(test_textoverlay_SOURCES) $(test_videooverlay_SOURCES)
 DIST_SOURCES = $(audio_trickplay_SOURCES) \
 	$(am__input_selector_test_SOURCES_DIST) \
 	$(am__output_selector_test_SOURCES_DIST) \
@@ -332,8 +340,8 @@
 	$(am__stress_videooverlay_SOURCES_DIST) $(test_box_SOURCES) \
 	$(am__test_colorkey_SOURCES_DIST) \
 	$(test_effect_switch_SOURCES) $(test_overlay_blending_SOURCES) \
-	$(test_reverseplay_SOURCES) $(test_scale_SOURCES) \
-	$(am__test_textoverlay_SOURCES_DIST) \
+	$(test_resample_SOURCES) $(test_reverseplay_SOURCES) \
+	$(test_scale_SOURCES) $(am__test_textoverlay_SOURCES_DIST) \
 	$(am__test_videooverlay_SOURCES_DIST)
 RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
 	ctags-recursive dvi-recursive html-recursive info-recursive \
@@ -596,6 +604,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -609,6 +620,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -646,6 +660,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
@@ -765,6 +780,9 @@
 test_scale_SOURCES = test-scale.c
 test_scale_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
 test_scale_LDADD = $(GST_LIBS) $(LIBM)
+test_resample_SOURCES = test-resample.c
+test_resample_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
+test_resample_LDADD = $(GST_LIBS) $(LIBM)
 test_box_SOURCES = test-box.c
 test_box_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
 test_box_LDADD = $(GST_LIBS) $(LIBM)
@@ -858,6 +876,10 @@
 	@rm -f test-overlay-blending$(EXEEXT)
 	$(AM_V_CCLD)$(test_overlay_blending_LINK) $(test_overlay_blending_OBJECTS) $(test_overlay_blending_LDADD) $(LIBS)
 
+test-resample$(EXEEXT): $(test_resample_OBJECTS) $(test_resample_DEPENDENCIES) $(EXTRA_test_resample_DEPENDENCIES) 
+	@rm -f test-resample$(EXEEXT)
+	$(AM_V_CCLD)$(test_resample_LINK) $(test_resample_OBJECTS) $(test_resample_LDADD) $(LIBS)
+
 test-reverseplay$(EXEEXT): $(test_reverseplay_OBJECTS) $(test_reverseplay_DEPENDENCIES) $(EXTRA_test_reverseplay_DEPENDENCIES) 
 	@rm -f test-reverseplay$(EXEEXT)
 	$(AM_V_CCLD)$(test_reverseplay_LINK) $(test_reverseplay_OBJECTS) $(test_reverseplay_LDADD) $(LIBS)
@@ -891,6 +913,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_colorkey-test-colorkey.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_effect_switch-test-effect-switch.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_overlay_blending-test-overlay-blending.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_resample-test-resample.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_reverseplay-test-reverseplay.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_scale-test-scale.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_textoverlay-test-textoverlay.Po@am__quote@
@@ -1074,6 +1097,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) $(test_overlay_blending_CFLAGS) $(CFLAGS) -c -o test_overlay_blending-test-overlay-blending.obj `if test -f 'test-overlay-blending.c'; then $(CYGPATH_W) 'test-overlay-blending.c'; else $(CYGPATH_W) '$(srcdir)/test-overlay-blending.c'; fi`
 
+test_resample-test-resample.o: test-resample.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resample_CFLAGS) $(CFLAGS) -MT test_resample-test-resample.o -MD -MP -MF $(DEPDIR)/test_resample-test-resample.Tpo -c -o test_resample-test-resample.o `test -f 'test-resample.c' || echo '$(srcdir)/'`test-resample.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_resample-test-resample.Tpo $(DEPDIR)/test_resample-test-resample.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-resample.c' object='test_resample-test-resample.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) $(test_resample_CFLAGS) $(CFLAGS) -c -o test_resample-test-resample.o `test -f 'test-resample.c' || echo '$(srcdir)/'`test-resample.c
+
+test_resample-test-resample.obj: test-resample.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resample_CFLAGS) $(CFLAGS) -MT test_resample-test-resample.obj -MD -MP -MF $(DEPDIR)/test_resample-test-resample.Tpo -c -o test_resample-test-resample.obj `if test -f 'test-resample.c'; then $(CYGPATH_W) 'test-resample.c'; else $(CYGPATH_W) '$(srcdir)/test-resample.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_resample-test-resample.Tpo $(DEPDIR)/test_resample-test-resample.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test-resample.c' object='test_resample-test-resample.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) $(test_resample_CFLAGS) $(CFLAGS) -c -o test_resample-test-resample.obj `if test -f 'test-resample.c'; then $(CYGPATH_W) 'test-resample.c'; else $(CYGPATH_W) '$(srcdir)/test-resample.c'; fi`
+
 test_reverseplay-test-reverseplay.o: test-reverseplay.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_reverseplay_CFLAGS) $(CFLAGS) -MT test_reverseplay-test-reverseplay.o -MD -MP -MF $(DEPDIR)/test_reverseplay-test-reverseplay.Tpo -c -o test_reverseplay-test-reverseplay.o `test -f 'test-reverseplay.c' || echo '$(srcdir)/'`test-reverseplay.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_reverseplay-test-reverseplay.Tpo $(DEPDIR)/test_reverseplay-test-reverseplay.Po
diff --git a/tests/icles/playback/Makefile.in b/tests/icles/playback/Makefile.in
index ed84e80..56c36ad 100644
--- a/tests/icles/playback/Makefile.in
+++ b/tests/icles/playback/Makefile.in
@@ -100,6 +100,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -445,6 +446,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -458,6 +462,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -495,6 +502,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/tests/icles/test-colorkey.c b/tests/icles/test-colorkey.c
index 62b041d..12b7732 100644
--- a/tests/icles/test-colorkey.c
+++ b/tests/icles/test-colorkey.c
@@ -23,6 +23,9 @@
 #include "config.h"
 #endif
 
+/* FIXME: gdk_cairo_create() is deprecated nowadays */
+#define GDK_DISABLE_DEPRECATION_WARNINGS
+
 #include <stdlib.h>
 #include <string.h>
 
diff --git a/tests/icles/test-resample.c b/tests/icles/test-resample.c
new file mode 100644
index 0000000..a956125
--- /dev/null
+++ b/tests/icles/test-resample.c
@@ -0,0 +1,123 @@
+/* GStreamer interactive audioresample test
+ * Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.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 <stdlib.h>
+
+#include <gst/gst.h>
+
+static GstElement *
+make_pipeline (gint type)
+{
+  GstElement *result;
+  gchar *pstr;
+
+  switch (type) {
+    case 0:
+      pstr = g_strdup_printf ("audiotestsrc ! audio/x-raw,rate=44100 ! "
+          " audioresample ! capsfilter name=filter ! capssetter caps="
+          "audio/x-raw,rate=44100 ! wavenc ! filesink location=test.wav");
+      break;
+    default:
+      return NULL;
+  }
+
+  result = gst_parse_launch_full (pstr, NULL, GST_PARSE_FLAG_NONE, NULL);
+  g_print ("created test %d: \"%s\"\n", type, pstr);
+  g_free (pstr);
+
+  return result;
+}
+
+typedef struct
+{
+  gint rate;
+  GstElement *filter;
+} Data;
+
+static GstPadProbeReturn
+have_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
+{
+  Data *data = user_data;
+  gchar *capsstr;
+  GstCaps *caps;
+
+  g_print ("resample to %d   \r", data->rate);
+
+  capsstr = g_strdup_printf ("audio/x-raw, rate=(int)%d", data->rate);
+  caps = gst_caps_from_string (capsstr);
+  g_free (capsstr);
+  g_object_set (data->filter, "caps", caps, NULL);
+  gst_caps_unref (caps);
+
+  data->rate += 100;
+
+  if (data->rate > 128000)
+    gst_element_post_message (data->filter,
+        gst_message_new_application (GST_OBJECT (data->filter),
+            gst_structure_new_empty ("my-message")));
+
+  return GST_PAD_PROBE_OK;
+}
+
+int
+main (int argc, char **argv)
+{
+  GstElement *pipe;
+  GstMessage *message;
+  GstPad *srcpad;
+  Data data;
+
+  gst_init (&argc, &argv);
+
+  pipe = make_pipeline (0);
+  if (pipe == NULL)
+    return -1;
+
+  data.rate = 1000;
+  data.filter = gst_bin_get_by_name (GST_BIN (pipe), "filter");
+  g_assert (data.filter);
+
+  srcpad = gst_element_get_static_pad (data.filter, "src");
+  gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM, have_probe,
+      &data, NULL);
+  gst_object_unref (srcpad);
+
+  gst_element_set_state (pipe, GST_STATE_PLAYING);
+
+  while (TRUE) {
+    message =
+        gst_bus_poll (GST_ELEMENT_BUS (pipe),
+        GST_MESSAGE_ERROR | GST_MESSAGE_APPLICATION, 50 * GST_MSECOND);
+    if (message) {
+      g_print ("got error           \n");
+
+      gst_message_unref (message);
+      break;
+    }
+  }
+  gst_object_unref (data.filter);
+  gst_element_set_state (pipe, GST_STATE_NULL);
+  gst_object_unref (pipe);
+
+  return 0;
+}
diff --git a/tools/Makefile.in b/tools/Makefile.in
index 32f9782..c166edb 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -101,6 +101,7 @@
 	$(top_srcdir)/common/m4/as-libtool.m4 \
 	$(top_srcdir)/common/m4/as-version.m4 \
 	$(top_srcdir)/common/m4/ax_create_stdint_h.m4 \
+	$(top_srcdir)/common/m4/ax_pthread.m4 \
 	$(top_srcdir)/common/m4/gst-arch.m4 \
 	$(top_srcdir)/common/m4/gst-args.m4 \
 	$(top_srcdir)/common/m4/gst-check.m4 \
@@ -466,6 +467,9 @@
 PLUGINDIR = @PLUGINDIR@
 POSUB = @POSUB@
 PROFILE_CFLAGS = @PROFILE_CFLAGS@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
 PYTHON = @PYTHON@
 PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
 PYTHON_PLATFORM = @PYTHON_PLATFORM@
@@ -479,6 +483,9 @@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+SSE2_CFLAGS = @SSE2_CFLAGS@
+SSE41_CFLAGS = @SSE41_CFLAGS@
+SSE_CFLAGS = @SSE_CFLAGS@
 STRIP = @STRIP@
 THEORA_CFLAGS = @THEORA_CFLAGS@
 THEORA_LIBS = @THEORA_LIBS@
@@ -516,6 +523,7 @@
 am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
 bindir = @bindir@
 build = @build@
 build_alias = @build_alias@
diff --git a/tools/gst-device-monitor.c b/tools/gst-device-monitor.c
index c0a8ec1..43a127f 100644
--- a/tools/gst-device-monitor.c
+++ b/tools/gst-device-monitor.c
@@ -128,10 +128,12 @@
     case GST_MESSAGE_DEVICE_ADDED:
       gst_message_parse_device_added (msg, &device);
       device_added (device);
+      gst_object_unref (device);
       break;
     case GST_MESSAGE_DEVICE_REMOVED:
       gst_message_parse_device_removed (msg, &device);
       device_removed (device);
+      gst_object_unref (device);
       break;
     default:
       g_print ("%s message\n", GST_MESSAGE_TYPE_NAME (msg));
diff --git a/tools/gst-play.c b/tools/gst-play.c
index 6a70f0e..5708737 100644
--- a/tools/gst-play.c
+++ b/tools/gst-play.c
@@ -920,6 +920,7 @@
 {
   const gchar *prop_cur, *prop_n, *prop_get, *name;
   gint cur = -1, n = -1;
+  guint flag, cur_flags;
 
   switch (track_type) {
     case GST_PLAY_TRACK_TYPE_AUDIO:
@@ -927,48 +928,70 @@
       prop_cur = "current-audio";
       prop_n = "n-audio";
       name = "audio";
+      flag = 0x2;
       break;
     case GST_PLAY_TRACK_TYPE_VIDEO:
       prop_get = "get-video-tags";
       prop_cur = "current-video";
       prop_n = "n-video";
       name = "video";
+      flag = 0x1;
       break;
     case GST_PLAY_TRACK_TYPE_SUBTITLE:
       prop_get = "get-text-tags";
       prop_cur = "current-text";
       prop_n = "n-text";
       name = "subtitle";
+      flag = 0x4;
       break;
     default:
       return;
   }
 
-  g_object_get (play->playbin, prop_cur, &cur, prop_n, &n, NULL);
+  g_object_get (play->playbin, prop_cur, &cur, prop_n, &n, "flags", &cur_flags,
+      NULL);
 
   if (n < 1) {
     g_print ("No %s tracks.\n", name);
-  } else if (n == 1) {
-    g_print ("No other %s tracks to switch to.\n", name);
   } else {
     gchar *lcode = NULL, *lname = NULL;
     const gchar *lang = NULL;
     GstTagList *tags = NULL;
 
-    cur = (cur + 1) % n;
-    g_signal_emit_by_name (play->playbin, prop_get, cur, &tags);
-    if (tags != NULL) {
-      if (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &lcode))
-        lang = gst_tag_get_language_name (lcode);
-      else if (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_NAME, &lname))
-        lang = lname;
-      gst_tag_list_unref (tags);
-    }
-    if (lang != NULL)
-      g_print ("Switching to %s track %d of %d (%s).\n", name, cur + 1, n,
-          lang);
+    if (!(cur_flags & flag))
+      cur = 0;
     else
-      g_print ("Switching to %s track %d of %d.\n", name, cur + 1, n);
+      cur = (cur + 1) % (n + 1);
+
+    if (cur >= n && track_type != GST_PLAY_TRACK_TYPE_VIDEO) {
+      cur = -1;
+      g_print ("Disabling %s.           \n", name);
+      if (cur_flags & flag) {
+        cur_flags &= ~flag;
+        g_object_set (play->playbin, "flags", cur_flags, NULL);
+      }
+    } else {
+      /* For video we only want to switch between streams, not disable it altogether */
+      if (cur >= n)
+        cur = 0;
+      if (!(cur_flags & flag) && track_type != GST_PLAY_TRACK_TYPE_VIDEO) {
+        cur_flags |= flag;
+        g_object_set (play->playbin, "flags", cur_flags, NULL);
+      }
+      g_signal_emit_by_name (play->playbin, prop_get, cur, &tags);
+      if (tags != NULL) {
+        if (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &lcode))
+          lang = gst_tag_get_language_name (lcode);
+        else if (gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_NAME, &lname))
+          lang = lname;
+        gst_tag_list_unref (tags);
+      }
+      if (lang != NULL)
+        g_print ("Switching to %s track %d of %d (%s).\n", name, cur + 1, n,
+            lang);
+      else
+        g_print ("Switching to %s track %d of %d.\n", name, cur + 1, n);
+    }
     g_object_set (play->playbin, prop_cur, cur, NULL);
     g_free (lcode);
     g_free (lname);
@@ -1289,5 +1312,6 @@
   g_free (video_sink);
 
   g_print ("\n");
+  gst_deinit ();
   return 0;
 }
diff --git a/win32/common/_stdint.h b/win32/common/_stdint.h
index 33ddb19..8d38855 100644
--- a/win32/common/_stdint.h
+++ b/win32/common/_stdint.h
@@ -1,8 +1,8 @@
 #ifndef _GST_PLUGINS_BASE__STDINT_H
 #define _GST_PLUGINS_BASE__STDINT_H 1
 #ifndef _GENERATED_STDINT_H
-#define _GENERATED_STDINT_H "gst-plugins-base 1.8.3"
-/* generated using gnu compiler gcc (Debian 6.1.1-12) 6.1.1 20160815 */
+#define _GENERATED_STDINT_H "gst-plugins-base 1.9.90"
+/* generated using gnu compiler gcc-6 (Debian 6.2.0-5) 6.2.0 20160927 */
 #define _STDINT_HAVE_STDINT_H 1
 #include <stdint.h>
 #endif
diff --git a/win32/common/audio-enumtypes.c b/win32/common/audio-enumtypes.c
index 853929c..5c95483 100644
--- a/win32/common/audio-enumtypes.c
+++ b/win32/common/audio-enumtypes.c
@@ -10,6 +10,7 @@
 #include "audio-converter.h"
 #include "audio-info.h"
 #include "audio-quantize.h"
+#include "audio-resampler.h"
 #include "gstaudioringbuffer.h"
 
 /* enumerations from "audio-format.h" */
@@ -343,6 +344,98 @@
   return g_define_type_id__volatile;
 }
 
+/* enumerations from "audio-resampler.h" */
+GType
+gst_audio_resampler_filter_mode_get_type (void)
+{
+  static volatile gsize g_define_type_id__volatile = 0;
+  if (g_once_init_enter (&g_define_type_id__volatile)) {
+    static const GEnumValue values[] = {
+      {GST_AUDIO_RESAMPLER_FILTER_MODE_INTERPOLATED,
+          "GST_AUDIO_RESAMPLER_FILTER_MODE_INTERPOLATED", "interpolated"},
+      {GST_AUDIO_RESAMPLER_FILTER_MODE_FULL,
+          "GST_AUDIO_RESAMPLER_FILTER_MODE_FULL", "full"},
+      {GST_AUDIO_RESAMPLER_FILTER_MODE_AUTO,
+          "GST_AUDIO_RESAMPLER_FILTER_MODE_AUTO", "auto"},
+      {0, NULL, NULL}
+    };
+    GType g_define_type_id =
+        g_enum_register_static ("GstAudioResamplerFilterMode", values);
+    g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+  }
+  return g_define_type_id__volatile;
+}
+
+GType
+gst_audio_resampler_filter_interpolation_get_type (void)
+{
+  static volatile gsize g_define_type_id__volatile = 0;
+  if (g_once_init_enter (&g_define_type_id__volatile)) {
+    static const GEnumValue values[] = {
+      {GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_NONE,
+          "GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_NONE", "none"},
+      {GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_LINEAR,
+          "GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_LINEAR", "linear"},
+      {GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_CUBIC,
+          "GST_AUDIO_RESAMPLER_FILTER_INTERPOLATION_CUBIC", "cubic"},
+      {0, NULL, NULL}
+    };
+    GType g_define_type_id =
+        g_enum_register_static ("GstAudioResamplerFilterInterpolation", values);
+    g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+  }
+  return g_define_type_id__volatile;
+}
+
+GType
+gst_audio_resampler_method_get_type (void)
+{
+  static volatile gsize g_define_type_id__volatile = 0;
+  if (g_once_init_enter (&g_define_type_id__volatile)) {
+    static const GEnumValue values[] = {
+      {GST_AUDIO_RESAMPLER_METHOD_NEAREST, "GST_AUDIO_RESAMPLER_METHOD_NEAREST",
+          "nearest"},
+      {GST_AUDIO_RESAMPLER_METHOD_LINEAR, "GST_AUDIO_RESAMPLER_METHOD_LINEAR",
+          "linear"},
+      {GST_AUDIO_RESAMPLER_METHOD_CUBIC, "GST_AUDIO_RESAMPLER_METHOD_CUBIC",
+          "cubic"},
+      {GST_AUDIO_RESAMPLER_METHOD_BLACKMAN_NUTTALL,
+          "GST_AUDIO_RESAMPLER_METHOD_BLACKMAN_NUTTALL", "blackman-nuttall"},
+      {GST_AUDIO_RESAMPLER_METHOD_KAISER, "GST_AUDIO_RESAMPLER_METHOD_KAISER",
+          "kaiser"},
+      {0, NULL, NULL}
+    };
+    GType g_define_type_id =
+        g_enum_register_static ("GstAudioResamplerMethod", values);
+    g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+  }
+  return g_define_type_id__volatile;
+}
+
+GType
+gst_audio_resampler_flags_get_type (void)
+{
+  static volatile gsize g_define_type_id__volatile = 0;
+  if (g_once_init_enter (&g_define_type_id__volatile)) {
+    static const GFlagsValue values[] = {
+      {GST_AUDIO_RESAMPLER_FLAG_NONE, "GST_AUDIO_RESAMPLER_FLAG_NONE", "none"},
+      {GST_AUDIO_RESAMPLER_FLAG_NON_INTERLEAVED_IN,
+            "GST_AUDIO_RESAMPLER_FLAG_NON_INTERLEAVED_IN",
+          "non-interleaved-in"},
+      {GST_AUDIO_RESAMPLER_FLAG_NON_INTERLEAVED_OUT,
+            "GST_AUDIO_RESAMPLER_FLAG_NON_INTERLEAVED_OUT",
+          "non-interleaved-out"},
+      {GST_AUDIO_RESAMPLER_FLAG_VARIABLE_RATE,
+          "GST_AUDIO_RESAMPLER_FLAG_VARIABLE_RATE", "variable-rate"},
+      {0, NULL, NULL}
+    };
+    GType g_define_type_id =
+        g_flags_register_static ("GstAudioResamplerFlags", values);
+    g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+  }
+  return g_define_type_id__volatile;
+}
+
 /* enumerations from "gstaudioringbuffer.h" */
 GType
 gst_audio_ring_buffer_state_get_type (void)
diff --git a/win32/common/audio-enumtypes.h b/win32/common/audio-enumtypes.h
index 7d03861..f529f49 100644
--- a/win32/common/audio-enumtypes.h
+++ b/win32/common/audio-enumtypes.h
@@ -42,6 +42,16 @@
 GType gst_audio_quantize_flags_get_type (void);
 #define GST_TYPE_AUDIO_QUANTIZE_FLAGS (gst_audio_quantize_flags_get_type())
 
+/* enumerations from "audio-resampler.h" */
+GType gst_audio_resampler_filter_mode_get_type (void);
+#define GST_TYPE_AUDIO_RESAMPLER_FILTER_MODE (gst_audio_resampler_filter_mode_get_type())
+GType gst_audio_resampler_filter_interpolation_get_type (void);
+#define GST_TYPE_AUDIO_RESAMPLER_FILTER_INTERPOLATION (gst_audio_resampler_filter_interpolation_get_type())
+GType gst_audio_resampler_method_get_type (void);
+#define GST_TYPE_AUDIO_RESAMPLER_METHOD (gst_audio_resampler_method_get_type())
+GType gst_audio_resampler_flags_get_type (void);
+#define GST_TYPE_AUDIO_RESAMPLER_FLAGS (gst_audio_resampler_flags_get_type())
+
 /* enumerations from "gstaudioringbuffer.h" */
 GType gst_audio_ring_buffer_state_get_type (void);
 #define GST_TYPE_AUDIO_RING_BUFFER_STATE (gst_audio_ring_buffer_state_get_type())
diff --git a/win32/common/config.h b/win32/common/config.h
index 4293787..790115d 100644
--- a/win32/common/config.h
+++ b/win32/common/config.h
@@ -90,7 +90,7 @@
 #define GST_PACKAGE_ORIGIN "Unknown package origin"
 
 /* GStreamer package release date/time for plugins as YYYY-MM-DD */
-#define GST_PACKAGE_RELEASE_DATETIME "2016-08-19"
+#define GST_PACKAGE_RELEASE_DATETIME "2016-09-30"
 
 /* Define if static plugins should be built */
 #undef GST_PLUGIN_BUILD_STATIC
@@ -164,6 +164,14 @@
    */
 #undef HAVE_DCGETTEXT
 
+/* Define to 1 if you have the declaration of `__i386__', and to 0 if you
+   don't. */
+#undef HAVE_DECL___I386__
+
+/* Define to 1 if you have the declaration of `__x86_64__', and to 0 if you
+   don't. */
+#undef HAVE_DECL___X86_64__
+
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
@@ -248,9 +256,27 @@
 /* Define to 1 if you have the <process.h> header file. */
 #define HAVE_PROCESS_H 1
 
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Have PTHREAD_PRIO_INHERIT. */
+#undef HAVE_PTHREAD_PRIO_INHERIT
+
 /* Define if RDTSC is available */
 #undef HAVE_RDTSC
 
+/* Define to 1 if you have the <smmintrin.h> header file. */
+#undef HAVE_SMMINTRIN_H
+
+/* SSE support is enabled */
+#undef HAVE_SSE
+
+/* SSE2 support is enabled */
+#undef HAVE_SSE2
+
+/* SSE4.1 support is enabled */
+#undef HAVE_SSE41
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
@@ -339,7 +365,7 @@
 #define PACKAGE_NAME "GStreamer Base Plug-ins"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "GStreamer Base Plug-ins 1.8.3"
+#define PACKAGE_STRING "GStreamer Base Plug-ins 1.9.90"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "gst-plugins-base"
@@ -348,7 +374,7 @@
 #undef PACKAGE_URL
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "1.8.3"
+#define PACKAGE_VERSION "1.9.90"
 
 /* directory where plugins are located */
 #ifdef _DEBUG
@@ -357,6 +383,10 @@
 #  define PLUGINDIR PREFIX "\\lib\\gstreamer-0.11"
 #endif
 
+/* Define to necessary symbol if this constant uses a non-standard name on
+   your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
 /* The size of `char', as computed by sizeof. */
 #undef SIZEOF_CHAR
 
@@ -382,7 +412,7 @@
 #undef USE_TREMOLO
 
 /* Version number of package */
-#define VERSION "1.8.3"
+#define VERSION "1.9.90"
 
 /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
    significant byte first (like Motorola and SPARC, unlike Intel). */
diff --git a/win32/common/libgstapp.def b/win32/common/libgstapp.def
index de8fdb4..1a7184e 100644
--- a/win32/common/libgstapp.def
+++ b/win32/common/libgstapp.def
@@ -14,9 +14,12 @@
 	gst_app_sink_set_emit_signals
 	gst_app_sink_set_max_buffers
 	gst_app_sink_set_wait_on_eos
+	gst_app_sink_try_pull_preroll
+	gst_app_sink_try_pull_sample
 	gst_app_src_end_of_stream
 	gst_app_src_get_caps
 	gst_app_src_get_current_level_bytes
+	gst_app_src_get_duration
 	gst_app_src_get_emit_signals
 	gst_app_src_get_latency
 	gst_app_src_get_max_bytes
@@ -27,6 +30,7 @@
 	gst_app_src_push_sample
 	gst_app_src_set_callbacks
 	gst_app_src_set_caps
+	gst_app_src_set_duration
 	gst_app_src_set_emit_signals
 	gst_app_src_set_latency
 	gst_app_src_set_max_bytes
diff --git a/win32/common/libgstaudio.def b/win32/common/libgstaudio.def
index d0b7f44..fa39be3 100644
--- a/win32/common/libgstaudio.def
+++ b/win32/common/libgstaudio.def
@@ -36,6 +36,7 @@
 	gst_audio_channel_position_get_type
 	gst_audio_channel_positions_from_mask
 	gst_audio_channel_positions_to_mask
+	gst_audio_channel_positions_to_string
 	gst_audio_channel_positions_to_valid_order
 	gst_audio_check_valid_channel_positions
 	gst_audio_clipping_meta_api_get_type
@@ -75,6 +76,7 @@
 	gst_audio_decoder_merge_tags
 	gst_audio_decoder_negotiate
 	gst_audio_decoder_proxy_getcaps
+	gst_audio_decoder_set_allocation_caps
 	gst_audio_decoder_set_drainable
 	gst_audio_decoder_set_estimate_rate
 	gst_audio_decoder_set_latency
@@ -108,6 +110,7 @@
 	gst_audio_encoder_merge_tags
 	gst_audio_encoder_negotiate
 	gst_audio_encoder_proxy_getcaps
+	gst_audio_encoder_set_allocation_caps
 	gst_audio_encoder_set_drainable
 	gst_audio_encoder_set_frame_max
 	gst_audio_encoder_set_frame_samples_max
@@ -154,6 +157,19 @@
 	gst_audio_quantize_reset
 	gst_audio_quantize_samples
 	gst_audio_reorder_channels
+	gst_audio_resampler_filter_interpolation_get_type
+	gst_audio_resampler_filter_mode_get_type
+	gst_audio_resampler_flags_get_type
+	gst_audio_resampler_free
+	gst_audio_resampler_get_in_frames
+	gst_audio_resampler_get_max_latency
+	gst_audio_resampler_get_out_frames
+	gst_audio_resampler_method_get_type
+	gst_audio_resampler_new
+	gst_audio_resampler_options_set_quality
+	gst_audio_resampler_resample
+	gst_audio_resampler_reset
+	gst_audio_resampler_update
 	gst_audio_ring_buffer_acquire
 	gst_audio_ring_buffer_activate
 	gst_audio_ring_buffer_advance
diff --git a/win32/common/libgstpbutils.def b/win32/common/libgstpbutils.def
index 785bfb4..302b6cb 100644
--- a/win32/common/libgstpbutils.def
+++ b/win32/common/libgstpbutils.def
@@ -2,9 +2,11 @@
 	gst_audio_visualizer_get_type
 	gst_audio_visualizer_shader_get_type
 	gst_codec_utils_aac_caps_set_level_and_profile
+	gst_codec_utils_aac_get_channels
 	gst_codec_utils_aac_get_index_from_sample_rate
 	gst_codec_utils_aac_get_level
 	gst_codec_utils_aac_get_profile
+	gst_codec_utils_aac_get_sample_rate
 	gst_codec_utils_aac_get_sample_rate_from_index
 	gst_codec_utils_h264_caps_set_level_and_profile
 	gst_codec_utils_h264_get_level
diff --git a/win32/common/libgstrtp.def b/win32/common/libgstrtp.def
index 52f654f..38c7c28 100644
--- a/win32/common/libgstrtp.def
+++ b/win32/common/libgstrtp.def
@@ -12,7 +12,17 @@
 	gst_rtcp_buffer_validate_data_reduced
 	gst_rtcp_buffer_validate_reduced
 	gst_rtcp_ntp_to_unix
+	gst_rtcp_packet_add_profile_specific_ext
 	gst_rtcp_packet_add_rb
+	gst_rtcp_packet_app_get_data
+	gst_rtcp_packet_app_get_data_length
+	gst_rtcp_packet_app_get_name
+	gst_rtcp_packet_app_get_ssrc
+	gst_rtcp_packet_app_get_subtype
+	gst_rtcp_packet_app_set_data_length
+	gst_rtcp_packet_app_set_name
+	gst_rtcp_packet_app_set_ssrc
+	gst_rtcp_packet_app_set_subtype
 	gst_rtcp_packet_bye_add_ssrc
 	gst_rtcp_packet_bye_add_ssrcs
 	gst_rtcp_packet_bye_get_nth_ssrc
@@ -20,6 +30,7 @@
 	gst_rtcp_packet_bye_get_reason_len
 	gst_rtcp_packet_bye_get_ssrc_count
 	gst_rtcp_packet_bye_set_reason
+	gst_rtcp_packet_copy_profile_specific_ext
 	gst_rtcp_packet_fb_get_fci
 	gst_rtcp_packet_fb_get_fci_length
 	gst_rtcp_packet_fb_get_media_ssrc
@@ -32,6 +43,8 @@
 	gst_rtcp_packet_get_count
 	gst_rtcp_packet_get_length
 	gst_rtcp_packet_get_padding
+	gst_rtcp_packet_get_profile_specific_ext
+	gst_rtcp_packet_get_profile_specific_ext_length
 	gst_rtcp_packet_get_rb
 	gst_rtcp_packet_get_rb_count
 	gst_rtcp_packet_get_type
@@ -85,6 +98,7 @@
 	gst_rtp_buffer_compare_seqnum
 	gst_rtp_buffer_default_clock_rate
 	gst_rtp_buffer_ext_timestamp
+	gst_rtp_buffer_flags_get_type
 	gst_rtp_buffer_get_csrc
 	gst_rtp_buffer_get_csrc_count
 	gst_rtp_buffer_get_extension
diff --git a/win32/common/libgstvideo.def b/win32/common/libgstvideo.def
index 7b25d99..cff4651 100644
--- a/win32/common/libgstvideo.def
+++ b/win32/common/libgstvideo.def
@@ -7,6 +7,8 @@
 	gst_buffer_add_video_overlay_composition_meta
 	gst_buffer_add_video_region_of_interest_meta
 	gst_buffer_add_video_region_of_interest_meta_id
+	gst_buffer_add_video_time_code_meta
+	gst_buffer_add_video_time_code_meta_full
 	gst_buffer_get_video_meta
 	gst_buffer_get_video_meta_id
 	gst_buffer_get_video_region_of_interest_meta_id
@@ -134,6 +136,7 @@
 	gst_video_decoder_set_output_state
 	gst_video_decoder_set_packetized
 	gst_video_decoder_set_use_default_pad_acceptcaps
+	gst_video_direction_get_type
 	gst_video_dither_flags_get_type
 	gst_video_dither_free
 	gst_video_dither_line
@@ -224,6 +227,7 @@
 	gst_video_orientation_get_type
 	gst_video_orientation_get_vcenter
 	gst_video_orientation_get_vflip
+	gst_video_orientation_method_get_type
 	gst_video_orientation_set_hcenter
 	gst_video_orientation_set_hflip
 	gst_video_orientation_set_vcenter
@@ -283,4 +287,21 @@
 	gst_video_tile_get_index
 	gst_video_tile_mode_get_type
 	gst_video_tile_type_get_type
+	gst_video_time_code_add_frames
+	gst_video_time_code_clear
+	gst_video_time_code_compare
+	gst_video_time_code_copy
+	gst_video_time_code_frames_since_daily_jam
+	gst_video_time_code_free
+	gst_video_time_code_get_type
+	gst_video_time_code_increment_frame
+	gst_video_time_code_init
+	gst_video_time_code_is_valid
+	gst_video_time_code_meta_api_get_type
+	gst_video_time_code_meta_get_info
+	gst_video_time_code_new
+	gst_video_time_code_new_empty
+	gst_video_time_code_nsec_since_daily_jam
+	gst_video_time_code_to_date_time
+	gst_video_time_code_to_string
 	gst_video_transfer_function_get_type
diff --git a/win32/common/video-enumtypes.c b/win32/common/video-enumtypes.c
index bade190..1e7c3ba 100644
--- a/win32/common/video-enumtypes.c
+++ b/win32/common/video-enumtypes.c
@@ -17,6 +17,33 @@
 #include "video-frame.h"
 #include "video-scaler.h"
 
+/* enumerations from "video.h" */
+GType
+gst_video_orientation_method_get_type (void)
+{
+  static volatile gsize g_define_type_id__volatile = 0;
+  if (g_once_init_enter (&g_define_type_id__volatile)) {
+    static const GEnumValue values[] = {
+      {GST_VIDEO_ORIENTATION_IDENTITY, "GST_VIDEO_ORIENTATION_IDENTITY",
+          "identity"},
+      {GST_VIDEO_ORIENTATION_90R, "GST_VIDEO_ORIENTATION_90R", "90r"},
+      {GST_VIDEO_ORIENTATION_180, "GST_VIDEO_ORIENTATION_180", "180"},
+      {GST_VIDEO_ORIENTATION_90L, "GST_VIDEO_ORIENTATION_90L", "90l"},
+      {GST_VIDEO_ORIENTATION_HORIZ, "GST_VIDEO_ORIENTATION_HORIZ", "horiz"},
+      {GST_VIDEO_ORIENTATION_VERT, "GST_VIDEO_ORIENTATION_VERT", "vert"},
+      {GST_VIDEO_ORIENTATION_UL_LR, "GST_VIDEO_ORIENTATION_UL_LR", "ul-lr"},
+      {GST_VIDEO_ORIENTATION_UR_LL, "GST_VIDEO_ORIENTATION_UR_LL", "ur-ll"},
+      {GST_VIDEO_ORIENTATION_AUTO, "GST_VIDEO_ORIENTATION_AUTO", "auto"},
+      {GST_VIDEO_ORIENTATION_CUSTOM, "GST_VIDEO_ORIENTATION_CUSTOM", "custom"},
+      {0, NULL, NULL}
+    };
+    GType g_define_type_id =
+        g_enum_register_static ("GstVideoOrientationMethod", values);
+    g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+  }
+  return g_define_type_id__volatile;
+}
+
 /* enumerations from "video-format.h" */
 GType
 gst_video_format_get_type (void)
@@ -86,6 +113,9 @@
       {GST_VIDEO_FORMAT_A444_10BE, "GST_VIDEO_FORMAT_A444_10BE", "a444-10be"},
       {GST_VIDEO_FORMAT_A444_10LE, "GST_VIDEO_FORMAT_A444_10LE", "a444-10le"},
       {GST_VIDEO_FORMAT_NV61, "GST_VIDEO_FORMAT_NV61", "nv61"},
+      {GST_VIDEO_FORMAT_P010_10BE, "GST_VIDEO_FORMAT_P010_10BE", "p010-10be"},
+      {GST_VIDEO_FORMAT_P010_10LE, "GST_VIDEO_FORMAT_P010_10LE", "p010-10le"},
+      {GST_VIDEO_FORMAT_IYU2, "GST_VIDEO_FORMAT_IYU2", "iyu2"},
       {0, NULL, NULL}
     };
     GType g_define_type_id = g_enum_register_static ("GstVideoFormat", values);
@@ -798,12 +828,14 @@
 {
   static volatile gsize g_define_type_id__volatile = 0;
   if (g_once_init_enter (&g_define_type_id__volatile)) {
-    static const GEnumValue values[] = {
+    static const GFlagsValue values[] = {
       {GST_VIDEO_RESAMPLER_FLAG_NONE, "GST_VIDEO_RESAMPLER_FLAG_NONE", "none"},
+      {GST_VIDEO_RESAMPLER_FLAG_HALF_TAPS, "GST_VIDEO_RESAMPLER_FLAG_HALF_TAPS",
+          "half-taps"},
       {0, NULL, NULL}
     };
     GType g_define_type_id =
-        g_enum_register_static ("GstVideoResamplerFlags", values);
+        g_flags_register_static ("GstVideoResamplerFlags", values);
     g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
   }
   return g_define_type_id__volatile;
diff --git a/win32/common/video-enumtypes.h b/win32/common/video-enumtypes.h
index 090e7ee..fbe59f5 100644
--- a/win32/common/video-enumtypes.h
+++ b/win32/common/video-enumtypes.h
@@ -8,6 +8,10 @@
 
 G_BEGIN_DECLS
 
+/* enumerations from "video.h" */
+GType gst_video_orientation_method_get_type (void);
+#define GST_TYPE_VIDEO_ORIENTATION_METHOD (gst_video_orientation_method_get_type())
+
 /* enumerations from "video-format.h" */
 GType gst_video_format_get_type (void);
 #define GST_TYPE_VIDEO_FORMAT (gst_video_format_get_type())