Merge tag 'upstream/1.5.0.1+git20150513' into debian-experimental

Upstream version 1.5.0.1+git20150513
diff --git a/INSTALL b/INSTALL
index b42a17a..2099840 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,48 +1,80 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
+Inc.
+
+   Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.  This file is offered as-is,
+without warranty of any kind.
+
 Basic Installation
 ==================
 
-   These are generic installation instructions.
+   Briefly, the shell command `./configure && make && make install'
+should configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.  Some packages provide this
+`INSTALL' file but do not implement all of the features documented
+below.  The lack of an optional feature in a given package is not
+necessarily a bug.  More recommendations for GNU packages can be found
+in *note Makefile Conventions: (standards)Makefile Conventions.
 
    The `configure' shell script attempts to guess correct values for
 various system-dependent variables used during compilation.  It uses
 those values to create a `Makefile' in each directory of the package.
 It may also create one or more `.h' files containing system-dependent
 definitions.  Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, a file
-`config.cache' that saves the results of its tests to speed up
-reconfiguring, and a file `config.log' containing compiler output
-(useful mainly for debugging `configure').
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
 
    If you need to do unusual things to compile the package, please try
 to figure out how `configure' could check whether to do them, and mail
 diffs or instructions to the address given in the `README' so they can
-be considered for the next release.  If at some point `config.cache'
-contains results you don't want to keep, you may remove or edit it.
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
 
-   The file `configure.in' is used to create `configure' by a program
-called `autoconf'.  You only need `configure.in' if you want to change
-it or regenerate `configure' using a newer version of `autoconf'.
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
 
-The simplest way to compile this package is:
+   The simplest way to compile this package is:
 
   1. `cd' to the directory containing the package's source code and type
-     `./configure' to configure the package for your system.  If you're
-     using `csh' on an old version of System V, you might need to type
-     `sh ./configure' instead to prevent `csh' from trying to execute
-     `configure' itself.
+     `./configure' to configure the package for your system.
 
-     Running `configure' takes awhile.  While running, it prints some
-     messages telling which features it is checking for.
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
 
   2. Type `make' to compile the package.
 
   3. Optionally, type `make check' to run any self-tests that come with
-     the package.
+     the package, generally using the just-built uninstalled binaries.
 
   4. Type `make install' to install the programs and any data files and
-     documentation.
+     documentation.  When installing into a prefix owned by root, it is
+     recommended that the package be configured and built as a regular
+     user, and only the `make install' phase executed with root
+     privileges.
 
-  5. You can remove the program binaries and object files from the
+  5. Optionally, type `make installcheck' to repeat any self-tests, but
+     this time using the binaries in their final installed location.
+     This target does not install anything.  Running this target as a
+     regular user, particularly if the prior `make install' required
+     root privileges, verifies that the installation completed
+     correctly.
+
+  6. You can remove the program binaries and object files from the
      source code directory by typing `make clean'.  To also remove the
      files that `configure' created (so you can compile the package for
      a different kind of computer), type `make distclean'.  There is
@@ -51,62 +83,119 @@
      all sorts of other programs in order to regenerate files that came
      with the distribution.
 
+  7. Often, you can also type `make uninstall' to remove the installed
+     files again.  In practice, not all packages have tested that
+     uninstallation works correctly, even though it is required by the
+     GNU Coding Standards.
+
+  8. Some packages, particularly those that use Automake, provide `make
+     distcheck', which can by used by developers to test that all other
+     targets like `make install' and `make uninstall' work correctly.
+     This target is generally not run by end users.
+
 Compilers and Options
 =====================
 
    Some systems require unusual options for compilation or linking that
-the `configure' script does not know about.  You can give `configure'
-initial values for variables by setting them in the environment.  Using
-a Bourne-compatible shell, you can do that on the command line like
-this:
-     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
 
-Or on systems that have the `env' program, you can do it like this:
-     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
 
 Compiling For Multiple Architectures
 ====================================
 
    You can compile the package for more than one kind of computer at the
 same time, by placing the object files for each architecture in their
-own directory.  To do this, you must use a version of `make' that
-supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+own directory.  To do this, you can use GNU `make'.  `cd' to the
 directory where you want the object files and executables to go and run
 the `configure' script.  `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.
+source code in the directory that `configure' is in and in `..'.  This
+is known as a "VPATH" build.
 
-   If you have to use a `make' that does not supports the `VPATH'
-variable, you have to compile the package for one architecture at a time
-in the source code directory.  After you have installed the package for
-one architecture, use `make distclean' before reconfiguring for another
-architecture.
+   With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+   On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor.  Like
+this:
+
+     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+                 CPP="gcc -E" CXXCPP="g++ -E"
+
+   This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
 
 Installation Names
 ==================
 
-   By default, `make install' will install the package's files in
-`/usr/local/bin', `/usr/local/man', etc.  You can specify an
-installation prefix other than `/usr/local' by giving `configure' the
-option `--prefix=PATH'.
+   By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX', where PREFIX must be an
+absolute file name.
 
    You can specify separate installation prefixes for
 architecture-specific files and architecture-independent files.  If you
-give `configure' the option `--exec-prefix=PATH', the package will use
-PATH as the prefix for installing programs and libraries.
-Documentation and other data files will still use the regular prefix.
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
 
    In addition, if you use an unusual directory layout you can give
-options like `--bindir=PATH' to specify different values for particular
+options like `--bindir=DIR' to specify different values for particular
 kinds of files.  Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.
+you can set and what kinds of files go in them.  In general, the
+default for these options is expressed in terms of `${prefix}', so that
+specifying just `--prefix' will affect all of the other directory
+specifications that were not explicitly provided.
+
+   The most portable way to affect installation locations is to pass the
+correct locations to `configure'; however, many packages provide one or
+both of the following shortcuts of passing variable assignments to the
+`make install' command line to change installation locations without
+having to reconfigure or recompile.
+
+   The first method involves providing an override variable for each
+affected directory.  For example, `make install
+prefix=/alternate/directory' will choose an alternate location for all
+directory configuration variables that were expressed in terms of
+`${prefix}'.  Any directories that were specified during `configure',
+but not in terms of `${prefix}', must each be overridden at install
+time for the entire installation to be relocated.  The approach of
+makefile variable overrides for each directory variable is required by
+the GNU Coding Standards, and ideally causes no recompilation.
+However, some platforms have known limitations with the semantics of
+shared libraries that end up requiring recompilation when using this
+method, particularly noticeable in packages that use GNU Libtool.
+
+   The second method involves providing the `DESTDIR' variable.  For
+example, `make install DESTDIR=/alternate/directory' will prepend
+`/alternate/directory' before all installation names.  The approach of
+`DESTDIR' overrides is not required by the GNU Coding Standards, and
+does not work on platforms that have drive letters.  On the other hand,
+it does better at avoiding recompilation issues, and works well even
+when some directory options were not specified in terms of `${prefix}'
+at `configure' time.
+
+Optional Features
+=================
 
    If the package supports it, you can cause programs to be installed
 with an extra prefix or suffix on their names by giving `configure' the
 option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
 
-Optional Features
-=================
-
    Some packages pay attention to `--enable-FEATURE' options to
 `configure', where FEATURE indicates an optional part of the package.
 They may also pay attention to `--with-PACKAGE' options, where PACKAGE
@@ -119,25 +208,80 @@
 you can use the `configure' options `--x-includes=DIR' and
 `--x-libraries=DIR' to specify their locations.
 
+   Some packages offer the ability to configure how verbose the
+execution of `make' will be.  For these packages, running `./configure
+--enable-silent-rules' sets the default to minimal output, which can be
+overridden with `make V=1'; while running `./configure
+--disable-silent-rules' sets the default to verbose, which can be
+overridden with `make V=0'.
+
+Particular systems
+==================
+
+   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+     ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+   HP-UX `make' updates targets which have the same time stamps as
+their prerequisites, which makes it generally unusable when shipped
+generated files such as `configure' are involved.  Use GNU `make'
+instead.
+
+   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
+a workaround.  If GNU CC is not installed, it is therefore recommended
+to try
+
+     ./configure CC="cc"
+
+and if that doesn't work, try
+
+     ./configure CC="cc -nodtk"
+
+   On Solaris, don't put `/usr/ucb' early in your `PATH'.  This
+directory contains several dysfunctional programs; working variants of
+these programs are available in `/usr/bin'.  So, if you need `/usr/ucb'
+in your `PATH', put it _after_ `/usr/bin'.
+
+   On Haiku, software installed for all users goes in `/boot/common',
+not `/usr/local'.  It is recommended to use the following options:
+
+     ./configure --prefix=/boot/common
+
 Specifying the System Type
 ==========================
 
-   There may be some features `configure' can not figure out
-automatically, but needs to determine by the type of host the package
-will run on.  Usually `configure' can figure that out, but if it prints
-a message saying it can not guess the host type, give it the
-`--host=TYPE' option.  TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name with three fields:
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
      CPU-COMPANY-SYSTEM
 
-See the file `config.sub' for the possible values of each field.  If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the host type.
+where SYSTEM can have one of these forms:
 
-   If you are building compiler tools for cross-compiling, you can also
-use the `--target=TYPE' option to select the type of system they will
-produce code for and the `--build=TYPE' option to select the type of
-system on which you are compiling the package.
+     OS
+     KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
 
 Sharing Defaults
 ================
@@ -150,19 +294,56 @@
 `CONFIG_SITE' environment variable to the location of the site script.
 A warning: not all `configure' scripts look for a site script.
 
-Operation Controls
+Defining Variables
 ==================
 
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf limitation.  Until the limitation is lifted, you can use
+this workaround:
+
+     CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
    `configure' recognizes the following options to control how it
 operates.
 
-`--cache-file=FILE'
-     Use and save the results of the tests in FILE instead of
-     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
-     debugging `configure'.
-
 `--help'
-     Print a summary of the options to `configure', and exit.
+`-h'
+     Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+     Print a summary of the options unique to this package's
+     `configure', and exit.  The `short' variant lists options used
+     only in the top level, while the `recursive' variant lists options
+     also present in any nested packages.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
 
 `--quiet'
 `--silent'
@@ -175,8 +356,15 @@
      Look for the package's source code in directory DIR.  Usually
      `configure' can determine that directory automatically.
 
-`--version'
-     Print the version of Autoconf used to generate the `configure'
-     script, and exit.
+`--prefix=DIR'
+     Use DIR as the installation prefix.  *note Installation Names::
+     for more details, including other options available for fine-tuning
+     the installation locations.
 
-`configure' also accepts some other, not widely useful, options.
+`--no-create'
+`-n'
+     Run the configure checks, but stop before creating any output
+     files.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
diff --git a/autogen.sh b/autogen.sh
index a4e27b7..4e8ed7a 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -57,24 +57,13 @@
 
 printf "+ check for build tools"
 if test ! -z "$NOCHECK"; then echo ": skipped version checks"; else  echo; fi
-version_check "autoconf" "$AUTOCONF autoconf autoconf270 autoconf269 autoconf268 " \
+version_check "autoreconf" "autoreconf " \
               "ftp://ftp.gnu.org/pub/gnu/autoconf/" 2 68 || DIE=1
-version_check "automake" "$AUTOMAKE automake automake-1.11" \
-              "ftp://ftp.gnu.org/pub/gnu/automake/" 1 11 || DIE=1
-version_check "autopoint" "autopoint" \
-              "ftp://ftp.gnu.org/pub/gnu/gettext/" 0 17 || DIE=1
-version_check "libtoolize" "$LIBTOOLIZE libtoolize glibtoolize" \
-              "ftp://ftp.gnu.org/pub/gnu/libtool/" 2 2 6 || DIE=1
 version_check "pkg-config" "" \
               "http://www.freedesktop.org/software/pkgconfig" 0 8 0 || DIE=1
 
 die_check $DIE
 
-aclocal_check || DIE=1
-autoheader_check || DIE=1
-
-die_check $DIE
-
 # if no arguments specified then this will be printed
 if test -z "$*" && test -z "$NOCONFIGURE"; then
   echo "+ checking for autogen.sh options"
@@ -88,22 +77,13 @@
 
 # autopoint
 if test -d po ; then
-  tool_run "$autopoint" "--force"
+  tool_run "autopoint" "--force"
 fi
 
 # aclocal
 if test -f acinclude.m4; then rm acinclude.m4; fi
 
-tool_run "$libtoolize" "--copy --force"
-tool_run "$aclocal" "-I m4 -I common/m4 $ACLOCAL_FLAGS"
-tool_run "$autoheader"
-
-# touch the stamp-h.in build stamp so we don't re-run autoheader in maintainer mode
-echo timestamp > stamp-h.in 2> /dev/null
-
-tool_run "$autoconf"
-debug "automake: $automake"
-tool_run "$automake" "--add-missing --copy"
+autoreconf --force --install || exit 1
 
 test -n "$NOCONFIGURE" && {
   echo "+ skipping configure stage for package $package, as requested."
diff --git a/common/check.mak b/common/check.mak
index efd5458..8a90b5d 100644
--- a/common/check.mak
+++ b/common/check.mak
@@ -16,38 +16,38 @@
 # run any given test by running make test.check
 # if the test fails, run it again at at least debug level 2
 %.check: %
-	@$(TESTS_ENVIRONMENT)					\
+	@$(AM_TESTS_ENVIRONMENT)					\
 	CK_DEFAULT_TIMEOUT=20					\
 	$* ||							\
-	$(TESTS_ENVIRONMENT)					\
+	$(AM_TESTS_ENVIRONMENT)					\
 	GST_DEBUG=$$GST_DEBUG,*:2				\
 	CK_DEFAULT_TIMEOUT=20					\
 	$*
 
 # just like 'check', but don't run it again if it fails (useful for debugging)
 %.check-norepeat: %
-	@$(TESTS_ENVIRONMENT)					\
+	@$(AM_TESTS_ENVIRONMENT)					\
 	CK_DEFAULT_TIMEOUT=20					\
 	$*
 
 # run any given test in a loop
 %.torture: %
 	@for i in `seq 1 $(LOOPS)`; do				\
-	$(TESTS_ENVIRONMENT)					\
+	$(AM_TESTS_ENVIRONMENT)					\
 	CK_DEFAULT_TIMEOUT=20					\
 	$*; done
 
 # run any given test in an infinite loop
 %.forever: %
 	@while true; do						\
-	$(TESTS_ENVIRONMENT)					\
+	$(AM_TESTS_ENVIRONMENT)					\
 	CK_DEFAULT_TIMEOUT=20					\
 	$* || break; done
 
 # valgrind any given test by running make test.valgrind
 %.valgrind: %
 	@valgrind_log=$(subst /,-,$*-valgrind.log);		\
-	$(TESTS_ENVIRONMENT)					\
+	$(AM_TESTS_ENVIRONMENT)					\
 	CK_DEFAULT_TIMEOUT=360					\
 	G_SLICE=always-malloc					\
 	$(LIBTOOL) --mode=execute				\
@@ -65,7 +65,7 @@
 
 # valgrind any given test and generate suppressions for it
 %.valgrind.gen-suppressions: %
-	@$(TESTS_ENVIRONMENT)					\
+	@$(AM_TESTS_ENVIRONMENT)					\
 	CK_DEFAULT_TIMEOUT=360					\
 	G_SLICE=always-malloc					\
 	$(LIBTOOL) --mode=execute				\
@@ -95,7 +95,7 @@
 
 # gdb any given test by running make test.gdb
 %.gdb: %
-	@$(TESTS_ENVIRONMENT)					\
+	@$(AM_TESTS_ENVIRONMENT)					\
 	CK_FORK=no						\
 	$(LIBTOOL) --mode=execute				\
 	gdb $*
@@ -205,7 +205,7 @@
 GST_INSPECT = $(GST_TOOLS_DIR)/gst-inspect-$(GST_API_VERSION)
 inspect:
 	@echo "Inspecting features ..."
-	@for e in `$(TESTS_ENVIRONMENT) $(GST_INSPECT) | head -n -2 	\
+	@for e in `$(AM_TESTS_ENVIRONMENT) $(GST_INSPECT) | head -n -2 	\
 	  | cut -d: -f2`;						\
 	  do echo Inspecting $$e;					\
 	     $(GST_INSPECT) $$e > /dev/null 2>&1; done
diff --git a/common/gst-autogen.sh b/common/gst-autogen.sh
index 78cab66..c5798d0 100644
--- a/common/gst-autogen.sh
+++ b/common/gst-autogen.sh
@@ -169,54 +169,6 @@
   return 1;
 }
 
-aclocal_check ()
-{
-  # normally aclocal is part of automake
-  # so we expect it to be in the same place as automake
-  # so if a different automake is supplied, we need to adapt as well
-  # so how's about replacing automake with aclocal in the set var,
-  # and saving that in $aclocal ?
-  # note, this will fail if the actual automake isn't called automake*
-  # or if part of the path before it contains it
-  if [ -z "$automake" ]; then
-    echo "Error: no automake variable set !"
-    return 1
-  else
-    aclocal=`echo $automake | sed s/automake/aclocal/`
-    debug "aclocal: $aclocal"
-    if [ "$aclocal" != "aclocal" ];
-    then
-      CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-aclocal=$aclocal"
-    fi
-    if [ ! -x `which $aclocal` ]; then
-      echo "Error: cannot execute $aclocal !"
-      return 1
-    fi
-  fi
-}
-
-autoheader_check ()
-{
-  # same here - autoheader is part of autoconf
-  # use the same voodoo
-  if [ -z "$autoconf" ]; then
-    echo "Error: no autoconf variable set !"
-    return 1
-  else
-    autoheader=`echo $autoconf | sed s/autoconf/autoheader/`
-    debug "autoheader: $autoheader"
-    if [ "$autoheader" != "autoheader" ];
-    then
-      CONFIGURE_DEF_OPT="$CONFIGURE_DEF_OPT --with-autoheader=$autoheader"
-    fi
-    if [ ! -x `which $autoheader` ]; then
-      echo "Error: cannot execute $autoheader !"
-      return 1
-    fi
-  fi
-
-}
-
 die_check ()
 {
   # call with $DIE
diff --git a/common/gst.supp b/common/gst.supp
index c08f660..5e2aaf9 100644
--- a/common/gst.supp
+++ b/common/gst.supp
@@ -3972,3 +3972,37 @@
   timer_create(evp)
   fun:timer_create@@GLIBC_2.3.3
 }
+
+{
+   closures aren't valgrind friendly (bgo#739850)
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:calloc
+   ...
+   fun:g_cclosure_new
+}
+
+{
+   closures aren't valgrind friendly (bgo#739850)
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   ...
+   fun:g_closure_add_invalidate_notifier
+}
+
+{
+   closures aren't valgrind friendly (bgo#739850)
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:calloc
+   ...
+   fun:g_closure_new_simple
+}
+
+{
+   glib/giomodules2 (from libsoup.supp)
+   Memcheck:Leak
+   ...
+   fun:_g_io_module_get_default
+}
diff --git a/config.h.in b/config.h.in
index 87312f8..49084ff 100644
--- a/config.h.in
+++ b/config.h.in
@@ -301,9 +301,6 @@
 /* Define if gudev is installed */
 #undef HAVE_GUDEV
 
-/* Define to 1 if you have the <highgui.h> header file. */
-#undef HAVE_HIGHGUI_H
-
 /* Define to enable http live streaming plugin (used by hls). */
 #undef HAVE_HLS
 
@@ -412,9 +409,41 @@
 /* Define to enable opencv plugins (used by opencv). */
 #undef HAVE_OPENCV
 
+/* Define to 1 if you have the <opencv2/contrib/contrib.hpp> header file. */
+#undef HAVE_OPENCV2_CONTRIB_CONTRIB_HPP
+
+/* Define to 1 if you have the <opencv2/core/core_c.h> header file. */
+#undef HAVE_OPENCV2_CORE_CORE_C_H
+
+/* Define to 1 if you have the <opencv2/core/types_c.h> header file. */
+#undef HAVE_OPENCV2_CORE_TYPES_C_H
+
+/* Define to 1 if you have the <opencv2/core/version.hpp> header file. */
+#undef HAVE_OPENCV2_CORE_VERSION_HPP
+
 /* Define to 1 if you have the <opencv2/highgui/highgui_c.h> header file. */
 #undef HAVE_OPENCV2_HIGHGUI_HIGHGUI_C_H
 
+/* Define to 1 if you have the <opencv2/imgproc/imgproc_c.h> header file. */
+#undef HAVE_OPENCV2_IMGPROC_IMGPROC_C_H
+
+/* Define to 1 if you have the <opencv2/imgproc/imgproc.hpp> header file. */
+#undef HAVE_OPENCV2_IMGPROC_IMGPROC_HPP
+
+/* Define to 1 if you have the <opencv2/legacy/compat.hpp> header file. */
+#undef HAVE_OPENCV2_LEGACY_COMPAT_HPP
+
+/* Define to 1 if you have the <opencv2/legacy/legacy.hpp> header file. */
+#undef HAVE_OPENCV2_LEGACY_LEGACY_HPP
+
+/* Define to 1 if you have the <opencv2/objdetect/objdetect.hpp> header file.
+   */
+#undef HAVE_OPENCV2_OBJDETECT_OBJDETECT_HPP
+
+/* Define to 1 if you have the <opencv2/video/background_segm.hpp> header
+   file. */
+#undef HAVE_OPENCV2_VIDEO_BACKGROUND_SEGM_HPP
+
 /* Define to enable openexr library (used by openexr). */
 #undef HAVE_OPENEXR
 
diff --git a/configure b/configure
index 4e6402f..3c13b3c 100755
--- a/configure
+++ b/configure
@@ -34540,7 +34540,7 @@
   save_LIBS="$LIBS"
   CFLAGS="$CFLAGS $DIRECTX_CFLAGS"
   LDFLAGS="$LDFLAGS $DIRECTX_LDFLAGS"
-  LIBS="$LIBS -ldsound -ldxerr9 -luser32"
+  LIBS="$LIBS -lwinmm -ldsound -ldxerr9 -luser32"
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DirectSound LDFLAGS" >&5
 $as_echo_n "checking for DirectSound LDFLAGS... " >&6; }
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -34549,6 +34549,7 @@
 #include <windows.h>
 #include <dxerr9.h>
 #include <dsound.h>
+#include <mmsystem.h>
 
 int
 main ()
@@ -34575,7 +34576,7 @@
   LIBS=$save_LIBS
 
   if test "x$HAVE_DIRECTSOUND" = "xyes";  then
-        DIRECTSOUND_LIBS="-ldsound -ldxerr9 -luser32"
+        DIRECTSOUND_LIBS="-lwinmm -ldsound -ldxerr9 -luser32"
 
 
 
@@ -38592,6 +38593,9 @@
 
    HAVE_DECKLINK=no
    case "$host" in
+     *android*)
+       HAVE_DECKLINK=no
+       ;;
      *-*linux*)
        if test "x$HAVE_PTHREAD_H" = "xyes"; then
          { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
@@ -38683,7 +38687,7 @@
             HAVE_DECKLINK=yes
             DECKLINK_CXXFLAGS=
             DECKLINK_LIBS="-lpthread -ldl"
-	    HAVE_DECKLINK_OSX=yes
+            HAVE_DECKLINK_OSX=yes
 
 fi
 
@@ -44811,7 +44815,18 @@
 
     OLD_CPPFLAGS=$CPPFLAGS
     CPPFLAGS=$OPENCV_CFLAGS
-    for ac_header in highgui.h opencv2/highgui/highgui_c.h
+    something_not_found=no
+    for ac_header in opencv2/contrib/contrib.hpp \
+                      opencv2/core/core_c.h \
+                      opencv2/core/types_c.h \
+                      opencv2/core/version.hpp \
+                      opencv2/highgui/highgui_c.h \
+                      opencv2/imgproc/imgproc.hpp \
+                      opencv2/imgproc/imgproc_c.h \
+                      opencv2/legacy/compat.hpp \
+                      opencv2/legacy/legacy.hpp \
+                      opencv2/objdetect/objdetect.hpp \
+                      opencv2/video/background_segm.hpp
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -44820,6 +44835,8 @@
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
+else
+  something_not_found=yes
 fi
 
 done
@@ -44832,12 +44849,12 @@
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-    if test $ac_cv_header_highgui_h = "yes" -o $ac_cv_header_opencv2_highgui_highgui_c_h = "yes" ; then
-      HAVE_OPENCV="yes"
-    else
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: neither highgui.h nor opencv2/highgui/highgui_c.h could not be found" >&5
-$as_echo "neither highgui.h nor opencv2/highgui/highgui_c.h could not be found" >&6; }
+    if test $something_not_found = "yes"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: not all opencv2 headers were found" >&5
+$as_echo "not all opencv2 headers were found" >&6; }
       HAVE_OPENCV="no"
+    else
+      HAVE_OPENCV="yes"
     fi
 
 fi
@@ -45122,7 +45139,7 @@
   HAVE_OPENH264=no
 
 
-  which="openh264"
+  which="openh264 >= 1.3.0"
     required="no"
 
 
diff --git a/configure.ac b/configure.ac
index f466a3e..f5ce28c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_PREREQ([2.68])
+AC_PREREQ([2.69])
 
 dnl initialize autoconf
 dnl when going to/from release please set the nano (fourth number) right !
@@ -8,7 +8,7 @@
 AG_GST_INIT
 
 dnl initialize automake
-AM_INIT_AUTOMAKE([-Wno-portability 1.11 no-dist-gzip dist-xz tar-ustar subdir-objects])
+AM_INIT_AUTOMAKE([-Wno-portability 1.14 no-dist-gzip dist-xz tar-ustar subdir-objects])
 
 dnl define PACKAGE_VERSION_* variables
 AS_VERSION
@@ -1397,12 +1397,13 @@
   save_LIBS="$LIBS"
   CFLAGS="$CFLAGS $DIRECTX_CFLAGS"
   LDFLAGS="$LDFLAGS $DIRECTX_LDFLAGS"
-  LIBS="$LIBS -ldsound -ldxerr9 -luser32"
+  LIBS="$LIBS -lwinmm -ldsound -ldxerr9 -luser32"
   AC_MSG_CHECKING(for DirectSound LDFLAGS)
   AC_LINK_IFELSE([AC_LANG_PROGRAM([[
 #include <windows.h>
 #include <dxerr9.h>
 #include <dsound.h>
+#include <mmsystem.h>
 ]], [[
   DXGetErrorString9 (0);
   DirectSoundCreate(NULL, NULL, NULL);
@@ -1416,7 +1417,7 @@
 
   if test "x$HAVE_DIRECTSOUND" = "xyes";  then
     dnl this is much more than we want
-    DIRECTSOUND_LIBS="-ldsound -ldxerr9 -luser32"
+    DIRECTSOUND_LIBS="-lwinmm -ldsound -ldxerr9 -luser32"
     AC_SUBST(DIRECTX_CFLAGS)
     AC_SUBST(DIRECTX_LDFLAGS)
     AC_SUBST(DIRECTSOUND_LIBS)
@@ -1866,6 +1867,9 @@
 AG_GST_CHECK_FEATURE(DECKLINK, [decklink], decklink, [
    HAVE_DECKLINK=no
    case "$host" in
+     *android*)
+       HAVE_DECKLINK=no
+       ;;
      *-*linux*)
        if test "x$HAVE_PTHREAD_H" = "xyes"; then
          AC_CHECK_LIB(dl, dlopen,
@@ -1883,7 +1887,7 @@
             HAVE_DECKLINK=yes
             DECKLINK_CXXFLAGS=
             DECKLINK_LIBS="-lpthread -ldl"
-	    HAVE_DECKLINK_OSX=yes
+            HAVE_DECKLINK_OSX=yes
            ])
        fi
        ;;
@@ -2446,15 +2450,26 @@
     AC_LANG([C++])
     OLD_CPPFLAGS=$CPPFLAGS
     CPPFLAGS=$OPENCV_CFLAGS
-    AC_CHECK_HEADERS([highgui.h opencv2/highgui/highgui_c.h])
+    something_not_found=no
+    AC_CHECK_HEADERS([opencv2/contrib/contrib.hpp \
+                      opencv2/core/core_c.h \
+                      opencv2/core/types_c.h \
+                      opencv2/core/version.hpp \
+                      opencv2/highgui/highgui_c.h \
+                      opencv2/imgproc/imgproc.hpp \
+                      opencv2/imgproc/imgproc_c.h \
+                      opencv2/legacy/compat.hpp \
+                      opencv2/legacy/legacy.hpp \
+                      opencv2/objdetect/objdetect.hpp \
+                      opencv2/video/background_segm.hpp], [], [something_not_found=yes])
     CPPFLAGS=$OLD_CPPFLAGS
     AC_LANG([C])
 
-    if test $ac_cv_header_highgui_h = "yes" -o $ac_cv_header_opencv2_highgui_highgui_c_h = "yes" ; then
-      HAVE_OPENCV="yes"
-    else
-      AC_MSG_RESULT([neither highgui.h nor opencv2/highgui/highgui_c.h could not be found])
+    if test $something_not_found = "yes"; then
+      AC_MSG_RESULT([not all opencv2 headers were found])
       HAVE_OPENCV="no"
+    else
+      HAVE_OPENCV="yes"
     fi
   ], [
     HAVE_OPENCV="no"
@@ -2475,7 +2490,7 @@
 dnl *** openh264 ***
 translit(dnm, m, l) AM_CONDITIONAL(USE_OPENH264, true)
 AG_GST_CHECK_FEATURE(OPENH264, [openh264 library], openh264, [
-  AG_GST_PKG_CHECK_MODULES(OPENH264, openh264)
+  AG_GST_PKG_CHECK_MODULES(OPENH264, openh264 >= 1.3.0)
 ])
 
 dnl *** OpenJPEG ***
diff --git a/docs/libs/Makefile.am b/docs/libs/Makefile.am
index 5c6c919..967e3c8 100644
--- a/docs/libs/Makefile.am
+++ b/docs/libs/Makefile.am
@@ -58,6 +58,9 @@
 	$(top_builddir)/gst-libs/gst/uridownloader/libgsturidownloader-@GST_API_VERSION@.la \
 	$(top_builddir)/gst-libs/gst/mpegts/libgstmpegts-@GST_API_VERSION@.la \
 	$(top_builddir)/gst-libs/gst/gl/libgstgl-@GST_API_VERSION@.la \
+	-L$(top_builddir)/gst-libs/gst/adaptivedemux/.libs \
+	-L$(top_builddir)/gst-libs/gst/video/.libs \
+	-L$(top_builddir)/gst-libs/gst/base/.libs \
   $(GST_BASE_LIBS)
 
 GTKDOC_CC=$(LIBTOOL) --tag=CC --mode=compile $(CC)
diff --git a/docs/libs/Makefile.in b/docs/libs/Makefile.in
index 8e0f369..7b5a0bc 100644
--- a/docs/libs/Makefile.in
+++ b/docs/libs/Makefile.in
@@ -732,6 +732,9 @@
 	$(top_builddir)/gst-libs/gst/uridownloader/libgsturidownloader-@GST_API_VERSION@.la \
 	$(top_builddir)/gst-libs/gst/mpegts/libgstmpegts-@GST_API_VERSION@.la \
 	$(top_builddir)/gst-libs/gst/gl/libgstgl-@GST_API_VERSION@.la \
+	-L$(top_builddir)/gst-libs/gst/adaptivedemux/.libs \
+	-L$(top_builddir)/gst-libs/gst/video/.libs \
+	-L$(top_builddir)/gst-libs/gst/base/.libs \
   $(GST_BASE_LIBS)
 
 GTKDOC_CC = $(LIBTOOL) --tag=CC --mode=compile $(CC)
diff --git a/docs/libs/html/GstGLBufferPool.html b/docs/libs/html/GstGLBufferPool.html
index 605fa76..ab0041d 100644
--- a/docs/libs/html/GstGLBufferPool.html
+++ b/docs/libs/html/GstGLBufferPool.html
@@ -99,8 +99,8 @@
 <col width="200px" class="parameters_annotations">
 </colgroup>
 <tbody><tr>
-<td class="parameter_name"><p>display</p></td>
-<td class="parameter_description"><p>the <a class="link" href="GstGLDisplay.html" title="GstGLDisplay"><span class="type">GstGLDisplay</span></a> to use</p></td>
+<td class="parameter_name"><p>context</p></td>
+<td class="parameter_description"><p>the <a class="link" href="GstGLContext.html" title="GstGLContext"><span class="type">GstGLContext</span></a> to use</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
diff --git a/docs/libs/html/GstGLColorConvert.html b/docs/libs/html/GstGLColorConvert.html
index cb7261c..707852a 100644
--- a/docs/libs/html/GstGLColorConvert.html
+++ b/docs/libs/html/GstGLColorConvert.html
@@ -169,13 +169,13 @@
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
-<td class="parameter_name"><p>in_info</p></td>
-<td class="parameter_description"><p>input <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstvideo.html#GstVideoInfo"><span class="type">GstVideoInfo</span></a></p></td>
+<td class="parameter_name"><p>in_caps</p></td>
+<td class="parameter_description"><p>input <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstCaps.html"><span class="type">GstCaps</span></a></p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
-<td class="parameter_name"><p>out_info</p></td>
-<td class="parameter_description"><p>output <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstvideo.html#GstVideoInfo"><span class="type">GstVideoInfo</span></a></p></td>
+<td class="parameter_name"><p>out_caps</p></td>
+<td class="parameter_description"><p>output <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstCaps.html"><span class="type">GstCaps</span></a></p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
diff --git a/docs/libs/html/GstGLContext.html b/docs/libs/html/GstGLContext.html
index 3045885..45187b2 100644
--- a/docs/libs/html/GstGLContext.html
+++ b/docs/libs/html/GstGLContext.html
@@ -839,11 +839,6 @@
 </colgroup>
 <tbody>
 <tr>
-<td class="parameter_name"><p>context_type</p></td>
-<td class="parameter_description"><p>a <a class="link" href="gst-plugins-bad-libs-GstGLAPI.html#GstGLPlatform" title="enum GstGLPlatform"><span class="type">GstGLPlatform</span></a> specifying the type of context to retreive</p></td>
-<td class="parameter_annotations"> </td>
-</tr>
-<tr>
 <td class="parameter_name"><p>major</p></td>
 <td class="parameter_description"><p> (allow-none): the major version. </p></td>
 <td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
diff --git a/docs/libs/html/GstGLDisplay.html b/docs/libs/html/GstGLDisplay.html
index c9f7367..1a38293 100644
--- a/docs/libs/html/GstGLDisplay.html
+++ b/docs/libs/html/GstGLDisplay.html
@@ -229,11 +229,18 @@
 <col class="parameters_description">
 <col width="200px" class="parameters_annotations">
 </colgroup>
-<tbody><tr>
+<tbody>
+<tr>
 <td class="parameter_name"><p>display</p></td>
 <td class="parameter_description"><p>a <a class="link" href="GstGLDisplay.html" title="GstGLDisplay"><span class="type">GstGLDisplay</span></a></p></td>
 <td class="parameter_annotations"> </td>
-</tr></tbody>
+</tr>
+<tr>
+<td class="parameter_name"><p>gl_api</p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-bad-libs-GstGLAPI.html#GstGLAPI" title="enum GstGLAPI"><span class="type">GstGLAPI</span></a> to filter with</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
 </table></div>
 </div>
 </div>
@@ -299,6 +306,7 @@
 was successfully added. <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a> may be returned
 if there already exists another context for <em class="parameter"><code>context</code></em>
 's active thread.</p>
+<p>Must be called with the object lock held.</p>
 <p></p>
 </div>
 <p class="since">Since 1.6</p>
@@ -335,7 +343,8 @@
 <div class="refsect3">
 <a name="id-1.2.9.11.7.7.5"></a><h4>Returns</h4>
 <p> the <a class="link" href="GstGLContext.html" title="GstGLContext"><span class="type">GstGLContext</span></a> current on <em class="parameter"><code>thread</code></em>
-or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p>
+or <a href="https://developer.gnome.org/glib/unstable/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a></p>
+<p>Must be called with the object lock held. </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.6</p>
diff --git a/docs/libs/html/GstGLDownload.html b/docs/libs/html/GstGLDownload.html
index 9a19fcb..0e2fce7 100644
--- a/docs/libs/html/GstGLDownload.html
+++ b/docs/libs/html/GstGLDownload.html
@@ -151,18 +151,8 @@
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
-<td class="parameter_name"><p>v_format</p></td>
-<td class="parameter_description"><p>a <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstvideo.html#GstVideoFormat"><span class="type">GstVideoFormat</span></a></p></td>
-<td class="parameter_annotations"> </td>
-</tr>
-<tr>
-<td class="parameter_name"><p>out_width</p></td>
-<td class="parameter_description"><p>the width to download to</p></td>
-<td class="parameter_annotations"> </td>
-</tr>
-<tr>
-<td class="parameter_name"><p>out_height</p></td>
-<td class="parameter_description"><p>the height to download to</p></td>
+<td class="parameter_name"><p>out_info</p></td>
+<td class="parameter_description"><p>a <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstvideo.html#GstVideoInfo"><span class="type">GstVideoInfo</span></a></p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
diff --git a/docs/libs/html/GstGLFilter.html b/docs/libs/html/GstGLFilter.html
index 2a64b24..3c96b06 100644
--- a/docs/libs/html/GstGLFilter.html
+++ b/docs/libs/html/GstGLFilter.html
@@ -351,11 +351,7 @@
   gboolean (*set_caps)          (GstGLFilter* filter, GstCaps* incaps, GstCaps* outcaps);
   gboolean (*filter)            (GstGLFilter *filter, GstBuffer *inbuf, GstBuffer *outbuf);
   gboolean (*filter_texture)    (GstGLFilter *filter, guint in_tex, guint out_tex);
-  gboolean (*onInitFBO)         (GstGLFilter *filter);
-
-  void (*onStart)               (GstGLFilter *filter);
-  void (*onStop)                (GstGLFilter *filter);
-  void (*onReset)               (GstGLFilter *filter);
+  gboolean (*init_fbo)          (GstGLFilter *filter);
 
   /* useful to init and cleanup custom gl resources */
   void (*display_init_cb)       (GstGLFilter *filter);
@@ -401,27 +397,11 @@
 <td class="struct_member_annotations"> </td>
 </tr>
 <tr>
-<td class="struct_member_name"><p><em class="structfield"><code><a name="GstGLFilterClass.onInitFBO"></a>onInitFBO</code></em> ()</p></td>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="GstGLFilterClass.init-fbo"></a>init_fbo</code></em> ()</p></td>
 <td class="struct_member_description"><p>perform initialization when the Framebuffer object is created</p></td>
 <td class="struct_member_annotations"> </td>
 </tr>
 <tr>
-<td class="struct_member_name"><p><em class="structfield"><code><a name="GstGLFilterClass.onStart"></a>onStart</code></em> ()</p></td>
-<td class="struct_member_description"><p>called when element activates see also <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstBaseTransform.html"><span class="type">GstBaseTransform</span></a></p></td>
-<td class="struct_member_annotations"> </td>
-</tr>
-<tr>
-<td class="struct_member_name"><p><em class="structfield"><code><a name="GstGLFilterClass.onStop"></a>onStop</code></em> ()</p></td>
-<td class="struct_member_description"><p>called when the element deactivates e also <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstBaseTransform.html"><span class="type">GstBaseTransform</span></a></p></td>
-<td class="struct_member_annotations"> </td>
-</tr>
-<tr>
-<td class="struct_member_name"><p><em class="structfield"><code><a name="GstGLFilterClass.onReset"></a>onReset</code></em> ()</p></td>
-<td class="struct_member_description"><p>called on inizialation and after <em class="parameter"><code>onStop</code></em>
-</p></td>
-<td class="struct_member_annotations"> </td>
-</tr>
-<tr>
 <td class="struct_member_name"><p><em class="structfield"><code><a name="GstGLFilterClass.display-init-cb"></a>display_init_cb</code></em> ()</p></td>
 <td class="struct_member_description"><p>execute arbitrary gl code on start</p></td>
 <td class="struct_member_annotations"> </td>
diff --git a/docs/libs/html/GstGLUpload.html b/docs/libs/html/GstGLUpload.html
index 8e4c7db..f7bcfa9 100644
--- a/docs/libs/html/GstGLUpload.html
+++ b/docs/libs/html/GstGLUpload.html
@@ -175,13 +175,13 @@
 </tr>
 <tr>
 <td class="parameter_name"><p>in_caps</p></td>
-<td class="parameter_description"><p> (allow-none): (out): the input <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstCaps.html"><span class="type">GstCaps</span></a>. </p></td>
-<td class="parameter_annotations"><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></td>
+<td class="parameter_description"><p> the input <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstCaps.html"><span class="type">GstCaps</span></a>. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
 </tr>
 <tr>
-<td class="parameter_name"><p>ou_caps</p></td>
-<td class="parameter_description"><p> (allow-none): (out): the output <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstCaps.html"><span class="type">GstCaps</span></a>. </p></td>
-<td class="parameter_annotations"><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></td>
+<td class="parameter_name"><p>out_caps</p></td>
+<td class="parameter_description"><p> the output <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstCaps.html"><span class="type">GstCaps</span></a>. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
 </tr>
 </tbody>
 </table></div>
diff --git a/docs/libs/html/api-index-full.html b/docs/libs/html/api-index-full.html
index ea51afe..bcac363 100644
--- a/docs/libs/html/api-index-full.html
+++ b/docs/libs/html/api-index-full.html
@@ -68,6 +68,10 @@
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="gst-plugins-bad-libs-GstAggregator.html#gst-aggregator-get-latency" title="gst_aggregator_get_latency ()">gst_aggregator_get_latency</a>, function in <a class="link" href="gst-plugins-bad-libs-GstAggregator.html" title="GstAggregator">GstAggregator</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="gst-plugins-bad-libs-GstAggregator.html#gst-aggregator-iterate-sinkpads" title="gst_aggregator_iterate_sinkpads ()">gst_aggregator_iterate_sinkpads</a>, function in <a class="link" href="gst-plugins-bad-libs-GstAggregator.html" title="GstAggregator">GstAggregator</a>
 </dt>
 <dd></dd>
diff --git a/docs/libs/html/gst-plugins-bad-libs-1.0.devhelp2 b/docs/libs/html/gst-plugins-bad-libs-1.0.devhelp2
index 65c43c3..a197a40 100644
--- a/docs/libs/html/gst-plugins-bad-libs-1.0.devhelp2
+++ b/docs/libs/html/gst-plugins-bad-libs-1.0.devhelp2
@@ -390,6 +390,7 @@
     <keyword type="function" name="gst_aggregator_finish_buffer ()" link="gst-plugins-bad-libs-GstAggregator.html#gst-aggregator-finish-buffer"/>
     <keyword type="function" name="gst_aggregator_set_src_caps ()" link="gst-plugins-bad-libs-GstAggregator.html#gst-aggregator-set-src-caps"/>
     <keyword type="function" name="gst_aggregator_iterate_sinkpads ()" link="gst-plugins-bad-libs-GstAggregator.html#gst-aggregator-iterate-sinkpads"/>
+    <keyword type="function" name="gst_aggregator_get_latency ()" link="gst-plugins-bad-libs-GstAggregator.html#gst-aggregator-get-latency"/>
     <keyword type="struct" name="struct GstAggregator" link="gst-plugins-bad-libs-GstAggregator.html#GstAggregator"/>
     <keyword type="struct" name="struct GstAggregatorClass" link="gst-plugins-bad-libs-GstAggregator.html#GstAggregatorClass"/>
     <keyword type="function" name="gst_aggregator_pad_steal_buffer ()" link="gst-plugins-bad-libs-GstAggregatorPad.html#gst-aggregator-pad-steal-buffer"/>
diff --git a/docs/libs/html/gst-plugins-bad-libs-Base-MPEG-TS-sections.html b/docs/libs/html/gst-plugins-bad-libs-Base-MPEG-TS-sections.html
index b6fbd67..7c2c876 100644
--- a/docs/libs/html/gst-plugins-bad-libs-Base-MPEG-TS-sections.html
+++ b/docs/libs/html/gst-plugins-bad-libs-Base-MPEG-TS-sections.html
@@ -549,7 +549,7 @@
 gst_mpegts_section_from_pat (<em class="parameter"><code><a href="https://developer.gnome.org/glib/unstable/glib-Pointer-Arrays.html#GPtrArray"><span class="type">GPtrArray</span></a> *programs</code></em>,
                              <em class="parameter"><code><span class="type">guint16</span> ts_id</code></em>);</pre>
 <p>Creates a PAT <a class="link" href="gst-plugins-bad-libs-Base-MPEG-TS-sections.html#GstMpegtsSection"><span class="type">GstMpegtsSection</span></a> from the <em class="parameter"><code>programs</code></em>
- array of <a href="../gst-plugins-bad-libs-1.0/gst-plugins-bad-libs-Base-MPEG-TS-sections.html#GstMpegtsPatProgram"><span class="type">GstMpegtsPatPrograms</span></a></p>
+ array of <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/gst-plugins-bad-libs-Base-MPEG-TS-sections.html#GstMpegtsPatProgram"><span class="type">GstMpegtsPatPrograms</span></a></p>
 <div class="refsect3">
 <a name="id-1.2.5.4.9.14.5"></a><h4>Parameters</h4>
 <div class="informaltable"><table width="100%" border="0">
diff --git a/docs/libs/html/gst-plugins-bad-libs-GstAggregator.html b/docs/libs/html/gst-plugins-bad-libs-GstAggregator.html
index b54fb8d..d3de038 100644
--- a/docs/libs/html/gst-plugins-bad-libs-GstAggregator.html
+++ b/docs/libs/html/gst-plugins-bad-libs-GstAggregator.html
@@ -64,6 +64,14 @@
 <a class="link" href="gst-plugins-bad-libs-GstAggregator.html#gst-aggregator-iterate-sinkpads" title="gst_aggregator_iterate_sinkpads ()">gst_aggregator_iterate_sinkpads</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
+<tr>
+<td class="function_type">
+<a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstClock.html#GstClockTime"><span class="returnvalue">GstClockTime</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="gst-plugins-bad-libs-GstAggregator.html#gst-aggregator-get-latency" title="gst_aggregator_get_latency ()">gst_aggregator_get_latency</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
 </tbody>
 </table></div>
 </div>
@@ -117,6 +125,12 @@
    subclass, it should instead return GST_FLOW_EOS in its aggregate
    implementation.
  </p></li>
+<li class="listitem"><p>
+   Note that the aggregator logic regarding gap event handling is to turn
+   these into gap buffers with matching PTS and duration. It will also
+   flag these buffers with GST_BUFFER_FLAG_GAP and GST_BUFFER_FLAG_DROPPABLE
+   to ease their identification and subsequent processing.
+ </p></li>
 </ul></div>
 </div>
 <div class="refsect1">
@@ -222,6 +236,37 @@
 </table></div>
 </div>
 </div>
+<hr>
+<div class="refsect2">
+<a name="gst-aggregator-get-latency"></a><h3>gst_aggregator_get_latency ()</h3>
+<pre class="programlisting"><a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstClock.html#GstClockTime"><span class="returnvalue">GstClockTime</span></a>
+gst_aggregator_get_latency (<em class="parameter"><code><a class="link" href="gst-plugins-bad-libs-GstAggregator.html#GstAggregator" title="struct GstAggregator"><span class="type">GstAggregator</span></a> *self</code></em>);</pre>
+<p>Retrieves the latency values reported by <em class="parameter"><code>self</code></em>
+ in response to the latency
+query, or <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstClock.html#GST-CLOCK-TIME-NONE:CAPS"><code class="literal">GST_CLOCK_TIME_NONE</code></a> if there is not live source connected and the element
+will not wait for the clock.</p>
+<p>Typically only called by subclasses.</p>
+<div class="refsect3">
+<a name="id-1.2.7.2.6.5.6"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>self</p></td>
+<td class="parameter_description"><p>a <a class="link" href="gst-plugins-bad-libs-GstAggregator.html#GstAggregator" title="struct GstAggregator"><span class="type">GstAggregator</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="id-1.2.7.2.6.5.7"></a><h4>Returns</h4>
+<p> The latency or <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstClock.html#GST-CLOCK-TIME-NONE:CAPS"><code class="literal">GST_CLOCK_TIME_NONE</code></a> if the element does not sync</p>
+<p></p>
+</div>
+</div>
 </div>
 <div class="refsect1">
 <a name="gst-plugins-bad-libs-GstAggregator.other_details"></a><h2>Types and Values</h2>
@@ -395,7 +440,7 @@
 <td class="struct_member_description"><p>Mandatory.
 Called when buffers are queued on all sinkpads. Classes
 should iterate the GstElement-&gt;sinkpads and peek or steal
-buffers from the <a href="../gst-plugins-bad-libs-1.0/gst-plugins-bad-libs-GstAggregatorPad.html#GstAggregatorPad"><span class="type">GstAggregatorPads</span></a>. If the subclass returns
+buffers from the <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/gst-plugins-bad-libs-GstAggregatorPad.html#GstAggregatorPad"><span class="type">GstAggregatorPads</span></a>. If the subclass returns
 GST_FLOW_EOS, sending of the eos event will be taken care
 of. Once / if a buffer has been constructed from the
 aggregated buffers, the subclass should call _finish_buffer.</p></td>
diff --git a/docs/libs/html/gst-plugins-bad-libs-GstVideoAggregatorPad.html b/docs/libs/html/gst-plugins-bad-libs-GstVideoAggregatorPad.html
index a6c3729..d30038b 100644
--- a/docs/libs/html/gst-plugins-bad-libs-GstVideoAggregatorPad.html
+++ b/docs/libs/html/gst-plugins-bad-libs-GstVideoAggregatorPad.html
@@ -66,6 +66,12 @@
   GstVideoInfo info;
 
   GstBuffer *buffer;
+  /* The caps on the pad may not match the buffer above because of two reasons:
+   * 1) When caps change, the info above will get updated, but the buffer might
+   *    not since it might be pending on the GstAggregatorPad
+   * 2) We might reject the new buffer in fill_queues() and reuse a previous
+   *    buffer which has older GstVideoInfo
+   * Hence, we need to maintain a GstVideoInfo for mapping buffers separately */
   GstVideoInfo buffer_vinfo;
 
   GstVideoFrame *aggregated_frame;
diff --git a/docs/libs/html/gst-plugins-bad-libs-gstglmemory.html b/docs/libs/html/gst-plugins-bad-libs-gstglmemory.html
index 1acf1f6..42e3417 100644
--- a/docs/libs/html/gst-plugins-bad-libs-gstglmemory.html
+++ b/docs/libs/html/gst-plugins-bad-libs-gstglmemory.html
@@ -627,7 +627,7 @@
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
-<td class="parameter_name"><p>param</p></td>
+<td class="parameter_name"><p>params</p></td>
 <td class="parameter_description"><p>a <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstAllocator.html#GstAllocationParams"><span class="type">GstAllocationParams</span></a></p></td>
 <td class="parameter_annotations"> </td>
 </tr>
diff --git a/docs/libs/html/index.sgml b/docs/libs/html/index.sgml
index aa1f534..53e6bf4 100644
--- a/docs/libs/html/index.sgml
+++ b/docs/libs/html/index.sgml
@@ -427,6 +427,7 @@
 <ANCHOR id="gst-aggregator-finish-buffer" href="gst-plugins-bad-libs-1.0/gst-plugins-bad-libs-GstAggregator.html#gst-aggregator-finish-buffer">
 <ANCHOR id="gst-aggregator-set-src-caps" href="gst-plugins-bad-libs-1.0/gst-plugins-bad-libs-GstAggregator.html#gst-aggregator-set-src-caps">
 <ANCHOR id="gst-aggregator-iterate-sinkpads" href="gst-plugins-bad-libs-1.0/gst-plugins-bad-libs-GstAggregator.html#gst-aggregator-iterate-sinkpads">
+<ANCHOR id="gst-aggregator-get-latency" href="gst-plugins-bad-libs-1.0/gst-plugins-bad-libs-GstAggregator.html#gst-aggregator-get-latency">
 <ANCHOR id="gst-plugins-bad-libs-GstAggregator.other_details" href="gst-plugins-bad-libs-1.0/gst-plugins-bad-libs-GstAggregator.html#gst-plugins-bad-libs-GstAggregator.other_details">
 <ANCHOR id="GstAggregator" href="gst-plugins-bad-libs-1.0/gst-plugins-bad-libs-GstAggregator.html#GstAggregator">
 <ANCHOR id="GstAggregatorClass" href="gst-plugins-bad-libs-1.0/gst-plugins-bad-libs-GstAggregator.html#GstAggregatorClass">
diff --git a/docs/plugins/html/gst-plugins-bad-plugins-audiomixer.html b/docs/plugins/html/gst-plugins-bad-plugins-audiomixer.html
index c383c94..5bd0b3f 100644
--- a/docs/plugins/html/gst-plugins-bad-plugins-audiomixer.html
+++ b/docs/plugins/html/gst-plugins-bad-plugins-audiomixer.html
@@ -91,7 +91,7 @@
     <span class="lineart">╰──</span> <a href="https://developer.gnome.org/gobject/unstable/gobject-The-Base-Object-Type.html#GInitiallyUnowned">GInitiallyUnowned</a>
         <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstObject.html">GstObject</a>
             <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html">GstElement</a>
-                <span class="lineart">╰──</span> GstAggregator
+                <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/gst-plugins-bad-libs-GstAggregator.html#GstAggregator">GstAggregator</a>
                     <span class="lineart">╰──</span> GstAudioMixer
 </pre>
 </div>
diff --git a/docs/plugins/html/gst-plugins-bad-plugins-compositor.html b/docs/plugins/html/gst-plugins-bad-plugins-compositor.html
index 3c0aee4..f3c1c3f 100644
--- a/docs/plugins/html/gst-plugins-bad-plugins-compositor.html
+++ b/docs/plugins/html/gst-plugins-bad-plugins-compositor.html
@@ -54,12 +54,12 @@
     <span class="lineart">╰──</span> <a href="https://developer.gnome.org/gobject/unstable/gobject-The-Base-Object-Type.html#GInitiallyUnowned">GInitiallyUnowned</a>
         <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstObject.html">GstObject</a>
             <span class="lineart">├──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html">GstElement</a>
-            <span class="lineart">│</span>   <span class="lineart">╰──</span> GstAggregator
-            <span class="lineart">│</span>       <span class="lineart">╰──</span> GstVideoAggregator
+            <span class="lineart">│</span>   <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/gst-plugins-bad-libs-GstAggregator.html#GstAggregator">GstAggregator</a>
+            <span class="lineart">│</span>       <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/gst-plugins-bad-libs-GstVideoAggregator.html#GstVideoAggregator">GstVideoAggregator</a>
             <span class="lineart">│</span>           <span class="lineart">╰──</span> GstCompositor
             <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstPad.html">GstPad</a>
-                <span class="lineart">╰──</span> GstAggregatorPad
-                    <span class="lineart">╰──</span> GstVideoAggregatorPad
+                <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/gst-plugins-bad-libs-GstAggregatorPad.html#GstAggregatorPad">GstAggregatorPad</a>
+                    <span class="lineart">╰──</span> <a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-bad-libs/html/gst-plugins-bad-libs-GstVideoAggregatorPad.html#GstVideoAggregatorPad">GstVideoAggregatorPad</a>
                         <span class="lineart">╰──</span> GstCompositorPad
 </pre>
 </div>
diff --git a/docs/plugins/html/gst-plugins-bad-plugins-fpsdisplaysink.html b/docs/plugins/html/gst-plugins-bad-plugins-fpsdisplaysink.html
index 355eacb..d32bd8e 100644
--- a/docs/plugins/html/gst-plugins-bad-plugins-fpsdisplaysink.html
+++ b/docs/plugins/html/gst-plugins-bad-plugins-fpsdisplaysink.html
@@ -163,7 +163,7 @@
 4</pre></td>
         <td class="listing_code"><pre class="programlisting">gst<span class="gtkdoc opt">-</span>launch videotestsrc <span class="gtkdoc opt">!</span> fpsdisplaysink
 gst<span class="gtkdoc opt">-</span>launch videotestsrc <span class="gtkdoc opt">!</span> fpsdisplaysink text<span class="gtkdoc opt">-</span>overlay<span class="gtkdoc opt">=</span><span class="keyword">false</span>
-gst<span class="gtkdoc opt">-</span>launch filesrc location<span class="gtkdoc opt">=</span>video<span class="gtkdoc opt">.</span>avi <span class="gtkdoc opt">!</span> decodebin2 name<span class="gtkdoc opt">=</span>d <span class="gtkdoc opt">!</span> queue <span class="gtkdoc opt">!</span> fpsdisplaysink d<span class="gtkdoc opt">. !</span> queue <span class="gtkdoc opt">!</span> fakesink sync<span class="gtkdoc opt">=</span><span class="keyword">true</span>
+gst<span class="gtkdoc opt">-</span>launch filesrc location<span class="gtkdoc opt">=</span>video<span class="gtkdoc opt">.</span>avi <span class="gtkdoc opt">!</span> decodebin name<span class="gtkdoc opt">=</span>d <span class="gtkdoc opt">!</span> queue <span class="gtkdoc opt">!</span> fpsdisplaysink d<span class="gtkdoc opt">. !</span> queue <span class="gtkdoc opt">!</span> fakesink sync<span class="gtkdoc opt">=</span><span class="keyword">true</span>
 gst<span class="gtkdoc opt">-</span>launch playbin uri<span class="gtkdoc opt">=</span>file<span class="gtkdoc opt">:</span><span class="gtkdoc slc">///path/to/video.avi video-sink=&quot;fpsdisplaysink&quot; audio-sink=fakesink</span></pre></td>
       </tr>
     </tbody>
diff --git a/ext/apexsink/gstapexraop.c b/ext/apexsink/gstapexraop.c
index 0a78096..af4f573 100644
--- a/ext/apexsink/gstapexraop.c
+++ b/ext/apexsink/gstapexraop.c
@@ -252,7 +252,7 @@
   {
     struct asvals
     {
-      gulong url_key;
+      guint32 url_key;
       guint64 conn_id;
       guchar challenge[16];
     } v;
@@ -284,7 +284,7 @@
     return GST_RTSP_STS_DESTINATION_UNREACHABLE;
 
   RAND_bytes (randbuf.buf, sizeof (randbuf));
-  sprintf ((gchar *) conn->url_abspath, "%lu", randbuf.v.url_key);
+  sprintf ((gchar *) conn->url_abspath, "%u", randbuf.v.url_key);
   sprintf ((char *) conn->cid, "%16" G_GINT64_MODIFIER "x", randbuf.v.conn_id);
 
   RAND_bytes (conn->aes_ky, AES_BLOCK_SIZE);
diff --git a/ext/dash/gstdashdemux.c b/ext/dash/gstdashdemux.c
index 16c5488..1b18ec1 100644
--- a/ext/dash/gstdashdemux.c
+++ b/ext/dash/gstdashdemux.c
@@ -214,7 +214,7 @@
 static gint64
 gst_dash_demux_get_manifest_update_interval (GstAdaptiveDemux * demux);
 static GstFlowReturn
-gst_dash_demux_update_manifest (GstAdaptiveDemux * demux, GstBuffer * buf);
+gst_dash_demux_update_manifest_data (GstAdaptiveDemux * demux, GstBuffer * buf);
 static gint64
 gst_dash_demux_stream_get_fragment_waiting_time (GstAdaptiveDemuxStream *
     stream);
@@ -354,7 +354,8 @@
   gstadaptivedemux_class->seek = gst_dash_demux_seek;
 
   gstadaptivedemux_class->process_manifest = gst_dash_demux_process_manifest;
-  gstadaptivedemux_class->update_manifest = gst_dash_demux_update_manifest;
+  gstadaptivedemux_class->update_manifest_data =
+      gst_dash_demux_update_manifest_data;
   gstadaptivedemux_class->get_manifest_update_interval =
       gst_dash_demux_get_manifest_update_interval;
 
@@ -484,6 +485,9 @@
     active_stream = gst_mpdparser_get_active_stream_by_index (demux->client, i);
     if (active_stream == NULL)
       continue;
+    /* TODO: support 'application' mimeType */
+    if (active_stream->mimeType == GST_STREAM_APPLICATION)
+      continue;
 
     srcpad = gst_dash_demux_create_pad (demux, active_stream);
     caps = gst_dash_demux_get_input_caps (demux, active_stream);
@@ -1142,7 +1146,8 @@
 }
 
 static GstFlowReturn
-gst_dash_demux_update_manifest (GstAdaptiveDemux * demux, GstBuffer * buffer)
+gst_dash_demux_update_manifest_data (GstAdaptiveDemux * demux,
+    GstBuffer * buffer)
 {
   GstDashDemux *dashdemux = GST_DASH_DEMUX_CAST (demux);
   GstMpdClient *new_client = NULL;
diff --git a/ext/dash/gstmpdparser.c b/ext/dash/gstmpdparser.c
index 369aca4..21f84f1 100644
--- a/ext/dash/gstmpdparser.c
+++ b/ext/dash/gstmpdparser.c
@@ -1329,6 +1329,9 @@
     return;
   }
 
+  mult_seg_base_type->duration = 0;
+  mult_seg_base_type->startNumber = 1;
+
   /* Inherit attribute values from parent */
   if (parent) {
     mult_seg_base_type->duration = parent->duration;
@@ -1345,8 +1348,10 @@
     mult_seg_base_type->duration = intval;
   }
 
-  gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "startNumber", 1,
-      &mult_seg_base_type->startNumber);
+  if (gst_mpdparser_get_xml_prop_unsigned_integer (a_node, "startNumber", 1,
+          &intval)) {
+    mult_seg_base_type->startNumber = intval;
+  }
 
   GST_LOG ("extension of MultipleSegmentBaseType extension:");
   gst_mpdparser_parse_seg_base_type_ext (&mult_seg_base_type->SegBaseType,
diff --git a/ext/dtls/gstdtlsagent.c b/ext/dtls/gstdtlsagent.c
index 837ef30..af5b75c 100644
--- a/ext/dtls/gstdtlsagent.c
+++ b/ext/dtls/gstdtlsagent.c
@@ -42,9 +42,7 @@
 GST_DEBUG_CATEGORY_STATIC (gst_dtls_agent_debug);
 #define GST_CAT_DEFAULT gst_dtls_agent_debug
 
-G_DEFINE_TYPE_WITH_CODE (GstDtlsAgent, gst_dtls_agent, G_TYPE_OBJECT,
-    GST_DEBUG_CATEGORY_INIT (gst_dtls_agent_debug, "dtlsagent", 0,
-        "DTLS Agent"));
+G_DEFINE_TYPE (GstDtlsAgent, gst_dtls_agent, G_TYPE_OBJECT);
 
 #define GST_DTLS_AGENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), GST_TYPE_DTLS_AGENT, GstDtlsAgentPrivate))
 
@@ -115,6 +113,9 @@
   gint num_locks;
 
   if (g_once_init_enter (&is_init)) {
+    GST_DEBUG_CATEGORY_INIT (gst_dtls_agent_debug, "dtlsagent", 0,
+        "DTLS Agent");
+
     if (OPENSSL_VERSION_NUMBER < 0x1000100fL) {
       GST_WARNING_OBJECT (NULL,
           "Incorrect OpenSSL version, should be >= 1.0.1, is %s",
diff --git a/ext/dtls/gstdtlsconnection.c b/ext/dtls/gstdtlsconnection.c
index c84e9f2..0d6d827 100644
--- a/ext/dtls/gstdtlsconnection.c
+++ b/ext/dtls/gstdtlsconnection.c
@@ -74,16 +74,17 @@
 
 static int connection_ex_index;
 
+static GstClock *system_clock;
+static void handle_timeout (gpointer data, gpointer user_data);
+
 struct _GstDtlsConnectionPrivate
 {
   SSL *ssl;
   BIO *bio;
-  GThread *thread;
 
   gboolean is_client;
   gboolean is_alive;
   gboolean keys_exported;
-  gboolean timeout_set;
 
   GMutex mutex;
   GCond condition;
@@ -92,6 +93,9 @@
   gint bio_buffer_offset;
 
   GClosure *send_closure;
+
+  gboolean timeout_pending;
+  GThreadPool *thread_pool;
 };
 
 static void gst_dtls_connection_finalize (GObject * gobject);
@@ -99,7 +103,6 @@
     const GValue *, GParamSpec *);
 
 static void log_state (GstDtlsConnection *, const gchar * str);
-static gpointer connection_timeout_thread_func (GstDtlsConnection *);
 static void export_srtp_keys (GstDtlsConnection *);
 static void openssl_poll (GstDtlsConnection *);
 static int openssl_verify_callback (int preverify_ok,
@@ -154,6 +157,8 @@
   _gst_dtls_init_openssl ();
 
   gobject_class->finalize = gst_dtls_connection_finalize;
+
+  system_clock = gst_system_clock_obtain ();
 }
 
 static void
@@ -164,14 +169,12 @@
 
   priv->ssl = NULL;
   priv->bio = NULL;
-  priv->thread = NULL;
 
   priv->send_closure = NULL;
 
   priv->is_client = FALSE;
   priv->is_alive = TRUE;
   priv->keys_exported = FALSE;
-  priv->timeout_set = FALSE;
 
   priv->bio_buffer = NULL;
   priv->bio_buffer_len = 0;
@@ -179,6 +182,13 @@
 
   g_mutex_init (&priv->mutex);
   g_cond_init (&priv->condition);
+
+  /* Thread pool for handling timeouts, we only need one thread for that
+   * really and share threads with all other thread pools around there as
+   * this is not going to happen very often */
+  priv->thread_pool = g_thread_pool_new (handle_timeout, self, 1, FALSE, NULL);
+  g_assert (priv->thread_pool);
+  priv->timeout_pending = FALSE;
 }
 
 static void
@@ -187,6 +197,8 @@
   GstDtlsConnection *self = GST_DTLS_CONNECTION (gobject);
   GstDtlsConnectionPrivate *priv = self->priv;
 
+  g_thread_pool_free (priv->thread_pool, TRUE, TRUE);
+  priv->thread_pool = NULL;
 
   SSL_free (priv->ssl);
   priv->ssl = NULL;
@@ -247,8 +259,6 @@
 {
   GstDtlsConnectionPrivate *priv;
 
-  g_return_if_fail (GST_IS_DTLS_CONNECTION (self));
-
   priv = self->priv;
 
   g_return_if_fail (priv->send_closure);
@@ -260,7 +270,6 @@
   GST_TRACE_OBJECT (self, "locked @ start");
 
   priv->is_alive = TRUE;
-  priv->timeout_set = FALSE;
   priv->bio_buffer = NULL;
   priv->bio_buffer_len = 0;
   priv->bio_buffer_offset = 0;
@@ -277,42 +286,114 @@
   openssl_poll (self);
 
   log_state (self, "first poll done");
-  priv->thread = NULL;
 
   GST_TRACE_OBJECT (self, "unlocking @ start");
   g_mutex_unlock (&priv->mutex);
 }
 
-void
-gst_dtls_connection_start_timeout (GstDtlsConnection * self)
+static void
+handle_timeout (gpointer data, gpointer user_data)
+{
+  GstDtlsConnection *self = user_data;
+  GstDtlsConnectionPrivate *priv;
+  gint ret;
+
+  priv = self->priv;
+
+  g_mutex_lock (&priv->mutex);
+  priv->timeout_pending = FALSE;
+  if (priv->is_alive) {
+    ret = DTLSv1_handle_timeout (priv->ssl);
+
+    GST_DEBUG_OBJECT (self, "handle timeout returned %d, is_alive: %d", ret,
+        priv->is_alive);
+
+    if (ret < 0) {
+      GST_WARNING_OBJECT (self, "handling timeout failed");
+    } else if (ret > 0) {
+      log_state (self, "handling timeout before poll");
+      openssl_poll (self);
+      log_state (self, "handling timeout after poll");
+    }
+  }
+  g_mutex_unlock (&priv->mutex);
+}
+
+static gboolean
+schedule_timeout_handling (GstClock * clock, GstClockTime time, GstClockID id,
+    gpointer user_data)
+{
+  GstDtlsConnection *self = user_data;
+
+  g_mutex_lock (&self->priv->mutex);
+  if (self->priv->is_alive && !self->priv->timeout_pending) {
+    self->priv->timeout_pending = TRUE;
+
+    GST_TRACE_OBJECT (self, "Schedule timeout now");
+    g_thread_pool_push (self->priv->thread_pool, GINT_TO_POINTER (0xc0ffee),
+        NULL);
+  }
+  g_mutex_unlock (&self->priv->mutex);
+
+  return TRUE;
+}
+
+static void
+gst_dtls_connection_check_timeout_locked (GstDtlsConnection * self)
 {
   GstDtlsConnectionPrivate *priv;
-  GError *error = NULL;
-  gchar *thread_name;
+  struct timeval timeout;
+  gint64 end_time, wait_time;
 
   g_return_if_fail (GST_IS_DTLS_CONNECTION (self));
 
   priv = self->priv;
 
-  thread_name = g_strdup_printf ("connection_thread_%p", self);
+  if (DTLSv1_get_timeout (priv->ssl, &timeout)) {
+    wait_time = timeout.tv_sec * G_USEC_PER_SEC + timeout.tv_usec;
+
+    GST_DEBUG_OBJECT (self, "waiting for %" G_GINT64_FORMAT " usec", wait_time);
+    if (wait_time) {
+      GstClockID clock_id;
+      GstClockReturn clock_return;
+
+      end_time = gst_clock_get_time (system_clock) + wait_time * GST_USECOND;
+
+      clock_id = gst_clock_new_single_shot_id (system_clock, end_time);
+      clock_return =
+          gst_clock_id_wait_async (clock_id, schedule_timeout_handling,
+          g_object_ref (self), (GDestroyNotify) g_object_unref);
+      g_assert (clock_return == GST_CLOCK_OK);
+      gst_clock_id_unref (clock_id);
+    } else {
+      if (self->priv->is_alive && !self->priv->timeout_pending) {
+        self->priv->timeout_pending = TRUE;
+        GST_TRACE_OBJECT (self, "Schedule timeout now");
+
+        g_thread_pool_push (self->priv->thread_pool, GINT_TO_POINTER (0xc0ffee),
+            NULL);
+      }
+    }
+  } else {
+    GST_DEBUG_OBJECT (self, "no timeout set");
+  }
+}
+
+void
+gst_dtls_connection_check_timeout (GstDtlsConnection * self)
+{
+  GstDtlsConnectionPrivate *priv;
+
+  g_return_if_fail (GST_IS_DTLS_CONNECTION (self));
+
+  priv = self->priv;
 
   GST_TRACE_OBJECT (self, "locking @ start_timeout");
   g_mutex_lock (&priv->mutex);
   GST_TRACE_OBJECT (self, "locked @ start_timeout");
-
-  GST_INFO_OBJECT (self, "starting connection timeout");
-  priv->thread = g_thread_try_new (thread_name,
-      (GThreadFunc) connection_timeout_thread_func, self, &error);
-  if (error) {
-    GST_WARNING_OBJECT (self, "error creating connection thread: %s (%d)",
-        error->message, error->code);
-    g_clear_error (&error);
-  }
-
-  g_free (thread_name);
-
-  GST_TRACE_OBJECT (self, "unlocking @ start_timeout");
+  gst_dtls_connection_check_timeout_locked (self);
   g_mutex_unlock (&priv->mutex);
+  GST_TRACE_OBJECT (self, "unlocking @ start_timeout");
 }
 
 void
@@ -360,11 +441,6 @@
   GST_TRACE_OBJECT (self, "unlocking @ close");
   g_mutex_unlock (&self->priv->mutex);
 
-  if (self->priv->thread) {
-    g_thread_join (self->priv->thread);
-    self->priv->thread = NULL;
-  }
-
   GST_DEBUG_OBJECT (self, "closed connection");
 }
 
@@ -497,70 +573,6 @@
       states, SSL_get_state (priv->ssl), SSL_state_string_long (priv->ssl));
 }
 
-static gpointer
-connection_timeout_thread_func (GstDtlsConnection * self)
-{
-  GstDtlsConnectionPrivate *priv = self->priv;
-  struct timeval timeout;
-  gint64 end_time, wait_time;
-  gint ret;
-
-  while (priv->is_alive) {
-    GST_TRACE_OBJECT (self, "locking @ timeout");
-    g_mutex_lock (&priv->mutex);
-    GST_TRACE_OBJECT (self, "locked @ timeout");
-
-    if (DTLSv1_get_timeout (priv->ssl, &timeout)) {
-      wait_time = timeout.tv_sec * G_USEC_PER_SEC + timeout.tv_usec;
-
-      if (wait_time) {
-        GST_DEBUG_OBJECT (self, "waiting for %" G_GINT64_FORMAT " usec",
-            wait_time);
-
-        end_time = g_get_monotonic_time () + wait_time;
-
-        GST_TRACE_OBJECT (self, "wait @ timeout");
-        g_cond_wait_until (&priv->condition, &priv->mutex, end_time);
-        GST_TRACE_OBJECT (self, "continued @ timeout");
-      }
-
-      ret = DTLSv1_handle_timeout (priv->ssl);
-
-      GST_DEBUG_OBJECT (self, "handle timeout returned %d, is_alive: %d", ret,
-          priv->is_alive);
-
-      if (ret < 0) {
-        GST_TRACE_OBJECT (self, "unlocking @ timeout failed");
-        g_mutex_unlock (&priv->mutex);
-        break;                  /* self failed after DTLS1_TMO_ALERT_COUNT (12) attempts */
-      }
-
-      if (ret > 0) {
-        log_state (self, "handling timeout before poll");
-        openssl_poll (self);
-        log_state (self, "handling timeout after poll");
-      }
-    } else {
-      GST_DEBUG_OBJECT (self, "waiting indefinitely");
-
-      priv->timeout_set = FALSE;
-
-      while (!priv->timeout_set && priv->is_alive) {
-        GST_TRACE_OBJECT (self, "wait @ timeout");
-        g_cond_wait (&priv->condition, &priv->mutex);
-      }
-      GST_TRACE_OBJECT (self, "continued @ timeout");
-    }
-
-    GST_TRACE_OBJECT (self, "unlocking @ timeout");
-    g_mutex_unlock (&priv->mutex);
-  }
-
-  log_state (self, "timeout thread exiting");
-
-  return NULL;
-}
-
 static void
 export_srtp_keys (GstDtlsConnection * self)
 {
@@ -577,16 +589,16 @@
   struct
   {
     Key client_key;
-    Key servgst_key;
+    Key server_key;
     Salt client_salt;
-    Salt servgst_salt;
+    Salt server_salt;
   } exported_keys;
 
   struct
   {
     Key key;
     Salt salt;
-  } client_key, servgst_key;
+  } client_key, server_key;
 
   SRTP_PROTECTION_PROFILE *profile;
   GstDtlsSrtpCipher cipher;
@@ -623,17 +635,17 @@
   }
 
   client_key.key = exported_keys.client_key;
-  servgst_key.key = exported_keys.servgst_key;
+  server_key.key = exported_keys.server_key;
   client_key.salt = exported_keys.client_salt;
-  servgst_key.salt = exported_keys.servgst_salt;
+  server_key.salt = exported_keys.server_salt;
 
   if (self->priv->is_client) {
     g_signal_emit (self, signals[SIGNAL_ON_ENCODER_KEY], 0, &client_key, cipher,
         auth);
-    g_signal_emit (self, signals[SIGNAL_ON_DECODER_KEY], 0, &servgst_key,
+    g_signal_emit (self, signals[SIGNAL_ON_DECODER_KEY], 0, &server_key,
         cipher, auth);
   } else {
-    g_signal_emit (self, signals[SIGNAL_ON_ENCODER_KEY], 0, &servgst_key,
+    g_signal_emit (self, signals[SIGNAL_ON_ENCODER_KEY], 0, &server_key,
         cipher, auth);
     g_signal_emit (self, signals[SIGNAL_ON_DECODER_KEY], 0, &client_key, cipher,
         auth);
@@ -853,8 +865,7 @@
     case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
     case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
       GST_LOG_OBJECT (self, "BIO: Timeout set");
-      priv->timeout_set = TRUE;
-      g_cond_signal (&priv->condition);
+      gst_dtls_connection_check_timeout_locked (self);
       return 1;
     case BIO_CTRL_RESET:
       priv->bio_buffer = NULL;
diff --git a/ext/dtls/gstdtlsconnection.h b/ext/dtls/gstdtlsconnection.h
index 1f901ac..6260b93 100644
--- a/ext/dtls/gstdtlsconnection.h
+++ b/ext/dtls/gstdtlsconnection.h
@@ -85,7 +85,7 @@
 GType gst_dtls_connection_get_type(void) G_GNUC_CONST;
 
 void gst_dtls_connection_start(GstDtlsConnection *, gboolean is_client);
-void gst_dtls_connection_start_timeout(GstDtlsConnection *);
+void gst_dtls_connection_check_timeout(GstDtlsConnection *);
 
 /*
  * Stops the connections, it is not required to call this function.
@@ -102,7 +102,7 @@
  * Sets the closure that will be called whenever data needs to be sent.
  *
  * The closure will get called with the following arguments:
- * void cb(GstDtlsConnection *, gpointer data, gint length, gpointer usgst_data)
+ * void cb(GstDtlsConnection *, gpointer data, gint length, gpointer user_data)
  */
 void gst_dtls_connection_set_send_callback(GstDtlsConnection *, GClosure *);
 
diff --git a/ext/dtls/gstdtlsdec.c b/ext/dtls/gstdtlsdec.c
index a8aa806..0881a8f 100644
--- a/ext/dtls/gstdtlsdec.c
+++ b/ext/dtls/gstdtlsdec.c
@@ -96,9 +96,11 @@
 
 static void on_key_received (GstDtlsConnection *, gpointer key, guint cipher,
     guint auth, GstDtlsDec *);
-static gboolean on_pegst_certificate_received (GstDtlsConnection *, gchar * pem,
+static gboolean on_peer_certificate_received (GstDtlsConnection *, gchar * pem,
     GstDtlsDec *);
 static GstFlowReturn sink_chain (GstPad *, GstObject * parent, GstBuffer *);
+static GstFlowReturn sink_chain_list (GstPad *, GstObject * parent,
+    GstBufferList *);
 
 static GstDtlsAgent *get_agent_by_pem (const gchar * pem);
 static void agent_weak_ref_notify (gchar * pem, GstDtlsAgent *);
@@ -150,7 +152,7 @@
   properties[PROP_DECODER_KEY] =
       g_param_spec_boxed ("decoder-key",
       "Decoder key",
-      "SRTP key that should be used by the decider",
+      "SRTP key that should be used by the decoder",
       GST_TYPE_CAPS, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
 
   properties[PROP_SRTP_CIPHER] =
@@ -189,9 +191,9 @@
   self->agent = get_agent_by_pem (NULL);
   self->connection_id = NULL;
   self->connection = NULL;
-  self->pegst_pem = NULL;
+  self->peer_pem = NULL;
 
-  self->decodgst_key = NULL;
+  self->decoder_key = NULL;
   self->srtp_cipher = DEFAULT_SRTP_CIPHER;
   self->srtp_auth = DEFAULT_SRTP_AUTH;
 
@@ -202,6 +204,7 @@
   g_return_if_fail (sink);
 
   gst_pad_set_chain_function (sink, GST_DEBUG_FUNCPTR (sink_chain));
+  gst_pad_set_chain_list_function (sink, GST_DEBUG_FUNCPTR (sink_chain_list));
 
   gst_element_add_pad (GST_ELEMENT (self), sink);
 }
@@ -211,16 +214,16 @@
 {
   GstDtlsDec *self = GST_DTLS_DEC (object);
 
-  if (self->decodgst_key) {
-    gst_buffer_unref (self->decodgst_key);
-    self->decodgst_key = NULL;
+  if (self->decoder_key) {
+    gst_buffer_unref (self->decoder_key);
+    self->decoder_key = NULL;
   }
 
   g_free (self->connection_id);
   self->connection_id = NULL;
 
-  g_free (self->pegst_pem);
-  self->pegst_pem = NULL;
+  g_free (self->peer_pem);
+  self->peer_pem = NULL;
 
   g_mutex_clear (&self->src_mutex);
 
@@ -287,10 +290,10 @@
           gst_dtls_agent_get_certificate_pem (self->agent));
       break;
     case PROP_PEER_PEM:
-      g_value_set_string (value, self->pegst_pem);
+      g_value_set_string (value, self->peer_pem);
       break;
     case PROP_DECODER_KEY:
-      g_value_set_boxed (value, self->decodgst_key);
+      g_value_set_boxed (value, self->decoder_key);
       break;
     case PROP_SRTP_CIPHER:
       g_value_set_uint (value, self->srtp_cipher);
@@ -315,7 +318,7 @@
         g_signal_connect_object (self->connection,
             "on-decoder-key", G_CALLBACK (on_key_received), self, 0);
         g_signal_connect_object (self->connection,
-            "on-peer-certificate", G_CALLBACK (on_pegst_certificate_received),
+            "on-peer-certificate", G_CALLBACK (on_peer_certificate_received),
             self, 0);
       } else {
         GST_WARNING_OBJECT (self,
@@ -337,6 +340,7 @@
     GstPadTemplate * tmpl, const gchar * name, const GstCaps * caps)
 {
   GstDtlsDec *self = GST_DTLS_DEC (element);
+  GstPad *pad;
 
   GST_DEBUG_OBJECT (element, "requesting pad");
 
@@ -344,20 +348,26 @@
   g_return_val_if_fail (tmpl->direction == GST_PAD_SRC, NULL);
 
   g_mutex_lock (&self->src_mutex);
-
-  self->src = gst_pad_new_from_template (tmpl, name);
-  g_return_val_if_fail (self->src, NULL);
-
-  if (caps) {
-    g_object_set (self->src, "caps", caps, NULL);
+  if (self->src) {
+    GST_ERROR_OBJECT (self, "Pad %s:%s exists already",
+        GST_DEBUG_PAD_NAME (self->src));
+    g_mutex_unlock (&self->src_mutex);
+    return NULL;
   }
 
-  gst_pad_set_active (self->src, TRUE);
-  gst_element_add_pad (element, self->src);
-
+  self->src = pad = gst_pad_new_from_template (tmpl, name);
+  gst_object_ref (pad);
   g_mutex_unlock (&self->src_mutex);
 
-  return self->src;
+  gst_pad_set_active (pad, TRUE);
+
+  if (caps)
+    gst_pad_set_caps (pad, (GstCaps *) caps);
+
+  gst_element_add_pad (element, pad);
+  gst_object_unref (pad);
+
+  return pad;
 }
 
 static void
@@ -365,16 +375,17 @@
 {
   GstDtlsDec *self = GST_DTLS_DEC (element);
 
-  g_mutex_lock (&self->src_mutex);
-
   g_return_if_fail (self->src == pad);
-  gst_element_remove_pad (element, self->src);
+
+  g_mutex_lock (&self->src_mutex);
+  gst_object_unref (self->src);
   self->src = NULL;
+  g_mutex_unlock (&self->src_mutex);
+
+  gst_element_remove_pad (element, pad);
 
   GST_DEBUG_OBJECT (self, "releasing src pad");
 
-  g_mutex_unlock (&self->src_mutex);
-
   GST_ELEMENT_GET_CLASS (element)->release_pad (element, pad);
 }
 
@@ -391,7 +402,7 @@
   self->srtp_auth = auth;
 
   key_dup = g_memdup (key, GST_DTLS_SRTP_MASTER_KEY_LENGTH);
-  self->decodgst_key =
+  self->decoder_key =
       gst_buffer_new_wrapped (key_dup, GST_DTLS_SRTP_MASTER_KEY_LENGTH);
 
   key_str = g_base64_encode (key, GST_DTLS_SRTP_MASTER_KEY_LENGTH);
@@ -402,7 +413,7 @@
 }
 
 static gboolean
-signal_pegst_certificate_received (GWeakRef * ref)
+signal_peer_certificate_received (GWeakRef * ref)
 {
   GstDtlsDec *self;
 
@@ -421,7 +432,7 @@
 }
 
 static gboolean
-on_pegst_certificate_received (GstDtlsConnection * connection, gchar * pem,
+on_peer_certificate_received (GstDtlsConnection * connection, gchar * pem,
     GstDtlsDec * self)
 {
   GWeakRef *ref;
@@ -430,23 +441,101 @@
 
   GST_DEBUG_OBJECT (self, "Received peer certificate PEM: \n%s", pem);
 
-  self->pegst_pem = g_strdup (pem);
+  self->peer_pem = g_strdup (pem);
 
   ref = g_new (GWeakRef, 1);
   g_weak_ref_init (ref, self);
 
-  g_idle_add ((GSourceFunc) signal_pegst_certificate_received, ref);
+  g_idle_add ((GSourceFunc) signal_peer_certificate_received, ref);
 
   return TRUE;
 }
 
+static gint
+process_buffer (GstDtlsDec * self, GstBuffer * buffer)
+{
+  GstMapInfo map_info;
+  gint size;
+
+  if (!gst_buffer_map (buffer, &map_info, GST_MAP_READWRITE))
+    return 0;
+
+  if (!map_info.size) {
+    gst_buffer_unmap (buffer, &map_info);
+    return 0;
+  }
+
+  size =
+      gst_dtls_connection_process (self->connection, map_info.data,
+      map_info.size);
+  gst_buffer_unmap (buffer, &map_info);
+
+  if (size <= 0)
+    return size;
+
+  gst_buffer_set_size (buffer, size);
+
+  return size;
+}
+
+static gboolean
+process_buffer_from_list (GstBuffer ** buffer, guint idx, gpointer user_data)
+{
+  GstDtlsDec *self = GST_DTLS_DEC (user_data);
+  gint size;
+
+  *buffer = gst_buffer_make_writable (*buffer);
+  size = process_buffer (self, *buffer);
+  if (size <= 0)
+    gst_buffer_replace (buffer, NULL);
+
+  return TRUE;
+}
+
+static GstFlowReturn
+sink_chain_list (GstPad * pad, GstObject * parent, GstBufferList * list)
+{
+  GstDtlsDec *self = GST_DTLS_DEC (parent);
+  GstFlowReturn ret = GST_FLOW_OK;
+  GstPad *other_pad;
+
+  list = gst_buffer_list_make_writable (list);
+  gst_buffer_list_foreach (list, process_buffer_from_list, self);
+
+  if (gst_buffer_list_length (list) == 0) {
+    GST_DEBUG_OBJECT (self, "Not produced any buffers");
+    gst_buffer_list_unref (list);
+
+    return GST_FLOW_OK;
+  }
+
+  g_mutex_lock (&self->src_mutex);
+  other_pad = self->src;
+  if (other_pad)
+    gst_object_ref (other_pad);
+  g_mutex_unlock (&self->src_mutex);
+
+  if (other_pad) {
+    GST_LOG_OBJECT (self, "decoded buffer list with length %u, pushing",
+        gst_buffer_list_length (list));
+    ret = gst_pad_push_list (other_pad, list);
+    gst_object_unref (other_pad);
+  } else {
+    GST_LOG_OBJECT (self, "dropped buffer list with length %d, not linked",
+        gst_buffer_list_length (list));
+    gst_buffer_list_unref (list);
+  }
+
+  return ret;
+}
+
 static GstFlowReturn
 sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
 {
   GstDtlsDec *self = GST_DTLS_DEC (parent);
   GstFlowReturn ret = GST_FLOW_OK;
-  GstMapInfo map_info = GST_MAP_INFO_INIT;
   gint size;
+  GstPad *other_pad;
 
   if (!self->agent) {
     gst_buffer_unref (buffer);
@@ -456,17 +545,8 @@
   GST_DEBUG_OBJECT (self, "received buffer from %s with length %zd",
       self->connection_id, gst_buffer_get_size (buffer));
 
-  gst_buffer_map (buffer, &map_info, GST_MAP_READWRITE);
-
-  if (!map_info.size) {
-    gst_buffer_unmap (buffer, &map_info);
-    return GST_FLOW_OK;
-  }
-
-  size =
-      gst_dtls_connection_process (self->connection, map_info.data,
-      map_info.size);
-  gst_buffer_unmap (buffer, &map_info);
+  buffer = gst_buffer_make_writable (buffer);
+  size = process_buffer (self, buffer);
 
   if (size <= 0) {
     gst_buffer_unref (buffer);
@@ -475,18 +555,20 @@
   }
 
   g_mutex_lock (&self->src_mutex);
+  other_pad = self->src;
+  if (other_pad)
+    gst_object_ref (other_pad);
+  g_mutex_unlock (&self->src_mutex);
 
-  if (self->src) {
-    gst_buffer_set_size (buffer, size);
+  if (other_pad) {
     GST_LOG_OBJECT (self, "decoded buffer with length %d, pushing", size);
-    ret = gst_pad_push (self->src, buffer);
+    ret = gst_pad_push (other_pad, buffer);
+    gst_object_unref (other_pad);
   } else {
     GST_LOG_OBJECT (self, "dropped buffer with length %d, not linked", size);
     gst_buffer_unref (buffer);
   }
 
-  g_mutex_unlock (&self->src_mutex);
-
   return ret;
 }
 
diff --git a/ext/dtls/gstdtlsdec.h b/ext/dtls/gstdtlsdec.h
index 2c5fc4a..8d2560e 100644
--- a/ext/dtls/gstdtlsdec.h
+++ b/ext/dtls/gstdtlsdec.h
@@ -57,9 +57,9 @@
     GstDtlsConnection *connection;
     GMutex connection_mutex;
     gchar *connection_id;
-    gchar *pegst_pem;
+    gchar *peer_pem;
 
-    GstBuffer *decodgst_key;
+    GstBuffer *decoder_key;
     guint srtp_cipher;
     guint srtp_auth;
 };
diff --git a/ext/dtls/gstdtlsenc.c b/ext/dtls/gstdtlsenc.c
index ff4b4d2..477af10 100644
--- a/ext/dtls/gstdtlsenc.c
+++ b/ext/dtls/gstdtlsenc.c
@@ -182,12 +182,11 @@
 
   self->is_client = DEFAULT_IS_CLIENT;
 
-  self->encodgst_key = NULL;
+  self->encoder_key = NULL;
   self->srtp_cipher = DEFAULT_SRTP_CIPHER;
   self->srtp_auth = DEFAULT_SRTP_AUTH;
 
-  self->queue = g_ptr_array_sized_new (INITIAL_QUEUE_SIZE);
-
+  g_queue_init (&self->queue);
   g_mutex_init (&self->queue_lock);
   g_cond_init (&self->queue_cond_add);
 
@@ -205,17 +204,14 @@
 {
   GstDtlsEnc *self = GST_DTLS_ENC (object);
 
-  if (self->encodgst_key) {
-    gst_buffer_unref (self->encodgst_key);
-    self->encodgst_key = NULL;
+  if (self->encoder_key) {
+    gst_buffer_unref (self->encoder_key);
+    self->encoder_key = NULL;
   }
 
   g_mutex_lock (&self->queue_lock);
-
-  g_ptr_array_set_free_func (self->queue, (GDestroyNotify) gst_buffer_unref);
-  g_ptr_array_unref (self->queue);
-  self->queue = NULL;
-
+  g_queue_foreach (&self->queue, (GFunc) gst_buffer_unref, NULL);
+  g_queue_clear (&self->queue);
   g_mutex_unlock (&self->queue_lock);
 
   g_mutex_clear (&self->queue_lock);
@@ -258,7 +254,7 @@
       g_value_set_boolean (value, self->is_client);
       break;
     case PROP_ENCODER_KEY:
-      g_value_set_boxed (value, self->encodgst_key);
+      g_value_set_boxed (value, self->encoder_key);
       break;
     case PROP_SRTP_CIPHER:
       g_value_set_uint (value, self->srtp_cipher);
@@ -300,15 +296,8 @@
         return GST_STATE_CHANGE_FAILURE;
       }
       break;
-    case GST_STATE_CHANGE_READY_TO_PAUSED:
-      GST_DEBUG_OBJECT (self, "starting connection %s", self->connection_id);
-      gst_dtls_connection_start (self->connection, self->is_client);
-
-      gst_pad_set_active (self->src, TRUE);
-      break;
     case GST_STATE_CHANGE_PAUSED_TO_READY:
       GST_DEBUG_OBJECT (self, "stopping connection %s", self->connection_id);
-      gst_pad_set_active (self->src, FALSE);
 
       gst_dtls_connection_stop (self->connection);
       break;
@@ -328,6 +317,15 @@
 
   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
 
+  switch (transition) {
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+      GST_DEBUG_OBJECT (self, "starting connection %s", self->connection_id);
+      gst_dtls_connection_start (self->connection, self->is_client);
+      break;
+    default:
+      break;
+  }
+
   return ret;
 }
 
@@ -370,6 +368,7 @@
   if (active) {
     GST_DEBUG_OBJECT (self, "src pad activating in push mode");
 
+    self->flushing = FALSE;
     self->send_initial_events = TRUE;
     success =
         gst_pad_start_task (pad, (GstTaskFunction) src_task_loop, self->src,
@@ -381,7 +380,9 @@
     GST_DEBUG_OBJECT (self, "deactivating src pad");
 
     g_mutex_lock (&self->queue_lock);
-    GST_PAD_MODE (pad) = GST_PAD_MODE_NONE;
+    g_queue_foreach (&self->queue, (GFunc) gst_buffer_unref, NULL);
+    g_queue_clear (&self->queue);
+    self->flushing = TRUE;
     g_cond_signal (&self->queue_cond_add);
     g_mutex_unlock (&self->queue_lock);
     success = gst_pad_stop_task (pad);
@@ -398,26 +399,26 @@
 {
   GstDtlsEnc *self = GST_DTLS_ENC (GST_PAD_PARENT (pad));
   GstFlowReturn ret;
-  GstPad *peer;
-  gboolean pegst_is_active;
+  GstBuffer *buffer;
+  gboolean check_connection_timeout = FALSE;
 
   GST_TRACE_OBJECT (self, "src loop: acquiring lock");
   g_mutex_lock (&self->queue_lock);
   GST_TRACE_OBJECT (self, "src loop: acquired lock");
 
-  if (!gst_pad_is_active (pad)) {
+  if (self->flushing) {
     GST_LOG_OBJECT (self, "src task loop entered on inactive pad");
     GST_TRACE_OBJECT (self, "src loop: releasing lock");
     g_mutex_unlock (&self->queue_lock);
     return;
   }
 
-  while (!self->queue->len) {
+  while (g_queue_is_empty (&self->queue)) {
     GST_TRACE_OBJECT (self, "src loop: queue empty, waiting for add");
     g_cond_wait (&self->queue_cond_add, &self->queue_lock);
     GST_TRACE_OBJECT (self, "src loop: add signaled");
 
-    if (!gst_pad_is_active (pad)) {
+    if (self->flushing) {
       GST_LOG_OBJECT (self, "pad inactive, task returning");
       GST_TRACE_OBJECT (self, "src loop: releasing lock");
       g_mutex_unlock (&self->queue_lock);
@@ -426,47 +427,35 @@
   }
   GST_TRACE_OBJECT (self, "src loop: queue has element");
 
-  peer = gst_pad_get_peer (pad);
-  pegst_is_active = gst_pad_is_active (peer);
-  gst_object_unref (peer);
+  buffer = g_queue_pop_head (&self->queue);
+  g_mutex_unlock (&self->queue_lock);
 
-  if (pegst_is_active) {
-    GstBuffer *buffer;
-    gboolean start_connection_timeout = FALSE;
+  if (self->send_initial_events) {
+    GstSegment segment;
+    gchar s_id[32];
+    GstCaps *caps;
 
-    if (self->send_initial_events) {
-      GstSegment segment;
-      gchar s_id[32];
-      GstCaps *caps;
+    self->send_initial_events = FALSE;
 
-      g_snprintf (s_id, sizeof (s_id), "dtlsenc-%08x", g_random_int ());
-      gst_pad_push_event (self->src, gst_event_new_stream_start (s_id));
-      caps = gst_caps_new_empty_simple ("application/x-dtls");
-      gst_pad_push_event (self->src, gst_event_new_caps (caps));
-      gst_caps_unref (caps);
-      gst_segment_init (&segment, GST_FORMAT_BYTES);
-      gst_pad_push_event (self->src, gst_event_new_segment (&segment));
-      self->send_initial_events = FALSE;
-      start_connection_timeout = TRUE;
-    }
+    g_snprintf (s_id, sizeof (s_id), "dtlsenc-%08x", g_random_int ());
+    gst_pad_push_event (self->src, gst_event_new_stream_start (s_id));
+    caps = gst_caps_new_empty_simple ("application/x-dtls");
+    gst_pad_push_event (self->src, gst_event_new_caps (caps));
+    gst_caps_unref (caps);
+    gst_segment_init (&segment, GST_FORMAT_BYTES);
+    gst_pad_push_event (self->src, gst_event_new_segment (&segment));
+    check_connection_timeout = TRUE;
+  }
 
-    buffer = g_ptr_array_remove_index (self->queue, 0);
+  GST_TRACE_OBJECT (self, "src loop: releasing lock");
 
-    GST_TRACE_OBJECT (self, "src loop: releasing lock");
-    g_mutex_unlock (&self->queue_lock);
+  ret = gst_pad_push (self->src, buffer);
+  if (check_connection_timeout)
+    gst_dtls_connection_check_timeout (self->connection);
 
-    ret = gst_pad_push (self->src, buffer);
-    if (start_connection_timeout)
-      gst_dtls_connection_start_timeout (self->connection);
-
-    if (G_UNLIKELY (ret != GST_FLOW_OK)) {
-      GST_WARNING_OBJECT (self, "failed to push buffer on src pad: %s",
-          gst_flow_get_name (ret));
-    }
-  } else {
-    g_warn_if_reached ();
-    GST_TRACE_OBJECT (self, "src loop: releasing lock");
-    g_mutex_unlock (&self->queue_lock);
+  if (G_UNLIKELY (ret != GST_FLOW_OK)) {
+    GST_WARNING_OBJECT (self, "failed to push buffer on src pad: %s",
+        gst_flow_get_name (ret));
   }
 }
 
@@ -511,7 +500,7 @@
   self->srtp_auth = auth;
 
   key_dup = g_memdup (key, GST_DTLS_SRTP_MASTER_KEY_LENGTH);
-  self->encodgst_key =
+  self->encoder_key =
       gst_buffer_new_wrapped (key_dup, GST_DTLS_SRTP_MASTER_KEY_LENGTH);
 
   key_str = g_base64_encode (key, GST_DTLS_SRTP_MASTER_KEY_LENGTH);
@@ -536,7 +525,7 @@
   g_mutex_lock (&self->queue_lock);
   GST_TRACE_OBJECT (self, "send data: acquired lock");
 
-  g_ptr_array_add (self->queue, buffer);
+  g_queue_push_tail (&self->queue, buffer);
 
   GST_TRACE_OBJECT (self, "send data: signaling add");
   g_cond_signal (&self->queue_cond_add);
diff --git a/ext/dtls/gstdtlsenc.h b/ext/dtls/gstdtlsenc.h
index 6dc6bbd..622936f 100644
--- a/ext/dtls/gstdtlsenc.h
+++ b/ext/dtls/gstdtlsenc.h
@@ -47,16 +47,17 @@
 
     GstPad *src;
 
-    GPtrArray *queue;
+    GQueue queue;
     GMutex queue_lock;
     GCond queue_cond_add;
+    gboolean flushing;
 
     GstDtlsConnection *connection;
     gchar *connection_id;
 
     gboolean is_client;
 
-    GstBuffer *encodgst_key;
+    GstBuffer *encoder_key;
     guint srtp_cipher;
     guint srtp_auth;
 
diff --git a/ext/dtls/gstdtlssrtpdec.c b/ext/dtls/gstdtlssrtpdec.c
index 347fefd..d80328d 100644
--- a/ext/dtls/gstdtlssrtpdec.c
+++ b/ext/dtls/gstdtlssrtpdec.c
@@ -37,10 +37,17 @@
     GST_STATIC_CAPS_ANY);
 
 static GstStaticPadTemplate rtp_src_template =
-    GST_STATIC_PAD_TEMPLATE ("rtp_src",
+GST_STATIC_PAD_TEMPLATE ("rtp_src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("application/x-rtp;application/x-rtcp")
+    GST_STATIC_CAPS ("application/x-rtp")
+    );
+
+static GstStaticPadTemplate rtcp_src_template =
+GST_STATIC_PAD_TEMPLATE ("rtcp_src",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("application/x-rtcp")
     );
 
 static GstStaticPadTemplate data_src_template =
@@ -77,18 +84,15 @@
 
 static GstPad *gst_dtls_srtp_dec_request_new_pad (GstElement *,
     GstPadTemplate *, const gchar * name, const GstCaps *);
-static GstCaps *on_decodgst_request_key (GstElement * srtp_decoder, guint ssrc,
+static GstCaps *on_decoder_request_key (GstElement * srtp_decoder, guint ssrc,
     GstDtlsSrtpBin *);
-static void on_pegst_pem (GstElement * srtp_decoder, GParamSpec * pspec,
+static void on_peer_pem (GstElement * srtp_decoder, GParamSpec * pspec,
     GstDtlsSrtpDec * self);
 
 static void gst_dtls_srtp_dec_remove_dtls_element (GstDtlsSrtpBin *);
-static GstPadProbeReturn remove_dtls_decodgst_probe_callback (GstPad *,
+static GstPadProbeReturn remove_dtls_decoder_probe_callback (GstPad *,
     GstPadProbeInfo *, GstElement *);
 
-static GstPadProbeReturn drop_funnel_rtcp_caps (GstPad *, GstPadProbeInfo *,
-    gpointer);
-
 static void
 gst_dtls_srtp_dec_class_init (GstDtlsSrtpDecClass * klass)
 {
@@ -130,6 +134,8 @@
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&rtp_src_template));
   gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&rtcp_src_template));
+  gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&data_src_template));
 
   gst_element_class_set_static_metadata (element_class,
@@ -144,19 +150,19 @@
 {
   GstElementClass *klass = GST_ELEMENT_GET_CLASS (GST_ELEMENT (self));
   GstPadTemplate *templ;
-  GstPad *target_pad, *ghost_pad, *pad;
+  GstPad *target_pad, *ghost_pad;
   gboolean ret;
 
 /*
-                                 +--------------------+
-            +--------------+  .-o|       dtlsdec      |o-R----------data
-            |          dtls|o-'  +--------------------+
+                                 +-----------+
+            +--------------+  .-o|  dtlsdec  |o-R----data
+            |          dtls|o-'  +-----------+
     sink---o|  dtlsdemux   |
-            |       srt(c)p|o-.  +-----------+     +-----------+
-            +--------------+  '-o|srtp    rtp|o---o|rtp        |
-                                 |  srtpdec  |     |   funnel  |o---rt(c)p
-                                o|srtcp  rtcp|o---o|rtcp       |
-                                 +-----------+     +-----------+
+            |       srt(c)p|o-.  +-----------+
+            +--------------+  '-o|srtp    rtp|o------rtp
+                                 |  srtpdec  |
+                                o|srtcp  rtcp|o------rtcp
+                                 +-----------+
 */
 
   self->srtp_dec = gst_element_factory_make ("srtpdec", "srtp-decoder");
@@ -176,15 +182,9 @@
     GST_ERROR_OBJECT (self, "failed to create dtls_dec");
     return;
   }
-  self->funnel = gst_element_factory_make ("funnel", "funnel");
-  if (!self->funnel) {
-    GST_ERROR_OBJECT (self, "failed to create funnel");
-    return;
-  }
 
   gst_bin_add_many (GST_BIN (self),
-      self->dtls_srtp_demux,
-      self->bin.dtls_element, self->srtp_dec, self->funnel, NULL);
+      self->dtls_srtp_demux, self->bin.dtls_element, self->srtp_dec, NULL);
 
   ret =
       gst_element_link_pads (self->dtls_srtp_demux, "dtls_src",
@@ -194,21 +194,9 @@
       gst_element_link_pads (self->dtls_srtp_demux, "rtp_src", self->srtp_dec,
       "rtp_sink");
   g_return_if_fail (ret);
-  ret =
-      gst_element_link_pads (self->srtp_dec, "rtp_src", self->funnel, "sink_0");
-  g_return_if_fail (ret);
-  ret =
-      gst_element_link_pads (self->srtp_dec, "rtcp_src", self->funnel,
-      "sink_1");
-  g_return_if_fail (ret);
-
-  pad = gst_element_get_static_pad (self->funnel, "sink_1");
-  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
-      drop_funnel_rtcp_caps, NULL, NULL);
-  gst_object_unref (pad);
 
   templ = gst_element_class_get_pad_template (klass, "rtp_src");
-  target_pad = gst_element_get_static_pad (self->funnel, "src");
+  target_pad = gst_element_get_static_pad (self->srtp_dec, "rtp_src");
   ghost_pad = gst_ghost_pad_new_from_template ("rtp_src", target_pad, templ);
   gst_object_unref (target_pad);
   g_return_if_fail (ghost_pad);
@@ -216,6 +204,15 @@
   ret = gst_element_add_pad (GST_ELEMENT (self), ghost_pad);
   g_return_if_fail (ret);
 
+  templ = gst_element_class_get_pad_template (klass, "rtcp_src");
+  target_pad = gst_element_get_static_pad (self->srtp_dec, "rtcp_src");
+  ghost_pad = gst_ghost_pad_new_from_template ("rtcp_src", target_pad, templ);
+  gst_object_unref (target_pad);
+  g_return_if_fail (ghost_pad);
+
+  ret = gst_element_add_pad (GST_ELEMENT (self), ghost_pad);
+  g_return_if_fail (ret);
+
   templ = gst_element_class_get_pad_template (klass, "sink");
   target_pad = gst_element_get_static_pad (self->dtls_srtp_demux, "sink");
   ghost_pad = gst_ghost_pad_new_from_template ("sink", target_pad, templ);
@@ -226,9 +223,9 @@
   g_return_if_fail (ret);
 
   g_signal_connect (self->srtp_dec, "request-key",
-      G_CALLBACK (on_decodgst_request_key), self);
+      G_CALLBACK (on_decoder_request_key), self);
   g_signal_connect (self->bin.dtls_element, "notify::peer-pem",
-      G_CALLBACK (on_pegst_pem), self);
+      G_CALLBACK (on_peer_pem), self);
 }
 
 static void
@@ -318,7 +315,7 @@
 }
 
 static GstCaps *
-on_decodgst_request_key (GstElement * srtp_decoder,
+on_decoder_request_key (GstElement * srtp_decoder,
     guint ssrc, GstDtlsSrtpBin * bin)
 {
   GstCaps *key_caps;
@@ -385,13 +382,15 @@
     }
 
     return key_caps;
+  } else {
+    GST_WARNING_OBJECT (bin, "no srtp key available yet");
   }
 
   return NULL;
 }
 
 static void
-on_pegst_pem (GstElement * srtp_decoder, GParamSpec * pspec,
+on_peer_pem (GstElement * srtp_decoder, GParamSpec * pspec,
     GstDtlsSrtpDec * self)
 {
   g_return_if_fail (self);
@@ -412,7 +411,7 @@
   demux_pad = gst_element_get_static_pad (self->dtls_srtp_demux, "dtls_src");
 
   id = gst_pad_add_probe (demux_pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
-      (GstPadProbeCallback) remove_dtls_decodgst_probe_callback,
+      (GstPadProbeCallback) remove_dtls_decoder_probe_callback,
       bin->dtls_element, NULL);
   g_return_if_fail (id);
   bin->dtls_element = NULL;
@@ -425,7 +424,7 @@
 }
 
 static GstPadProbeReturn
-remove_dtls_decodgst_probe_callback (GstPad * pad,
+remove_dtls_decoder_probe_callback (GstPad * pad,
     GstPadProbeInfo * info, GstElement * element)
 {
   gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info));
@@ -435,40 +434,3 @@
 
   return GST_PAD_PROBE_OK;
 }
-
-static GstPadProbeReturn
-drop_funnel_rtcp_caps (GstPad * pad, GstPadProbeInfo * info, gpointer data)
-{
-  /* FIXME: This is needed for setting the proper caps until
-   * GStreamer supports MIXED caps or another mechanism to
-   * prevent renegotiation all the time when two different caps
-   * are going over the same pad
-   */
-  if (GST_EVENT_TYPE (info->data) == GST_EVENT_CAPS) {
-    GstCaps *caps, *peercaps;
-    GstStructure *s;
-
-    gst_event_parse_caps (GST_EVENT (info->data), &caps);
-    s = gst_caps_get_structure (caps, 0);
-    if (gst_structure_has_name (s, "application/x-rtcp")) {
-      peercaps = gst_pad_query_caps (pad, NULL);
-
-      /* If the peer does not accept RTCP, we are linked to
-       * the RTP sinkpad of rtpbin. In that case we have to
-       * drop the RTCP caps and assume that we sent RTP caps
-       * before here, which is very likely but not guaranteed
-       * if for some reason we receive RTCP before any RTP.
-       * In that unlikely case we will get event misordering
-       * warnings later, instead of getting them always as
-       * happens now.
-       */
-      if (peercaps && !gst_caps_is_subset (caps, peercaps)) {
-        gst_caps_unref (peercaps);
-        return GST_PAD_PROBE_DROP;
-      }
-      gst_caps_replace (&peercaps, NULL);
-    }
-  }
-
-  return GST_PAD_PROBE_OK;
-}
diff --git a/ext/dtls/gstdtlssrtpdec.h b/ext/dtls/gstdtlssrtpdec.h
index d32a44b..3d64c15 100644
--- a/ext/dtls/gstdtlssrtpdec.h
+++ b/ext/dtls/gstdtlssrtpdec.h
@@ -46,7 +46,6 @@
 
     GstElement *dtls_srtp_demux;
     GstElement *srtp_dec;
-    GstElement *funnel;
 };
 
 struct _GstDtlsSrtpDecClass {
diff --git a/ext/dtls/gstdtlssrtpenc.c b/ext/dtls/gstdtlssrtpenc.c
index 35bf707..d7055b8 100644
--- a/ext/dtls/gstdtlssrtpenc.c
+++ b/ext/dtls/gstdtlssrtpenc.c
@@ -99,7 +99,7 @@
 static void on_key_received (GObject * encoder, GstDtlsSrtpEnc *);
 
 static void gst_dtls_srtp_enc_remove_dtls_element (GstDtlsSrtpBin *);
-static GstPadProbeReturn remove_dtls_encodgst_probe_callback (GstPad *,
+static GstPadProbeReturn remove_dtls_encoder_probe_callback (GstPad *,
     GstPadProbeInfo *, GstElement *);
 
 static void
@@ -410,7 +410,7 @@
 gst_dtls_srtp_enc_remove_dtls_element (GstDtlsSrtpBin * bin)
 {
   GstDtlsSrtpEnc *self = GST_DTLS_SRTP_ENC (bin);
-  GstPad *dtls_sink_pad, *pegst_pad;
+  GstPad *dtls_sink_pad, *peer_pad;
   gulong id;
   guint rtp_cipher = 1, rtcp_cipher = 1, rtp_auth = 1, rtcp_auth = 1;
 
@@ -436,26 +436,26 @@
     return;
   }
 
-  pegst_pad = gst_pad_get_peer (dtls_sink_pad);
-  g_return_if_fail (pegst_pad);
+  peer_pad = gst_pad_get_peer (dtls_sink_pad);
+  g_return_if_fail (peer_pad);
   gst_object_unref (dtls_sink_pad);
   dtls_sink_pad = NULL;
 
-  id = gst_pad_add_probe (pegst_pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
-      (GstPadProbeCallback) remove_dtls_encodgst_probe_callback,
+  id = gst_pad_add_probe (peer_pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
+      (GstPadProbeCallback) remove_dtls_encoder_probe_callback,
       bin->dtls_element, NULL);
   g_return_if_fail (id);
   bin->dtls_element = NULL;
 
-  gst_pad_push_event (pegst_pad,
+  gst_pad_push_event (peer_pad,
       gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
           gst_structure_new_empty ("dummy")));
 
-  gst_object_unref (pegst_pad);
+  gst_object_unref (peer_pad);
 }
 
 static GstPadProbeReturn
-remove_dtls_encodgst_probe_callback (GstPad * pad,
+remove_dtls_encoder_probe_callback (GstPad * pad,
     GstPadProbeInfo * info, GstElement * element)
 {
   gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info));
diff --git a/ext/dtls/gstdtlssrtpenc.h b/ext/dtls/gstdtlssrtpenc.h
index 5cc07ee..5dd603d 100644
--- a/ext/dtls/gstdtlssrtpenc.h
+++ b/ext/dtls/gstdtlssrtpenc.h
@@ -56,7 +56,7 @@
 
 gboolean gst_dtls_srtp_enc_plugin_init(GstPlugin *);
 
-guint gst_dtls_srtp_enc_get_ciphgst_value_by_nick(const gchar *ciphgst_nick);
+guint gst_dtls_srtp_enc_get_cipher_value_by_nick(const gchar *cipher_nick);
 guint gst_dtls_srtp_enc_get_auth_value_by_nick(const gchar *auth_nick);
 
 G_END_DECLS
diff --git a/ext/faac/Makefile.am b/ext/faac/Makefile.am
index 8727a21..007c66d 100644
--- a/ext/faac/Makefile.am
+++ b/ext/faac/Makefile.am
@@ -11,18 +11,3 @@
 libgstfaac_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstfaac.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstfaac -:SHARED libgstfaac \
-	 -:TAGS eng debug \
-	 -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstfaac_la_SOURCES) \
-	 -:CPPFLAGS $(CPPFLAGS) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstfaac_la_CFLAGS) \
-	 -:LDFLAGS $(libgstfaac_la_LDFLAGS) \
-	           $(libgstfaac_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/ext/faac/Makefile.in b/ext/faac/Makefile.in
index db62636..6e58f22 100644
--- a/ext/faac/Makefile.in
+++ b/ext/faac/Makefile.in
@@ -1073,21 +1073,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstfaac -:SHARED libgstfaac \
-	 -:TAGS eng debug \
-	 -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstfaac_la_SOURCES) \
-	 -:CPPFLAGS $(CPPFLAGS) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstfaac_la_CFLAGS) \
-	 -:LDFLAGS $(libgstfaac_la_LDFLAGS) \
-	           $(libgstfaac_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/ext/faad/Makefile.am b/ext/faad/Makefile.am
index cf405f4..2aef183 100644
--- a/ext/faad/Makefile.am
+++ b/ext/faad/Makefile.am
@@ -10,18 +10,3 @@
 libgstfaad_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstfaad.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstfaad -:SHARED libgstfaad \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstfaad_la_SOURCES) \
-	 -:CPPFLAGS $(CPPFLAGS) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstfaad_la_CFLAGS) \
-	 -:LDFLAGS $(libgstfaad_la_LDFLAGS) \
-	           $(libgstfaad_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/ext/faad/Makefile.in b/ext/faad/Makefile.in
index 59bd578..a3eb642 100644
--- a/ext/faad/Makefile.in
+++ b/ext/faad/Makefile.in
@@ -1073,21 +1073,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstfaad -:SHARED libgstfaad \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstfaad_la_SOURCES) \
-	 -:CPPFLAGS $(CPPFLAGS) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstfaad_la_CFLAGS) \
-	 -:LDFLAGS $(libgstfaad_la_LDFLAGS) \
-	           $(libgstfaad_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/ext/gl/Makefile.am b/ext/gl/Makefile.am
index 7dc1041..5d02afc 100644
--- a/ext/gl/Makefile.am
+++ b/ext/gl/Makefile.am
@@ -17,6 +17,20 @@
 	effects/gstgleffectidentity.c \
 	effects/gstgleffectmirror.c \
 	effects/gstgleffectsqueeze.c \
+	effects/gstgleffectstretch.c \
+	effects/gstgleffectfisheye.c \
+	effects/gstgleffecttwirl.c \
+	effects/gstgleffectbulge.c \
+	effects/gstgleffecttunnel.c \
+	effects/gstgleffectsquare.c \
+	effects/gstgleffectlumatocurve.c \
+	effects/gstgleffectrgbtocurve.c \
+	effects/gstgleffectsin.c \
+	effects/gstgleffectxray.c \
+	effects/gstgleffectglow.c \
+	effects/gstgleffectblur.c \
+	effects/gstgleffectsobel.c \
+	effects/gstgleffectlaplacian.c \
 	gstglcolorscale.c \
 	gstglmixer.c \
 	gstglvideomixer.c \
@@ -45,30 +59,13 @@
 # full opengl required
 if USE_OPENGL
 libgstopengl_la_SOURCES += \
-	gstglfilterblur.c \
-	gstglfiltersobel.c \
-	gstglfilterlaplacian.c \
 	gstglfilterglass.c \
 	gstgldeinterlace.c \
 	gltestsrc.c \
 	gstgltestsrc.c \
-	gstglmosaic.c \
-	effects/gstgleffectstretch.c \
-	effects/gstgleffecttunnel.c \
-	effects/gstgleffectfisheye.c \
-	effects/gstgleffecttwirl.c \
-	effects/gstgleffectbulge.c \
-	effects/gstgleffectsquare.c \
-	effects/gstgleffectlumatocurve.c \
-	effects/gstgleffectrgbtocurve.c \
-	effects/gstgleffectsin.c \
-	effects/gstgleffectglow.c \
-	effects/gstgleffectxray.c
+	gstglmosaic.c
 
 noinst_HEADERS += \
-	gstglfilterblur.h \
-	gstglfiltersobel.h \
-	gstglfilterlaplacian.h \
 	gstglfilterglass.h \
 	gstgldeinterlace.h \
 	gltestsrc.h \
diff --git a/ext/gl/Makefile.in b/ext/gl/Makefile.in
index 9d79a39..83de156 100644
--- a/ext/gl/Makefile.in
+++ b/ext/gl/Makefile.in
@@ -83,30 +83,13 @@
 
 # full opengl required
 @USE_OPENGL_TRUE@am__append_1 = \
-@USE_OPENGL_TRUE@	gstglfilterblur.c \
-@USE_OPENGL_TRUE@	gstglfiltersobel.c \
-@USE_OPENGL_TRUE@	gstglfilterlaplacian.c \
 @USE_OPENGL_TRUE@	gstglfilterglass.c \
 @USE_OPENGL_TRUE@	gstgldeinterlace.c \
 @USE_OPENGL_TRUE@	gltestsrc.c \
 @USE_OPENGL_TRUE@	gstgltestsrc.c \
-@USE_OPENGL_TRUE@	gstglmosaic.c \
-@USE_OPENGL_TRUE@	effects/gstgleffectstretch.c \
-@USE_OPENGL_TRUE@	effects/gstgleffecttunnel.c \
-@USE_OPENGL_TRUE@	effects/gstgleffectfisheye.c \
-@USE_OPENGL_TRUE@	effects/gstgleffecttwirl.c \
-@USE_OPENGL_TRUE@	effects/gstgleffectbulge.c \
-@USE_OPENGL_TRUE@	effects/gstgleffectsquare.c \
-@USE_OPENGL_TRUE@	effects/gstgleffectlumatocurve.c \
-@USE_OPENGL_TRUE@	effects/gstgleffectrgbtocurve.c \
-@USE_OPENGL_TRUE@	effects/gstgleffectsin.c \
-@USE_OPENGL_TRUE@	effects/gstgleffectglow.c \
-@USE_OPENGL_TRUE@	effects/gstgleffectxray.c
+@USE_OPENGL_TRUE@	gstglmosaic.c
 
 @USE_OPENGL_TRUE@am__append_2 = \
-@USE_OPENGL_TRUE@	gstglfilterblur.h \
-@USE_OPENGL_TRUE@	gstglfiltersobel.h \
-@USE_OPENGL_TRUE@	gstglfilterlaplacian.h \
 @USE_OPENGL_TRUE@	gstglfilterglass.h \
 @USE_OPENGL_TRUE@	gstgldeinterlace.h \
 @USE_OPENGL_TRUE@	gltestsrc.h \
@@ -224,38 +207,25 @@
 	gstglsinkbin.c gstglsrcbin.c gstglimagesink.c \
 	gstglfiltercube.c gstgleffects.c effects/gstgleffectssources.c \
 	effects/gstgleffectidentity.c effects/gstgleffectmirror.c \
-	effects/gstgleffectsqueeze.c gstglcolorscale.c gstglmixer.c \
-	gstglvideomixer.c gstglfiltershader.c gstglfilterapp.c \
-	gstglfilterblur.c gstglfiltersobel.c gstglfilterlaplacian.c \
-	gstglfilterglass.c gstgldeinterlace.c gltestsrc.c \
-	gstgltestsrc.c gstglmosaic.c effects/gstgleffectstretch.c \
-	effects/gstgleffecttunnel.c effects/gstgleffectfisheye.c \
-	effects/gstgleffecttwirl.c effects/gstgleffectbulge.c \
+	effects/gstgleffectsqueeze.c effects/gstgleffectstretch.c \
+	effects/gstgleffectfisheye.c effects/gstgleffecttwirl.c \
+	effects/gstgleffectbulge.c effects/gstgleffecttunnel.c \
 	effects/gstgleffectsquare.c effects/gstgleffectlumatocurve.c \
 	effects/gstgleffectrgbtocurve.c effects/gstgleffectsin.c \
-	effects/gstgleffectglow.c effects/gstgleffectxray.c \
-	gstgldifferencematte.c gstgltransformation.c \
-	gstgltransformation.h gstgloverlay.c caopengllayersink.m
+	effects/gstgleffectxray.c effects/gstgleffectglow.c \
+	effects/gstgleffectblur.c effects/gstgleffectsobel.c \
+	effects/gstgleffectlaplacian.c gstglcolorscale.c gstglmixer.c \
+	gstglvideomixer.c gstglfiltershader.c gstglfilterapp.c \
+	gstglfilterglass.c gstgldeinterlace.c gltestsrc.c \
+	gstgltestsrc.c gstglmosaic.c gstgldifferencematte.c \
+	gstgltransformation.c gstgltransformation.h gstgloverlay.c \
+	caopengllayersink.m
 am__dirstamp = $(am__leading_dot)dirstamp
-@USE_OPENGL_TRUE@am__objects_1 = libgstopengl_la-gstglfilterblur.lo \
-@USE_OPENGL_TRUE@	libgstopengl_la-gstglfiltersobel.lo \
-@USE_OPENGL_TRUE@	libgstopengl_la-gstglfilterlaplacian.lo \
-@USE_OPENGL_TRUE@	libgstopengl_la-gstglfilterglass.lo \
+@USE_OPENGL_TRUE@am__objects_1 = libgstopengl_la-gstglfilterglass.lo \
 @USE_OPENGL_TRUE@	libgstopengl_la-gstgldeinterlace.lo \
 @USE_OPENGL_TRUE@	libgstopengl_la-gltestsrc.lo \
 @USE_OPENGL_TRUE@	libgstopengl_la-gstgltestsrc.lo \
-@USE_OPENGL_TRUE@	libgstopengl_la-gstglmosaic.lo \
-@USE_OPENGL_TRUE@	effects/libgstopengl_la-gstgleffectstretch.lo \
-@USE_OPENGL_TRUE@	effects/libgstopengl_la-gstgleffecttunnel.lo \
-@USE_OPENGL_TRUE@	effects/libgstopengl_la-gstgleffectfisheye.lo \
-@USE_OPENGL_TRUE@	effects/libgstopengl_la-gstgleffecttwirl.lo \
-@USE_OPENGL_TRUE@	effects/libgstopengl_la-gstgleffectbulge.lo \
-@USE_OPENGL_TRUE@	effects/libgstopengl_la-gstgleffectsquare.lo \
-@USE_OPENGL_TRUE@	effects/libgstopengl_la-gstgleffectlumatocurve.lo \
-@USE_OPENGL_TRUE@	effects/libgstopengl_la-gstgleffectrgbtocurve.lo \
-@USE_OPENGL_TRUE@	effects/libgstopengl_la-gstgleffectsin.lo \
-@USE_OPENGL_TRUE@	effects/libgstopengl_la-gstgleffectglow.lo \
-@USE_OPENGL_TRUE@	effects/libgstopengl_la-gstgleffectxray.lo
+@USE_OPENGL_TRUE@	libgstopengl_la-gstglmosaic.lo
 @HAVE_PNG_TRUE@@USE_OPENGL_TRUE@am__objects_2 = libgstopengl_la-gstgldifferencematte.lo
 @HAVE_GRAPHENE_TRUE@am__objects_3 =  \
 @HAVE_GRAPHENE_TRUE@	libgstopengl_la-gstgltransformation.lo
@@ -277,6 +247,20 @@
 	effects/libgstopengl_la-gstgleffectidentity.lo \
 	effects/libgstopengl_la-gstgleffectmirror.lo \
 	effects/libgstopengl_la-gstgleffectsqueeze.lo \
+	effects/libgstopengl_la-gstgleffectstretch.lo \
+	effects/libgstopengl_la-gstgleffectfisheye.lo \
+	effects/libgstopengl_la-gstgleffecttwirl.lo \
+	effects/libgstopengl_la-gstgleffectbulge.lo \
+	effects/libgstopengl_la-gstgleffecttunnel.lo \
+	effects/libgstopengl_la-gstgleffectsquare.lo \
+	effects/libgstopengl_la-gstgleffectlumatocurve.lo \
+	effects/libgstopengl_la-gstgleffectrgbtocurve.lo \
+	effects/libgstopengl_la-gstgleffectsin.lo \
+	effects/libgstopengl_la-gstgleffectxray.lo \
+	effects/libgstopengl_la-gstgleffectglow.lo \
+	effects/libgstopengl_la-gstgleffectblur.lo \
+	effects/libgstopengl_la-gstgleffectsobel.lo \
+	effects/libgstopengl_la-gstgleffectlaplacian.lo \
 	libgstopengl_la-gstglcolorscale.lo \
 	libgstopengl_la-gstglmixer.lo \
 	libgstopengl_la-gstglvideomixer.lo \
@@ -358,7 +342,6 @@
 	gstglimagesink.h gstglfiltercube.h gstgleffects.h \
 	effects/gstgleffectssources.h gstglcolorscale.h gstglmixer.h \
 	gstglvideomixer.h gstglfiltershader.h gstglfilterapp.h \
-	gstglfilterblur.h gstglfiltersobel.h gstglfilterlaplacian.h \
 	gstglfilterglass.h gstgldeinterlace.h gltestsrc.h \
 	gstgltestsrc.h gstglmosaic.h effects/gstgleffectscurves.h \
 	effects/gstgleffectlumatocurve.h gstgldifferencematte.h \
@@ -897,7 +880,14 @@
 	gstglsinkbin.c gstglsrcbin.c gstglimagesink.c \
 	gstglfiltercube.c gstgleffects.c effects/gstgleffectssources.c \
 	effects/gstgleffectidentity.c effects/gstgleffectmirror.c \
-	effects/gstgleffectsqueeze.c gstglcolorscale.c gstglmixer.c \
+	effects/gstgleffectsqueeze.c effects/gstgleffectstretch.c \
+	effects/gstgleffectfisheye.c effects/gstgleffecttwirl.c \
+	effects/gstgleffectbulge.c effects/gstgleffecttunnel.c \
+	effects/gstgleffectsquare.c effects/gstgleffectlumatocurve.c \
+	effects/gstgleffectrgbtocurve.c effects/gstgleffectsin.c \
+	effects/gstgleffectxray.c effects/gstgleffectglow.c \
+	effects/gstgleffectblur.c effects/gstgleffectsobel.c \
+	effects/gstgleffectlaplacian.c gstglcolorscale.c gstglmixer.c \
 	gstglvideomixer.c gstglfiltershader.c gstglfilterapp.c \
 	$(am__append_1) $(am__append_3) $(am__append_5) \
 	$(am__append_6) $(am__append_8)
@@ -1030,14 +1020,14 @@
 	effects/$(am__dirstamp) effects/$(DEPDIR)/$(am__dirstamp)
 effects/libgstopengl_la-gstgleffectstretch.lo:  \
 	effects/$(am__dirstamp) effects/$(DEPDIR)/$(am__dirstamp)
-effects/libgstopengl_la-gstgleffecttunnel.lo: effects/$(am__dirstamp) \
-	effects/$(DEPDIR)/$(am__dirstamp)
 effects/libgstopengl_la-gstgleffectfisheye.lo:  \
 	effects/$(am__dirstamp) effects/$(DEPDIR)/$(am__dirstamp)
 effects/libgstopengl_la-gstgleffecttwirl.lo: effects/$(am__dirstamp) \
 	effects/$(DEPDIR)/$(am__dirstamp)
 effects/libgstopengl_la-gstgleffectbulge.lo: effects/$(am__dirstamp) \
 	effects/$(DEPDIR)/$(am__dirstamp)
+effects/libgstopengl_la-gstgleffecttunnel.lo: effects/$(am__dirstamp) \
+	effects/$(DEPDIR)/$(am__dirstamp)
 effects/libgstopengl_la-gstgleffectsquare.lo: effects/$(am__dirstamp) \
 	effects/$(DEPDIR)/$(am__dirstamp)
 effects/libgstopengl_la-gstgleffectlumatocurve.lo:  \
@@ -1046,10 +1036,16 @@
 	effects/$(am__dirstamp) effects/$(DEPDIR)/$(am__dirstamp)
 effects/libgstopengl_la-gstgleffectsin.lo: effects/$(am__dirstamp) \
 	effects/$(DEPDIR)/$(am__dirstamp)
-effects/libgstopengl_la-gstgleffectglow.lo: effects/$(am__dirstamp) \
-	effects/$(DEPDIR)/$(am__dirstamp)
 effects/libgstopengl_la-gstgleffectxray.lo: effects/$(am__dirstamp) \
 	effects/$(DEPDIR)/$(am__dirstamp)
+effects/libgstopengl_la-gstgleffectglow.lo: effects/$(am__dirstamp) \
+	effects/$(DEPDIR)/$(am__dirstamp)
+effects/libgstopengl_la-gstgleffectblur.lo: effects/$(am__dirstamp) \
+	effects/$(DEPDIR)/$(am__dirstamp)
+effects/libgstopengl_la-gstgleffectsobel.lo: effects/$(am__dirstamp) \
+	effects/$(DEPDIR)/$(am__dirstamp)
+effects/libgstopengl_la-gstgleffectlaplacian.lo:  \
+	effects/$(am__dirstamp) effects/$(DEPDIR)/$(am__dirstamp)
 
 libgstopengl.la: $(libgstopengl_la_OBJECTS) $(libgstopengl_la_DEPENDENCIES) $(EXTRA_libgstopengl_la_DEPENDENCIES) 
 	$(AM_V_OBJCLD)$(libgstopengl_la_LINK) -rpath $(plugindir) $(libgstopengl_la_OBJECTS) $(libgstopengl_la_LIBADD) $(LIBS)
@@ -1073,12 +1069,9 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstopengl_la-gstgleffects.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstopengl_la-gstglfilterapp.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstopengl_la-gstglfilterbin.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstopengl_la-gstglfilterblur.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstopengl_la-gstglfiltercube.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstopengl_la-gstglfilterglass.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstopengl_la-gstglfilterlaplacian.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstopengl_la-gstglfiltershader.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstopengl_la-gstglfiltersobel.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstopengl_la-gstglimagesink.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstopengl_la-gstglmixer.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstopengl_la-gstglmixerbin.Plo@am__quote@
@@ -1091,14 +1084,17 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstopengl_la-gstgluploadelement.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstopengl_la-gstglvideomixer.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstopengl_la-gstopengl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/libgstopengl_la-gstgleffectblur.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/libgstopengl_la-gstgleffectbulge.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/libgstopengl_la-gstgleffectfisheye.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/libgstopengl_la-gstgleffectglow.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/libgstopengl_la-gstgleffectidentity.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/libgstopengl_la-gstgleffectlaplacian.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/libgstopengl_la-gstgleffectlumatocurve.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/libgstopengl_la-gstgleffectmirror.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/libgstopengl_la-gstgleffectrgbtocurve.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/libgstopengl_la-gstgleffectsin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/libgstopengl_la-gstgleffectsobel.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/libgstopengl_la-gstgleffectsquare.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/libgstopengl_la-gstgleffectsqueeze.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/libgstopengl_la-gstgleffectssources.Plo@am__quote@
@@ -1243,6 +1239,104 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectsqueeze.lo `test -f 'effects/gstgleffectsqueeze.c' || echo '$(srcdir)/'`effects/gstgleffectsqueeze.c
 
+effects/libgstopengl_la-gstgleffectstretch.lo: effects/gstgleffectstretch.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectstretch.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectstretch.Tpo -c -o effects/libgstopengl_la-gstgleffectstretch.lo `test -f 'effects/gstgleffectstretch.c' || echo '$(srcdir)/'`effects/gstgleffectstretch.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectstretch.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectstretch.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectstretch.c' object='effects/libgstopengl_la-gstgleffectstretch.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectstretch.lo `test -f 'effects/gstgleffectstretch.c' || echo '$(srcdir)/'`effects/gstgleffectstretch.c
+
+effects/libgstopengl_la-gstgleffectfisheye.lo: effects/gstgleffectfisheye.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectfisheye.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectfisheye.Tpo -c -o effects/libgstopengl_la-gstgleffectfisheye.lo `test -f 'effects/gstgleffectfisheye.c' || echo '$(srcdir)/'`effects/gstgleffectfisheye.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectfisheye.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectfisheye.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectfisheye.c' object='effects/libgstopengl_la-gstgleffectfisheye.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectfisheye.lo `test -f 'effects/gstgleffectfisheye.c' || echo '$(srcdir)/'`effects/gstgleffectfisheye.c
+
+effects/libgstopengl_la-gstgleffecttwirl.lo: effects/gstgleffecttwirl.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffecttwirl.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffecttwirl.Tpo -c -o effects/libgstopengl_la-gstgleffecttwirl.lo `test -f 'effects/gstgleffecttwirl.c' || echo '$(srcdir)/'`effects/gstgleffecttwirl.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffecttwirl.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffecttwirl.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffecttwirl.c' object='effects/libgstopengl_la-gstgleffecttwirl.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffecttwirl.lo `test -f 'effects/gstgleffecttwirl.c' || echo '$(srcdir)/'`effects/gstgleffecttwirl.c
+
+effects/libgstopengl_la-gstgleffectbulge.lo: effects/gstgleffectbulge.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectbulge.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectbulge.Tpo -c -o effects/libgstopengl_la-gstgleffectbulge.lo `test -f 'effects/gstgleffectbulge.c' || echo '$(srcdir)/'`effects/gstgleffectbulge.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectbulge.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectbulge.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectbulge.c' object='effects/libgstopengl_la-gstgleffectbulge.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectbulge.lo `test -f 'effects/gstgleffectbulge.c' || echo '$(srcdir)/'`effects/gstgleffectbulge.c
+
+effects/libgstopengl_la-gstgleffecttunnel.lo: effects/gstgleffecttunnel.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffecttunnel.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffecttunnel.Tpo -c -o effects/libgstopengl_la-gstgleffecttunnel.lo `test -f 'effects/gstgleffecttunnel.c' || echo '$(srcdir)/'`effects/gstgleffecttunnel.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffecttunnel.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffecttunnel.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffecttunnel.c' object='effects/libgstopengl_la-gstgleffecttunnel.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffecttunnel.lo `test -f 'effects/gstgleffecttunnel.c' || echo '$(srcdir)/'`effects/gstgleffecttunnel.c
+
+effects/libgstopengl_la-gstgleffectsquare.lo: effects/gstgleffectsquare.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectsquare.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectsquare.Tpo -c -o effects/libgstopengl_la-gstgleffectsquare.lo `test -f 'effects/gstgleffectsquare.c' || echo '$(srcdir)/'`effects/gstgleffectsquare.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectsquare.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectsquare.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectsquare.c' object='effects/libgstopengl_la-gstgleffectsquare.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectsquare.lo `test -f 'effects/gstgleffectsquare.c' || echo '$(srcdir)/'`effects/gstgleffectsquare.c
+
+effects/libgstopengl_la-gstgleffectlumatocurve.lo: effects/gstgleffectlumatocurve.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectlumatocurve.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectlumatocurve.Tpo -c -o effects/libgstopengl_la-gstgleffectlumatocurve.lo `test -f 'effects/gstgleffectlumatocurve.c' || echo '$(srcdir)/'`effects/gstgleffectlumatocurve.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectlumatocurve.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectlumatocurve.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectlumatocurve.c' object='effects/libgstopengl_la-gstgleffectlumatocurve.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectlumatocurve.lo `test -f 'effects/gstgleffectlumatocurve.c' || echo '$(srcdir)/'`effects/gstgleffectlumatocurve.c
+
+effects/libgstopengl_la-gstgleffectrgbtocurve.lo: effects/gstgleffectrgbtocurve.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectrgbtocurve.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectrgbtocurve.Tpo -c -o effects/libgstopengl_la-gstgleffectrgbtocurve.lo `test -f 'effects/gstgleffectrgbtocurve.c' || echo '$(srcdir)/'`effects/gstgleffectrgbtocurve.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectrgbtocurve.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectrgbtocurve.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectrgbtocurve.c' object='effects/libgstopengl_la-gstgleffectrgbtocurve.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectrgbtocurve.lo `test -f 'effects/gstgleffectrgbtocurve.c' || echo '$(srcdir)/'`effects/gstgleffectrgbtocurve.c
+
+effects/libgstopengl_la-gstgleffectsin.lo: effects/gstgleffectsin.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectsin.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectsin.Tpo -c -o effects/libgstopengl_la-gstgleffectsin.lo `test -f 'effects/gstgleffectsin.c' || echo '$(srcdir)/'`effects/gstgleffectsin.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectsin.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectsin.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectsin.c' object='effects/libgstopengl_la-gstgleffectsin.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectsin.lo `test -f 'effects/gstgleffectsin.c' || echo '$(srcdir)/'`effects/gstgleffectsin.c
+
+effects/libgstopengl_la-gstgleffectxray.lo: effects/gstgleffectxray.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectxray.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectxray.Tpo -c -o effects/libgstopengl_la-gstgleffectxray.lo `test -f 'effects/gstgleffectxray.c' || echo '$(srcdir)/'`effects/gstgleffectxray.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectxray.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectxray.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectxray.c' object='effects/libgstopengl_la-gstgleffectxray.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectxray.lo `test -f 'effects/gstgleffectxray.c' || echo '$(srcdir)/'`effects/gstgleffectxray.c
+
+effects/libgstopengl_la-gstgleffectglow.lo: effects/gstgleffectglow.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectglow.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectglow.Tpo -c -o effects/libgstopengl_la-gstgleffectglow.lo `test -f 'effects/gstgleffectglow.c' || echo '$(srcdir)/'`effects/gstgleffectglow.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectglow.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectglow.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectglow.c' object='effects/libgstopengl_la-gstgleffectglow.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectglow.lo `test -f 'effects/gstgleffectglow.c' || echo '$(srcdir)/'`effects/gstgleffectglow.c
+
+effects/libgstopengl_la-gstgleffectblur.lo: effects/gstgleffectblur.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectblur.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectblur.Tpo -c -o effects/libgstopengl_la-gstgleffectblur.lo `test -f 'effects/gstgleffectblur.c' || echo '$(srcdir)/'`effects/gstgleffectblur.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectblur.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectblur.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectblur.c' object='effects/libgstopengl_la-gstgleffectblur.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectblur.lo `test -f 'effects/gstgleffectblur.c' || echo '$(srcdir)/'`effects/gstgleffectblur.c
+
+effects/libgstopengl_la-gstgleffectsobel.lo: effects/gstgleffectsobel.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectsobel.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectsobel.Tpo -c -o effects/libgstopengl_la-gstgleffectsobel.lo `test -f 'effects/gstgleffectsobel.c' || echo '$(srcdir)/'`effects/gstgleffectsobel.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectsobel.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectsobel.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectsobel.c' object='effects/libgstopengl_la-gstgleffectsobel.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectsobel.lo `test -f 'effects/gstgleffectsobel.c' || echo '$(srcdir)/'`effects/gstgleffectsobel.c
+
+effects/libgstopengl_la-gstgleffectlaplacian.lo: effects/gstgleffectlaplacian.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectlaplacian.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectlaplacian.Tpo -c -o effects/libgstopengl_la-gstgleffectlaplacian.lo `test -f 'effects/gstgleffectlaplacian.c' || echo '$(srcdir)/'`effects/gstgleffectlaplacian.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectlaplacian.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectlaplacian.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectlaplacian.c' object='effects/libgstopengl_la-gstgleffectlaplacian.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectlaplacian.lo `test -f 'effects/gstgleffectlaplacian.c' || echo '$(srcdir)/'`effects/gstgleffectlaplacian.c
+
 libgstopengl_la-gstglcolorscale.lo: gstglcolorscale.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT libgstopengl_la-gstglcolorscale.lo -MD -MP -MF $(DEPDIR)/libgstopengl_la-gstglcolorscale.Tpo -c -o libgstopengl_la-gstglcolorscale.lo `test -f 'gstglcolorscale.c' || echo '$(srcdir)/'`gstglcolorscale.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstopengl_la-gstglcolorscale.Tpo $(DEPDIR)/libgstopengl_la-gstglcolorscale.Plo
@@ -1278,27 +1372,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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o libgstopengl_la-gstglfilterapp.lo `test -f 'gstglfilterapp.c' || echo '$(srcdir)/'`gstglfilterapp.c
 
-libgstopengl_la-gstglfilterblur.lo: gstglfilterblur.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT libgstopengl_la-gstglfilterblur.lo -MD -MP -MF $(DEPDIR)/libgstopengl_la-gstglfilterblur.Tpo -c -o libgstopengl_la-gstglfilterblur.lo `test -f 'gstglfilterblur.c' || echo '$(srcdir)/'`gstglfilterblur.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstopengl_la-gstglfilterblur.Tpo $(DEPDIR)/libgstopengl_la-gstglfilterblur.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gstglfilterblur.c' object='libgstopengl_la-gstglfilterblur.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o libgstopengl_la-gstglfilterblur.lo `test -f 'gstglfilterblur.c' || echo '$(srcdir)/'`gstglfilterblur.c
-
-libgstopengl_la-gstglfiltersobel.lo: gstglfiltersobel.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT libgstopengl_la-gstglfiltersobel.lo -MD -MP -MF $(DEPDIR)/libgstopengl_la-gstglfiltersobel.Tpo -c -o libgstopengl_la-gstglfiltersobel.lo `test -f 'gstglfiltersobel.c' || echo '$(srcdir)/'`gstglfiltersobel.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstopengl_la-gstglfiltersobel.Tpo $(DEPDIR)/libgstopengl_la-gstglfiltersobel.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gstglfiltersobel.c' object='libgstopengl_la-gstglfiltersobel.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o libgstopengl_la-gstglfiltersobel.lo `test -f 'gstglfiltersobel.c' || echo '$(srcdir)/'`gstglfiltersobel.c
-
-libgstopengl_la-gstglfilterlaplacian.lo: gstglfilterlaplacian.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT libgstopengl_la-gstglfilterlaplacian.lo -MD -MP -MF $(DEPDIR)/libgstopengl_la-gstglfilterlaplacian.Tpo -c -o libgstopengl_la-gstglfilterlaplacian.lo `test -f 'gstglfilterlaplacian.c' || echo '$(srcdir)/'`gstglfilterlaplacian.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstopengl_la-gstglfilterlaplacian.Tpo $(DEPDIR)/libgstopengl_la-gstglfilterlaplacian.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gstglfilterlaplacian.c' object='libgstopengl_la-gstglfilterlaplacian.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o libgstopengl_la-gstglfilterlaplacian.lo `test -f 'gstglfilterlaplacian.c' || echo '$(srcdir)/'`gstglfilterlaplacian.c
-
 libgstopengl_la-gstglfilterglass.lo: gstglfilterglass.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT libgstopengl_la-gstglfilterglass.lo -MD -MP -MF $(DEPDIR)/libgstopengl_la-gstglfilterglass.Tpo -c -o libgstopengl_la-gstglfilterglass.lo `test -f 'gstglfilterglass.c' || echo '$(srcdir)/'`gstglfilterglass.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstopengl_la-gstglfilterglass.Tpo $(DEPDIR)/libgstopengl_la-gstglfilterglass.Plo
@@ -1334,83 +1407,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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o libgstopengl_la-gstglmosaic.lo `test -f 'gstglmosaic.c' || echo '$(srcdir)/'`gstglmosaic.c
 
-effects/libgstopengl_la-gstgleffectstretch.lo: effects/gstgleffectstretch.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectstretch.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectstretch.Tpo -c -o effects/libgstopengl_la-gstgleffectstretch.lo `test -f 'effects/gstgleffectstretch.c' || echo '$(srcdir)/'`effects/gstgleffectstretch.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectstretch.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectstretch.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectstretch.c' object='effects/libgstopengl_la-gstgleffectstretch.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectstretch.lo `test -f 'effects/gstgleffectstretch.c' || echo '$(srcdir)/'`effects/gstgleffectstretch.c
-
-effects/libgstopengl_la-gstgleffecttunnel.lo: effects/gstgleffecttunnel.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffecttunnel.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffecttunnel.Tpo -c -o effects/libgstopengl_la-gstgleffecttunnel.lo `test -f 'effects/gstgleffecttunnel.c' || echo '$(srcdir)/'`effects/gstgleffecttunnel.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffecttunnel.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffecttunnel.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffecttunnel.c' object='effects/libgstopengl_la-gstgleffecttunnel.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffecttunnel.lo `test -f 'effects/gstgleffecttunnel.c' || echo '$(srcdir)/'`effects/gstgleffecttunnel.c
-
-effects/libgstopengl_la-gstgleffectfisheye.lo: effects/gstgleffectfisheye.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectfisheye.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectfisheye.Tpo -c -o effects/libgstopengl_la-gstgleffectfisheye.lo `test -f 'effects/gstgleffectfisheye.c' || echo '$(srcdir)/'`effects/gstgleffectfisheye.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectfisheye.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectfisheye.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectfisheye.c' object='effects/libgstopengl_la-gstgleffectfisheye.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectfisheye.lo `test -f 'effects/gstgleffectfisheye.c' || echo '$(srcdir)/'`effects/gstgleffectfisheye.c
-
-effects/libgstopengl_la-gstgleffecttwirl.lo: effects/gstgleffecttwirl.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffecttwirl.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffecttwirl.Tpo -c -o effects/libgstopengl_la-gstgleffecttwirl.lo `test -f 'effects/gstgleffecttwirl.c' || echo '$(srcdir)/'`effects/gstgleffecttwirl.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffecttwirl.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffecttwirl.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffecttwirl.c' object='effects/libgstopengl_la-gstgleffecttwirl.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffecttwirl.lo `test -f 'effects/gstgleffecttwirl.c' || echo '$(srcdir)/'`effects/gstgleffecttwirl.c
-
-effects/libgstopengl_la-gstgleffectbulge.lo: effects/gstgleffectbulge.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectbulge.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectbulge.Tpo -c -o effects/libgstopengl_la-gstgleffectbulge.lo `test -f 'effects/gstgleffectbulge.c' || echo '$(srcdir)/'`effects/gstgleffectbulge.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectbulge.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectbulge.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectbulge.c' object='effects/libgstopengl_la-gstgleffectbulge.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectbulge.lo `test -f 'effects/gstgleffectbulge.c' || echo '$(srcdir)/'`effects/gstgleffectbulge.c
-
-effects/libgstopengl_la-gstgleffectsquare.lo: effects/gstgleffectsquare.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectsquare.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectsquare.Tpo -c -o effects/libgstopengl_la-gstgleffectsquare.lo `test -f 'effects/gstgleffectsquare.c' || echo '$(srcdir)/'`effects/gstgleffectsquare.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectsquare.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectsquare.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectsquare.c' object='effects/libgstopengl_la-gstgleffectsquare.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectsquare.lo `test -f 'effects/gstgleffectsquare.c' || echo '$(srcdir)/'`effects/gstgleffectsquare.c
-
-effects/libgstopengl_la-gstgleffectlumatocurve.lo: effects/gstgleffectlumatocurve.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectlumatocurve.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectlumatocurve.Tpo -c -o effects/libgstopengl_la-gstgleffectlumatocurve.lo `test -f 'effects/gstgleffectlumatocurve.c' || echo '$(srcdir)/'`effects/gstgleffectlumatocurve.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectlumatocurve.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectlumatocurve.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectlumatocurve.c' object='effects/libgstopengl_la-gstgleffectlumatocurve.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectlumatocurve.lo `test -f 'effects/gstgleffectlumatocurve.c' || echo '$(srcdir)/'`effects/gstgleffectlumatocurve.c
-
-effects/libgstopengl_la-gstgleffectrgbtocurve.lo: effects/gstgleffectrgbtocurve.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectrgbtocurve.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectrgbtocurve.Tpo -c -o effects/libgstopengl_la-gstgleffectrgbtocurve.lo `test -f 'effects/gstgleffectrgbtocurve.c' || echo '$(srcdir)/'`effects/gstgleffectrgbtocurve.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectrgbtocurve.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectrgbtocurve.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectrgbtocurve.c' object='effects/libgstopengl_la-gstgleffectrgbtocurve.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectrgbtocurve.lo `test -f 'effects/gstgleffectrgbtocurve.c' || echo '$(srcdir)/'`effects/gstgleffectrgbtocurve.c
-
-effects/libgstopengl_la-gstgleffectsin.lo: effects/gstgleffectsin.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectsin.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectsin.Tpo -c -o effects/libgstopengl_la-gstgleffectsin.lo `test -f 'effects/gstgleffectsin.c' || echo '$(srcdir)/'`effects/gstgleffectsin.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectsin.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectsin.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectsin.c' object='effects/libgstopengl_la-gstgleffectsin.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectsin.lo `test -f 'effects/gstgleffectsin.c' || echo '$(srcdir)/'`effects/gstgleffectsin.c
-
-effects/libgstopengl_la-gstgleffectglow.lo: effects/gstgleffectglow.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectglow.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectglow.Tpo -c -o effects/libgstopengl_la-gstgleffectglow.lo `test -f 'effects/gstgleffectglow.c' || echo '$(srcdir)/'`effects/gstgleffectglow.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectglow.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectglow.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectglow.c' object='effects/libgstopengl_la-gstgleffectglow.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectglow.lo `test -f 'effects/gstgleffectglow.c' || echo '$(srcdir)/'`effects/gstgleffectglow.c
-
-effects/libgstopengl_la-gstgleffectxray.lo: effects/gstgleffectxray.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT effects/libgstopengl_la-gstgleffectxray.lo -MD -MP -MF effects/$(DEPDIR)/libgstopengl_la-gstgleffectxray.Tpo -c -o effects/libgstopengl_la-gstgleffectxray.lo `test -f 'effects/gstgleffectxray.c' || echo '$(srcdir)/'`effects/gstgleffectxray.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) effects/$(DEPDIR)/libgstopengl_la-gstgleffectxray.Tpo effects/$(DEPDIR)/libgstopengl_la-gstgleffectxray.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='effects/gstgleffectxray.c' object='effects/libgstopengl_la-gstgleffectxray.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 $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -c -o effects/libgstopengl_la-gstgleffectxray.lo `test -f 'effects/gstgleffectxray.c' || echo '$(srcdir)/'`effects/gstgleffectxray.c
-
 libgstopengl_la-gstgldifferencematte.lo: gstgldifferencematte.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstopengl_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstopengl_la_CFLAGS) $(CFLAGS) -MT libgstopengl_la-gstgldifferencematte.lo -MD -MP -MF $(DEPDIR)/libgstopengl_la-gstgldifferencematte.Tpo -c -o libgstopengl_la-gstgldifferencematte.lo `test -f 'gstgldifferencematte.c' || echo '$(srcdir)/'`gstgldifferencematte.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstopengl_la-gstgldifferencematte.Tpo $(DEPDIR)/libgstopengl_la-gstgldifferencematte.Plo
diff --git a/ext/gl/effects/gstgleffectblur.c b/ext/gl/effects/gstgleffectblur.c
new file mode 100644
index 0000000..07eb38d
--- /dev/null
+++ b/ext/gl/effects/gstgleffectblur.c
@@ -0,0 +1,122 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@gmail.com>
+ * Copyright (C) 2015 Michał Dębski <debski.mi.zd@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 "../gstgleffects.h"
+
+static float *
+gst_gl_effects_blur_kernel (void)
+{
+  /* gaussian kernel (well, actually vector), size 9, standard
+   * deviation 3.0 */
+  /* FIXME: make this a runtime property */
+  static gfloat *kernel = NULL;
+  if (G_UNLIKELY (NULL == kernel)) {
+    /* 3x3 matrix */
+    kernel = g_malloc (sizeof (gfloat) * 9);
+    fill_gaussian_kernel (kernel, 7, 3.f);
+  }
+  return kernel;
+}
+
+static void
+gst_gl_effects_blur_callback_hconv (gint width, gint height, guint texture,
+    gpointer data)
+{
+  GstGLShader *shader = NULL;
+  GstGLEffects *effects = GST_GL_EFFECTS (data);
+
+  if (NULL != (shader = gst_gl_effects_get_fragment_shader (effects, "hconv0",
+              hconv7_fragment_source_gles2, hconv7_fragment_source_opengl))) {
+    GstGLFilter *filter = GST_GL_FILTER (effects);
+    GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
+
+#if GST_GL_HAVE_OPENGL
+    if (USING_OPENGL (GST_GL_BASE_FILTER (filter)->context)) {
+      gl->MatrixMode (GL_PROJECTION);
+      gl->LoadIdentity ();
+    }
+#endif
+
+    gst_gl_shader_use (shader);
+
+    gl->ActiveTexture (GL_TEXTURE0);
+    gl->Enable (GL_TEXTURE_2D);
+    gl->BindTexture (GL_TEXTURE_2D, texture);
+    gl->Disable (GL_TEXTURE_2D);
+
+    gst_gl_shader_set_uniform_1i (shader, "tex", 0);
+    gst_gl_shader_set_uniform_1f (shader, "gauss_width", width);
+    gst_gl_shader_set_uniform_1fv (shader, "kernel", 7,
+        gst_gl_effects_blur_kernel ());
+
+    gst_gl_filter_draw_texture (filter, texture, width, height);
+  }
+}
+
+static void
+gst_gl_effects_blur_callback_vconv (gint width, gint height, guint texture,
+    gpointer data)
+{
+  GstGLShader *shader = NULL;
+  GstGLEffects *effects = GST_GL_EFFECTS (data);
+  GstGLFilter *filter = GST_GL_FILTER (effects);
+
+  if (NULL != (shader = gst_gl_effects_get_fragment_shader (effects, "vconv0",
+              vconv7_fragment_source_gles2, vconv7_fragment_source_opengl))) {
+    GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
+
+#if GST_GL_HAVE_OPENGL
+    if (USING_OPENGL (GST_GL_BASE_FILTER (filter)->context)) {
+      gl->MatrixMode (GL_PROJECTION);
+      gl->LoadIdentity ();
+    }
+#endif
+
+    gst_gl_shader_use (shader);
+
+    gl->ActiveTexture (GL_TEXTURE0);
+    gl->Enable (GL_TEXTURE_2D);
+    gl->BindTexture (GL_TEXTURE_2D, texture);
+    gl->Disable (GL_TEXTURE_2D);
+
+    gst_gl_shader_set_uniform_1i (shader, "tex", 0);
+    gst_gl_shader_set_uniform_1f (shader, "gauss_height", height);
+    gst_gl_shader_set_uniform_1fv (shader, "kernel", 7,
+        gst_gl_effects_blur_kernel ());
+
+    gst_gl_filter_draw_texture (filter, texture, width, height);
+  }
+}
+
+void
+gst_gl_effects_blur (GstGLEffects * effects)
+{
+  GstGLFilter *filter = GST_GL_FILTER (effects);
+
+  gst_gl_filter_render_to_target (filter, TRUE, effects->intexture,
+      effects->midtexture[0], gst_gl_effects_blur_callback_hconv, effects);
+  gst_gl_filter_render_to_target (filter, FALSE, effects->midtexture[0],
+      effects->outtexture, gst_gl_effects_blur_callback_vconv, effects);
+}
diff --git a/ext/gl/effects/gstgleffectbulge.c b/ext/gl/effects/gstgleffectbulge.c
index 75b9e2f..2e21025 100644
--- a/ext/gl/effects/gstgleffectbulge.c
+++ b/ext/gl/effects/gstgleffectbulge.c
@@ -33,23 +33,18 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "bulge0");
+  shader = gst_gl_effects_get_fragment_shader (effects, "bulge",
+      bulge_fragment_source_gles2, bulge_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "bulge0", shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          bulge_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context, "Failed to initialize bulge shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
@@ -59,9 +54,6 @@
 
   gst_gl_shader_set_uniform_1i (shader, "tex", 0);
 
-  gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f);
-  gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f);
-
   gst_gl_filter_draw_texture (filter, texture, width, height);
 }
 
diff --git a/ext/gl/effects/gstgleffectfisheye.c b/ext/gl/effects/gstgleffectfisheye.c
index 524b659..c94cd42 100644
--- a/ext/gl/effects/gstgleffectfisheye.c
+++ b/ext/gl/effects/gstgleffectfisheye.c
@@ -33,23 +33,18 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "fisheye0");
+  shader = gst_gl_effects_get_fragment_shader (effects, "fisheye",
+      fisheye_fragment_source_gles2, fisheye_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "fisheye0", shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          fisheye_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context, "Failed to initialize fisheye shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
@@ -59,9 +54,6 @@
 
   gst_gl_shader_set_uniform_1i (shader, "tex", 0);
 
-  gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f);
-  gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f);
-
   gst_gl_filter_draw_texture (filter, texture, width, height);
 }
 
diff --git a/ext/gl/effects/gstgleffectglow.c b/ext/gl/effects/gstgleffectglow.c
index 4853fd9..b387715 100644
--- a/ext/gl/effects/gstgleffectglow.c
+++ b/ext/gl/effects/gstgleffectglow.c
@@ -36,24 +36,19 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "glow0");
+  shader = gst_gl_effects_get_fragment_shader (effects, "luma_threshold",
+      luma_threshold_fragment_source_gles2,
+      luma_threshold_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "glow0", shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          luma_threshold_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context,
-        "Failed to initialize luma threshold shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
@@ -76,28 +71,22 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "glow1");
+  shader = gst_gl_effects_get_fragment_shader (effects, "hconv7",
+      hconv7_fragment_source_gles2, hconv7_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "glow1", shader);
-  }
+  if (!shader)
+    return;
 
   if (!kernel_ready) {
     fill_gaussian_kernel (gauss_kernel, 7, 10.0);
     kernel_ready = TRUE;
   }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          hconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context, "Failed to initialize hconv7 shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
-    return;
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
   }
-
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#endif
 
   gst_gl_shader_use (shader);
 
@@ -108,7 +97,7 @@
 
   gst_gl_shader_set_uniform_1i (shader, "tex", 1);
   gst_gl_shader_set_uniform_1fv (shader, "kernel", 7, gauss_kernel);
-  gst_gl_shader_set_uniform_1f (shader, "height", height);
+  gst_gl_shader_set_uniform_1f (shader, "gauss_width", width);
 
   gst_gl_filter_draw_texture (filter, texture, width, height);
 }
@@ -123,23 +112,18 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "glow2");
+  shader = gst_gl_effects_get_fragment_shader (effects, "vconv7",
+      vconv7_fragment_source_gles2, vconv7_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "glow2", shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          vconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context, "Failed to initialize vcon7 shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
@@ -150,7 +134,7 @@
 
   gst_gl_shader_set_uniform_1i (shader, "tex", 1);
   gst_gl_shader_set_uniform_1fv (shader, "kernel", 7, gauss_kernel);
-  gst_gl_shader_set_uniform_1f (shader, "width", width);
+  gst_gl_shader_set_uniform_1f (shader, "gauss_height", height);
 
   gst_gl_filter_draw_texture (filter, texture, width, height);
 }
@@ -165,23 +149,18 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "glow3");
+  shader = gst_gl_effects_get_fragment_shader (effects, "sum",
+      sum_fragment_source_gles2, sum_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "glow3", shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          sum_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context, "Failed to initialize sum shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
@@ -190,7 +169,7 @@
   gl->BindTexture (GL_TEXTURE_2D, effects->intexture);
   gl->Disable (GL_TEXTURE_2D);
 
-  gst_gl_shader_set_uniform_1f (shader, "alpha", 1.0);
+  gst_gl_shader_set_uniform_1f (shader, "alpha", 1.0f);
   gst_gl_shader_set_uniform_1i (shader, "base", 2);
 
   gl->ActiveTexture (GL_TEXTURE1);
@@ -212,11 +191,14 @@
   /* threshold */
   gst_gl_filter_render_to_target (filter, TRUE, effects->intexture,
       effects->midtexture[0], gst_gl_effects_glow_step_one, effects);
+
   /* blur */
   gst_gl_filter_render_to_target (filter, FALSE, effects->midtexture[0],
       effects->midtexture[1], gst_gl_effects_glow_step_two, effects);
+
   gst_gl_filter_render_to_target (filter, FALSE, effects->midtexture[1],
       effects->midtexture[2], gst_gl_effects_glow_step_three, effects);
+
   /* add blurred luma to intexture */
   gst_gl_filter_render_to_target (filter, FALSE, effects->midtexture[2],
       effects->outtexture, gst_gl_effects_glow_step_four, effects);
diff --git a/ext/gl/effects/gstgleffectidentity.c b/ext/gl/effects/gstgleffectidentity.c
index eec357e..58d0055 100644
--- a/ext/gl/effects/gstgleffectidentity.c
+++ b/ext/gl/effects/gstgleffectidentity.c
@@ -23,12 +23,6 @@
 
 #include "../gstgleffects.h"
 
-#define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
-#define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
-#define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
-#define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
-#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))
-
 static void
 gst_gl_effects_identity_callback (gint width, gint height, guint texture,
     gpointer data)
diff --git a/ext/gl/effects/gstgleffectlaplacian.c b/ext/gl/effects/gstgleffectlaplacian.c
new file mode 100644
index 0000000..b9dabcb
--- /dev/null
+++ b/ext/gl/effects/gstgleffectlaplacian.c
@@ -0,0 +1,74 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2010 Filippo Argiolas <filippo.argiolas@gmail.com>
+ * Copyright (C) 2015 Michał Dębski <debski.mi.zd@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 "../gstgleffects.h"
+
+static void
+gst_gl_effects_laplacian_callback (gint width, gint height, guint texture,
+    gpointer data)
+{
+  GstGLShader *shader = NULL;
+  GstGLEffects *effects = GST_GL_EFFECTS (data);
+  GstGLFilter *filter = GST_GL_FILTER (effects);
+
+  if (NULL != (shader = gst_gl_effects_get_fragment_shader (effects, "conv0",
+              conv9_fragment_source_gles2, conv9_fragment_source_opengl))) {
+    GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
+    static gfloat kernel[9] = { 0.0, -1.0, 0.0,
+      -1.0, 4.0, -1.0,
+      0.0, -1.0, 0.0
+    };
+
+#if GST_GL_HAVE_OPENGL
+    if (USING_OPENGL (GST_GL_BASE_FILTER (filter)->context)) {
+      gl->MatrixMode (GL_PROJECTION);
+      gl->LoadIdentity ();
+    }
+#endif
+
+    gst_gl_shader_use (shader);
+
+    gl->ActiveTexture (GL_TEXTURE0);
+    gl->Enable (GL_TEXTURE_2D);
+    gl->BindTexture (GL_TEXTURE_2D, texture);
+    gl->Disable (GL_TEXTURE_2D);
+
+    gst_gl_shader_set_uniform_1i (shader, "tex", 0);
+    gst_gl_shader_set_uniform_1f (shader, "height", height);
+    gst_gl_shader_set_uniform_1f (shader, "width", width);
+    gst_gl_shader_set_uniform_1fv (shader, "kernel", 9, kernel);
+    gst_gl_shader_set_uniform_1i (shader, "invert", effects->invert);
+
+    gst_gl_filter_draw_texture (filter, texture, width, height);
+  }
+}
+
+void
+gst_gl_effects_laplacian (GstGLEffects * effects)
+{
+  gst_gl_filter_render_to_target (GST_GL_FILTER (effects), TRUE,
+      effects->intexture, effects->outtexture,
+      gst_gl_effects_laplacian_callback, effects);
+}
diff --git a/ext/gl/effects/gstgleffectlumatocurve.c b/ext/gl/effects/gstgleffectlumatocurve.c
index 2ce1de3..0a925fe 100644
--- a/ext/gl/effects/gstgleffectlumatocurve.c
+++ b/ext/gl/effects/gstgleffectlumatocurve.c
@@ -34,41 +34,53 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "lumamap0");
+  shader = gst_gl_effects_get_fragment_shader (effects, "luma_to_curve",
+      luma_to_curve_fragment_source_gles2,
+      luma_to_curve_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "lumamap0", shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          luma_to_curve_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context,
-        "Failed to initialize luma to curve shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
   if (effects->curve[curve_index] == 0) {
     /* this parameters are needed to have a right, predictable, mapping */
     gl->GenTextures (1, &effects->curve[curve_index]);
-    gl->Enable (GL_TEXTURE_1D);
-    gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
-    gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-    gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 
-    gl->TexImage1D (GL_TEXTURE_1D, 0, curve->bytes_per_pixel,
-        curve->width, 0, GL_RGB, GL_UNSIGNED_BYTE, curve->pixel_data);
+#if GST_GL_HAVE_OPENGL
+    if (USING_OPENGL (context)) {
+      gl->Enable (GL_TEXTURE_1D);
+      gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
+      gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+      gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+      gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+      gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 
-    gl->Disable (GL_TEXTURE_1D);
+      gl->TexImage1D (GL_TEXTURE_1D, 0, curve->bytes_per_pixel,
+          curve->width, 0, GL_RGB, GL_UNSIGNED_BYTE, curve->pixel_data);
+
+      gl->Disable (GL_TEXTURE_1D);
+    }
+#endif
+    if (USING_GLES2 (context) || USING_OPENGL3 (context)) {
+      gl->Enable (GL_TEXTURE_2D);
+      gl->BindTexture (GL_TEXTURE_2D, effects->curve[curve_index]);
+      gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+      gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+      gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+      gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+      gl->TexImage2D (GL_TEXTURE_2D, 0, GL_RGB,
+          curve->width, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, curve->pixel_data);
+      gl->Disable (GL_TEXTURE_2D);
+    }
   }
 
   gl->ActiveTexture (GL_TEXTURE2);
@@ -79,13 +91,26 @@
 
   gl->Disable (GL_TEXTURE_2D);
 
-  gl->ActiveTexture (GL_TEXTURE1);
-  gl->Enable (GL_TEXTURE_1D);
-  gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->ActiveTexture (GL_TEXTURE1);
+    gl->Enable (GL_TEXTURE_1D);
+    gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
 
-  gst_gl_shader_set_uniform_1i (shader, "curve", 1);
+    gst_gl_shader_set_uniform_1i (shader, "curve", 1);
 
-  gl->Disable (GL_TEXTURE_1D);
+    gl->Disable (GL_TEXTURE_1D);
+  }
+#endif
+  if (USING_GLES2 (context) || USING_OPENGL3 (context)) {
+    gl->ActiveTexture (GL_TEXTURE1);
+    gl->Enable (GL_TEXTURE_2D);
+    gl->BindTexture (GL_TEXTURE_2D, effects->curve[curve_index]);
+
+    gst_gl_shader_set_uniform_1i (shader, "curve", 1);
+
+    gl->Disable (GL_TEXTURE_2D);
+  }
 
   gst_gl_filter_draw_texture (filter, texture, width, height);
 }
diff --git a/ext/gl/effects/gstgleffectmirror.c b/ext/gl/effects/gstgleffectmirror.c
index 1713d54..7a88f07 100644
--- a/ext/gl/effects/gstgleffectmirror.c
+++ b/ext/gl/effects/gstgleffectmirror.c
@@ -23,12 +23,6 @@
 
 #include "../gstgleffects.h"
 
-#define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
-#define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
-#define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
-#define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
-#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))
-
 static void
 gst_gl_effects_mirror_callback (gint width, gint height, guint texture,
     gpointer data)
@@ -39,37 +33,12 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "mirror0");
+  shader = gst_gl_effects_get_fragment_shader (effects, "mirror",
+      mirror_fragment_source_gles2, mirror_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "mirror0", shader);
+  if (!shader)
+    return;
 
-    if (USING_GLES2 (context) || USING_OPENGL3 (context)) {
-      if (!gst_gl_shader_compile_with_default_v_and_check (shader,
-              mirror_fragment_source_gles2, &filter->draw_attr_position_loc,
-              &filter->draw_attr_texture_loc)) {
-        /* gst gl context error is already set */
-        GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-            ("Failed to initialize squeeze shader, %s",
-                gst_gl_context_get_error ()), (NULL));
-        return;
-      }
-    }
-#if GST_GL_HAVE_OPENGL
-    if (USING_OPENGL (context)) {
-      if (!gst_gl_shader_compile_and_check (shader,
-              mirror_fragment_source_opengl, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-        gst_gl_context_set_error (context,
-            "Failed to initialize mirror shader");
-        GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-            ("%s", gst_gl_context_get_error ()), (NULL));
-        return;
-      }
-
-    }
-#endif
-  }
 #if GST_GL_HAVE_OPENGL
   if (USING_OPENGL (context)) {
     gl->MatrixMode (GL_PROJECTION);
diff --git a/ext/gl/effects/gstgleffectrgbtocurve.c b/ext/gl/effects/gstgleffectrgbtocurve.c
index 18b0905..b34a3f3 100644
--- a/ext/gl/effects/gstgleffectrgbtocurve.c
+++ b/ext/gl/effects/gstgleffectrgbtocurve.c
@@ -34,41 +34,51 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "rgbmap0");
+  shader = gst_gl_effects_get_fragment_shader (effects, "rgb_to_curve",
+      rgb_to_curve_fragment_source_gles2, rgb_to_curve_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "rgbmap0", shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          rgb_to_curve_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context,
-        "Failed to initialize rgb to curve shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
   if (effects->curve[curve_index] == 0) {
     /* this parameters are needed to have a right, predictable, mapping */
     gl->GenTextures (1, &effects->curve[curve_index]);
-    gl->Enable (GL_TEXTURE_1D);
-    gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
-    gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-    gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+#if GST_GL_HAVE_OPENGL
+    if (USING_OPENGL (context)) {
+      gl->Enable (GL_TEXTURE_1D);
+      gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
+      gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+      gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+      gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+      gl->TexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 
-    gl->TexImage1D (GL_TEXTURE_1D, 0, curve->bytes_per_pixel,
-        curve->width, 0, GL_RGB, GL_UNSIGNED_BYTE, curve->pixel_data);
+      gl->TexImage1D (GL_TEXTURE_1D, 0, GL_RGB,
+          curve->width, 0, GL_RGB, GL_UNSIGNED_BYTE, curve->pixel_data);
 
-    gl->Disable (GL_TEXTURE_1D);
+      gl->Disable (GL_TEXTURE_1D);
+    }
+#endif
+    if (USING_GLES2 (context) || USING_OPENGL3 (context)) {
+      gl->Enable (GL_TEXTURE_2D);
+      gl->BindTexture (GL_TEXTURE_2D, effects->curve[curve_index]);
+      gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+      gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+      gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+      gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+      gl->TexImage2D (GL_TEXTURE_2D, 0, GL_RGB,
+          curve->width, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, curve->pixel_data);
+      gl->Disable (GL_TEXTURE_2D);
+    }
   }
 
   gl->ActiveTexture (GL_TEXTURE0);
@@ -79,13 +89,26 @@
 
   gl->Disable (GL_TEXTURE_2D);
 
-  gl->ActiveTexture (GL_TEXTURE1);
-  gl->Enable (GL_TEXTURE_1D);
-  gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->ActiveTexture (GL_TEXTURE1);
+    gl->Enable (GL_TEXTURE_1D);
+    gl->BindTexture (GL_TEXTURE_1D, effects->curve[curve_index]);
 
-  gst_gl_shader_set_uniform_1i (shader, "curve", 1);
+    gst_gl_shader_set_uniform_1i (shader, "curve", 1);
 
-  gl->Disable (GL_TEXTURE_1D);
+    gl->Disable (GL_TEXTURE_1D);
+  }
+#endif
+  if (USING_GLES2 (context) || USING_OPENGL3 (context)) {
+    gl->ActiveTexture (GL_TEXTURE1);
+    gl->Enable (GL_TEXTURE_2D);
+    gl->BindTexture (GL_TEXTURE_2D, effects->curve[curve_index]);
+
+    gst_gl_shader_set_uniform_1i (shader, "curve", 1);
+
+    gl->Disable (GL_TEXTURE_2D);
+  }
 
   gst_gl_filter_draw_texture (filter, texture, width, height);
 }
diff --git a/ext/gl/effects/gstgleffectsin.c b/ext/gl/effects/gstgleffectsin.c
index 8d6be54..a28414d 100644
--- a/ext/gl/effects/gstgleffectsin.c
+++ b/ext/gl/effects/gstgleffectsin.c
@@ -33,23 +33,18 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "sin0");
+  shader = gst_gl_effects_get_fragment_shader (effects, "sin",
+      sin_fragment_source_gles2, sin_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "sin0", shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          sin_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context, "Failed to initialize sin shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
diff --git a/ext/gl/effects/gstgleffectsobel.c b/ext/gl/effects/gstgleffectsobel.c
new file mode 100644
index 0000000..fcb7847
--- /dev/null
+++ b/ext/gl/effects/gstgleffectsobel.c
@@ -0,0 +1,180 @@
+/*
+ * GStreamer
+ * Copyright (C) 2008-2010 Filippo Argiolas <filippo.argiolas@gmail.com>
+ * Copyright (C) 2015 Michał Dębski <debski.mi.zd@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 "../gstgleffects.h"
+
+static void
+gst_gl_effects_sobel_callback_desaturate (gint width, gint height,
+    guint texture, gpointer data)
+{
+  GstGLShader *shader = NULL;
+  GstGLEffects *effects = GST_GL_EFFECTS (data);
+  GstGLFilter *filter = GST_GL_FILTER (effects);
+
+  if (NULL != (shader = gst_gl_effects_get_fragment_shader (effects, "desat0",
+              desaturate_fragment_source_gles2,
+              desaturate_fragment_source_opengl))) {
+    GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
+
+#if GST_GL_HAVE_OPENGL
+    if (USING_OPENGL (GST_GL_BASE_FILTER (filter)->context)) {
+      gl->MatrixMode (GL_PROJECTION);
+      gl->LoadIdentity ();
+    }
+#endif
+
+    gst_gl_shader_use (shader);
+
+    gl->ActiveTexture (GL_TEXTURE0);
+    gl->Enable (GL_TEXTURE_2D);
+    gl->BindTexture (GL_TEXTURE_2D, texture);
+    gl->Disable (GL_TEXTURE_2D);
+
+    gst_gl_shader_set_uniform_1i (shader, "tex", 0);
+
+    gst_gl_filter_draw_texture (filter, texture, width, height);
+  }
+}
+
+static void
+gst_gl_effects_sobel_callback_hconv (gint width, gint height, guint texture,
+    gpointer data)
+{
+  GstGLShader *shader = NULL;
+  GstGLEffects *effects = GST_GL_EFFECTS (data);
+  GstGLFilter *filter = GST_GL_FILTER (effects);
+
+  if (NULL != (shader = gst_gl_effects_get_fragment_shader (effects, "hconv0",
+              sep_sobel_hconv3_fragment_source_gles2,
+              sep_sobel_hconv3_fragment_source_opengl))) {
+    GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
+
+#if GST_GL_HAVE_OPENGL
+    if (USING_OPENGL (GST_GL_BASE_FILTER (filter)->context)) {
+      gl->MatrixMode (GL_PROJECTION);
+      gl->LoadIdentity ();
+    }
+#endif
+
+    gst_gl_shader_use (shader);
+
+    gl->ActiveTexture (GL_TEXTURE0);
+    gl->Enable (GL_TEXTURE_2D);
+    gl->BindTexture (GL_TEXTURE_2D, texture);
+    gl->Disable (GL_TEXTURE_2D);
+
+    gst_gl_shader_set_uniform_1i (shader, "tex", 0);
+    gst_gl_shader_set_uniform_1f (shader, "width", width);
+
+    gst_gl_filter_draw_texture (filter, texture, width, height);
+  }
+}
+
+static void
+gst_gl_effects_sobel_callback_vconv (gint width, gint height, guint texture,
+    gpointer data)
+{
+  GstGLShader *shader = NULL;
+  GstGLEffects *effects = GST_GL_EFFECTS (data);
+  GstGLFilter *filter = GST_GL_FILTER (effects);
+
+  if (NULL != (shader = gst_gl_effects_get_fragment_shader (effects, "vconv0",
+              sep_sobel_vconv3_fragment_source_gles2,
+              sep_sobel_vconv3_fragment_source_opengl))) {
+    GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
+
+#if GST_GL_HAVE_OPENGL
+    if (USING_OPENGL (GST_GL_BASE_FILTER (filter)->context)) {
+      gl->MatrixMode (GL_PROJECTION);
+      gl->LoadIdentity ();
+    }
+#endif
+
+    gst_gl_shader_use (shader);
+
+    gl->ActiveTexture (GL_TEXTURE0);
+    gl->Enable (GL_TEXTURE_2D);
+    gl->BindTexture (GL_TEXTURE_2D, texture);
+    gl->Disable (GL_TEXTURE_2D);
+
+    gst_gl_shader_set_uniform_1i (shader, "tex", 0);
+    gst_gl_shader_set_uniform_1f (shader, "height", height);
+
+    gst_gl_filter_draw_texture (filter, texture, width, height);
+  }
+}
+
+static void
+gst_gl_effects_sobel_callback_length (gint width, gint height, guint texture,
+    gpointer data)
+{
+  GstGLShader *shader = NULL;
+  GstGLEffects *effects = GST_GL_EFFECTS (data);
+  GstGLFilter *filter = GST_GL_FILTER (effects);
+
+  if (NULL != (shader = gst_gl_effects_get_fragment_shader (effects, "len0",
+              sep_sobel_length_fragment_source_gles2,
+              sep_sobel_length_fragment_source_opengl))) {
+    GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
+
+#if GST_GL_HAVE_OPENGL
+    if (USING_OPENGL (GST_GL_BASE_FILTER (filter)->context)) {
+      gl->MatrixMode (GL_PROJECTION);
+      gl->LoadIdentity ();
+    }
+#endif
+
+    gst_gl_shader_use (shader);
+
+    gl->ActiveTexture (GL_TEXTURE0);
+    gl->Enable (GL_TEXTURE_2D);
+    gl->BindTexture (GL_TEXTURE_2D, texture);
+    gl->Disable (GL_TEXTURE_2D);
+
+    gst_gl_shader_set_uniform_1i (shader, "tex", 0);
+    gst_gl_shader_set_uniform_1i (shader, "invert", effects->invert);
+
+    gst_gl_filter_draw_texture (filter, texture, width, height);
+  }
+}
+
+void
+gst_gl_effects_sobel (GstGLEffects * effects)
+{
+  GstGLFilter *filter = GST_GL_FILTER (effects);
+
+  gst_gl_filter_render_to_target (filter, TRUE,
+      effects->intexture, effects->midtexture[0],
+      gst_gl_effects_sobel_callback_desaturate, effects);
+  gst_gl_filter_render_to_target (filter, FALSE,
+      effects->midtexture[0], effects->midtexture[1],
+      gst_gl_effects_sobel_callback_hconv, effects);
+  gst_gl_filter_render_to_target (filter, FALSE,
+      effects->midtexture[1], effects->midtexture[0],
+      gst_gl_effects_sobel_callback_vconv, effects);
+  gst_gl_filter_render_to_target (filter, FALSE,
+      effects->midtexture[0], effects->outtexture,
+      gst_gl_effects_sobel_callback_length, effects);
+}
diff --git a/ext/gl/effects/gstgleffectsquare.c b/ext/gl/effects/gstgleffectsquare.c
index b1619c0..40dd313 100644
--- a/ext/gl/effects/gstgleffectsquare.c
+++ b/ext/gl/effects/gstgleffectsquare.c
@@ -33,23 +33,18 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "square0");
+  shader = gst_gl_effects_get_fragment_shader (effects, "square",
+      square_fragment_source_gles2, square_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "square0", shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          square_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context, "Failed to initialize square shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
@@ -59,9 +54,6 @@
 
   gst_gl_shader_set_uniform_1i (shader, "tex", 0);
 
-  gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f);
-  gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f);
-
   gst_gl_filter_draw_texture (filter, texture, width, height);
 }
 
diff --git a/ext/gl/effects/gstgleffectsqueeze.c b/ext/gl/effects/gstgleffectsqueeze.c
index 863157a..7ba5e52 100644
--- a/ext/gl/effects/gstgleffectsqueeze.c
+++ b/ext/gl/effects/gstgleffectsqueeze.c
@@ -23,12 +23,6 @@
 
 #include "../gstgleffects.h"
 
-#define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
-#define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
-#define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
-#define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
-#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))
-
 static void
 gst_gl_effects_squeeze_callback (gint width, gint height, guint texture,
     gpointer data)
@@ -39,36 +33,12 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "squeeze0");
+  shader = gst_gl_effects_get_fragment_shader (effects, "squeeze",
+      squeeze_fragment_source_gles2, squeeze_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "squeeze0", shader);
+  if (!shader)
+    return;
 
-    if (USING_GLES2 (context) || USING_OPENGL3 (context)) {
-      if (!gst_gl_shader_compile_with_default_v_and_check (shader,
-              squeeze_fragment_source_gles2, &filter->draw_attr_position_loc,
-              &filter->draw_attr_texture_loc)) {
-        /* gst gl context error is already set */
-        GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-            ("Failed to initialize squeeze shader, %s",
-                gst_gl_context_get_error ()), (NULL));
-        return;
-      }
-    }
-#if GST_GL_HAVE_OPENGL
-    if (USING_OPENGL (context)) {
-      if (!gst_gl_shader_compile_and_check (shader,
-              squeeze_fragment_source_opengl, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-        gst_gl_context_set_error (context,
-            "Failed to initialize squeeze shader");
-        GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-            ("%s", gst_gl_context_get_error ()), (NULL));
-        return;
-      }
-    }
-#endif
-  }
 #if GST_GL_HAVE_OPENGL
   if (USING_OPENGL (context)) {
     gl->MatrixMode (GL_PROJECTION);
@@ -79,8 +49,7 @@
   gst_gl_shader_use (shader);
 
   gl->ActiveTexture (GL_TEXTURE0);
-  if (USING_OPENGL (context))
-    gl->Enable (GL_TEXTURE_2D);
+  gl->Enable (GL_TEXTURE_2D);
   gl->BindTexture (GL_TEXTURE_2D, texture);
 
   gst_gl_shader_set_uniform_1i (shader, "tex", 0);
diff --git a/ext/gl/effects/gstgleffectssources.c b/ext/gl/effects/gstgleffectssources.c
index 3786503..0060ff0 100644
--- a/ext/gl/effects/gstgleffectssources.c
+++ b/ext/gl/effects/gstgleffectssources.c
@@ -65,7 +65,6 @@
 /* *INDENT-OFF* */
 
 /* Mirror effect */
-#if GST_GL_HAVE_OPENGL
 const gchar *mirror_fragment_source_opengl =
   "uniform sampler2D tex;"
   "void main () {"
@@ -77,7 +76,7 @@
   "  vec4 color = texture2D (tex, texturecoord);"
   "  gl_FragColor = color * gl_Color;"
   "}";
-#endif
+
 const gchar *mirror_fragment_source_gles2 =
   "#ifdef GL_ES\n"
   "precision mediump float;\n"
@@ -93,7 +92,6 @@
   "}";
 
 /* Squeeze effect */
-#if GST_GL_HAVE_OPENGL
 const gchar *squeeze_fragment_source_opengl =
   "uniform sampler2D tex;"
   "void main () {"
@@ -105,7 +103,7 @@
   "  texturecoord = (normcoord + 0.5);"
   "  gl_FragColor = texture2D (tex, texturecoord);"
   "}";
-#endif
+
 const gchar *squeeze_fragment_source_gles2 =
   "#ifdef GL_ES\n"
   "precision mediump float;\n"
@@ -123,7 +121,7 @@
   "}";
 
 /* Stretch Effect */
-const gchar *stretch_fragment_source =
+const gchar *stretch_fragment_source_opengl =
   "uniform sampler2D tex;"
   "void main () {"
   "  vec2 texturecoord = gl_TexCoord[0].xy;"
@@ -136,8 +134,24 @@
   "  gl_FragColor = color * gl_Color;"
   "}";
 
+const gchar *stretch_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D tex;"
+  "void main () {"
+	"  vec2 texturecoord = v_texcoord.xy;"
+  "  vec2 normcoord;"
+  "  normcoord = texturecoord - 0.5;"
+  "  float r = length (normcoord);"
+  "  normcoord *= 2.0 - smoothstep(0.0, 0.35, r);"
+  "  texturecoord = normcoord + 0.5;"
+  "  gl_FragColor = texture2D (tex, texturecoord);"
+  "}";
+
 /* Light Tunnel effect */
-const gchar *tunnel_fragment_source =
+const gchar *tunnel_fragment_source_opengl =
   "uniform sampler2D tex;"
   "void main () {"
   "  vec2 texturecoord = gl_TexCoord[0].xy;"
@@ -152,23 +166,56 @@
   "  gl_FragColor = color;"
   "}";
 
+const gchar *tunnel_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D tex;"
+  "void main () {"
+  "  vec2 texturecoord = v_texcoord.xy;"
+  "  vec2 normcoord;"
+  /* little trick with normalized coords to obtain a circle with
+   * rect textures */
+  "  normcoord = (texturecoord - 0.5);"
+  "  float r = length(normcoord);"
+  "  normcoord *= clamp (r, 0.0, 0.275) / r;"
+  "  texturecoord = normcoord + 0.5;"
+  "  gl_FragColor = texture2D (tex, texturecoord);"
+  "}";
+
 /* FishEye effect */
-const gchar *fisheye_fragment_source =
+const gchar *fisheye_fragment_source_opengl =
   "uniform sampler2D tex;"
   "void main () {"
   "  vec2 texturecoord = gl_TexCoord[0].xy;"
   "  vec2 normcoord;"
   "  normcoord = texturecoord - 0.5;"
   "  float r = length (normcoord);"
-  "  normcoord *= r * sqrt(2);"
+  "  normcoord *= r * sqrt(2.0);"
   "  texturecoord = normcoord + 0.5;"
   "  vec4 color = texture2D (tex, texturecoord);"
   "  gl_FragColor = color;"
   "}";
 
+const gchar *fisheye_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D tex;"
+  "void main () {"
+  "  vec2 texturecoord = v_texcoord.xy;"
+  "  vec2 normcoord;"
+  "  normcoord = texturecoord - 0.5;"
+  "  float r = length (normcoord);"
+  "  normcoord *= r * sqrt(2);"
+  "  texturecoord = normcoord + 0.5;"
+  "  gl_FragColor = texture2D (tex, texturecoord);"
+  "}";
 
 /* Twirl effect */
-const gchar *twirl_fragment_source =
+const gchar *twirl_fragment_source_opengl =
   "uniform sampler2D tex;"
   "void main () {"
   "  vec2 texturecoord = gl_TexCoord[0].xy;"
@@ -188,9 +235,31 @@
   "  gl_FragColor = color;"
   "}";
 
+const gchar *twirl_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+	"uniform sampler2D tex;"
+  "void main () {"
+  "  vec2 texturecoord = v_texcoord.xy;"
+  "  vec2 normcoord;"
+  "  normcoord = texturecoord - 0.5;"
+  "  float r = length (normcoord);"
+  /* calculate rotation angle: maximum (about pi/2) at the origin and
+   * gradually decrease it up to 0.6 of each quadrant */
+  "  float phi = (1.0 - smoothstep (0.0, 0.3, r)) * 1.6;"
+  /* precalculate sin phi and cos phi, save some alu */
+  "  float s = sin(phi);"
+  "  float c = cos(phi);"
+  /* rotate */
+  "  normcoord *= mat2(c, s, -s, c);"
+  "  texturecoord = normcoord + 0.5;"
+  "  gl_FragColor = texture2D (tex, texturecoord);"
+  "}";
 
 /* Bulge effect */
-const gchar *bulge_fragment_source =
+const gchar *bulge_fragment_source_opengl =
   "uniform sampler2D tex;"
   "void main () {"
   "  vec2 texturecoord = gl_TexCoord[0].xy;"
@@ -203,9 +272,24 @@
   "  gl_FragColor = color;"
   "}";
 
+const gchar *bulge_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D tex;"
+  "void main () {"
+  "  vec2 texturecoord = v_texcoord.xy;"
+  "  vec2 normcoord;"
+  "  normcoord = texturecoord - 0.5;"
+  "  float r =  length (normcoord);"
+  "  normcoord *= smoothstep (-0.05, 0.25, r);"
+  "  texturecoord = normcoord + 0.5;"
+  "  gl_FragColor = texture2D (tex, texturecoord);"
+  "}";
 
 /* Square Effect */
-const gchar *square_fragment_source =
+const gchar *square_fragment_source_opengl =
   "uniform sampler2D tex;"
   "void main () {"
   "  vec2 texturecoord = gl_TexCoord[0].xy;"
@@ -219,8 +303,24 @@
   "  gl_FragColor = color * gl_Color;"
   "}";
 
+const gchar *square_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D tex;"
+  "void main () {"
+  "  vec2 texturecoord = v_texcoord.xy;"
+  "  vec2 normcoord;"
+  "  normcoord = texturecoord - 0.5;"
+  "  float r = length (normcoord);"
+  "  normcoord *= 1.0 + smoothstep(0.125, 0.25, abs(normcoord));"
+  "  normcoord /= 2.0; /* zoom amount */"
+  "  texturecoord = normcoord + 0.5;"
+  "  gl_FragColor = texture2D (tex, texturecoord);"
+  "}";
 
-const gchar *luma_threshold_fragment_source =
+const gchar *luma_threshold_fragment_source_opengl =
   "uniform sampler2D tex;"
   "void main () {"
   "  vec2 texturecoord = gl_TexCoord[0].st;"
@@ -229,7 +329,20 @@
   "  gl_FragColor = vec4 (vec3 (smoothstep (0.30, 0.50, luma)), color.a);"
   "}";
 
-const gchar *sep_sobel_length_fragment_source =
+const gchar *luma_threshold_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D tex;"
+  "void main () {"
+  "  vec2 texturecoord = v_texcoord.xy;"
+  "  vec4 color = texture2D(tex, texturecoord);"
+  "  float luma = dot(color.rgb, vec3(0.2125, 0.7154, 0.0721));"    /* BT.709 (from orange book) */
+  "  gl_FragColor = vec4 (vec3 (smoothstep (0.30, 0.50, luma)), color.a);"
+  "}";
+
+const gchar *sep_sobel_length_fragment_source_opengl =
   "uniform sampler2D tex;"
   "uniform bool invert;"
   "void main () {"
@@ -242,7 +355,24 @@
   "  gl_FragColor = abs(vec4(vec3(float(invert) - len), 1.0));"
   "}";
 
-const gchar *desaturate_fragment_source =
+const gchar *sep_sobel_length_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D tex;"
+  "uniform bool invert;"
+  "void main () {"
+  "  vec4 g = texture2D (tex, v_texcoord.xy);"
+  /* restore black background with grey edges */
+  "  g -= vec4(0.5, 0.5, 0.0, 0.0);"
+  "  float len = length (g);"
+  /* little trick to avoid IF operator */
+  /* TODO: test if a standalone inverting pass is worth */
+  "  gl_FragColor = abs(vec4(vec3(float(invert) - len), 1.0));"
+  "}";
+
+const gchar *desaturate_fragment_source_opengl =
   "uniform sampler2D tex;"
   "void main () {"
   "  vec4 color = texture2D (tex, gl_TexCoord[0].st);"
@@ -250,7 +380,19 @@
   "  gl_FragColor = vec4(vec3(luma), color.a);"
   "}";
 
-const gchar *sep_sobel_hconv3_fragment_source =
+const gchar *desaturate_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D tex;"
+  "void main () {"
+  "  vec4 color = texture2D (tex, v_texcoord.xy);"
+  "  float luma = dot(color.rgb, vec3(0.2125, 0.7154, 0.0721));"
+  "  gl_FragColor = vec4(vec3(luma), color.a);"
+  "}";
+
+const gchar *sep_sobel_hconv3_fragment_source_opengl =
   "uniform sampler2D tex;"
   "uniform float width;"
   "void main () {"
@@ -277,7 +419,38 @@
   "  gl_FragColor = sum + vec4(0.0, 0.5, 0.0, 0.0);"
   "}";
 
-const gchar *sep_sobel_vconv3_fragment_source =
+const gchar *sep_sobel_hconv3_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D tex;"
+  "uniform float width;"
+  "void main () {"
+  "  float w = 1.0 / width;"
+  "  vec2 texturecoord[3];"
+  "  texturecoord[1] = v_texcoord.xy;"
+  "  texturecoord[0] = texturecoord[1] - vec2(w, 0.0);"
+  "  texturecoord[2] = texturecoord[1] + vec2(w, 0.0);"
+  "  float grad_kern[3];"
+  "  grad_kern[0] = 1.0;"
+  "  grad_kern[1] = 0.0;"
+  "  grad_kern[2] = -1.0;"
+  "  float blur_kern[3];"
+  "  blur_kern[0] = 0.25;"
+  "  blur_kern[1] = 0.5;"
+  "  blur_kern[2] = 0.25;"
+  "  int i;"
+  "  vec4 sum = vec4 (0.0);"
+  "  for (i = 0; i < 3; i++) { "
+  "    vec4 neighbor = texture2D(tex, texturecoord[i]); "
+  "    sum.r = neighbor.r * blur_kern[i] + sum.r;"
+  "    sum.g = neighbor.g * grad_kern[i] + sum.g;"
+  "  }"
+  "  gl_FragColor = sum + vec4(0.0, 0.5, 0.0, 0.0);"
+  "}";
+
+const gchar *sep_sobel_vconv3_fragment_source_opengl =
   "uniform sampler2D tex;"
   "uniform float height;"
   "void main () {"
@@ -304,13 +477,44 @@
   "  gl_FragColor = sum + vec4(0.5, 0.0, 0.0, 0.0);"
   "}";
 
+const gchar *sep_sobel_vconv3_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D tex;"
+  "uniform float height;"
+  "void main () {"
+  "  float h = 1.0 / height;"
+  "  vec2 texturecoord[3];"
+  "  texturecoord[1] = v_texcoord.xy;"
+  "  texturecoord[0] = texturecoord[1] - vec2(0.0, h);"
+  "  texturecoord[2] = texturecoord[1] + vec2(0.0, h);"
+  "  float grad_kern[3];"
+  "  grad_kern[0] = 1.0;"
+  "  grad_kern[1] = 0.0;"
+  "  grad_kern[2] = -1.0;"
+  "  float blur_kern[3];"
+  "  blur_kern[0] = 0.25;"
+  "  blur_kern[1] = 0.5;"
+  "  blur_kern[2] = 0.25;"
+  "  int i;"
+  "  vec4 sum = vec4 (0.0);"
+  "  for (i = 0; i < 3; i++) { "
+  "    vec4 neighbor = texture2D(tex, texturecoord[i]); "
+  "    sum.r = neighbor.r * grad_kern[i] + sum.r;"
+  "    sum.g = neighbor.g * blur_kern[i] + sum.g;"
+  "  }"
+  "  gl_FragColor = sum + vec4(0.5, 0.0, 0.0, 0.0);"
+  "}";
+
 /* horizontal convolution 7x7 */
-const gchar *hconv7_fragment_source =
+const gchar *hconv7_fragment_source_opengl =
   "uniform sampler2D tex;"
   "uniform float kernel[7];"
-  "uniform float width;"
+  "uniform float gauss_width;"
   "void main () {"
-  "  float w = 1.0 / width;"
+  "  float w = 1.0 / gauss_width;"
   "  vec2 texturecoord[7];"
   "  texturecoord[3] = gl_TexCoord[0].st;"
   "  texturecoord[2] = texturecoord[3] - vec2(w, 0.0);"
@@ -328,13 +532,40 @@
   "  gl_FragColor = sum;"
   "}";
 
-/* vertical convolution 7x7 */
-const gchar *vconv7_fragment_source =
+const gchar *hconv7_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
   "uniform sampler2D tex;"
   "uniform float kernel[7];"
-  "uniform float height;"
+  "uniform float gauss_width;"
   "void main () {"
-  "  float h = 1.0 / height;"
+  "  float w = 1.0 / gauss_width;"
+  "  vec2 texturecoord[7];"
+  "  texturecoord[3] = v_texcoord.xy;"
+  "  texturecoord[2] = texturecoord[3] - vec2(w, 0.0);"
+  "  texturecoord[1] = texturecoord[2] - vec2(w, 0.0);"
+  "  texturecoord[0] = texturecoord[1] - vec2(w, 0.0);"
+  "  texturecoord[4] = texturecoord[3] + vec2(w, 0.0);"
+  "  texturecoord[5] = texturecoord[4] + vec2(w, 0.0);"
+  "  texturecoord[6] = texturecoord[5] + vec2(w, 0.0);"
+  "  int i;"
+  "  vec4 sum = vec4 (0.0);"
+  "  for (i = 0; i < 7; i++) { "
+  "    vec4 neighbor = texture2D(tex, texturecoord[i]); "
+  "    sum += neighbor * kernel[i];"
+  "  }"
+  "  gl_FragColor = sum;"
+  "}";
+
+/* vertical convolution 7x7 */
+const gchar *vconv7_fragment_source_opengl =
+  "uniform sampler2D tex;"
+  "uniform float kernel[7];"
+  "uniform float gauss_height;"
+  "void main () {"
+  "  float h = 1.0 / gauss_height;"
   "  vec2 texturecoord[7];"
   "  texturecoord[3] = gl_TexCoord[0].st;"
   "  texturecoord[2] = texturecoord[3] - vec2(0.0, h);"
@@ -352,9 +583,35 @@
   "  gl_FragColor = sum;"
   "}";
 
+const gchar *vconv7_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D tex;"
+  "uniform float kernel[7];"
+  "uniform float gauss_height;"
+  "void main () {"
+  "  float h = 1.0 / gauss_height;"
+  "  vec2 texturecoord[7];"
+  "  texturecoord[3] = v_texcoord.xy;"
+  "  texturecoord[2] = texturecoord[3] - vec2(0.0, h);"
+  "  texturecoord[1] = texturecoord[2] - vec2(0.0, h);"
+  "  texturecoord[0] = texturecoord[1] - vec2(0.0, h);"
+  "  texturecoord[4] = texturecoord[3] + vec2(0.0, h);"
+  "  texturecoord[5] = texturecoord[4] + vec2(0.0, h);"
+  "  texturecoord[6] = texturecoord[5] + vec2(0.0, h);"
+  "  int i;"
+  "  vec4 sum = vec4 (0.0);"
+  "  for (i = 0; i < 7; i++) { "
+  "    vec4 neighbor = texture2D(tex, texturecoord[i]);"
+  "    sum += neighbor * kernel[i];"
+  "  }"
+  "  gl_FragColor = sum;"
+  "}";
 
 /* TODO: support several blend modes */
-const gchar *sum_fragment_source =
+const gchar *sum_fragment_source_opengl =
   "uniform sampler2D base;"
   "uniform sampler2D blend;"
   "uniform float alpha;"
@@ -365,7 +622,22 @@
   "  gl_FragColor = alpha * basecolor + beta * blendcolor;"
   "}";
 
-const gchar *multiply_fragment_source =
+const gchar *sum_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D base;"
+  "uniform sampler2D blend;"
+  "uniform float alpha;"
+  "uniform float beta;"
+  "void main () {"
+  "  vec4 basecolor = texture2D (base, v_texcoord.xy);"
+  "  vec4 blendcolor = texture2D (blend, v_texcoord.xy);"
+  "  gl_FragColor = alpha * basecolor + beta * blendcolor;"
+  "}";
+
+const gchar *multiply_fragment_source_opengl =
   "uniform sampler2D base;"
   "uniform sampler2D blend;"
   "uniform float alpha;"
@@ -375,8 +647,22 @@
   "  gl_FragColor = (1.0 - alpha) * basecolor + alpha * basecolor * blendcolor;"
   "}";
 
+const gchar *multiply_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D base;"
+  "uniform sampler2D blend;"
+  "uniform float alpha;"
+  "void main () {"
+  "  vec4 basecolor = texture2D (base, v_texcoord.xy);"
+  "  vec4 blendcolor = texture2D (blend, v_texcoord.xy);"
+  "  gl_FragColor = (1.0 - alpha) * basecolor + alpha * basecolor * blendcolor;"
+  "}";
+
 /* lut operations, map luma to tex1d, see orange book (chapter 19) */
-const gchar *luma_to_curve_fragment_source =
+const gchar *luma_to_curve_fragment_source_opengl =
   "uniform sampler2D tex;"
   "uniform sampler1D curve;"
   "void main () {"
@@ -387,9 +673,23 @@
   "  gl_FragColor = color;"
   "}";
 
+const gchar *luma_to_curve_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D tex;"
+  "uniform sampler2D curve;"
+  "void main () {"
+  "  vec2 texturecoord = v_texcoord.xy;"
+  "  vec4 color = texture2D (tex, texturecoord);"
+  "  float luma = dot(color.rgb, vec3(0.2125, 0.7154, 0.0721));"
+  "  color = texture2D (curve, vec2(luma, 0.0));"
+  "  gl_FragColor = color;"
+  "}";
 
 /* lut operations, map rgb to tex1d, see orange book (chapter 19) */
-const gchar *rgb_to_curve_fragment_source =
+const gchar *rgb_to_curve_fragment_source_opengl =
   "uniform sampler2D tex;"
   "uniform sampler1D curve;"
   "void main () {"
@@ -402,7 +702,24 @@
   "  gl_FragColor = outcolor;"
   "}";
 
-const gchar *sin_fragment_source =
+const gchar *rgb_to_curve_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D tex;"
+  "uniform sampler2D curve;"
+  "void main () {"
+  "  vec4 color = texture2D (tex, v_texcoord.xy);"
+  "  vec4 outcolor;"
+  "  outcolor.r = texture2D (curve, vec2(color.r, 0.0)).r;"
+  "  outcolor.g = texture2D (curve, vec2(color.g, 0.0)).g;"
+  "  outcolor.b = texture2D (curve, vec2(color.b, 0.0)).b;"
+  "  outcolor.a = color.a;"
+  "  gl_FragColor = outcolor;"
+  "}";
+
+const gchar *sin_fragment_source_opengl =
   "uniform sampler2D tex;"
   "void main () {"
   "  vec4 color = texture2D (tex, vec2(gl_TexCoord[0].st));"
@@ -427,6 +744,35 @@
   "  gl_FragColor = color * mix + luma * (1.0 - mix);"
   "}";
 
+const gchar *sin_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D tex;"
+  "void main () {"
+  "  vec4 color = texture2D (tex, vec2(v_texcoord.xy));"
+  "  float luma = dot(color.rgb, vec3(0.2125, 0.7154, 0.0721));"
+/* calculate hue with the Preucil formula */
+  "  float cosh = color.r - 0.5*(color.g + color.b);"
+/* sqrt(3)/2 = 0.866 */
+  "  float sinh = 0.866*(color.g - color.b);"
+/* hue = atan2 h */
+  "  float sch = (1.0-sinh)*cosh;"
+/* ok this is a little trick I came up because I didn't find any
+ * detailed proof of the Preucil formula. The issue is that tan(h) is
+ * pi-periodic so the smoothstep thing gives both reds (h = 0) and
+ * cyans (h = 180). I don't want to use atan since it requires
+ * branching and doesn't work on i915. So take only the right half of
+ * the circle where cosine is positive */
+/* take a slightly purple color trying to get rid of human skin reds */
+/* tanh = +-1.0 for h = +-45, where yellow=60, magenta=-60 */
+  "  float a = smoothstep (0.3, 1.0, sch);"
+  "  float b = smoothstep (-0.4, -0.1, sinh);"
+  "  float mix = a * b;"
+  "  gl_FragColor = color * mix + luma * (1.0 - mix);"
+  "}";
+
 const gchar *interpolate_fragment_source =
   "uniform sampler2D base;"
   "uniform sampler2D blend;"
@@ -457,4 +803,66 @@
   "gl_FragColor = vec4 (step (0.12, length (savedcolor - currentcolor)));"
   "}";
 
+/* This filter is meant as a demo of gst-plugins-gl + glsl
+   capabilities. So I'm keeping this shader readable enough. If and
+   when this shader will be used in production be careful to hard code
+   kernel into the shader and remove unneeded zero multiplications in
+   the convolution */
+const gchar *conv9_fragment_source_opengl =
+  "uniform sampler2D tex;"
+  "uniform float kernel[9];"
+  "uniform float width, height;"
+  "uniform bool invert;"
+  "void main () {"
+  "  float w = 1.0 / width;"
+  "  float h = 1.0 / height;"
+  "  vec2 texturecoord[9];"
+  "  texturecoord[4] = gl_TexCoord[0].st;"                /*  0  0 */
+  "  texturecoord[5] = texturecoord[4] + vec2(w,   0.0);" /*  1  0 */
+  "  texturecoord[2] = texturecoord[5] - vec2(0.0, h);"   /*  1 -1 */
+  "  texturecoord[1] = texturecoord[2] - vec2(w,   0.0);" /*  0 -1 */
+  "  texturecoord[0] = texturecoord[1] - vec2(w,   0.0);" /* -1 -1 */
+  "  texturecoord[3] = texturecoord[0] + vec2(0.0, h);"   /* -1  0 */
+  "  texturecoord[6] = texturecoord[3] + vec2(0.0, h);"   /* -1  1 */
+  "  texturecoord[7] = texturecoord[6] + vec2(w,   0.0);" /*  0  1 */
+  "  texturecoord[8] = texturecoord[7] + vec2(w,   0.0);" /*  1  1 */
+  "  int i;"
+  "  vec3 sum = vec3 (0.0);"
+  "  for (i = 0; i < 9; i++) { "
+  "    vec4 neighbor = texture2D (tex, texturecoord[i]);"
+  "    sum += neighbor.xyz * kernel[i];"
+  "  }"
+  "  gl_FragColor = vec4 (abs(sum - vec3(float(invert))), 1.0);"
+  "}";
+
+const gchar *conv9_fragment_source_gles2 =
+  "#ifdef GL_ES\n"
+  "precision mediump float;\n"
+  "#endif\n"
+  "varying vec2 v_texcoord;"
+  "uniform sampler2D tex;"
+  "uniform float kernel[9];"
+  "uniform float width, height;"
+  "void main () {"
+  "  float w = 1.0 / width;"
+  "  float h = 1.0 / height;"
+  "  vec2 texturecoord[9];"
+  "  texturecoord[4] = v_texcoord.xy;"                    /*  0  0 */
+  "  texturecoord[5] = texturecoord[4] + vec2(w,   0.0);" /*  1  0 */
+  "  texturecoord[2] = texturecoord[5] - vec2(0.0, h);"   /*  1 -1 */
+  "  texturecoord[1] = texturecoord[2] - vec2(w,   0.0);" /*  0 -1 */
+  "  texturecoord[0] = texturecoord[1] - vec2(w,   0.0);" /* -1 -1 */
+  "  texturecoord[3] = texturecoord[0] + vec2(0.0, h);"   /* -1  0 */
+  "  texturecoord[6] = texturecoord[3] + vec2(0.0, h);"   /* -1  1 */
+  "  texturecoord[7] = texturecoord[6] + vec2(w,   0.0);" /*  0  1 */
+  "  texturecoord[8] = texturecoord[7] + vec2(w,   0.0);" /*  1  1 */
+  "  int i;"
+  "  vec3 sum = vec3 (0.0);"
+  "  for (i = 0; i < 9; i++) { "
+  "    vec4 neighbor = texture2D (tex, texturecoord[i]);"
+  "    sum += neighbor.xyz * kernel[i];"
+  "  }"
+  "  gl_FragColor = vec4 (abs(sum - vec3(float(invert))), 1.0);"
+  "}";
+
 /* *INDENT-ON* */
diff --git a/ext/gl/effects/gstgleffectssources.h b/ext/gl/effects/gstgleffectssources.h
index 76f0b5e..6e41c72 100644
--- a/ext/gl/effects/gstgleffectssources.h
+++ b/ext/gl/effects/gstgleffectssources.h
@@ -21,35 +21,53 @@
 #ifndef __GST_GL_EFFECTS_SOURCES_H__
 #define __GST_GL_EFFECTS_SOURCES_H__
 
-#if GST_GL_HAVE_OPENGL
 extern const gchar *mirror_fragment_source_opengl;
 extern const gchar *squeeze_fragment_source_opengl;
-#endif
+extern const gchar *stretch_fragment_source_opengl;
+extern const gchar *fisheye_fragment_source_opengl;
+extern const gchar *twirl_fragment_source_opengl;
+extern const gchar *bulge_fragment_source_opengl;
+extern const gchar *tunnel_fragment_source_opengl;
+extern const gchar *square_fragment_source_opengl;
+extern const gchar *luma_threshold_fragment_source_opengl;
+extern const gchar *hconv7_fragment_source_opengl;
+extern const gchar *vconv7_fragment_source_opengl;
+extern const gchar *sum_fragment_source_opengl;
+extern const gchar *luma_to_curve_fragment_source_opengl;
+extern const gchar *rgb_to_curve_fragment_source_opengl;
+extern const gchar *sin_fragment_source_opengl;
+extern const gchar *desaturate_fragment_source_opengl;
+extern const gchar *sep_sobel_hconv3_fragment_source_opengl;
+extern const gchar *sep_sobel_vconv3_fragment_source_opengl;
+extern const gchar *sep_sobel_length_fragment_source_opengl;
+extern const gchar *multiply_fragment_source_opengl;
+extern const gchar *conv9_fragment_source_opengl;
 
 extern const gchar *mirror_fragment_source_gles2;
 extern const gchar *squeeze_fragment_source_gles2;
+extern const gchar *stretch_fragment_source_gles2;
+extern const gchar *fisheye_fragment_source_gles2;
+extern const gchar *twirl_fragment_source_gles2;
+extern const gchar *bulge_fragment_source_gles2;
+extern const gchar *tunnel_fragment_source_gles2;
+extern const gchar *square_fragment_source_gles2;
+extern const gchar *luma_threshold_fragment_source_gles2;
+extern const gchar *hconv7_fragment_source_gles2;
+extern const gchar *vconv7_fragment_source_gles2;
+extern const gchar *sum_fragment_source_gles2;
+extern const gchar *luma_to_curve_fragment_source_gles2;
+extern const gchar *rgb_to_curve_fragment_source_gles2;
+extern const gchar *sin_fragment_source_gles2;
+extern const gchar *desaturate_fragment_source_gles2;
+extern const gchar *sep_sobel_hconv3_fragment_source_gles2;
+extern const gchar *sep_sobel_vconv3_fragment_source_gles2;
+extern const gchar *sep_sobel_length_fragment_source_gles2;
+extern const gchar *multiply_fragment_source_gles2;
+extern const gchar *conv9_fragment_source_gles2;
 
-extern const gchar *stretch_fragment_source;
-extern const gchar *tunnel_fragment_source;
-extern const gchar *fisheye_fragment_source;
-extern const gchar *twirl_fragment_source;
-extern const gchar *bulge_fragment_source;
-extern const gchar *square_fragment_source;
-extern const gchar *luma_threshold_fragment_source;
-extern const gchar *sep_sobel_length_fragment_source;
-extern const gchar *desaturate_fragment_source;
-extern const gchar *sep_sobel_hconv3_fragment_source;
-extern const gchar *sep_sobel_vconv3_fragment_source;
-extern const gchar *hconv7_fragment_source;
-extern const gchar *vconv7_fragment_source;
-extern const gchar *sum_fragment_source;
-extern const gchar *luma_to_curve_fragment_source;
-extern const gchar *rgb_to_curve_fragment_source;
-extern const gchar *sin_fragment_source;
 extern const gchar *interpolate_fragment_source;
 extern const gchar *texture_interp_fragment_source;
 extern const gchar *difference_fragment_source;
-extern const gchar *multiply_fragment_source;
 
 void fill_gaussian_kernel (float *kernel, int size, float sigma);
 
diff --git a/ext/gl/effects/gstgleffectstretch.c b/ext/gl/effects/gstgleffectstretch.c
index 206a097..0c645f9 100644
--- a/ext/gl/effects/gstgleffectstretch.c
+++ b/ext/gl/effects/gstgleffectstretch.c
@@ -33,24 +33,18 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "stretch0");
+  shader = gst_gl_effects_get_fragment_shader (effects, "stretch",
+      stretch_fragment_source_gles2, stretch_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "stretch0", shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          stretch_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context, "Failed to initialize stretch shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
+
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
   }
-
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
-
+#endif
   gst_gl_shader_use (shader);
 
   gl->ActiveTexture (GL_TEXTURE0);
@@ -59,9 +53,6 @@
 
   gst_gl_shader_set_uniform_1i (shader, "tex", 0);
 
-  gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f);
-  gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f);
-
   gst_gl_filter_draw_texture (filter, texture, width, height);
 }
 
diff --git a/ext/gl/effects/gstgleffecttunnel.c b/ext/gl/effects/gstgleffecttunnel.c
index b547436..3bacdae 100644
--- a/ext/gl/effects/gstgleffecttunnel.c
+++ b/ext/gl/effects/gstgleffecttunnel.c
@@ -33,23 +33,18 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "tunnel0");
+  shader = gst_gl_effects_get_fragment_shader (effects, "tunnel",
+      tunnel_fragment_source_gles2, tunnel_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "tunnel0", shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          tunnel_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context, "Failed to initialize tunnel shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
@@ -59,9 +54,6 @@
 
   gst_gl_shader_set_uniform_1i (shader, "tex", 0);
 
-  gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f);
-  gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f);
-
   gst_gl_filter_draw_texture (filter, texture, width, height);
 }
 
diff --git a/ext/gl/effects/gstgleffecttwirl.c b/ext/gl/effects/gstgleffecttwirl.c
index 3a9b374..2061c87 100644
--- a/ext/gl/effects/gstgleffecttwirl.c
+++ b/ext/gl/effects/gstgleffecttwirl.c
@@ -33,23 +33,18 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "twirl0");
+  shader = gst_gl_effects_get_fragment_shader (effects, "twirl",
+      twirl_fragment_source_gles2, twirl_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "twirl0", shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          twirl_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context, "Failed to initialize twirl shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
@@ -59,9 +54,6 @@
 
   gst_gl_shader_set_uniform_1i (shader, "tex", 0);
 
-  gst_gl_shader_set_uniform_1f (shader, "width", (gfloat) width / 2.0f);
-  gst_gl_shader_set_uniform_1f (shader, "height", (gfloat) height / 2.0f);
-
   gst_gl_filter_draw_texture (filter, texture, width, height);
 }
 
diff --git a/ext/gl/effects/gstgleffectxray.c b/ext/gl/effects/gstgleffectxray.c
index 79aeca1..5f104df 100644
--- a/ext/gl/effects/gstgleffectxray.c
+++ b/ext/gl/effects/gstgleffectxray.c
@@ -48,28 +48,22 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "xray1");
+  shader = gst_gl_effects_get_fragment_shader (effects, "hconv7",
+      hconv7_fragment_source_gles2, hconv7_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "xray1", shader);
-  }
+  if (!shader)
+    return;
 
   if (!kernel_ready) {
     fill_gaussian_kernel (gauss_kernel, 7, 1.5);
     kernel_ready = TRUE;
   }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          hconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context, "Failed to initialize hconv7 shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
-    return;
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
   }
-
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#endif
 
   gst_gl_shader_use (shader);
 
@@ -80,7 +74,7 @@
 
   gst_gl_shader_set_uniform_1i (shader, "tex", 1);
   gst_gl_shader_set_uniform_1fv (shader, "kernel", 9, gauss_kernel);
-  gst_gl_shader_set_uniform_1f (shader, "width", width);
+  gst_gl_shader_set_uniform_1f (shader, "gauss_width", width);
 
   gst_gl_filter_draw_texture (filter, texture, width, height);
 }
@@ -95,23 +89,18 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "xray2");
+  shader = gst_gl_effects_get_fragment_shader (effects, "vconv7",
+      vconv7_fragment_source_gles2, vconv7_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "xray2", shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          vconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context, "Failed to initialize vconv7 shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
@@ -122,7 +111,7 @@
 
   gst_gl_shader_set_uniform_1i (shader, "tex", 1);
   gst_gl_shader_set_uniform_1fv (shader, "kernel", 9, gauss_kernel);
-  gst_gl_shader_set_uniform_1f (shader, "height", height);
+  gst_gl_shader_set_uniform_1f (shader, "gauss_height", height);
 
   gst_gl_filter_draw_texture (filter, texture, width, height);
 }
@@ -138,24 +127,18 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "xray_desat");
+  shader = gst_gl_effects_get_fragment_shader (effects, "desaturate",
+      desaturate_fragment_source_gles2, desaturate_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "xray_desat", shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          desaturate_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context,
-        "Failed to initialize desaturate shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
@@ -178,25 +161,19 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "xray_sob_hconv");
+  shader = gst_gl_effects_get_fragment_shader (effects, "sobel_hconv3",
+      sep_sobel_hconv3_fragment_source_gles2,
+      sep_sobel_hconv3_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "xray_sob_hconv",
-        shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          sep_sobel_hconv3_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context,
-        "Failed to initialize sobel hvonc3 shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
@@ -221,25 +198,19 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "xray_sob_vconv");
+  shader = gst_gl_effects_get_fragment_shader (effects, "sobel_vconv3",
+      sep_sobel_vconv3_fragment_source_gles2,
+      sep_sobel_vconv3_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "xray_sob_vconv",
-        shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          sep_sobel_vconv3_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context,
-        "Failed to initialize sobel vconv3 shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
@@ -264,25 +235,19 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "xray_sob_len");
+  shader = gst_gl_effects_get_fragment_shader (effects, "sobel_length",
+      sep_sobel_length_fragment_source_gles2,
+      sep_sobel_length_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "xray_sob_len",
-        shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          sep_sobel_length_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context,
-        "Failed to initialize seobel length shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
@@ -308,23 +273,18 @@
   GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
   GstGLFuncs *gl = context->gl_vtable;
 
-  shader = g_hash_table_lookup (effects->shaderstable, "xray4");
+  shader = gst_gl_effects_get_fragment_shader (effects, "multiply",
+      multiply_fragment_source_gles2, multiply_fragment_source_opengl);
 
-  if (!shader) {
-    shader = gst_gl_shader_new (context);
-    g_hash_table_insert (effects->shaderstable, (gchar *) "xray4", shader);
-  }
-
-  if (!gst_gl_shader_compile_and_check (shader,
-          multiply_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
-    gst_gl_context_set_error (context, "Failed to initialize multiply shader");
-    GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
-        ("%s", gst_gl_context_get_error ()), (NULL));
+  if (!shader)
     return;
-  }
 
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
+#if GST_GL_HAVE_OPENGL
+  if (USING_OPENGL (context)) {
+    gl->MatrixMode (GL_PROJECTION);
+    gl->LoadIdentity ();
+  }
+#endif
 
   gst_gl_shader_use (shader);
 
diff --git a/ext/gl/gstglbasemixer.c b/ext/gl/gstglbasemixer.c
index f2eaa2f..0e670e0 100644
--- a/ext/gl/gstglbasemixer.c
+++ b/ext/gl/gstglbasemixer.c
@@ -41,7 +41,6 @@
     GValue * value, GParamSpec * pspec);
 static void gst_gl_base_mixer_pad_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
-static void gst_gl_base_mixer_pad_finalize (GObject * object);
 
 static void gst_gl_base_mixer_set_context (GstElement * element,
     GstContext * context);
@@ -81,20 +80,12 @@
   gobject_class->set_property = gst_gl_base_mixer_pad_set_property;
   gobject_class->get_property = gst_gl_base_mixer_pad_get_property;
 
-  gobject_class->finalize = gst_gl_base_mixer_pad_finalize;
-
   vaggpad_class->set_info = NULL;
   vaggpad_class->prepare_frame = NULL;
   vaggpad_class->clean_frame = NULL;
 }
 
 static void
-gst_gl_base_mixer_pad_finalize (GObject * object)
-{
-  G_OBJECT_CLASS (gst_gl_base_mixer_pad_parent_class)->finalize (object);
-}
-
-static void
 gst_gl_base_mixer_pad_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec)
 {
@@ -256,8 +247,6 @@
     GstBufferPool * pool, GstAllocator * allocator,
     GstAllocationParams * params, GstQuery * query);
 
-static void gst_gl_base_mixer_finalize (GObject * object);
-
 static void
 gst_gl_base_mixer_class_init (GstGLBaseMixerClass * klass)
 {
@@ -275,8 +264,6 @@
 
   g_type_class_add_private (klass, sizeof (GstGLBaseMixerPrivate));
 
-  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_gl_base_mixer_finalize);
-
   gobject_class->get_property = gst_gl_base_mixer_get_property;
   gobject_class->set_property = gst_gl_base_mixer_set_property;
 
@@ -323,19 +310,6 @@
 }
 
 static void
-gst_gl_base_mixer_finalize (GObject * object)
-{
-  GstGLBaseMixer *mix = GST_GL_BASE_MIXER (object);
-
-  if (mix->priv->other_context) {
-    gst_object_unref (mix->priv->other_context);
-    mix->priv->other_context = NULL;
-  }
-
-  G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
 gst_gl_base_mixer_set_context (GstElement * element, GstContext * context)
 {
   GstGLBaseMixer *mix = GST_GL_BASE_MIXER (element);
@@ -493,6 +467,7 @@
   _find_local_gl_context (mix);
 
   if (!mix->context) {
+    GST_OBJECT_LOCK (mix->display);
     do {
       if (mix->context)
         gst_object_unref (mix->context);
@@ -506,6 +481,7 @@
           goto context_error;
       }
     } while (!gst_gl_display_add_context (mix->display, mix->context));
+    GST_OBJECT_UNLOCK (mix->display);
   }
 
   if (mix_class->decide_allocation)
@@ -681,11 +657,6 @@
     mix->priv->pool = NULL;
   }
 
-  if (mix->display) {
-    gst_object_unref (mix->display);
-    mix->display = NULL;
-  }
-
   if (mix->context) {
     gst_object_unref (mix->context);
     mix->context = NULL;
@@ -724,6 +695,17 @@
     return ret;
 
   switch (transition) {
+    case GST_STATE_CHANGE_READY_TO_NULL:
+      if (mix->priv->other_context) {
+        gst_object_unref (mix->priv->other_context);
+        mix->priv->other_context = NULL;
+      }
+
+      if (mix->display) {
+        gst_object_unref (mix->display);
+        mix->display = NULL;
+      }
+      break;
     default:
       break;
   }
diff --git a/ext/gl/gstglcolorconvertelement.c b/ext/gl/gstglcolorconvertelement.c
index a3118f8..833d07e 100644
--- a/ext/gl/gstglcolorconvertelement.c
+++ b/ext/gl/gstglcolorconvertelement.c
@@ -35,7 +35,6 @@
         "glconvertelement", 0, "convert");
     );
 
-static void gst_gl_color_convert_element_finalize (GObject * object);
 static gboolean gst_gl_color_convert_element_set_caps (GstBaseTransform * bt,
     GstCaps * in_caps, GstCaps * out_caps);
 static GstCaps *gst_gl_color_convert_element_transform_caps (GstBaseTransform *
@@ -49,6 +48,8 @@
     GstBuffer * inbuf, GstBuffer ** outbuf);
 static GstFlowReturn gst_gl_color_convert_element_transform (GstBaseTransform *
     bt, GstBuffer * inbuf, GstBuffer * outbuf);
+static GstCaps *gst_gl_color_convert_element_fixate_caps (GstBaseTransform *
+    bt, GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
 
 static GstStaticPadTemplate gst_gl_color_convert_element_src_pad_template =
 GST_STATIC_PAD_TEMPLATE ("src",
@@ -62,6 +63,24 @@
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS (GST_GL_COLOR_CONVERT_VIDEO_CAPS));
 
+static gboolean
+gst_gl_color_convert_element_stop (GstBaseTransform * bt)
+{
+  GstGLColorConvertElement *convert = GST_GL_COLOR_CONVERT_ELEMENT (bt);
+
+  if (convert->convert) {
+    gst_object_unref (convert->convert);
+    convert->convert = NULL;
+  }
+
+  gst_caps_replace (&convert->in_caps, NULL);
+  gst_caps_replace (&convert->out_caps, NULL);
+
+  return
+      GST_BASE_TRANSFORM_CLASS (gst_gl_color_convert_element_parent_class)->stop
+      (bt);
+}
+
 static void
 gst_gl_color_convert_element_class_init (GstGLColorConvertElementClass * klass)
 {
@@ -75,6 +94,8 @@
   bt_class->prepare_output_buffer =
       gst_gl_color_convert_element_prepare_output_buffer;
   bt_class->transform = gst_gl_color_convert_element_transform;
+  bt_class->stop = gst_gl_color_convert_element_stop;
+  bt_class->fixate_caps = gst_gl_color_convert_element_fixate_caps;
 
   bt_class->passthrough_on_same_caps = TRUE;
 
@@ -89,8 +110,6 @@
       "OpenGL color converter", "Filter/Converter/Video",
       "Converts between color spaces using OpenGL shaders",
       "Matthew Waters <matthew@centricular.com>");
-
-  G_OBJECT_CLASS (klass)->finalize = gst_gl_color_convert_element_finalize;
 }
 
 static void
@@ -100,17 +119,6 @@
       TRUE);
 }
 
-static void
-gst_gl_color_convert_element_finalize (GObject * object)
-{
-  GstGLColorConvertElement *convert = GST_GL_COLOR_CONVERT_ELEMENT (object);
-
-  gst_caps_replace (&convert->in_caps, NULL);
-  gst_caps_replace (&convert->out_caps, NULL);
-
-  G_OBJECT_CLASS (gst_gl_color_convert_element_parent_class)->finalize (object);
-}
-
 static gboolean
 gst_gl_color_convert_element_set_caps (GstBaseTransform * bt,
     GstCaps * in_caps, GstCaps * out_caps)
@@ -206,3 +214,23 @@
 {
   return GST_FLOW_OK;
 }
+
+static GstCaps *
+gst_gl_color_convert_element_fixate_caps (GstBaseTransform *
+    bt, GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
+{
+  GstCaps *ret;
+
+  ret =
+      GST_BASE_TRANSFORM_CLASS
+      (gst_gl_color_convert_element_parent_class)->fixate_caps (bt, direction,
+      caps, othercaps);
+
+  if (direction == GST_PAD_SINK) {
+    if (gst_caps_is_subset (caps, ret)) {
+      gst_caps_replace (&ret, caps);
+    }
+  }
+
+  return ret;
+}
diff --git a/ext/gl/gstglcolorscale.c b/ext/gl/gstglcolorscale.c
index fa22bf9..a79e524 100644
--- a/ext/gl/gstglcolorscale.c
+++ b/ext/gl/gstglcolorscale.c
@@ -61,7 +61,7 @@
 
 #define DEBUG_INIT \
   GST_DEBUG_CATEGORY_INIT (gst_gl_colorscale_debug, "glcolorscale", 0, "glcolorscale element");
-
+#define gst_gl_colorscale_parent_class parent_class
 G_DEFINE_TYPE_WITH_CODE (GstGLColorscale, gst_gl_colorscale,
     GST_TYPE_GL_FILTER, DEBUG_INIT);
 
@@ -71,7 +71,7 @@
     GValue * value, GParamSpec * pspec);
 
 static gboolean gst_gl_colorscale_gen_gl_resources (GstGLFilter * filter);
-static void gst_gl_colorscale_del_gl_resources (GstGLFilter * filter);
+static gboolean gst_gl_colorscale_del_gl_resources (GstBaseTransform * trans);
 
 static gboolean gst_gl_colorscale_filter_texture (GstGLFilter * filter,
     guint in_tex, guint out_tex);
@@ -97,12 +97,13 @@
       "Filter/Effect/Video", "Colorspace converter and video scaler",
       "Julien Isorce <julien.isorce@gmail.com>");
 
-  filter_class->onInitFBO =
+  filter_class->init_fbo =
       GST_DEBUG_FUNCPTR (gst_gl_colorscale_gen_gl_resources);
-  filter_class->onStop = GST_DEBUG_FUNCPTR (gst_gl_colorscale_del_gl_resources);
 
   filter_class->filter_texture = gst_gl_colorscale_filter_texture;
 
+  basetransform_class->stop =
+      GST_DEBUG_FUNCPTR (gst_gl_colorscale_del_gl_resources);
   basetransform_class->passthrough_on_same_caps = TRUE;
   GST_GL_BASE_FILTER_CLASS (klass)->supported_gl_api =
       GST_GL_API_OPENGL | GST_GL_API_OPENGL3 | GST_GL_API_GLES2;
@@ -173,16 +174,18 @@
   return TRUE;
 }
 
-static void
-gst_gl_colorscale_del_gl_resources (GstGLFilter * filter)
+static gboolean
+gst_gl_colorscale_del_gl_resources (GstBaseTransform * trans)
 {
-  GstGLColorscale *colorscale = GST_GL_COLORSCALE (filter);
+  GstGLColorscale *colorscale = GST_GL_COLORSCALE (trans);
 
   if (colorscale->shader) {
-    gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
+    gst_gl_context_del_shader (GST_GL_BASE_FILTER (trans)->context,
         colorscale->shader);
     colorscale->shader = NULL;
   }
+
+  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
 }
 
 static gboolean
diff --git a/ext/gl/gstgldeinterlace.c b/ext/gl/gstgldeinterlace.c
index bf969f2..ce66666 100644
--- a/ext/gl/gstgldeinterlace.c
+++ b/ext/gl/gstgldeinterlace.c
@@ -48,7 +48,7 @@
 
 #define DEBUG_INIT \
   GST_DEBUG_CATEGORY_INIT (gst_gl_deinterlace_debug, "gldeinterlace", 0, "gldeinterlace element");
-
+#define gst_gl_deinterlace_parent_class parent_class
 G_DEFINE_TYPE_WITH_CODE (GstGLDeinterlace, gst_gl_deinterlace,
     GST_TYPE_GL_FILTER, DEBUG_INIT);
 
@@ -57,7 +57,7 @@
 static void gst_gl_deinterlace_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 
-static void gst_gl_deinterlace_reset (GstGLFilter * filter);
+static gboolean gst_gl_deinterlace_reset (GstBaseTransform * trans);
 static gboolean gst_gl_deinterlace_init_shader (GstGLFilter * filter);
 static gboolean gst_gl_deinterlace_filter (GstGLFilter * filter,
     GstBuffer * inbuf, GstBuffer * outbuf);
@@ -163,11 +163,12 @@
       "Deinterlacing based on fragment shaders",
       "Julien Isorce <julien.isorce@mail.com>");
 
+  GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_deinterlace_reset;
+
   GST_GL_FILTER_CLASS (klass)->filter = gst_gl_deinterlace_filter;
   GST_GL_FILTER_CLASS (klass)->filter_texture =
       gst_gl_deinterlace_filter_texture;
-  GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_deinterlace_init_shader;
-  GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_deinterlace_reset;
+  GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_deinterlace_init_shader;
 
   GST_GL_BASE_FILTER_CLASS (klass)->supported_gl_api = GST_GL_API_OPENGL;
 }
@@ -180,18 +181,20 @@
   filter->prev_tex = 0;
 }
 
-static void
-gst_gl_deinterlace_reset (GstGLFilter * filter)
+static gboolean
+gst_gl_deinterlace_reset (GstBaseTransform * trans)
 {
-  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter);
+  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (trans);
 
   gst_buffer_replace (&deinterlace_filter->prev_buffer, NULL);
 
   //blocking call, wait the opengl thread has destroyed the shader
   if (deinterlace_filter->shader)
-    gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
+    gst_gl_context_del_shader (GST_GL_BASE_FILTER (trans)->context,
         deinterlace_filter->shader);
   deinterlace_filter->shader = NULL;
+
+  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
 }
 
 static void
diff --git a/ext/gl/gstgldifferencematte.c b/ext/gl/gstgldifferencematte.c
index ce1b513..4f0a8f6 100644
--- a/ext/gl/gstgldifferencematte.c
+++ b/ext/gl/gstgldifferencematte.c
@@ -61,9 +61,6 @@
 static void gst_gl_differencematte_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 
-static void gst_gl_differencematte_init_resources (GstGLFilter * filter);
-static void gst_gl_differencematte_reset_resources (GstGLFilter * filter);
-
 static gboolean gst_gl_differencematte_filter_texture (GstGLFilter * filter,
     guint in_tex, guint out_tex);
 
@@ -109,7 +106,7 @@
   }
 
   if (!gst_gl_shader_compile_and_check (differencematte->shader[1],
-          hconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
+          hconv7_fragment_source_opengl, GST_GL_SHADER_FRAGMENT_SOURCE)) {
     gst_gl_context_set_error (GST_GL_BASE_FILTER (differencematte)->context,
         "Failed to initialize hconv7 shader");
     GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND,
@@ -118,7 +115,7 @@
   }
 
   if (!gst_gl_shader_compile_and_check (differencematte->shader[2],
-          vconv7_fragment_source, GST_GL_SHADER_FRAGMENT_SOURCE)) {
+          vconv7_fragment_source_opengl, GST_GL_SHADER_FRAGMENT_SOURCE)) {
     gst_gl_context_set_error (GST_GL_BASE_FILTER (differencematte)->context,
         "Failed to initialize vconv7 shader");
     GST_ELEMENT_ERROR (differencematte, RESOURCE, NOT_FOUND,
@@ -180,8 +177,6 @@
       gst_gl_differencematte_init_gl_resources;
   GST_GL_FILTER_CLASS (klass)->display_reset_cb =
       gst_gl_differencematte_reset_gl_resources;
-  GST_GL_FILTER_CLASS (klass)->onStart = gst_gl_differencematte_init_resources;
-  GST_GL_FILTER_CLASS (klass)->onStop = gst_gl_differencematte_reset_resources;
 
   g_object_class_install_property (gobject_class,
       PROP_LOCATION,
@@ -215,12 +210,6 @@
 }
 
 static void
-gst_gl_differencematte_reset_resources (GstGLFilter * filter)
-{
-//  GstGLDifferenceMatte* differencematte = GST_GL_DIFFERENCEMATTE(filter);
-}
-
-static void
 gst_gl_differencematte_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
 {
@@ -256,12 +245,6 @@
 }
 
 static void
-gst_gl_differencematte_init_resources (GstGLFilter * filter)
-{
-//  GstGLDifferenceMatte *differencematte = GST_GL_DIFFERENCEMATTE (filter);
-}
-
-static void
 gst_gl_differencematte_save_texture (gint width, gint height, guint texture,
     gpointer stuff)
 {
diff --git a/ext/gl/gstgldownloadelement.c b/ext/gl/gstgldownloadelement.c
index dfe0856..78afff5 100644
--- a/ext/gl/gstgldownloadelement.c
+++ b/ext/gl/gstgldownloadelement.c
@@ -34,7 +34,6 @@
     GST_DEBUG_CATEGORY_INIT (gst_gl_download_element_debug, "gldownloadelement",
         0, "download element");
     );
-static void gst_gl_download_element_finalize (GObject * object);
 
 static gboolean gst_gl_download_element_get_unit_size (GstBaseTransform * trans,
     GstCaps * caps, gsize * size);
@@ -82,9 +81,7 @@
 
   gst_element_class_set_metadata (element_class,
       "OpenGL uploader", "Filter/Video",
-      "Uploads data into OpenGL", "Matthew Waters <matthew@centricular.com>");
-
-  G_OBJECT_CLASS (klass)->finalize = gst_gl_download_element_finalize;
+      "Downloads data from OpenGL", "Matthew Waters <matthew@centricular.com>");
 }
 
 static void
@@ -94,12 +91,6 @@
       TRUE);
 }
 
-static void
-gst_gl_download_element_finalize (GObject * object)
-{
-  G_OBJECT_CLASS (gst_gl_download_element_parent_class)->finalize (object);
-}
-
 static gboolean
 gst_gl_download_element_set_caps (GstBaseTransform * bt, GstCaps * in_caps,
     GstCaps * out_caps)
diff --git a/ext/gl/gstgleffects.c b/ext/gl/gstgleffects.c
index a85e624..02878d2 100644
--- a/ext/gl/gstgleffects.c
+++ b/ext/gl/gstgleffects.c
@@ -39,19 +39,21 @@
 #include <gst/gl/gstglconfig.h>
 #include "gstgleffects.h"
 
-#define GST_TYPE_GL_EFFECTS            (gst_gl_effects_get_type())
-#define GST_GL_EFFECTS(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_GL_EFFECTS,GstGLEffects))
-#define GST_IS_GL_EFFECTS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_GL_EFFECTS))
-#define GST_GL_EFFECTS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass) , GST_TYPE_GL_EFFECTS,GstGLEffectsClass))
-#define GST_IS_GL_EFFECTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) , GST_TYPE_GL_EFFECTS))
-#define GST_GL_EFFECTS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj) , GST_TYPE_GL_EFFECTS,GstGLEffectsClass))
-
 #define GST_CAT_DEFAULT gst_gl_effects_debug
 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
 
+enum
+{
+  PROP_0 = 0x0,
+  PROP_EFFECT = 0x1 << 1,
+  PROP_HSWAP = 0x1 << 2,
+  PROP_INVERT = 0x1 << 3
+};
+
 #define DEBUG_INIT \
   GST_DEBUG_CATEGORY_INIT (gst_gl_effects_debug, "gleffects", 0, "gleffects element");
 
+#define gst_gl_effects_parent_class parent_class
 G_DEFINE_TYPE_WITH_CODE (GstGLEffects, gst_gl_effects, GST_TYPE_GL_FILTER,
     DEBUG_INIT);
 
@@ -60,8 +62,8 @@
 static void gst_gl_effects_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-static void gst_gl_effects_init_resources (GstGLFilter * filter);
-static void gst_gl_effects_reset_resources (GstGLFilter * filter);
+static gboolean gst_gl_effects_init_resources (GstBaseTransform * trans);
+static gboolean gst_gl_effects_reset_resources (GstBaseTransform * trans);
 
 static gboolean gst_gl_effects_on_init_gl_context (GstGLFilter * filter);
 
@@ -70,6 +72,8 @@
 
 static gboolean gst_gl_effects_filter_texture (GstGLFilter * filter,
     guint in_tex, guint out_tex);
+static gboolean gst_gl_effects_filters_is_property_supported (const
+    GstGLEffectsFilterDescriptor *, gint property);
 
 /* dont' forget to edit the following when a new effect is added */
 typedef enum
@@ -90,24 +94,24 @@
   GST_GL_EFFECT_XRAY,
   GST_GL_EFFECT_SIN,
   GST_GL_EFFECT_GLOW,
+  GST_GL_EFFECT_SOBEL,
+  GST_GL_EFFECT_BLUR,
+  GST_GL_EFFECT_LAPLACIAN,
   GST_GL_N_EFFECTS
 } GstGLEffectsEffect;
 
-#define GST_TYPE_GL_EFFECTS_EFFECT (gst_gl_effects_effect_get_type ())
-static GType
-gst_gl_effects_effect_get_type (void)
+static const GEnumValue *
+gst_gl_effects_get_effects (void)
 {
-  static GType gl_effects_effect_type = 0;
   static const GEnumValue effect_types[] = {
     {GST_GL_EFFECT_IDENTITY, "Do nothing Effect", "identity"},
     {GST_GL_EFFECT_MIRROR, "Mirror Effect", "mirror"},
     {GST_GL_EFFECT_SQUEEZE, "Squeeze Effect", "squeeze"},
-#if GST_GL_HAVE_OPENGL
     {GST_GL_EFFECT_STRETCH, "Stretch Effect", "stretch"},
+    {GST_GL_EFFECT_TUNNEL, "Light Tunnel Effect", "tunnel"},
     {GST_GL_EFFECT_FISHEYE, "FishEye Effect", "fisheye"},
     {GST_GL_EFFECT_TWIRL, "Twirl Effect", "twirl"},
     {GST_GL_EFFECT_BULGE, "Bulge Effect", "bulge"},
-    {GST_GL_EFFECT_TUNNEL, "Light Tunnel Effect", "tunnel"},
     {GST_GL_EFFECT_SQUARE, "Square Effect", "square"},
     {GST_GL_EFFECT_HEAT, "Heat Signature Effect", "heat"},
     {GST_GL_EFFECT_SEPIA, "Sepia Toning Effect", "sepia"},
@@ -116,13 +120,23 @@
     {GST_GL_EFFECT_XRAY, "Glowing negative effect", "xray"},
     {GST_GL_EFFECT_SIN, "All Grey but Red Effect", "sin"},
     {GST_GL_EFFECT_GLOW, "Glow Lighting Effect", "glow"},
-#endif
+    {GST_GL_EFFECT_SOBEL, "Sobel edge detection Effect", "sobel"},
+    {GST_GL_EFFECT_BLUR, "Blur with 9x9 separable convolution Effect", "blur"},
+    {GST_GL_EFFECT_LAPLACIAN, "Laplacian Convolution Demo Effect", "laplacian"},
     {0, NULL, NULL}
   };
+  return effect_types;
+}
 
+#define GST_TYPE_GL_EFFECTS_EFFECT (gst_gl_effects_effect_get_type ())
+static GType
+gst_gl_effects_effect_get_type (void)
+{
+  static GType gl_effects_effect_type = 0;
   if (!gl_effects_effect_type) {
     gl_effects_effect_type =
-        g_enum_register_static ("GstGLEffectsEffect", effect_types);
+        g_enum_register_static ("GstGLEffectsEffect",
+        gst_gl_effects_get_effects ());
   }
   return gl_effects_effect_type;
 }
@@ -131,7 +145,6 @@
 gst_gl_effects_set_effect (GstGLEffects * effects, gint effect_type)
 {
   GstGLBaseFilterClass *filter_class = GST_GL_BASE_FILTER_GET_CLASS (effects);
-  GstGLContext *context = GST_GL_BASE_FILTER (effects)->context;
 
   switch (effect_type) {
     case GST_GL_EFFECT_IDENTITY:
@@ -152,78 +165,106 @@
           GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
       effects->current_effect = effect_type;
       break;
-  }
-
-  if (context
-      && (gst_gl_context_get_gl_api (context) & GST_GL_API_OPENGL) ==
-      GST_GL_API_NONE) {
-    GST_ELEMENT_WARNING (effects, RESOURCE, SETTINGS, ("%s",
-            "cannot change effect type"), ("%s",
-            "the current OpenGL context does not support the GL API required"));
-    return;
-  }
-#if GST_GL_HAVE_OPENGL
-  switch (effect_type) {
-    case GST_GL_EFFECT_IDENTITY:
-    case GST_GL_EFFECT_MIRROR:
-    case GST_GL_EFFECT_SQUEEZE:
-      break;
     case GST_GL_EFFECT_STRETCH:
       effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_stretch;
-      filter_class->supported_gl_api = GST_GL_API_OPENGL;
+      filter_class->supported_gl_api =
+          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+      effects->current_effect = effect_type;
       break;
     case GST_GL_EFFECT_TUNNEL:
       effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_tunnel;
-      filter_class->supported_gl_api = GST_GL_API_OPENGL;
+      filter_class->supported_gl_api =
+          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+      effects->current_effect = effect_type;
       break;
     case GST_GL_EFFECT_FISHEYE:
       effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_fisheye;
-      filter_class->supported_gl_api = GST_GL_API_OPENGL;
+      filter_class->supported_gl_api =
+          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+      effects->current_effect = effect_type;
       break;
     case GST_GL_EFFECT_TWIRL:
       effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_twirl;
-      filter_class->supported_gl_api = GST_GL_API_OPENGL;
+      filter_class->supported_gl_api =
+          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+      effects->current_effect = effect_type;
       break;
     case GST_GL_EFFECT_BULGE:
       effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_bulge;
-      filter_class->supported_gl_api = GST_GL_API_OPENGL;
+      filter_class->supported_gl_api =
+          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+      effects->current_effect = effect_type;
       break;
     case GST_GL_EFFECT_SQUARE:
       effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_square;
-      filter_class->supported_gl_api = GST_GL_API_OPENGL;
+      filter_class->supported_gl_api =
+          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+      effects->current_effect = effect_type;
       break;
     case GST_GL_EFFECT_HEAT:
       effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_heat;
-      filter_class->supported_gl_api = GST_GL_API_OPENGL;
+      filter_class->supported_gl_api =
+          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+      effects->current_effect = effect_type;
       break;
     case GST_GL_EFFECT_SEPIA:
       effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_sepia;
-      filter_class->supported_gl_api = GST_GL_API_OPENGL;
+      filter_class->supported_gl_api =
+          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+      effects->current_effect = effect_type;
       break;
     case GST_GL_EFFECT_XPRO:
       effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_xpro;
-      filter_class->supported_gl_api = GST_GL_API_OPENGL;
+      filter_class->supported_gl_api =
+          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+      effects->current_effect = effect_type;
       break;
     case GST_GL_EFFECT_LUMA_XPRO:
       effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_luma_xpro;
-      filter_class->supported_gl_api = GST_GL_API_OPENGL;
-      break;
-    case GST_GL_EFFECT_XRAY:
-      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_xray;
-      filter_class->supported_gl_api = GST_GL_API_OPENGL;
+      filter_class->supported_gl_api =
+          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+      effects->current_effect = effect_type;
       break;
     case GST_GL_EFFECT_SIN:
       effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_sin;
-      filter_class->supported_gl_api = GST_GL_API_OPENGL;
+      filter_class->supported_gl_api =
+          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+      effects->current_effect = effect_type;
+      break;
+    case GST_GL_EFFECT_XRAY:
+      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_sin;
+      filter_class->supported_gl_api =
+          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+      effects->current_effect = effect_type;
       break;
     case GST_GL_EFFECT_GLOW:
       effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_glow;
-      filter_class->supported_gl_api = GST_GL_API_OPENGL;
+      filter_class->supported_gl_api =
+          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+      effects->current_effect = effect_type;
+      break;
+    case GST_GL_EFFECT_SOBEL:
+      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_sobel;
+      filter_class->supported_gl_api =
+          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+      effects->current_effect = effect_type;
+      break;
+    case GST_GL_EFFECT_BLUR:
+      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_blur;
+      filter_class->supported_gl_api =
+          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+      effects->current_effect = effect_type;
+      break;
+    case GST_GL_EFFECT_LAPLACIAN:
+      effects->effect = (GstGLEffectProcessFunc) gst_gl_effects_laplacian;
+      filter_class->supported_gl_api =
+          GST_GL_API_GLES2 | GST_GL_API_OPENGL | GST_GL_API_OPENGL3;
+      effects->current_effect = effect_type;
       break;
     default:
       g_assert_not_reached ();
   }
-#endif
+
   effects->current_effect = effect_type;
 }
 
@@ -276,37 +317,19 @@
 static void
 gst_gl_effects_class_init (GstGLEffectsClass * klass)
 {
-  GObjectClass *gobject_class;
-  GstElementClass *element_class;
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 
-  gobject_class = (GObjectClass *) klass;
-  element_class = GST_ELEMENT_CLASS (klass);
-
-  gobject_class->set_property = gst_gl_effects_set_property;
-  gobject_class->get_property = gst_gl_effects_get_property;
+  GST_BASE_TRANSFORM_CLASS (klass)->start = gst_gl_effects_init_resources;
+  GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_effects_reset_resources;
 
   GST_GL_FILTER_CLASS (klass)->filter_texture = gst_gl_effects_filter_texture;
   GST_GL_FILTER_CLASS (klass)->display_init_cb =
       gst_gl_effects_init_gl_resources;
   GST_GL_FILTER_CLASS (klass)->display_reset_cb =
       gst_gl_effects_reset_gl_resources;
-  GST_GL_FILTER_CLASS (klass)->onStart = gst_gl_effects_init_resources;
-  GST_GL_FILTER_CLASS (klass)->onStop = gst_gl_effects_reset_resources;
-  GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_effects_on_init_gl_context;
+  GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_effects_on_init_gl_context;
 
-  g_object_class_install_property (gobject_class,
-      PROP_EFFECT,
-      g_param_spec_enum ("effect",
-          "Effect",
-          "Select which effect apply to GL video texture",
-          GST_TYPE_GL_EFFECTS_EFFECT,
-          GST_GL_EFFECT_IDENTITY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class,
-      PROP_HSWAP,
-      g_param_spec_boolean ("hswap",
-          "Horizontal Swap",
-          "Switch video texture left to right, useful with webcams",
-          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  klass->filter_descriptor = NULL;
 
   gst_element_class_set_metadata (element_class,
       "Gstreamer OpenGL Effects", "Filter/Effect/Video",
@@ -318,6 +341,46 @@
 }
 
 static void
+gst_gl_effects_filter_class_init (GstGLEffectsClass * klass,
+    const GstGLEffectsFilterDescriptor * filter_descriptor)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  klass->filter_descriptor = filter_descriptor;
+
+  gobject_class->set_property = gst_gl_effects_set_property;
+  gobject_class->get_property = gst_gl_effects_get_property;
+
+  /* if filterDescriptor is null it's a generic gleffects */
+  if (!filter_descriptor) {
+    g_object_class_install_property (gobject_class,
+        PROP_EFFECT,
+        g_param_spec_enum ("effect",
+            "Effect",
+            "Select which effect apply to GL video texture",
+            GST_TYPE_GL_EFFECTS_EFFECT,
+            GST_GL_EFFECT_IDENTITY,
+            G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  }
+
+  g_object_class_install_property (gobject_class,
+      PROP_HSWAP,
+      g_param_spec_boolean ("hswap",
+          "Horizontal Swap",
+          "Switch video texture left to right, useful with webcams",
+          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /* FIXME: make it work on every effect */
+  if (gst_gl_effects_filters_is_property_supported (filter_descriptor,
+          PROP_INVERT)) {
+    g_object_class_install_property (gobject_class, PROP_INVERT,
+        g_param_spec_boolean ("invert", "Invert the colors for sobel effect",
+            "Invert colors to get dark edges on bright background when using sobel effect",
+            FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  }
+}
+
+static void
 set_horizontal_swap (GstGLContext * context, gpointer data)
 {
 #if GST_GL_HAVE_OPENGL
@@ -338,8 +401,16 @@
 static void
 gst_gl_effects_init (GstGLEffects * effects)
 {
-  effects->effect = gst_gl_effects_identity;
   effects->horizontal_swap = FALSE;
+  effects->invert = FALSE;
+  effects->effect = gst_gl_effects_identity;
+}
+
+static void
+gst_gl_effects_filter_init (GstGLEffects * effects)
+{
+  gst_gl_effects_set_effect (effects,
+      GST_GL_EFFECTS_GET_CLASS (effects)->filter_descriptor->effect);
 }
 
 static void
@@ -354,20 +425,22 @@
   value = NULL;
 }
 
-static void
-gst_gl_effects_reset_resources (GstGLFilter * filter)
+static gboolean
+gst_gl_effects_reset_resources (GstBaseTransform * trans)
 {
-  GstGLEffects *effects = GST_GL_EFFECTS (filter);
+  GstGLEffects *effects = GST_GL_EFFECTS (trans);
 
   /* release shaders in the gl thread */
   g_hash_table_foreach (effects->shaderstable, gst_gl_effects_ghash_func_clean,
-      filter);
+      effects);
 
   /* clean the htable without calling values destructors
    * because shaders have been released in the glthread
    * through the foreach func */
   g_hash_table_unref (effects->shaderstable);
   effects->shaderstable = NULL;
+
+  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
 }
 
 static void
@@ -383,6 +456,9 @@
     case PROP_HSWAP:
       effects->horizontal_swap = g_value_get_boolean (value);
       break;
+    case PROP_INVERT:
+      effects->invert = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -402,16 +478,19 @@
     case PROP_HSWAP:
       g_value_set_boolean (value, effects->horizontal_swap);
       break;
+    case PROP_INVERT:
+      g_value_set_boolean (value, effects->invert);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
 }
 
-static void
-gst_gl_effects_init_resources (GstGLFilter * filter)
+static gboolean
+gst_gl_effects_init_resources (GstBaseTransform * trans)
 {
-  GstGLEffects *effects = GST_GL_EFFECTS (filter);
+  GstGLEffects *effects = GST_GL_EFFECTS (trans);
   gint i;
 
   effects->shaderstable = g_hash_table_new (g_str_hash, g_str_equal);
@@ -422,6 +501,8 @@
   for (i = 0; i < GST_GL_EFFECTS_N_CURVES; i++) {
     effects->curve[i] = 0;
   }
+
+  return GST_BASE_TRANSFORM_CLASS (parent_class)->start (trans);
 }
 
 static gboolean
@@ -447,3 +528,150 @@
 
   return TRUE;
 }
+
+GstGLShader *
+gst_gl_effects_get_fragment_shader (GstGLEffects * effects,
+    const gchar * shader_name, const gchar * shader_source_gles2,
+    const gchar * shader_source_opengl)
+{
+  GstGLShader *shader;
+  GstGLFilter *filter = GST_GL_FILTER (effects);
+  GstGLContext *context = GST_GL_BASE_FILTER (filter)->context;
+
+  shader = g_hash_table_lookup (effects->shaderstable, shader_name);
+
+  if (!shader) {
+    shader = gst_gl_shader_new (context);
+    g_hash_table_insert (effects->shaderstable, (gchar *) shader_name, shader);
+
+    if (USING_GLES2 (context) || USING_OPENGL3 (context)) {
+      if (!gst_gl_shader_compile_with_default_v_and_check (shader,
+              shader_source_gles2, &filter->draw_attr_position_loc,
+              &filter->draw_attr_texture_loc)) {
+        /* gst gl context error is already set */
+        GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND,
+            ("Failed to initialize %s shader, %s",
+                shader_name, gst_gl_context_get_error ()), (NULL));
+        return NULL;
+      }
+    }
+#if GST_GL_HAVE_OPENGL
+    if (!gst_gl_shader_compile_and_check (shader,
+            shader_source_opengl, GST_GL_SHADER_FRAGMENT_SOURCE)) {
+      gst_gl_context_set_error (context, "Failed to initialize %s shader",
+          shader_name);
+      GST_ELEMENT_ERROR (effects, RESOURCE, NOT_FOUND, ("%s",
+              gst_gl_context_get_error ()), (NULL));
+      return NULL;
+    }
+#endif
+  }
+
+  return shader;
+}
+
+static const GstGLEffectsFilterDescriptor *
+gst_gl_effects_filters_supported_properties (void)
+{
+  /* Horizontal swap property is supported by all filters */
+  static const GstGLEffectsFilterDescriptor effects[] = {
+    {GST_GL_EFFECT_SOBEL, PROP_INVERT, NULL},
+    {GST_GL_EFFECT_LAPLACIAN, PROP_INVERT, NULL},
+    {0, 0, NULL}
+  };
+  return effects;
+}
+
+static inline gboolean
+gst_gl_effects_filters_is_property_supported (const GstGLEffectsFilterDescriptor
+    * descriptor, gint property)
+{
+  /* generic filter (NULL descriptor) supports all properties */
+  return !descriptor || (descriptor->supported_properties & property);
+}
+
+static const GstGLEffectsFilterDescriptor *
+gst_gl_effects_filters_descriptors (void)
+{
+  static GstGLEffectsFilterDescriptor *descriptors = NULL;
+  if (!descriptors) {
+    const GEnumValue *effect = gst_gl_effects_get_effects ();
+    guint n_filters = 0;
+    for (const GEnumValue * e = effect; NULL != e->value_nick; ++e, ++n_filters) {
+    }
+
+    descriptors = g_new0 (GstGLEffectsFilterDescriptor, n_filters + 1);
+    for (guint i = 0; i < n_filters; ++i, ++effect) {
+      descriptors[i].effect = effect->value;
+      descriptors[i].filter_name = effect->value_nick;
+    }
+
+    for (const GstGLEffectsFilterDescriptor * defined =
+        gst_gl_effects_filters_supported_properties ();
+        0 != defined->supported_properties; ++defined) {
+
+      guint i = 0;
+      for (; i < n_filters; ++i) {
+        if (descriptors[i].effect == defined->effect) {
+          descriptors[i].supported_properties = defined->supported_properties;
+          break;
+        }
+      }
+      if (i >= n_filters) {
+        GST_WARNING ("Could not match gstgleffects-%s descriptor",
+            defined->filter_name);
+      }
+    }
+  }
+  return descriptors;
+}
+
+gboolean
+gst_gl_effects_register_filters (GstPlugin * plugin, GstRank rank)
+{
+  static volatile gsize registered = 0;
+
+  if (g_once_init_enter (&registered)) {
+    GTypeInfo info = {
+      sizeof (GstGLEffectsClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) gst_gl_effects_filter_class_init,
+      NULL,
+      NULL,
+      sizeof (GstGLEffects),
+      0,
+      NULL
+    };
+    GType generic_type =
+        g_type_register_static (GST_TYPE_GL_EFFECTS, "GstGLEffectsGeneric",
+        &info, 0);
+
+    if (gst_element_register (plugin, "gleffects", rank, generic_type)) {
+      for (const GstGLEffectsFilterDescriptor * filters =
+          gst_gl_effects_filters_descriptors (); NULL != filters->filter_name;
+          ++filters) {
+        gchar *name = g_strdup_printf ("gleffects_%s", filters->filter_name);
+        GTypeInfo info = {
+          sizeof (GstGLEffectsClass),
+          NULL,
+          NULL,
+          (GClassInitFunc) gst_gl_effects_filter_class_init,
+          NULL,
+          filters,
+          sizeof (GstGLEffects),
+          0,
+          (GInstanceInitFunc) gst_gl_effects_filter_init
+        };
+        GType type =
+            g_type_register_static (GST_TYPE_GL_EFFECTS, name, &info, 0);
+        if (!gst_element_register (plugin, name, rank, type)) {
+          GST_WARNING ("Could not register %s", name);
+        }
+        g_free (name);
+      }
+    }
+    g_once_init_leave (&registered, generic_type);
+  }
+  return registered;
+}
diff --git a/ext/gl/gstgleffects.h b/ext/gl/gstgleffects.h
index 71bec25..3d30067 100644
--- a/ext/gl/gstgleffects.h
+++ b/ext/gl/gstgleffects.h
@@ -26,7 +26,6 @@
 
 G_BEGIN_DECLS
 
-
 #define GST_TYPE_GL_EFFECTS            (gst_gl_effects_get_type())
 #define GST_GL_EFFECTS(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_GL_EFFECTS,GstGLEffects))
 #define GST_IS_GL_EFFECTS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_GL_EFFECTS))
@@ -34,9 +33,21 @@
 #define GST_IS_GL_EFFECTS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) , GST_TYPE_GL_EFFECTS))
 #define GST_GL_EFFECTS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj) , GST_TYPE_GL_EFFECTS,GstGLEffectsClass))
 
+#define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
+#define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
+#define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
+#define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
+#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))
+
 typedef struct _GstGLEffects GstGLEffects;
 typedef struct _GstGLEffectsClass GstGLEffectsClass;
 
+typedef struct {
+  gint effect;
+  guint supported_properties;
+  const gchar *filter_name;
+} GstGLEffectsFilterDescriptor;
+
 typedef void (* GstGLEffectProcessFunc) (GstGLEffects *effects);
 
 #define NEEDED_TEXTURES 5
@@ -66,22 +77,19 @@
   GHashTable *shaderstable;
 
   gboolean horizontal_swap; /* switch left to right */
+  gboolean invert; /* colours */
 };
 
 struct _GstGLEffectsClass
 {
   GstGLFilterClass filter_class;
+  const GstGLEffectsFilterDescriptor *filter_descriptor;
 };
 
-enum
-{
-  PROP_0,
-  PROP_EFFECT,
-  PROP_HSWAP
-};
-
-
 GType gst_gl_effects_get_type (void);
+gboolean gst_gl_effects_register_filters (GstPlugin *, GstRank);
+GstGLShader* gst_gl_effects_get_fragment_shader (GstGLEffects *effects,
+    const gchar * shader_name, const gchar * shader_source_gles2, const gchar * shader_source_opengl);
 
 void gst_gl_effects_identity (GstGLEffects *effects);
 void gst_gl_effects_mirror (GstGLEffects *effects);
@@ -99,6 +107,9 @@
 void gst_gl_effects_luma_xpro (GstGLEffects *effects);
 void gst_gl_effects_sin (GstGLEffects *effects);
 void gst_gl_effects_glow (GstGLEffects *effects);
+void gst_gl_effects_sobel (GstGLEffects *effects);
+void gst_gl_effects_blur (GstGLEffects *effects);
+void gst_gl_effects_laplacian (GstGLEffects *effects);
 
 G_END_DECLS
 
diff --git a/ext/gl/gstglfilterbin.c b/ext/gl/gstglfilterbin.c
index 9bab3d3..a8e703e 100644
--- a/ext/gl/gstglfilterbin.c
+++ b/ext/gl/gstglfilterbin.c
@@ -48,7 +48,6 @@
     GST_TYPE_BIN, GST_DEBUG_CATEGORY_INIT (gst_gl_filter_bin_debug,
         "glfilterbin", 0, "glfilterbin element"););
 
-static void gst_gl_filter_bin_finalize (GObject * object);
 static void gst_gl_filter_bin_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 static void gst_gl_filter_bin_set_property (GObject * object, guint prop_id,
@@ -62,28 +61,25 @@
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS ("video/x-raw(ANY)"));
 
-static GstStaticPadTemplate _sink_pad_template =
-GST_STATIC_PAD_TEMPLATE ("sink",
-    GST_PAD_SINK,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("video/x-raw(ANY)"));
-
 static void
 gst_gl_filter_bin_class_init (GstGLFilterBinClass * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+  GstCaps *upload_caps;
 
   element_class->change_state = gst_gl_filter_bin_change_state;
 
   gobject_class->set_property = gst_gl_filter_bin_set_property;
   gobject_class->get_property = gst_gl_filter_bin_get_property;
-  gobject_class->finalize = gst_gl_filter_bin_finalize;
 
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&_src_pad_template));
+
+  upload_caps = gst_gl_upload_get_input_template_caps ();
   gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&_sink_pad_template));
+      gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, upload_caps));
+  gst_caps_unref (upload_caps);
 
   g_object_class_install_property (gobject_class, PROP_FILTER,
       g_param_spec_object ("filter",
@@ -236,12 +232,6 @@
   }
 }
 
-static void
-gst_gl_filter_bin_finalize (GObject * object)
-{
-  G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
 static GstStateChangeReturn
 gst_gl_filter_bin_change_state (GstElement * element, GstStateChange transition)
 {
diff --git a/ext/gl/gstglfilterblur.c b/ext/gl/gstglfilterblur.c
deleted file mode 100644
index 842a014..0000000
--- a/ext/gl/gstglfilterblur.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@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-glfilterblur
- *
- * Blur with 9x9 separable convolution.
- *
- * <refsect2>
- * <title>Examples</title>
- * |[
- * gst-launch videotestsrc ! glupload ! glfilterblur ! glimagesink
- * ]|
- * FBO (Frame Buffer Object) and GLSL (OpenGL Shading Language) are required.
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gstglfilterblur.h"
-#include "effects/gstgleffectssources.h"
-
-#define GST_CAT_DEFAULT gst_gl_filterblur_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-#define DEBUG_INIT \
-  GST_DEBUG_CATEGORY_INIT (gst_gl_filterblur_debug, "glfilterblur", 0, "glfilterblur element");
-
-G_DEFINE_TYPE_WITH_CODE (GstGLFilterBlur, gst_gl_filterblur,
-    GST_TYPE_GL_FILTER, DEBUG_INIT);
-
-static void gst_gl_filterblur_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-static void gst_gl_filterblur_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-static void gst_gl_filter_filterblur_reset (GstGLFilter * filter);
-
-static gboolean gst_gl_filterblur_init_shader (GstGLFilter * filter);
-static gboolean gst_gl_filterblur_filter_texture (GstGLFilter * filter,
-    guint in_tex, guint out_tex);
-static void gst_gl_filterblur_hcallback (gint width, gint height, guint texture,
-    gpointer stuff);
-static void gst_gl_filterblur_vcallback (gint width, gint height, guint texture,
-    gpointer stuff);
-
-
-static void
-gst_gl_filterblur_init_resources (GstGLFilter * filter)
-{
-  GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter);
-  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
-
-  gl->GenTextures (1, &filterblur->midtexture);
-  gl->BindTexture (GL_TEXTURE_2D, filterblur->midtexture);
-  gl->TexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8,
-      GST_VIDEO_INFO_WIDTH (&filter->out_info),
-      GST_VIDEO_INFO_HEIGHT (&filter->out_info),
-      0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-}
-
-static void
-gst_gl_filterblur_reset_resources (GstGLFilter * filter)
-{
-  GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter);
-  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
-
-  gl->DeleteTextures (1, &filterblur->midtexture);
-}
-
-static void
-gst_gl_filterblur_class_init (GstGLFilterBlurClass * klass)
-{
-  GObjectClass *gobject_class;
-  GstElementClass *element_class;
-
-  gobject_class = (GObjectClass *) klass;
-  element_class = GST_ELEMENT_CLASS (klass);
-
-  gobject_class->set_property = gst_gl_filterblur_set_property;
-  gobject_class->get_property = gst_gl_filterblur_get_property;
-
-  gst_element_class_set_metadata (element_class, "Gstreamer OpenGL Blur",
-      "Filter/Effect/Video", "Blur with 9x9 separable convolution",
-      "Filippo Argiolas <filippo.argiolas@gmail.com>");
-
-  GST_GL_FILTER_CLASS (klass)->filter_texture =
-      gst_gl_filterblur_filter_texture;
-  GST_GL_FILTER_CLASS (klass)->display_init_cb =
-      gst_gl_filterblur_init_resources;
-  GST_GL_FILTER_CLASS (klass)->display_reset_cb =
-      gst_gl_filterblur_reset_resources;
-  GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filterblur_init_shader;
-  GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_filter_filterblur_reset;
-
-  GST_GL_BASE_FILTER_CLASS (klass)->supported_gl_api = GST_GL_API_OPENGL;
-}
-
-static void
-gst_gl_filterblur_init (GstGLFilterBlur * filterblur)
-{
-  filterblur->shader0 = NULL;
-  filterblur->shader1 = NULL;
-  filterblur->midtexture = 0;
-  /* gaussian kernel (well, actually vector), size 9, standard
-   * deviation 3.0 */
-  /* FIXME: eventually make this a runtime property */
-  fill_gaussian_kernel (filterblur->gauss_kernel, 7, 3.0);
-}
-
-static void
-gst_gl_filter_filterblur_reset (GstGLFilter * filter)
-{
-  GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter);
-
-  //blocking call, wait the opengl thread has destroyed the shader
-  if (filterblur->shader0)
-    gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
-        filterblur->shader0);
-  filterblur->shader0 = NULL;
-
-  //blocking call, wait the opengl thread has destroyed the shader
-  if (filterblur->shader1)
-    gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
-        filterblur->shader1);
-  filterblur->shader1 = NULL;
-}
-
-static void
-gst_gl_filterblur_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  /* GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (object); */
-
-  switch (prop_id) {
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_gl_filterblur_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  /* GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (object); */
-
-  switch (prop_id) {
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static gboolean
-gst_gl_filterblur_init_shader (GstGLFilter * filter)
-{
-  GstGLFilterBlur *blur_filter = GST_GL_FILTERBLUR (filter);
-
-  //blocking call, wait the opengl thread has compiled the shader
-  if (!gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0,
-          hconv7_fragment_source, &blur_filter->shader0))
-    return FALSE;
-
-  //blocking call, wait the opengl thread has compiled the shader
-  if (!gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0,
-          vconv7_fragment_source, &blur_filter->shader1))
-    return FALSE;
-
-  return TRUE;
-}
-
-static gboolean
-gst_gl_filterblur_filter_texture (GstGLFilter * filter, guint in_tex,
-    guint out_tex)
-{
-  GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter);
-
-  gst_gl_filter_render_to_target (filter, TRUE, in_tex,
-      filterblur->midtexture, gst_gl_filterblur_hcallback, filterblur);
-
-  gst_gl_filter_render_to_target (filter, FALSE, filterblur->midtexture,
-      out_tex, gst_gl_filterblur_vcallback, filterblur);
-
-  return TRUE;
-}
-
-static void
-gst_gl_filterblur_hcallback (gint width, gint height, guint texture,
-    gpointer stuff)
-{
-  GstGLFilter *filter = GST_GL_FILTER (stuff);
-  GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter);
-  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
-
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
-
-  gst_gl_shader_use (filterblur->shader0);
-
-  gl->ActiveTexture (GL_TEXTURE1);
-  gl->Enable (GL_TEXTURE_2D);
-  gl->BindTexture (GL_TEXTURE_2D, texture);
-  gl->Disable (GL_TEXTURE_2D);
-
-  gst_gl_shader_set_uniform_1i (filterblur->shader0, "tex", 1);
-  gst_gl_shader_set_uniform_1fv (filterblur->shader0, "kernel", 7,
-      filterblur->gauss_kernel);
-  gst_gl_shader_set_uniform_1f (filterblur->shader0, "width", width);
-
-  gst_gl_filter_draw_texture (filter, texture, width, height);
-}
-
-
-static void
-gst_gl_filterblur_vcallback (gint width, gint height, guint texture,
-    gpointer stuff)
-{
-  GstGLFilter *filter = GST_GL_FILTER (stuff);
-  GstGLFilterBlur *filterblur = GST_GL_FILTERBLUR (filter);
-  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
-
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
-
-  gst_gl_shader_use (filterblur->shader1);
-
-  gl->ActiveTexture (GL_TEXTURE1);
-  gl->Enable (GL_TEXTURE_2D);
-  gl->BindTexture (GL_TEXTURE_2D, texture);
-  gl->Disable (GL_TEXTURE_2D);
-
-  gst_gl_shader_set_uniform_1i (filterblur->shader1, "tex", 1);
-  gst_gl_shader_set_uniform_1fv (filterblur->shader1, "kernel", 7,
-      filterblur->gauss_kernel);
-  gst_gl_shader_set_uniform_1f (filterblur->shader1, "height", height);
-
-  gst_gl_filter_draw_texture (filter, texture, width, height);
-}
diff --git a/ext/gl/gstglfilterblur.h b/ext/gl/gstglfilterblur.h
deleted file mode 100644
index 9604d05..0000000
--- a/ext/gl/gstglfilterblur.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@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_GL_FILTERBLUR_H_
-#define _GST_GL_FILTERBLUR_H_
-
-#include <gst/gl/gstglfilter.h>
-
-#define GST_TYPE_GL_FILTERBLUR            (gst_gl_filterblur_get_type())
-#define GST_GL_FILTERBLUR(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_FILTERBLUR,GstGLFilterBlur))
-#define GST_IS_GL_FILTERBLUR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_FILTERBLUR))
-#define GST_GL_FILTERBLUR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_GL_FILTERBLUR,GstGLFilterBlurClass))
-#define GST_IS_GL_FILTERBLUR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_GL_FILTERBLUR))
-#define GST_GL_FILTERBLUR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_GL_FILTERBLUR,GstGLFilterBlurClass))
-
-typedef struct _GstGLFilterBlur GstGLFilterBlur;
-typedef struct _GstGLFilterBlurClass GstGLFilterBlurClass;
-
-struct _GstGLFilterBlur
-{
-  GstGLFilter filter;
-  GstGLShader *shader0;
-  GstGLShader *shader1;
-
-  GLuint midtexture;
-  float gauss_kernel[7];
-};
-
-struct _GstGLFilterBlurClass
-{
-  GstGLFilterClass filter_class;
-};
-
-GType gst_gl_filterblur_get_type (void);
-
-#endif /* _GST_GL_FILTERBLUR_H_ */
diff --git a/ext/gl/gstglfiltercube.c b/ext/gl/gstglfiltercube.c
index 518b295..ad529b3 100644
--- a/ext/gl/gstglfiltercube.c
+++ b/ext/gl/gstglfiltercube.c
@@ -64,7 +64,7 @@
 
 #define DEBUG_INIT \
     GST_DEBUG_CATEGORY_INIT (gst_gl_filter_cube_debug, "glfiltercube", 0, "glfiltercube element");
-
+#define gst_gl_filter_cube_parent_class parent_class
 G_DEFINE_TYPE_WITH_CODE (GstGLFilterCube, gst_gl_filter_cube,
     GST_TYPE_GL_FILTER, DEBUG_INIT);
 
@@ -73,9 +73,10 @@
 static void gst_gl_filter_cube_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
+static gboolean gst_gl_filter_cube_stop (GstBaseTransform * trans);
+
 static gboolean gst_gl_filter_cube_set_caps (GstGLFilter * filter,
     GstCaps * incaps, GstCaps * outcaps);
-static void gst_gl_filter_cube_reset (GstGLFilter * filter);
 static void gst_gl_filter_cube_reset_gl (GstGLFilter * filter);
 static gboolean gst_gl_filter_cube_init_shader (GstGLFilter * filter);
 static void _callback (gpointer stuff);
@@ -138,8 +139,9 @@
   gobject_class->set_property = gst_gl_filter_cube_set_property;
   gobject_class->get_property = gst_gl_filter_cube_get_property;
 
-  GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filter_cube_init_shader;
-  GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_filter_cube_reset;
+  GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_filter_cube_stop;
+
+  GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_filter_cube_init_shader;
   GST_GL_FILTER_CLASS (klass)->display_reset_cb = gst_gl_filter_cube_reset_gl;
   GST_GL_FILTER_CLASS (klass)->set_caps = gst_gl_filter_cube_set_caps;
   GST_GL_FILTER_CLASS (klass)->filter_texture =
@@ -290,18 +292,26 @@
     gl->DeleteBuffers (1, &cube_filter->vertex_buffer);
     cube_filter->vertex_buffer = 0;
   }
+
+  if (cube_filter->shader) {
+    gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
+        cube_filter->shader);
+    cube_filter->shader = NULL;
+  }
 }
 
-static void
-gst_gl_filter_cube_reset (GstGLFilter * filter)
+static gboolean
+gst_gl_filter_cube_stop (GstBaseTransform * trans)
 {
-  GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (filter);
+  GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (trans);
 
   /* blocking call, wait the opengl thread has destroyed the shader */
   if (cube_filter->shader)
-    gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
+    gst_gl_context_del_shader (GST_GL_BASE_FILTER (trans)->context,
         cube_filter->shader);
   cube_filter->shader = NULL;
+
+  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
 }
 
 static gboolean
@@ -309,6 +319,11 @@
 {
   GstGLFilterCube *cube_filter = GST_GL_FILTER_CUBE (filter);
 
+  if (cube_filter->shader) {
+    gst_object_unref (cube_filter->shader);
+    cube_filter->shader = NULL;
+  }
+
   /* blocking call, wait the opengl thread has compiled the shader */
   return gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context,
       cube_v_src, cube_f_src, &cube_filter->shader);
diff --git a/ext/gl/gstglfilterglass.c b/ext/gl/gstglfilterglass.c
index 0fe109a..0709954 100644
--- a/ext/gl/gstglfilterglass.c
+++ b/ext/gl/gstglfilterglass.c
@@ -53,7 +53,7 @@
 
 #define DEBUG_INIT \
   GST_DEBUG_CATEGORY_INIT (gst_gl_filter_glass_debug, "glfilterglass", 0, "glfilterglass element");
-
+#define gst_gl_filter_glass_parent_class parent_class
 G_DEFINE_TYPE_WITH_CODE (GstGLFilterGlass, gst_gl_filter_glass,
     GST_TYPE_GL_FILTER, DEBUG_INIT);
 
@@ -62,7 +62,8 @@
 static void gst_gl_filter_glass_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-static void gst_gl_filter_glass_reset (GstGLFilter * filter);
+static gboolean gst_gl_filter_glass_reset (GstBaseTransform * trans);
+
 static gboolean gst_gl_filter_glass_init_shader (GstGLFilter * filter);
 static gboolean gst_gl_filter_glass_filter_texture (GstGLFilter * filter,
     guint in_tex, guint out_tex);
@@ -160,8 +161,8 @@
 
   GST_GL_FILTER_CLASS (klass)->filter_texture =
       gst_gl_filter_glass_filter_texture;
-  GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filter_glass_init_shader;
-  GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_filter_glass_reset;
+  GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_filter_glass_init_shader;
+  GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_filter_glass_reset;
 
   GST_GL_BASE_FILTER_CLASS (klass)->supported_gl_api = GST_GL_API_OPENGL;
 }
@@ -173,20 +174,22 @@
   filter->timestamp = 0;
 }
 
-static void
-gst_gl_filter_glass_reset (GstGLFilter * filter)
+static gboolean
+gst_gl_filter_glass_reset (GstBaseTransform * trans)
 {
-  GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (filter);
+  GstGLFilterGlass *glass_filter = GST_GL_FILTER_GLASS (trans);
 
   //blocking call, wait the opengl thread has destroyed the shader
   if (glass_filter->shader)
-    gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
+    gst_gl_context_del_shader (GST_GL_BASE_FILTER (trans)->context,
         glass_filter->shader);
   glass_filter->shader = NULL;
   if (glass_filter->passthrough_shader)
-    gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
+    gst_gl_context_del_shader (GST_GL_BASE_FILTER (trans)->context,
         glass_filter->passthrough_shader);
   glass_filter->passthrough_shader = NULL;
+
+  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
 }
 
 static void
diff --git a/ext/gl/gstglfilterlaplacian.c b/ext/gl/gstglfilterlaplacian.c
deleted file mode 100644
index da656bc..0000000
--- a/ext/gl/gstglfilterlaplacian.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2008-2010 Filippo Argiolas <filippo.argiolas@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-glfilterlaplacian
- *
- * Laplacian Convolution Demo Filter.
- *
- * <refsect2>
- * <title>Examples</title>
- * |[
- * gst-launch videotestsrc ! glupload ! glfilterlaplacian ! glimagesink
- * ]|
- * FBO (Frame Buffer Object) and GLSL (OpenGL Shading Language) are required.
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gstglfilterlaplacian.h"
-
-#define GST_CAT_DEFAULT gst_gl_filter_laplacian_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-enum
-{
-  PROP_0
-};
-
-#define DEBUG_INIT \
-  GST_DEBUG_CATEGORY_INIT (gst_gl_filter_laplacian_debug, "glfilterlaplacian", 0, "glfilterlaplacian element");
-
-G_DEFINE_TYPE_WITH_CODE (GstGLFilterLaplacian, gst_gl_filter_laplacian,
-    GST_TYPE_GL_FILTER, DEBUG_INIT);
-
-static void gst_gl_filter_laplacian_set_property (GObject * object,
-    guint prop_id, const GValue * value, GParamSpec * pspec);
-static void gst_gl_filter_laplacian_get_property (GObject * object,
-    guint prop_id, GValue * value, GParamSpec * pspec);
-
-static void gst_gl_filter_laplacian_reset (GstGLFilter * filter);
-static gboolean gst_gl_filter_laplacian_init_shader (GstGLFilter * filter);
-static gboolean gst_gl_filter_laplacian_filter_texture (GstGLFilter * filter,
-    guint in_tex, guint out_tex);
-static void gst_gl_filter_laplacian_callback (gint width, gint height,
-    guint texture, gpointer stuff);
-
-/* *INDENT-OFF* */
-
-/* This filter is meant as a demo of gst-plugins-gl + glsl
-   capabilities. So I'm keeping this shader readable enough. If and
-   when this shader will be used in production be careful to hard code
-   kernel into the shader and remove unneeded zero multiplications in
-   the convolution */
-static const gchar *convolution_fragment_source =
-  "uniform sampler2D tex;"
-  "uniform float kernel[9];"
-  "uniform float width, height;"
-  "void main () {"
-  "  float w = 1.0 / width;"
-  "  float h = 1.0 / height;"
-  "  vec2 texturecoord[9];"
-  "  texturecoord[4] = gl_TexCoord[0].st;"                /*  0  0 */
-  "  texturecoord[5] = texturecoord[4] + vec2(w,   0.0);" /*  1  0 */
-  "  texturecoord[2] = texturecoord[5] - vec2(0.0, h);" /*  1 -1 */
-  "  texturecoord[1] = texturecoord[2] - vec2(w,   0.0);" /*  0 -1 */
-  "  texturecoord[0] = texturecoord[1] - vec2(w,   0.0);" /* -1 -1 */
-  "  texturecoord[3] = texturecoord[0] + vec2(0.0, h);" /* -1  0 */
-  "  texturecoord[6] = texturecoord[3] + vec2(0.0, h);" /* -1  1 */
-  "  texturecoord[7] = texturecoord[6] + vec2(w,   0.0);" /*  0  1 */
-  "  texturecoord[8] = texturecoord[7] + vec2(w,   0.0);" /*  1  1 */
-  "  int i;"
-  "  vec4 sum = vec4 (0.0);"
-  "  for (i = 0; i < 9; i++) { "
-  "    vec4 neighbor = texture2D(tex, texturecoord[i]);"
-  "    sum += neighbor * kernel[i];"
-  "  }"
-  "  gl_FragColor = sum;"
-  "}";
-/* *INDENT-ON* */
-
-static void
-gst_gl_filter_laplacian_class_init (GstGLFilterLaplacianClass * klass)
-{
-  GObjectClass *gobject_class;
-  GstElementClass *element_class;
-
-  gobject_class = (GObjectClass *) klass;
-  element_class = GST_ELEMENT_CLASS (klass);
-
-  gobject_class->set_property = gst_gl_filter_laplacian_set_property;
-  gobject_class->get_property = gst_gl_filter_laplacian_get_property;
-
-  gst_element_class_set_metadata (element_class,
-      "OpenGL laplacian filter", "Filter/Effect/Video",
-      "Laplacian Convolution Demo Filter",
-      "Filippo Argiolas <filippo.argiolas@gmail.com>");
-
-  GST_GL_FILTER_CLASS (klass)->filter_texture =
-      gst_gl_filter_laplacian_filter_texture;
-  GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filter_laplacian_init_shader;
-  GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_filter_laplacian_reset;
-
-  GST_GL_BASE_FILTER_CLASS (klass)->supported_gl_api = GST_GL_API_OPENGL;
-}
-
-static void
-gst_gl_filter_laplacian_init (GstGLFilterLaplacian * filter)
-{
-  filter->shader = NULL;
-}
-
-static void
-gst_gl_filter_laplacian_reset (GstGLFilter * filter)
-{
-  GstGLFilterLaplacian *laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter);
-
-  //blocking call, wait the opengl thread has destroyed the shader
-  if (laplacian_filter->shader)
-    gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
-        laplacian_filter->shader);
-  laplacian_filter->shader = NULL;
-}
-
-static void
-gst_gl_filter_laplacian_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  //GstGLFilterLaplacian *filter = GST_GL_FILTER_LAPLACIAN (object);
-
-  switch (prop_id) {
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_gl_filter_laplacian_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  //GstGLFilterLaplacian *filter = GST_GL_FILTER_LAPLACIAN (object);
-
-  switch (prop_id) {
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static gboolean
-gst_gl_filter_laplacian_init_shader (GstGLFilter * filter)
-{
-  GstGLFilterLaplacian *laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter);
-
-  //blocking call, wait the opengl thread has compiled the shader
-  return gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0,
-      convolution_fragment_source, &laplacian_filter->shader);
-}
-
-static gboolean
-gst_gl_filter_laplacian_filter_texture (GstGLFilter * filter, guint in_tex,
-    guint out_tex)
-{
-  gpointer laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter);
-
-
-  //blocking call, use a FBO
-  gst_gl_filter_render_to_target (filter, TRUE, in_tex, out_tex,
-      gst_gl_filter_laplacian_callback, laplacian_filter);
-
-  return TRUE;
-}
-
-//opengl scene, params: input texture (not the output filter->texture)
-static void
-gst_gl_filter_laplacian_callback (gint width, gint height, guint texture,
-    gpointer stuff)
-{
-  GstGLFilter *filter = GST_GL_FILTER (stuff);
-  GstGLFilterLaplacian *laplacian_filter = GST_GL_FILTER_LAPLACIAN (filter);
-  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
-
-  gfloat kernel[9] = { 0.0, -1.0, 0.0,
-    -1.0, 4.0, -1.0,
-    0.0, -1.0, 0.0
-  };
-
-  gl->MatrixMode (GL_PROJECTION);
-  gl->LoadIdentity ();
-
-  gst_gl_shader_use (laplacian_filter->shader);
-
-  gl->ActiveTexture (GL_TEXTURE0);
-  gl->Enable (GL_TEXTURE_2D);
-  gl->BindTexture (GL_TEXTURE_2D, texture);
-
-  gst_gl_shader_set_uniform_1i (laplacian_filter->shader, "tex", 0);
-  gst_gl_shader_set_uniform_1fv (laplacian_filter->shader, "kernel", 9, kernel);
-  gst_gl_shader_set_uniform_1f (laplacian_filter->shader, "width",
-      (gfloat) width);
-  gst_gl_shader_set_uniform_1f (laplacian_filter->shader, "height",
-      (gfloat) height);
-
-  gst_gl_filter_draw_texture (filter, texture, width, height);
-}
diff --git a/ext/gl/gstglfilterlaplacian.h b/ext/gl/gstglfilterlaplacian.h
deleted file mode 100644
index 90a54e3..0000000
--- a/ext/gl/gstglfilterlaplacian.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* 
- * GStreamer
- * Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@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_GL_FILTERLAPLACIAN_H_
-#define _GST_GL_FILTERLAPLACIAN_H_
-
-#include <gst/gl/gstglfilter.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_GL_FILTER_LAPLACIAN            (gst_gl_filter_laplacian_get_type())
-#define GST_GL_FILTER_LAPLACIAN(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_FILTER_LAPLACIAN,GstGLFilterLaplacian))
-#define GST_IS_GL_FILTER_LAPLACIAN(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_FILTER_LAPLACIAN))
-#define GST_GL_FILTER_LAPLACIAN_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_GL_FILTER_LAPLACIAN,GstGLFilterLaplacianClass))
-#define GST_IS_GL_FILTER_LAPLACIAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_GL_FILTER_LAPLACIAN))
-#define GST_GL_FILTER_LAPLACIAN_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_GL_FILTER_LAPLACIAN,GstGLFilterLaplacianClass))
-
-typedef struct _GstGLFilterLaplacian GstGLFilterLaplacian;
-typedef struct _GstGLFilterLaplacianClass GstGLFilterLaplacianClass;
-
-struct _GstGLFilterLaplacian
-{
-  GstGLFilter filter;
-  GstGLShader *shader;
-};
-
-struct _GstGLFilterLaplacianClass
-{
-  GstGLFilterClass filter_class;
-};
-
-GType gst_gl_filter_laplacian_get_type (void);
-
-G_END_DECLS
-
-#endif /* _GST_GLFILTERLAPLACIAN_H_ */
diff --git a/ext/gl/gstglfiltershader.c b/ext/gl/gstglfiltershader.c
index 91c4cfb..0b96ebb 100644
--- a/ext/gl/gstglfiltershader.c
+++ b/ext/gl/gstglfiltershader.c
@@ -67,7 +67,7 @@
 
 #define DEBUG_INIT \
   GST_DEBUG_CATEGORY_INIT (gst_gl_filtershader_debug, "glshader", 0, "glshader element");
-
+#define gst_gl_filtershader_parent_class parent_class
 G_DEFINE_TYPE_WITH_CODE (GstGLFilterShader, gst_gl_filtershader,
     GST_TYPE_GL_FILTER, DEBUG_INIT);
 
@@ -75,7 +75,7 @@
     const GValue * value, GParamSpec * pspec);
 static void gst_gl_filtershader_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
-static void gst_gl_filter_filtershader_reset (GstGLFilter * filter);
+static gboolean gst_gl_filter_filtershader_reset (GstBaseTransform * trans);
 
 static gboolean gst_gl_filtershader_load_shader (GstGLFilterShader *
     filter_shader, char *filename, char **storage);
@@ -140,6 +140,8 @@
       "OpenGL fragment shader filter", "Filter/Effect",
       "Load GLSL fragment shader from file", "<luc.deschenaux@freesurf.ch>");
 
+  GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_filter_filtershader_reset;
+
   GST_GL_FILTER_CLASS (klass)->filter = gst_gl_filtershader_filter;
   GST_GL_FILTER_CLASS (klass)->filter_texture =
       gst_gl_filtershader_filter_texture;
@@ -147,8 +149,7 @@
       gst_gl_filtershader_init_resources;
   GST_GL_FILTER_CLASS (klass)->display_reset_cb =
       gst_gl_filtershader_reset_resources;
-  GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filtershader_init_shader;
-  GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_filter_filtershader_reset;
+  GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_filtershader_init_shader;
 
   GST_GL_BASE_FILTER_CLASS (klass)->supported_gl_api =
       GST_GL_API_OPENGL | GST_GL_API_GLES2 | GST_GL_API_OPENGL3;
@@ -160,16 +161,18 @@
   filtershader->shader0 = NULL;
 }
 
-static void
-gst_gl_filter_filtershader_reset (GstGLFilter * filter)
+static gboolean
+gst_gl_filter_filtershader_reset (GstBaseTransform * trans)
 {
-  GstGLFilterShader *filtershader = GST_GL_FILTERSHADER (filter);
+  GstGLFilterShader *filtershader = GST_GL_FILTERSHADER (trans);
 
   //blocking call, wait the opengl thread has destroyed the shader
   if (filtershader->shader0)
-    gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
+    gst_gl_context_del_shader (GST_GL_BASE_FILTER (trans)->context,
         filtershader->shader0);
   filtershader->shader0 = NULL;
+
+  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
 }
 
 static void
@@ -186,8 +189,9 @@
         g_free (filtershader->filename);
       }
       if (filtershader->compiled) {
-        //gst_gl_context_del_shader (filtershader->filter.context, filtershader->shader0);
-        gst_gl_filter_filtershader_reset (&filtershader->filter);
+        if (filtershader->shader0)
+          gst_gl_context_del_shader (GST_GL_BASE_FILTER (filtershader)->context,
+              filtershader->shader0);
         filtershader->shader0 = 0;
       }
       filtershader->filename = g_strdup (g_value_get_string (value));
diff --git a/ext/gl/gstglfiltersobel.c b/ext/gl/gstglfiltersobel.c
deleted file mode 100644
index f70b6d2..0000000
--- a/ext/gl/gstglfiltersobel.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2008-2010 Filippo Argiolas <filippo.argiolas@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-glfiltersobel.
- *
- * Sobel Edge Detection.
- *
- * <refsect2>
- * <title>Examples</title>
- * |[
- * gst-launch videotestsrc ! glupload ! glfiltersobel ! glimagesink
- * ]|
- * FBO (Frame Buffer Object) and GLSL (OpenGL Shading Language) are required.
- * </refsect2>
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "gstglfiltersobel.h"
-#include "effects/gstgleffectssources.h"
-
-enum
-{
-  PROP_0,
-  PROP_INVERT
-};
-
-#define GST_CAT_DEFAULT gst_gl_filtersobel_debug
-GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-
-#define DEBUG_INIT \
-  GST_DEBUG_CATEGORY_INIT (gst_gl_filtersobel_debug, "glfiltersobel", 0, "glfiltersobel element");
-
-G_DEFINE_TYPE_WITH_CODE (GstGLFilterSobel, gst_gl_filtersobel,
-    GST_TYPE_GL_FILTER, DEBUG_INIT);
-
-static void gst_gl_filtersobel_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec);
-static void gst_gl_filtersobel_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec);
-static void gst_gl_filter_filtersobel_reset (GstGLFilter * filter);
-
-static gboolean gst_gl_filtersobel_init_shader (GstGLFilter * filter);
-static gboolean gst_gl_filtersobel_filter_texture (GstGLFilter * filter,
-    guint in_tex, guint out_tex);
-
-static void gst_gl_filtersobel_length (gint width, gint height, guint texture,
-    gpointer stuff);
-
-static void
-gst_gl_filtersobel_init_resources (GstGLFilter * filter)
-{
-  GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (filter);
-  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
-  int i;
-
-  for (i = 0; i < 2; i++) {
-    gl->GenTextures (1, &filtersobel->midtexture[i]);
-    gl->BindTexture (GL_TEXTURE_2D, filtersobel->midtexture[i]);
-    gl->TexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8,
-        GST_VIDEO_INFO_WIDTH (&filter->out_info),
-        GST_VIDEO_INFO_HEIGHT (&filter->out_info),
-        0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-    gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-  }
-}
-
-static void
-gst_gl_filtersobel_reset_resources (GstGLFilter * filter)
-{
-  GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (filter);
-  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
-  int i;
-
-  for (i = 0; i < 2; i++) {
-    gl->DeleteTextures (1, &filtersobel->midtexture[i]);
-  }
-}
-
-static void
-gst_gl_filtersobel_class_init (GstGLFilterSobelClass * klass)
-{
-  GObjectClass *gobject_class;
-  GstElementClass *element_class;
-
-  gobject_class = (GObjectClass *) klass;
-  element_class = GST_ELEMENT_CLASS (klass);
-
-  gobject_class->set_property = gst_gl_filtersobel_set_property;
-  gobject_class->get_property = gst_gl_filtersobel_get_property;
-
-  GST_GL_FILTER_CLASS (klass)->filter_texture =
-      gst_gl_filtersobel_filter_texture;
-  GST_GL_FILTER_CLASS (klass)->display_init_cb =
-      gst_gl_filtersobel_init_resources;
-  GST_GL_FILTER_CLASS (klass)->display_reset_cb =
-      gst_gl_filtersobel_reset_resources;
-  GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filtersobel_init_shader;
-  GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_filter_filtersobel_reset;
-
-  g_object_class_install_property (gobject_class,
-      PROP_INVERT,
-      g_param_spec_boolean ("invert",
-          "Invert the colors",
-          "Invert colors to get dark edges on bright background",
-          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  gst_element_class_set_metadata (element_class,
-      "Gstreamer OpenGL Sobel", "Filter/Effect/Video", "Sobel edge detection",
-      "Filippo Argiolas <filippo.argiolas@gmail.com>");
-
-  GST_GL_BASE_FILTER_CLASS (klass)->supported_gl_api = GST_GL_API_OPENGL;
-}
-
-static void
-gst_gl_filtersobel_init (GstGLFilterSobel * filtersobel)
-{
-  int i;
-  filtersobel->hconv = NULL;
-  filtersobel->vconv = NULL;
-  filtersobel->invert = FALSE;
-  for (i = 0; i < 2; i++) {
-    filtersobel->midtexture[i] = 0;
-  }
-}
-
-static void
-gst_gl_filter_filtersobel_reset (GstGLFilter * filter)
-{
-  GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (filter);
-
-  //blocking call, wait the opengl thread has destroyed the shader
-  if (filtersobel->desat)
-    gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
-        filtersobel->desat);
-  filtersobel->desat = NULL;
-
-  if (filtersobel->hconv)
-    gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
-        filtersobel->hconv);
-  filtersobel->hconv = NULL;
-
-  if (filtersobel->vconv)
-    gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
-        filtersobel->vconv);
-  filtersobel->vconv = NULL;
-
-  if (filtersobel->len)
-    gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
-        filtersobel->len);
-  filtersobel->len = NULL;
-}
-
-static void
-gst_gl_filtersobel_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (object);
-
-  switch (prop_id) {
-    case PROP_INVERT:
-      filtersobel->invert = g_value_get_boolean (value);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_gl_filtersobel_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * pspec)
-{
-  GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (object);
-
-  switch (prop_id) {
-    case PROP_INVERT:
-      g_value_set_boolean (value, filtersobel->invert);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static gboolean
-gst_gl_filtersobel_init_shader (GstGLFilter * filter)
-{
-  GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (filter);
-  gboolean ret = TRUE;
-
-  //blocking call, wait the opengl thread has compiled the shader
-  ret =
-      gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0,
-      desaturate_fragment_source, &filtersobel->desat);
-  ret &=
-      gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0,
-      sep_sobel_hconv3_fragment_source, &filtersobel->hconv);
-  ret &=
-      gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0,
-      sep_sobel_vconv3_fragment_source, &filtersobel->vconv);
-  ret &=
-      gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0,
-      sep_sobel_length_fragment_source, &filtersobel->len);
-
-  return ret;
-}
-
-static gboolean
-gst_gl_filtersobel_filter_texture (GstGLFilter * filter, guint in_tex,
-    guint out_tex)
-{
-  GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (filter);
-
-  gst_gl_filter_render_to_target_with_shader (filter, TRUE, in_tex,
-      filtersobel->midtexture[0], filtersobel->desat);
-  gst_gl_filter_render_to_target_with_shader (filter, FALSE,
-      filtersobel->midtexture[0], filtersobel->midtexture[1],
-      filtersobel->hconv);
-  gst_gl_filter_render_to_target_with_shader (filter, FALSE,
-      filtersobel->midtexture[1], filtersobel->midtexture[0],
-      filtersobel->vconv);
-  gst_gl_filter_render_to_target (filter, FALSE, filtersobel->midtexture[0],
-      out_tex, gst_gl_filtersobel_length, filtersobel);
-
-  return TRUE;
-}
-
-static void
-gst_gl_filtersobel_length (gint width, gint height, guint texture,
-    gpointer stuff)
-{
-  GstGLFilter *filter = GST_GL_FILTER (stuff);
-  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
-  GstGLFilterSobel *filtersobel = GST_GL_FILTERSOBEL (filter);
-
-  glMatrixMode (GL_PROJECTION);
-  glLoadIdentity ();
-
-  gst_gl_shader_use (filtersobel->len);
-
-  gl->ActiveTexture (GL_TEXTURE1);
-  gl->Enable (GL_TEXTURE_2D);
-  gl->BindTexture (GL_TEXTURE_2D, texture);
-  gl->Disable (GL_TEXTURE_2D);
-
-  gst_gl_shader_set_uniform_1i (filtersobel->len, "tex", 1);
-  gst_gl_shader_set_uniform_1i (filtersobel->len, "invert",
-      filtersobel->invert);
-
-  gst_gl_filter_draw_texture (filter, texture, width, height);
-}
diff --git a/ext/gl/gstglfiltersobel.h b/ext/gl/gstglfiltersobel.h
deleted file mode 100644
index 3b88baf..0000000
--- a/ext/gl/gstglfiltersobel.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2008 Filippo Argiolas <filippo.argiolas@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_GL_FILTERSOBEL_H_
-#define _GST_GL_FILTERSOBEL_H_
-
-#include <gst/gl/gstglfilter.h>
-
-#define GST_TYPE_GL_FILTERSOBEL            (gst_gl_filtersobel_get_type())
-#define GST_GL_FILTERSOBEL(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_FILTERSOBEL,GstGLFilterSobel))
-#define GST_IS_GL_FILTERSOBEL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_FILTERSOBEL))
-#define GST_GL_FILTERSOBEL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_GL_FILTERSOBEL,GstGLFilterSobelClass))
-#define GST_IS_GL_FILTERSOBEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_GL_FILTERSOBEL))
-#define GST_GL_FILTERSOBEL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_GL_FILTERSOBEL,GstGLFilterSobelClass))
-
-typedef struct _GstGLFilterSobel GstGLFilterSobel;
-typedef struct _GstGLFilterSobelClass GstGLFilterSobelClass;
-
-struct _GstGLFilterSobel
-{
-  GstGLFilter filter;
-  GstGLShader *hconv;
-  GstGLShader *vconv;
-  GstGLShader *len;
-  GstGLShader *desat;
-
-  GLuint midtexture[5];
-
-  gboolean invert;
-};
-
-struct _GstGLFilterSobelClass
-{
-  GstGLFilterClass filter_class;
-};
-
-GType gst_gl_filtersobel_get_type (void);
-
-#endif /* _GST_GL_FILTERSOBEL_H_ */
diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c
index ae3f3df..15aebe2 100644
--- a/ext/gl/gstglimagesink.c
+++ b/ext/gl/gstglimagesink.c
@@ -325,8 +325,6 @@
 static void gst_glimage_sink_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * param_spec);
 
-static gboolean gst_glimage_sink_stop (GstBaseSink * bsink);
-
 static gboolean gst_glimage_sink_query (GstBaseSink * bsink, GstQuery * query);
 static void gst_glimage_sink_set_context (GstElement * element,
     GstContext * context);
@@ -547,7 +545,6 @@
   gstbasesink_class->get_times = gst_glimage_sink_get_times;
   gstbasesink_class->prepare = gst_glimage_sink_prepare;
   gstbasesink_class->propose_allocation = gst_glimage_sink_propose_allocation;
-  gstbasesink_class->stop = gst_glimage_sink_stop;
 
   gstvideosink_class->show_frame =
       GST_DEBUG_FUNCPTR (gst_glimage_sink_show_frame);
@@ -624,11 +621,6 @@
 
   g_mutex_clear (&glimage_sink->drawing_lock);
 
-  if (glimage_sink->other_context) {
-    gst_object_unref (glimage_sink->other_context);
-    glimage_sink->other_context = NULL;
-  }
-
   g_free (glimage_sink->display_name);
 
   GST_DEBUG ("finalized");
@@ -698,6 +690,7 @@
   GST_DEBUG_OBJECT (gl_sink, "Ensuring setup");
 
   if (!gl_sink->context) {
+    GST_OBJECT_LOCK (gl_sink->display);
     do {
       GstGLContext *other_context;
       GstGLWindow *window;
@@ -770,6 +763,7 @@
         gst_object_unref (other_context);
       gst_object_unref (window);
     } while (!gst_gl_display_add_context (gl_sink->display, gl_sink->context));
+    GST_OBJECT_UNLOCK (gl_sink->display);
   } else
     GST_DEBUG_OBJECT (gl_sink, "Already have a context");
 
@@ -803,10 +797,8 @@
     {
       const gchar *context_type;
       GstContext *context, *old_context;
-      gboolean ret;
 
-      ret =
-          gst_gl_handle_context_query ((GstElement *) glimage_sink, query,
+      res = gst_gl_handle_context_query ((GstElement *) glimage_sink, query,
           &glimage_sink->display, &glimage_sink->other_context);
       if (glimage_sink->display)
         gst_gl_display_filter_gl_api (glimage_sink->display, SUPPORTED_GL_APIS);
@@ -829,12 +821,14 @@
         gst_query_set_context (query, context);
         gst_context_unref (context);
 
-        ret = glimage_sink->context != NULL;
+        res = glimage_sink->context != NULL;
       }
-      GST_DEBUG_OBJECT (glimage_sink, "context query of type %s %i",
-          context_type, ret);
+      GST_LOG_OBJECT (glimage_sink, "context query of type %s %i", context_type,
+          res);
 
-      return ret;
+      if (res)
+        return res;
+      break;
     }
     case GST_QUERY_DRAIN:
     {
@@ -862,19 +856,6 @@
   return res;
 }
 
-static gboolean
-gst_glimage_sink_stop (GstBaseSink * bsink)
-{
-  GstGLImageSink *glimage_sink = GST_GLIMAGE_SINK (bsink);
-
-  if (glimage_sink->pool) {
-    gst_object_unref (glimage_sink->pool);
-    glimage_sink->pool = NULL;
-  }
-
-  return TRUE;
-}
-
 static void
 gst_glimage_sink_set_context (GstElement * element, GstContext * context)
 {
@@ -908,6 +889,9 @@
       gst_gl_display_filter_gl_api (glimage_sink->display, SUPPORTED_GL_APIS);
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
+      if (!_ensure_gl_setup (glimage_sink))
+        return GST_STATE_CHANGE_FAILURE;
+
       g_atomic_int_set (&glimage_sink->to_quit, 0);
       break;
     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
@@ -942,6 +926,18 @@
 
       GST_VIDEO_SINK_WIDTH (glimage_sink) = 1;
       GST_VIDEO_SINK_HEIGHT (glimage_sink) = 1;
+      /* Clear cached caps */
+      if (glimage_sink->caps) {
+        gst_caps_unref (glimage_sink->caps);
+        glimage_sink->caps = NULL;
+      }
+
+      /* we're losing the context, this pool is no use anymore */
+      if (glimage_sink->pool) {
+        gst_object_unref (glimage_sink->pool);
+        glimage_sink->pool = NULL;
+      }
+
       if (glimage_sink->context) {
         GstGLWindow *window = gst_gl_context_get_window (glimage_sink->context);
 
@@ -952,19 +948,30 @@
         gst_gl_window_set_draw_callback (window, NULL, NULL, NULL);
         gst_gl_window_set_close_callback (window, NULL, NULL, NULL);
 
+        if (glimage_sink->key_sig_id)
+          g_signal_handler_disconnect (window, glimage_sink->key_sig_id);
+        glimage_sink->key_sig_id = 0;
+        if (glimage_sink->mouse_sig_id)
+          g_signal_handler_disconnect (window, glimage_sink->mouse_sig_id);
+        glimage_sink->mouse_sig_id = 0;
+
         gst_object_unref (window);
         gst_object_unref (glimage_sink->context);
         glimage_sink->context = NULL;
       }
+      break;
+    }
+    case GST_STATE_CHANGE_READY_TO_NULL:
+      if (glimage_sink->other_context) {
+        gst_object_unref (glimage_sink->other_context);
+        glimage_sink->other_context = NULL;
+      }
 
       if (glimage_sink->display) {
         gst_object_unref (glimage_sink->display);
         glimage_sink->display = NULL;
       }
       break;
-    }
-    case GST_STATE_CHANGE_READY_TO_NULL:
-      break;
     default:
       break;
   }
@@ -1001,7 +1008,7 @@
   GstCaps *tmp = NULL;
   GstCaps *result = NULL;
 
-  tmp = gst_caps_from_string ("video/x-raw(memory:GLMemory),format=RGBA");
+  tmp = gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD (bsink));
 
   if (filter) {
     result = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST);
@@ -1085,6 +1092,8 @@
       GST_VIDEO_SINK_HEIGHT (glimage_sink));
 
   glimage_sink->info = vinfo;
+  glimage_sink->caps = gst_caps_ref (caps);
+
   if (!_ensure_gl_setup (glimage_sink))
     return FALSE;
 
@@ -1516,8 +1525,7 @@
   gl->BindTexture (GL_TEXTURE_2D, 0);
 
   sample = gst_sample_new (gl_sink->stored_buffer,
-      gst_video_info_to_caps (&gl_sink->info),
-      &GST_BASE_SINK (gl_sink)->segment, NULL);
+      gl_sink->caps, &GST_BASE_SINK (gl_sink)->segment, NULL);
 
   g_signal_emit (gl_sink, gst_glimage_sink_signals[CLIENT_DRAW_SIGNAL], 0,
       gl_sink->context, sample, &do_redisplay);
@@ -1577,8 +1585,12 @@
 
   window = gst_gl_context_get_window (gl_sink->context);
 
-  g_signal_handler_disconnect (window, gl_sink->key_sig_id);
-  g_signal_handler_disconnect (window, gl_sink->mouse_sig_id);
+  if (gl_sink->key_sig_id)
+    g_signal_handler_disconnect (window, gl_sink->key_sig_id);
+  gl_sink->key_sig_id = 0;
+  if (gl_sink->mouse_sig_id)
+    g_signal_handler_disconnect (window, gl_sink->mouse_sig_id);
+  gl_sink->mouse_sig_id = 0;
 
   g_atomic_int_set (&gl_sink->to_quit, 1);
 
diff --git a/ext/gl/gstglimagesink.h b/ext/gl/gstglimagesink.h
index 1eed7b3..ce93ba7 100644
--- a/ext/gl/gstglimagesink.h
+++ b/ext/gl/gstglimagesink.h
@@ -61,6 +61,7 @@
 
     //caps
     GstVideoInfo info;
+    GstCaps *caps;
 
     GstGLDisplay *display;
     GstGLContext *context;
diff --git a/ext/gl/gstglmixer.c b/ext/gl/gstglmixer.c
index 51bd517..119ab5a 100644
--- a/ext/gl/gstglmixer.c
+++ b/ext/gl/gstglmixer.c
@@ -42,7 +42,6 @@
     GValue * value, GParamSpec * pspec);
 static void gst_gl_mixer_pad_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
-static void gst_gl_mixer_pad_finalize (GObject * object);
 
 enum
 {
@@ -73,20 +72,12 @@
   gobject_class->set_property = gst_gl_mixer_pad_set_property;
   gobject_class->get_property = gst_gl_mixer_pad_get_property;
 
-  gobject_class->finalize = gst_gl_mixer_pad_finalize;
-
   vaggpad_class->set_info = NULL;
   vaggpad_class->prepare_frame = NULL;
   vaggpad_class->clean_frame = NULL;
 }
 
 static void
-gst_gl_mixer_pad_finalize (GObject * object)
-{
-  G_OBJECT_CLASS (gst_gl_mixer_pad_parent_class)->finalize (object);
-}
-
-static void
 gst_gl_mixer_pad_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec)
 {
@@ -123,6 +114,26 @@
   return ret;
 }
 
+static void
+_find_best_format (GstVideoAggregator * vagg, GstCaps * downstream_caps,
+    GstVideoInfo * best_info, gboolean * at_least_one_alpha)
+{
+  GstVideoInfo tmp_info;
+
+  GST_VIDEO_AGGREGATOR_CLASS (parent_class)->find_best_format (vagg,
+      downstream_caps, best_info, at_least_one_alpha);
+
+  gst_video_info_set_format (&tmp_info, GST_VIDEO_FORMAT_RGBA,
+      best_info->width, best_info->height);
+  tmp_info.par_n = best_info->par_n;
+  tmp_info.par_d = best_info->par_d;
+  tmp_info.fps_n = best_info->fps_n;
+  tmp_info.fps_d = best_info->fps_d;
+  tmp_info.flags = best_info->flags;
+  tmp_info.interlace_mode = best_info->interlace_mode;
+  *best_info = tmp_info;
+}
+
 static gboolean
 gst_gl_mixer_propose_allocation (GstGLBaseMixer * base_mix,
     GstGLBaseMixerPad * base_pad, GstQuery * decide_query, GstQuery * query)
@@ -222,27 +233,27 @@
   GstCaps *template_caps;
   GstCaps *filtered_caps;
   GstCaps *returned_caps;
-  gboolean had_current_caps = TRUE;
 
   template_caps = gst_pad_get_pad_template_caps (pad);
 
   sinkcaps = gst_pad_get_current_caps (pad);
   if (sinkcaps == NULL) {
-    had_current_caps = FALSE;
-    sinkcaps = template_caps;
+    sinkcaps = gst_caps_ref (template_caps);
   } else {
-    sinkcaps = gst_caps_merge (sinkcaps, template_caps);
+    sinkcaps = gst_caps_merge (sinkcaps, gst_caps_ref (template_caps));
   }
 
-  filtered_caps = sinkcaps;
-  if (filter)
+  if (filter) {
     filtered_caps = gst_caps_intersect (sinkcaps, filter);
+    gst_caps_unref (sinkcaps);
+  } else {
+    filtered_caps = sinkcaps;   /* pass ownership */
+  }
+
   returned_caps = gst_caps_intersect (filtered_caps, template_caps);
 
-  if (filter)
-    gst_caps_unref (filtered_caps);
-  if (had_current_caps)
-    gst_caps_unref (template_caps);
+  gst_caps_unref (template_caps);
+  gst_caps_unref (filtered_caps);
 
   GST_DEBUG_OBJECT (pad, "returning %" GST_PTR_FORMAT, returned_caps);
 
@@ -375,7 +386,7 @@
   videoaggregator_class->get_output_buffer = gst_gl_mixer_get_output_buffer;
   videoaggregator_class->negotiated_caps = _negotiated_caps;
   videoaggregator_class->update_caps = _update_caps;
-  videoaggregator_class->find_best_format = NULL;
+  videoaggregator_class->find_best_format = _find_best_format;
 
   mix_class->propose_allocation = gst_gl_mixer_propose_allocation;
   mix_class->decide_allocation = gst_gl_mixer_decide_allocation;
@@ -413,6 +424,9 @@
   GstGLMixer *mix = GST_GL_MIXER (object);
   GstGLMixerPrivate *priv = mix->priv;
 
+  if (mix->out_caps)
+    gst_caps_unref (mix->out_caps);
+
   g_mutex_clear (&priv->gl_resource_lock);
   g_cond_clear (&priv->gl_resource_cond);
   G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -508,7 +522,6 @@
   GstCaps *caps;
   guint min, max, size;
   gboolean update_pool;
-  GError *error = NULL;
   guint out_width, out_height;
 
   out_width = GST_VIDEO_INFO_WIDTH (&vagg->info);
@@ -572,8 +585,7 @@
 
 context_error:
   {
-    GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, ("%s", error->message),
-        (NULL));
+    GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, ("Context error"), (NULL));
     return FALSE;
   }
 }
@@ -754,9 +766,9 @@
   GstElement *element = GST_ELEMENT (agg);
 
   GST_OBJECT_LOCK (mix);
-  mix->array_buffers = g_ptr_array_new_full (element->numsinkpads,
+  mix->array_buffers = g_ptr_array_new_full (element->numsinkpads, NULL);
+  mix->frames = g_ptr_array_new_full (element->numsinkpads,
       (GDestroyNotify) _free_glmixer_frame_data);
-  mix->frames = g_ptr_array_new_full (element->numsinkpads, NULL);
 
   g_ptr_array_set_size (mix->array_buffers, element->numsinkpads);
   g_ptr_array_set_size (mix->frames, element->numsinkpads);
diff --git a/ext/gl/gstglmixerbin.c b/ext/gl/gstglmixerbin.c
index 2dada97..ae8abef 100644
--- a/ext/gl/gstglmixerbin.c
+++ b/ext/gl/gstglmixerbin.c
@@ -110,12 +110,6 @@
     GST_STATIC_CAPS ("video/x-raw(ANY)")
     );
 
-static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%u",
-    GST_PAD_SINK,
-    GST_PAD_REQUEST,
-    GST_STATIC_CAPS ("video/x-raw(ANY)")
-    );
-
 static void gst_gl_mixer_bin_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
 static void gst_gl_mixer_bin_get_property (GObject * object, guint prop_id,
@@ -133,6 +127,7 @@
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+  GstCaps *upload_caps;
 
   g_type_class_add_private (klass, sizeof (GstGLMixerBinPrivate));
 
@@ -178,8 +173,12 @@
 
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&src_factory));
+
+  upload_caps = gst_gl_upload_get_input_template_caps ();
   gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_factory));
+      gst_pad_template_new ("sink_%u", GST_PAD_SINK, GST_PAD_REQUEST,
+          upload_caps));
+  gst_caps_unref (upload_caps);
 }
 
 static void
@@ -425,7 +424,6 @@
 
   mixer_pad =
       gst_element_request_pad (self->mixer, mixer_templ, req_name, NULL);
-  gst_object_unref (mixer_templ);
   g_return_val_if_fail (mixer_pad, NULL);
 
   if (!_create_input_chain (self, chain, mixer_pad)) {
diff --git a/ext/gl/gstgloverlay.c b/ext/gl/gstgloverlay.c
index 2dd5326..916389b 100644
--- a/ext/gl/gstgloverlay.c
+++ b/ext/gl/gstgloverlay.c
@@ -68,8 +68,6 @@
 static void gst_gl_overlay_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-static void gst_gl_overlay_reset_resources (GstGLFilter * filter);
-
 static void gst_gl_overlay_before_transform (GstBaseTransform * trans,
     GstBuffer * outbuf);
 static gboolean gst_gl_overlay_filter_texture (GstGLFilter * filter,
@@ -187,8 +185,7 @@
   GST_GL_FILTER_CLASS (klass)->filter_texture = gst_gl_overlay_filter_texture;
   GST_GL_FILTER_CLASS (klass)->display_reset_cb =
       gst_gl_overlay_reset_gl_resources;
-  GST_GL_FILTER_CLASS (klass)->onStop = gst_gl_overlay_reset_resources;
-  GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_overlay_init_gl_resources;
+  GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_overlay_init_gl_resources;
 
   GST_BASE_TRANSFORM_CLASS (klass)->before_transform =
       GST_DEBUG_FUNCPTR (gst_gl_overlay_before_transform);
@@ -267,11 +264,6 @@
 }
 
 static void
-gst_gl_overlay_reset_resources (GstGLFilter * filter)
-{
-}
-
-static void
 gst_gl_overlay_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
 {
diff --git a/ext/gl/gstglsinkbin.c b/ext/gl/gstglsinkbin.c
index ec6a1e2..1f4bd53 100644
--- a/ext/gl/gstglsinkbin.c
+++ b/ext/gl/gstglsinkbin.c
@@ -30,7 +30,6 @@
 GST_DEBUG_CATEGORY (gst_debug_gl_sink_bin);
 #define GST_CAT_DEFAULT gst_debug_gl_sink_bin
 
-static void gst_gl_sink_bin_finalize (GObject * object);
 static void gst_gl_sink_bin_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * param_spec);
 static void gst_gl_sink_bin_get_property (GObject * object, guint prop_id,
@@ -44,12 +43,6 @@
 static void gst_gl_sink_bin_navigation_interface_init (gpointer g_iface,
     gpointer g_iface_data);
 
-static GstStaticPadTemplate gst_gl_sink_bin_template =
-GST_STATIC_PAD_TEMPLATE ("sink",
-    GST_PAD_SINK,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("video/x-raw(ANY)"));
-
 enum
 {
   PROP_0,
@@ -80,6 +73,7 @@
 {
   GObjectClass *gobject_class;
   GstElementClass *element_class;
+  GstCaps *upload_caps;
 
   gobject_class = (GObjectClass *) klass;
   element_class = GST_ELEMENT_CLASS (klass);
@@ -88,7 +82,6 @@
 
   gobject_class->set_property = gst_gl_sink_bin_set_property;
   gobject_class->get_property = gst_gl_sink_bin_get_property;
-  gobject_class->finalize = gst_gl_sink_bin_finalize;
 
   g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO,
       g_param_spec_boolean ("force-aspect-ratio",
@@ -121,14 +114,10 @@
       "Infrastructure to process GL textures",
       "Matthew Waters <matthew@centricular.com>");
 
+  upload_caps = gst_gl_upload_get_input_template_caps ();
   gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_gl_sink_bin_template));
-}
-
-static void
-gst_gl_sink_bin_finalize (GObject * object)
-{
-  G_OBJECT_CLASS (parent_class)->finalize (object);
+      gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, upload_caps));
+  gst_caps_unref (upload_caps);
 }
 
 static void
diff --git a/ext/gl/gstglsrcbin.c b/ext/gl/gstglsrcbin.c
index 58d34c6..76510a0 100644
--- a/ext/gl/gstglsrcbin.c
+++ b/ext/gl/gstglsrcbin.c
@@ -27,7 +27,6 @@
 GST_DEBUG_CATEGORY (gst_debug_gl_src_bin);
 #define GST_CAT_DEFAULT gst_debug_gl_src_bin
 
-static void gst_gl_src_bin_finalize (GObject * object);
 static void gst_gl_src_bin_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * param_spec);
 static void gst_gl_src_bin_get_property (GObject * object, guint prop_id,
@@ -76,7 +75,6 @@
 
   gobject_class->set_property = gst_gl_src_bin_set_property;
   gobject_class->get_property = gst_gl_src_bin_get_property;
-  gobject_class->finalize = gst_gl_src_bin_finalize;
 
   g_object_class_install_property (gobject_class, PROP_SRC,
       g_param_spec_object ("src",
@@ -109,12 +107,6 @@
 }
 
 static void
-gst_gl_src_bin_finalize (GObject * object)
-{
-  G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
 gst_gl_src_bin_init (GstGLSrcBin * self)
 {
   gboolean res = TRUE;
diff --git a/ext/gl/gstgltestsrc.c b/ext/gl/gstgltestsrc.c
index dbd5610..eba66b0 100644
--- a/ext/gl/gstgltestsrc.c
+++ b/ext/gl/gstgltestsrc.c
@@ -80,10 +80,8 @@
     const GValue * value, GParamSpec * pspec);
 static void gst_gl_test_src_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
-static void gst_gl_test_src_dispose (GObject * object);
 
 static gboolean gst_gl_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps);
-static GstCaps *gst_gl_test_src_getcaps (GstBaseSrc * bsrc, GstCaps * filter);
 static GstCaps *gst_gl_test_src_fixate (GstBaseSrc * bsrc, GstCaps * caps);
 
 static gboolean gst_gl_test_src_is_seekable (GstBaseSrc * psrc);
@@ -156,7 +154,6 @@
 
   gobject_class->set_property = gst_gl_test_src_set_property;
   gobject_class->get_property = gst_gl_test_src_get_property;
-  gobject_class->dispose = gst_gl_test_src_dispose;
 
   g_object_class_install_property (gobject_class, PROP_PATTERN,
       g_param_spec_enum ("pattern", "Pattern",
@@ -183,7 +180,6 @@
   element_class->change_state = gst_gl_test_src_change_state;
 
   gstbasesrc_class->set_caps = gst_gl_test_src_setcaps;
-  gstbasesrc_class->get_caps = gst_gl_test_src_getcaps;
   gstbasesrc_class->is_seekable = gst_gl_test_src_is_seekable;
   gstbasesrc_class->do_seek = gst_gl_test_src_do_seek;
   gstbasesrc_class->query = gst_gl_test_src_query;
@@ -387,18 +383,6 @@
 }
 
 static void
-gst_gl_test_src_dispose (GObject * object)
-{
-  GstGLTestSrc *src = GST_GL_TEST_SRC (object);
-
-  if (src->other_context)
-    gst_object_unref (src->other_context);
-  src->other_context = NULL;
-
-  G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-static void
 gst_gl_test_src_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
 {
@@ -465,24 +449,6 @@
   }
 }
 
-static GstCaps *
-gst_gl_test_src_getcaps (GstBaseSrc * bsrc, GstCaps * filter)
-{
-  GstCaps *tmp = NULL;
-  GstCaps *result =
-      gst_caps_from_string ("video/x-raw(memory:GLMemory),format=RGBA");
-
-  if (filter) {
-    tmp = gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);
-    gst_caps_unref (result);
-    result = tmp;
-  }
-
-  GST_DEBUG_OBJECT (bsrc, "returning caps: %" GST_PTR_FORMAT, result);
-
-  return result;
-}
-
 static void
 gst_gl_test_src_set_context (GstElement * element, GstContext * context)
 {
@@ -749,11 +715,6 @@
     src->context = NULL;
   }
 
-  if (src->display) {
-    gst_object_unref (src->display);
-    src->display = NULL;
-  }
-
   return TRUE;
 }
 
@@ -816,6 +777,7 @@
   _find_local_gl_context (src);
 
   if (!src->context) {
+    GST_OBJECT_LOCK (src->display);
     do {
       if (src->context)
         gst_object_unref (src->context);
@@ -828,6 +790,7 @@
           goto context_error;
       }
     } while (!gst_gl_display_add_context (src->display, src->context));
+    GST_OBJECT_UNLOCK (src->display);
   }
 
   out_width = GST_VIDEO_INFO_WIDTH (&src->out_info);
@@ -932,6 +895,17 @@
     return ret;
 
   switch (transition) {
+    case GST_STATE_CHANGE_READY_TO_NULL:
+      if (src->other_context) {
+        gst_object_unref (src->other_context);
+        src->other_context = NULL;
+      }
+
+      if (src->display) {
+        gst_object_unref (src->display);
+        src->display = NULL;
+      }
+      break;
     default:
       break;
   }
diff --git a/ext/gl/gstgltransformation.c b/ext/gl/gstgltransformation.c
index f9273c7..4bd022e 100644
--- a/ext/gl/gstgltransformation.c
+++ b/ext/gl/gstgltransformation.c
@@ -52,6 +52,8 @@
 #define GST_CAT_DEFAULT gst_gl_transformation_debug
 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
 
+#define gst_gl_transformation_parent_class parent_class
+
 enum
 {
   PROP_0,
@@ -83,7 +85,7 @@
     GstCaps * incaps, GstCaps * outcaps);
 
 static void gst_gl_transformation_reset_gl (GstGLFilter * filter);
-static void gst_gl_transformation_reset (GstGLFilter * filter);
+static gboolean gst_gl_transformation_stop (GstBaseTransform * trans);
 static gboolean gst_gl_transformation_init_shader (GstGLFilter * filter);
 static void gst_gl_transformation_callback (gpointer stuff);
 static void gst_gl_transformation_build_mvp (GstGLTransformation *
@@ -128,13 +130,13 @@
   gobject_class->set_property = gst_gl_transformation_set_property;
   gobject_class->get_property = gst_gl_transformation_get_property;
 
-  GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_transformation_init_shader;
+  GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_transformation_init_shader;
   GST_GL_FILTER_CLASS (klass)->display_reset_cb =
       gst_gl_transformation_reset_gl;
-  GST_GL_FILTER_CLASS (klass)->onReset = gst_gl_transformation_reset;
   GST_GL_FILTER_CLASS (klass)->set_caps = gst_gl_transformation_set_caps;
   GST_GL_FILTER_CLASS (klass)->filter_texture =
       gst_gl_transformation_filter_texture;
+  GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_transformation_stop;
 
   g_object_class_install_property (gobject_class, PROP_FOV,
       g_param_spec_float ("fov", "Fov", "Field of view angle in degrees",
@@ -404,18 +406,26 @@
     gl->DeleteBuffers (1, &transformation->vertex_buffer);
     transformation->vertex_buffer = 0;
   }
+
+  if (transformation->shader) {
+    gst_object_unref (transformation->shader);
+    transformation->shader = NULL;
+  }
 }
 
-static void
-gst_gl_transformation_reset (GstGLFilter * filter)
+static gboolean
+gst_gl_transformation_stop (GstBaseTransform * trans)
 {
-  GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter);
+  GstGLBaseFilter *basefilter = GST_GL_BASE_FILTER (trans);
+  GstGLTransformation *transformation = GST_GL_TRANSFORMATION (trans);
 
   /* blocking call, wait until the opengl thread has destroyed the shader */
-  if (transformation->shader)
-    gst_gl_context_del_shader (GST_GL_BASE_FILTER (filter)->context,
-        transformation->shader);
-  transformation->shader = NULL;
+  if (basefilter->context && transformation->shader) {
+    gst_gl_context_del_shader (basefilter->context, transformation->shader);
+    transformation->shader = NULL;
+  }
+
+  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
 }
 
 static gboolean
@@ -423,6 +433,11 @@
 {
   GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter);
 
+  if (transformation->shader) {
+    gst_object_unref (transformation->shader);
+    transformation->shader = NULL;
+  }
+
   if (gst_gl_context_get_gl_api (GST_GL_BASE_FILTER (filter)->context)) {
     /* blocking call, wait until the opengl thread has compiled the shader */
     return gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context,
diff --git a/ext/gl/gstgluploadelement.c b/ext/gl/gstgluploadelement.c
index a8971d8..be01143 100644
--- a/ext/gl/gstgluploadelement.c
+++ b/ext/gl/gstgluploadelement.c
@@ -27,16 +27,6 @@
 #include <gst/gl/gl.h>
 #include "gstgluploadelement.h"
 
-#if GST_GL_HAVE_PLATFORM_EGL
-#include <gst/gl/egl/gsteglimagememory.h>
-#endif
-
-#define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
-#define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
-#define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
-#define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
-#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))
-
 GST_DEBUG_CATEGORY_STATIC (gst_gl_upload_element_debug);
 #define GST_CAT_DEFAULT gst_gl_upload_element_debug
 
@@ -46,7 +36,6 @@
     GST_DEBUG_CATEGORY_INIT (gst_gl_upload_element_debug, "gluploadelement", 0,
         "glupload Element");
     );
-static void gst_gl_upload_element_finalize (GObject * object);
 
 static gboolean gst_gl_upload_element_get_unit_size (GstBaseTransform * trans,
     GstCaps * caps, gsize * size);
@@ -65,6 +54,7 @@
     GstBuffer * buffer, GstBuffer ** outbuf);
 static GstFlowReturn gst_gl_upload_element_transform (GstBaseTransform * bt,
     GstBuffer * buffer, GstBuffer * outbuf);
+static gboolean gst_gl_upload_element_stop (GstBaseTransform * bt);
 
 static GstStaticPadTemplate gst_gl_upload_element_src_pad_template =
 GST_STATIC_PAD_TEMPLATE ("src",
@@ -72,17 +62,12 @@
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS ("video/x-raw(ANY)"));
 
-static GstStaticPadTemplate gst_gl_upload_element_sink_pad_template =
-GST_STATIC_PAD_TEMPLATE ("sink",
-    GST_PAD_SINK,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("video/x-raw(ANY)"));
-
 static void
 gst_gl_upload_element_class_init (GstGLUploadElementClass * klass)
 {
   GstBaseTransformClass *bt_class = GST_BASE_TRANSFORM_CLASS (klass);
   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+  GstCaps *upload_caps;
 
   bt_class->query = gst_gl_upload_element_query;
   bt_class->transform_caps = _gst_gl_upload_element_transform_caps;
@@ -92,19 +77,21 @@
   bt_class->get_unit_size = gst_gl_upload_element_get_unit_size;
   bt_class->prepare_output_buffer = gst_gl_upload_element_prepare_output_buffer;
   bt_class->transform = gst_gl_upload_element_transform;
+  bt_class->stop = gst_gl_upload_element_stop;
 
   bt_class->passthrough_on_same_caps = TRUE;
 
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&gst_gl_upload_element_src_pad_template));
+
+  upload_caps = gst_gl_upload_get_input_template_caps ();
   gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_gl_upload_element_sink_pad_template));
+      gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, upload_caps));
+  gst_caps_unref (upload_caps);
 
   gst_element_class_set_metadata (element_class,
       "OpenGL uploader", "Filter/Video",
       "Uploads data into OpenGL", "Matthew Waters <matthew@centricular.com>");
-
-  G_OBJECT_CLASS (klass)->finalize = gst_gl_upload_element_finalize;
 }
 
 static void
@@ -113,10 +100,10 @@
   gst_base_transform_set_prefer_passthrough (GST_BASE_TRANSFORM (upload), TRUE);
 }
 
-static void
-gst_gl_upload_element_finalize (GObject * object)
+static gboolean
+gst_gl_upload_element_stop (GstBaseTransform * bt)
 {
-  GstGLUploadElement *upload = GST_GL_UPLOAD_ELEMENT (object);
+  GstGLUploadElement *upload = GST_GL_UPLOAD_ELEMENT (bt);
 
   if (upload->upload) {
     gst_object_unref (upload->upload);
@@ -126,7 +113,7 @@
   gst_caps_replace (&upload->in_caps, NULL);
   gst_caps_replace (&upload->out_caps, NULL);
 
-  G_OBJECT_CLASS (gst_gl_upload_element_parent_class)->finalize (object);
+  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (bt);
 }
 
 static gboolean
@@ -195,8 +182,10 @@
   gst_caps_replace (&upload->in_caps, in_caps);
   gst_caps_replace (&upload->out_caps, out_caps);
 
-  if (upload->upload)
+  if (upload->upload) {
+    gst_gl_upload_release_buffer (upload->upload);
     return gst_gl_upload_set_caps (upload->upload, in_caps, out_caps);
+  }
 
   return TRUE;
 }
diff --git a/ext/gl/gstglvideomixer.c b/ext/gl/gstglvideomixer.c
index c399e92..f7a3eb1 100644
--- a/ext/gl/gstglvideomixer.c
+++ b/ext/gl/gstglvideomixer.c
@@ -621,9 +621,49 @@
   }
 }
 
+static void
+_mixer_pad_get_output_size (GstGLVideoMixer * mix,
+    GstGLVideoMixerPad * mix_pad, gint * width, gint * height)
+{
+  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix);
+  GstVideoAggregatorPad *vagg_pad = GST_VIDEO_AGGREGATOR_PAD (mix_pad);
+  gint pad_width, pad_height;
+  gint dar_n, dar_d;
+
+  pad_width =
+      mix_pad->width <=
+      0 ? GST_VIDEO_INFO_WIDTH (&vagg_pad->info) : mix_pad->width;
+  pad_height =
+      mix_pad->height <=
+      0 ? GST_VIDEO_INFO_HEIGHT (&vagg_pad->info) : mix_pad->height;
+
+  gst_util_fraction_multiply (GST_VIDEO_INFO_PAR_N (&vagg_pad->info),
+      GST_VIDEO_INFO_PAR_D (&vagg_pad->info),
+      GST_VIDEO_INFO_PAR_D (&vagg->info), GST_VIDEO_INFO_PAR_N (&vagg->info),
+      &dar_n, &dar_d);
+  GST_LOG_OBJECT (mix_pad, "scaling %ux%u by %u/%u (%u/%u / %u/%u)", pad_width,
+      pad_height, dar_n, dar_d, GST_VIDEO_INFO_PAR_N (&vagg_pad->info),
+      GST_VIDEO_INFO_PAR_D (&vagg_pad->info),
+      GST_VIDEO_INFO_PAR_N (&vagg->info), GST_VIDEO_INFO_PAR_D (&vagg->info));
+
+  if (pad_height % dar_n == 0) {
+    pad_height = gst_util_uint64_scale_int (pad_width, dar_n, dar_d);
+  } else if (pad_width % dar_d == 0) {
+    pad_width = gst_util_uint64_scale_int (pad_height, dar_d, dar_n);
+  } else {
+    pad_height = gst_util_uint64_scale_int (pad_width, dar_n, dar_d);
+  }
+
+  if (width)
+    *width = pad_width;
+  if (height)
+    *height = pad_height;
+}
+
 static GstCaps *
 _update_caps (GstVideoAggregator * vagg, GstCaps * caps)
 {
+  GstGLVideoMixer *mix = GST_GL_VIDEO_MIXER (vagg);
   GList *l;
   gint best_width = -1, best_height = -1;
   GstVideoInfo info;
@@ -640,15 +680,7 @@
     gint this_width, this_height;
     gint width, height;
 
-    if (mixer_pad->width > 0)
-      width = mixer_pad->width;
-    else
-      width = GST_VIDEO_INFO_WIDTH (&vaggpad->info);
-
-    if (mixer_pad->height > 0)
-      height = mixer_pad->height;
-    else
-      height = GST_VIDEO_INFO_HEIGHT (&vaggpad->info);
+    _mixer_pad_get_output_size (mix, mixer_pad, &width, &height);
 
     if (width == 0 || height == 0)
       continue;
@@ -709,21 +741,23 @@
 gst_gl_video_mixer_reset (GstGLMixer * mixer)
 {
   GstGLVideoMixer *video_mixer = GST_GL_VIDEO_MIXER (mixer);
+  GstGLContext *context = GST_GL_BASE_MIXER (mixer)->context;
 
   video_mixer->input_frames = NULL;
 
+  GST_DEBUG_OBJECT (mixer, "context:%p", context);
+
   if (video_mixer->shader)
-    gst_gl_context_del_shader (GST_GL_BASE_MIXER (mixer)->context,
-        video_mixer->shader);
+    gst_gl_context_del_shader (context, video_mixer->shader);
   video_mixer->shader = NULL;
 
   if (video_mixer->checker)
-    gst_gl_context_del_shader (GST_GL_BASE_MIXER (mixer)->context,
-        video_mixer->checker);
+    gst_gl_context_del_shader (context, video_mixer->checker);
   video_mixer->checker = NULL;
 
-  gst_gl_context_thread_add (GST_GL_BASE_MIXER (mixer)->context,
-      (GstGLContextThreadFunc) _reset_gl, mixer);
+  if (GST_GL_BASE_MIXER (mixer)->context)
+    gst_gl_context_thread_add (context, (GstGLContextThreadFunc) _reset_gl,
+        mixer);
 }
 
 static gboolean
@@ -842,6 +876,7 @@
 gst_gl_video_mixer_callback (gpointer stuff)
 {
   GstGLVideoMixer *video_mixer = GST_GL_VIDEO_MIXER (stuff);
+  GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (stuff);
   GstGLMixer *mixer = GST_GL_MIXER (video_mixer);
   GstGLFuncs *gl = GST_GL_BASE_MIXER (mixer)->context->gl_vtable;
 
@@ -856,8 +891,8 @@
 
   guint count = 0;
 
-  out_width = GST_VIDEO_INFO_WIDTH (&GST_VIDEO_AGGREGATOR (stuff)->info);
-  out_height = GST_VIDEO_INFO_HEIGHT (&GST_VIDEO_AGGREGATOR (stuff)->info);
+  out_width = GST_VIDEO_INFO_WIDTH (&vagg->info);
+  out_height = GST_VIDEO_INFO_HEIGHT (&vagg->info);
 
   gst_gl_context_clear_shader (GST_GL_BASE_MIXER (mixer)->context);
   gl->BindTexture (GL_TEXTURE_2D, 0);
@@ -889,6 +924,7 @@
   while (count < video_mixer->input_frames->len) {
     GstGLMixerFrameData *frame;
     GstGLVideoMixerPad *pad;
+    GstVideoInfo *v_info;
     guint in_tex;
     guint in_width, in_height;
 
@@ -908,8 +944,9 @@
       continue;
     }
     pad = (GstGLVideoMixerPad *) frame->pad;
-    in_width = GST_VIDEO_INFO_WIDTH (&GST_VIDEO_AGGREGATOR_PAD (pad)->info);
-    in_height = GST_VIDEO_INFO_HEIGHT (&GST_VIDEO_AGGREGATOR_PAD (pad)->info);
+    v_info = &GST_VIDEO_AGGREGATOR_PAD (pad)->info;
+    in_width = GST_VIDEO_INFO_WIDTH (v_info);
+    in_height = GST_VIDEO_INFO_HEIGHT (v_info);
 
     if (!frame->texture || in_width <= 0 || in_height <= 0
         || pad->alpha == 0.0f) {
@@ -922,11 +959,10 @@
     in_tex = frame->texture;
 
     if (pad->geometry_change || !pad->vertex_buffer) {
-      guint pad_width, pad_height;
+      gint pad_width, pad_height;
       gfloat w, h;
 
-      pad_width = pad->width <= 0 ? in_width : pad->width;
-      pad_height = pad->height <= 0 ? in_height : pad->height;
+      _mixer_pad_get_output_size (video_mixer, pad, &pad_width, &pad_height);
 
       w = ((gfloat) pad_width / (gfloat) out_width);
       h = ((gfloat) pad_height / (gfloat) out_height);
@@ -952,6 +988,8 @@
 
       gl->BufferData (GL_ARRAY_BUFFER, 4 * 5 * sizeof (GLfloat), v_vertices,
           GL_STATIC_DRAW);
+
+      pad->geometry_change = FALSE;
     } else {
       gl->BindBuffer (GL_ARRAY_BUFFER, pad->vertex_buffer);
     }
diff --git a/ext/gl/gstopengl.c b/ext/gl/gstopengl.c
index 452efdd..308c65c 100644
--- a/ext/gl/gstopengl.c
+++ b/ext/gl/gstopengl.c
@@ -69,11 +69,8 @@
 
 #if GST_GL_HAVE_OPENGL
 #include "gstgltestsrc.h"
-#include "gstglfilterlaplacian.h"
 #include "gstglfilterglass.h"
-#include "gstglfilterblur.h"
 /* #include "gstglfilterreflectedscreen.h" */
-#include "gstglfiltersobel.h"
 #include "gstgldeinterlace.h"
 #include "gstglmosaic.h"
 #if HAVE_PNG
@@ -119,18 +116,23 @@
     return FALSE;
   }
 
+  if (!gst_element_register (plugin, "glimagesinkelement",
+          GST_RANK_NONE, gst_glimage_sink_get_type ())) {
+    return FALSE;
+  }
+
   if (!gst_element_register (plugin, "glupload",
-          GST_RANK_SECONDARY, GST_TYPE_GL_UPLOAD_ELEMENT)) {
+          GST_RANK_NONE, GST_TYPE_GL_UPLOAD_ELEMENT)) {
     return FALSE;
   }
 
   if (!gst_element_register (plugin, "gldownload",
-          GST_RANK_SECONDARY, GST_TYPE_GL_DOWNLOAD_ELEMENT)) {
+          GST_RANK_NONE, GST_TYPE_GL_DOWNLOAD_ELEMENT)) {
     return FALSE;
   }
 
   if (!gst_element_register (plugin, "glcolorconvert",
-          GST_RANK_SECONDARY, GST_TYPE_GL_COLOR_CONVERT_ELEMENT)) {
+          GST_RANK_NONE, GST_TYPE_GL_COLOR_CONVERT_ELEMENT)) {
     return FALSE;
   }
 
@@ -164,10 +166,10 @@
     return FALSE;
   }
 #endif
-  if (!gst_element_register (plugin, "gleffects",
-          GST_RANK_NONE, gst_gl_effects_get_type ())) {
+
+  if (!gst_gl_effects_register_filters (plugin, GST_RANK_NONE)) {
     return FALSE;
-  }
+  };
 
   if (!gst_element_register (plugin, "glcolorscale",
           GST_RANK_NONE, GST_TYPE_GL_COLORSCALE)) {
@@ -179,6 +181,11 @@
     return FALSE;
   }
 
+  if (!gst_element_register (plugin, "glvideomixerelement",
+          GST_RANK_NONE, gst_gl_video_mixer_get_type ())) {
+    return FALSE;
+  }
+
   if (!gst_element_register (plugin, "glshader",
           GST_RANK_NONE, gst_gl_filtershader_get_type ())) {
     return FALSE;
@@ -202,21 +209,6 @@
     return FALSE;
   }
 
-  if (!gst_element_register (plugin, "glfilterblur",
-          GST_RANK_NONE, gst_gl_filterblur_get_type ())) {
-    return FALSE;
-  }
-
-  if (!gst_element_register (plugin, "glfiltersobel",
-          GST_RANK_NONE, gst_gl_filtersobel_get_type ())) {
-    return FALSE;
-  }
-
-  if (!gst_element_register (plugin, "glfilterlaplacian",
-          GST_RANK_NONE, GST_TYPE_GL_FILTER_LAPLACIAN)) {
-    return FALSE;
-  }
-
   if (!gst_element_register (plugin, "glfilterglass",
           GST_RANK_NONE, GST_TYPE_GL_FILTER_GLASS)) {
     return FALSE;
diff --git a/ext/hls/Makefile.am b/ext/hls/Makefile.am
index 6ef163b..f66880f 100644
--- a/ext/hls/Makefile.am
+++ b/ext/hls/Makefile.am
@@ -24,17 +24,3 @@
 	gsthlssink.h			\
 	gstm3u8playlist.h		\
 	m3u8.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgsthls -:SHARED libgsthls \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgsthls_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgsthls_la_CFLAGS) \
-	 -:LDFLAGS $(libgsthls_la_LDFLAGS) \
-	           $(libgsthls_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/ext/hls/Makefile.in b/ext/hls/Makefile.in
index 140ce07..bb91c7a 100644
--- a/ext/hls/Makefile.in
+++ b/ext/hls/Makefile.in
@@ -1126,20 +1126,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgsthls -:SHARED libgsthls \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgsthls_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgsthls_la_CFLAGS) \
-	 -:LDFLAGS $(libgsthls_la_LDFLAGS) \
-	           $(libgsthls_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/ext/hls/gsthlsdemux.c b/ext/hls/gsthlsdemux.c
index fad5a7b..5513815 100644
--- a/ext/hls/gsthlsdemux.c
+++ b/ext/hls/gsthlsdemux.c
@@ -100,8 +100,7 @@
     demux);
 static gboolean gst_hls_demux_process_manifest (GstAdaptiveDemux * demux,
     GstBuffer * buf);
-static GstFlowReturn gst_hls_demux_update_manifest (GstAdaptiveDemux * demux,
-    GstBuffer * buf);
+static GstFlowReturn gst_hls_demux_update_manifest (GstAdaptiveDemux * demux);
 static gboolean gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek);
 static gboolean
 gst_hls_demux_start_fragment (GstAdaptiveDemux * demux,
@@ -130,11 +129,6 @@
 {
   GstHLSDemux *demux = GST_HLS_DEMUX (obj);
 
-  if (demux->downloader != NULL) {
-    g_object_unref (demux->downloader);
-    demux->downloader = NULL;
-  }
-
   gst_hls_demux_reset (GST_ADAPTIVE_DEMUX_CAST (demux));
   gst_m3u8_client_free (demux->client);
 
@@ -207,11 +201,7 @@
 static void
 gst_hls_demux_init (GstHLSDemux * demux)
 {
-  /* Downloader */
-  demux->downloader = gst_uri_downloader_new ();
-
   demux->do_typefind = TRUE;
-
 }
 
 static void
@@ -250,7 +240,6 @@
   switch (transition) {
     case GST_STATE_CHANGE_READY_TO_PAUSED:
       gst_hls_demux_reset (GST_ADAPTIVE_DEMUX_CAST (demux));
-      gst_uri_downloader_reset (demux->downloader);
       break;
     default:
       break;
@@ -307,7 +296,7 @@
   GstSeekType start_type, stop_type;
   gint64 start, stop;
   gdouble rate;
-  GList *walk;
+  GList *walk, *current_file = NULL;
   GstClockTime current_pos, target_pos;
   gint64 current_sequence;
   GstM3U8MediaFile *file;
@@ -335,7 +324,7 @@
     GST_M3U8_CLIENT_UNLOCK (hlsdemux->client);
     gst_m3u8_client_set_current (hlsdemux->client,
         hlsdemux->client->main->iframe_lists->data);
-    gst_uri_downloader_reset (hlsdemux->downloader);
+    gst_uri_downloader_reset (demux->downloader);
     if (!gst_hls_demux_update_playlist (hlsdemux, FALSE, &err)) {
       GST_ELEMENT_ERROR_FROM_ERROR (hlsdemux, "Could not switch playlist", err);
       return FALSE;
@@ -354,7 +343,7 @@
     GST_M3U8_CLIENT_UNLOCK (hlsdemux->client);
     gst_m3u8_client_set_current (hlsdemux->client,
         hlsdemux->client->main->lists->data);
-    gst_uri_downloader_reset (hlsdemux->downloader);
+    gst_uri_downloader_reset (demux->downloader);
     if (!gst_hls_demux_update_playlist (hlsdemux, FALSE, &err)) {
       GST_ELEMENT_ERROR_FROM_ERROR (hlsdemux, "Could not switch playlist", err);
       return FALSE;
@@ -376,22 +365,23 @@
     file = walk->data;
 
     current_sequence = file->sequence;
+    current_file = walk;
     if (current_pos <= target_pos && target_pos < current_pos + file->duration) {
       break;
     }
     current_pos += file->duration;
   }
-  GST_M3U8_CLIENT_UNLOCK (hlsdemux->client);
 
   if (walk == NULL) {
     GST_DEBUG_OBJECT (demux, "seeking further than track duration");
     current_sequence++;
   }
 
-  GST_M3U8_CLIENT_LOCK (hlsdemux->client);
   GST_DEBUG_OBJECT (demux, "seeking to sequence %u", (guint) current_sequence);
   hlsdemux->reset_pts = TRUE;
   hlsdemux->client->sequence = current_sequence;
+  hlsdemux->client->current_file =
+      current_file ? current_file : hlsdemux->client->current->files;
   hlsdemux->client->sequence_position = current_pos;
   GST_M3U8_CLIENT_UNLOCK (hlsdemux->client);
 
@@ -399,7 +389,7 @@
 }
 
 static GstFlowReturn
-gst_hls_demux_update_manifest (GstAdaptiveDemux * demux, GstBuffer * buf)
+gst_hls_demux_update_manifest (GstAdaptiveDemux * demux)
 {
   GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
   if (!gst_hls_demux_update_playlist (hlsdemux, TRUE, NULL))
@@ -514,7 +504,7 @@
 
       GST_INFO_OBJECT (demux, "Fetching key %s", hlsdemux->current_key);
       key_fragment =
-          gst_uri_downloader_fetch_uri (hlsdemux->downloader,
+          gst_uri_downloader_fetch_uri (demux->downloader,
           hlsdemux->current_key, hlsdemux->client->main ?
           hlsdemux->client->main->uri : NULL, FALSE, FALSE,
           hlsdemux->client->current ? hlsdemux->client->current->
@@ -544,10 +534,71 @@
 }
 
 static GstFlowReturn
+gst_hls_demux_handle_buffer (GstAdaptiveDemux * demux,
+    GstAdaptiveDemuxStream * stream, GstBuffer * buffer, gboolean force)
+{
+  GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
+
+  if (G_UNLIKELY (hlsdemux->do_typefind && buffer != NULL)) {
+    GstCaps *caps = NULL;
+    GstMapInfo info;
+    guint buffer_size;
+    GstTypeFindProbability prob = GST_TYPE_FIND_NONE;
+
+    gst_buffer_map (buffer, &info, GST_MAP_READ);
+    buffer_size = info.size;
+
+    /* Typefind could miss if buffer is too small. In this case we
+     * will retry later */
+    if (buffer_size >= (2 * 1024)) {
+      caps =
+          gst_type_find_helper_for_data (GST_OBJECT_CAST (hlsdemux), info.data,
+          info.size, &prob);
+    }
+    gst_buffer_unmap (buffer, &info);
+
+    if (G_UNLIKELY (!caps)) {
+      /* Only fail typefinding if we already a good amount of data
+       * and we still don't know the type */
+      if (buffer_size > (2 * 1024 * 1024) || force) {
+        GST_ELEMENT_ERROR (hlsdemux, STREAM, TYPE_NOT_FOUND,
+            ("Could not determine type of stream"), (NULL));
+        gst_buffer_unref (buffer);
+        return GST_FLOW_NOT_NEGOTIATED;
+      } else {
+        if (hlsdemux->pending_buffer)
+          hlsdemux->pending_buffer =
+              gst_buffer_append (buffer, hlsdemux->pending_buffer);
+        else
+          hlsdemux->pending_buffer = buffer;
+        return GST_FLOW_OK;
+      }
+    }
+
+    GST_DEBUG_OBJECT (hlsdemux, "Typefind result: %" GST_PTR_FORMAT " prob:%d",
+        caps, prob);
+
+    if (!hlsdemux->input_caps
+        || !gst_caps_is_equal (caps, hlsdemux->input_caps)) {
+      gst_caps_replace (&hlsdemux->input_caps, caps);
+      GST_INFO_OBJECT (demux, "Input source caps: %" GST_PTR_FORMAT,
+          hlsdemux->input_caps);
+    }
+    gst_adaptive_demux_stream_set_caps (stream, caps);
+    hlsdemux->do_typefind = FALSE;
+  }
+
+  if (buffer)
+    return gst_adaptive_demux_stream_push_buffer (stream, buffer);
+  return GST_FLOW_OK;
+}
+
+static GstFlowReturn
 gst_hls_demux_finish_fragment (GstAdaptiveDemux * demux,
     GstAdaptiveDemuxStream * stream)
 {
   GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
+  GstFlowReturn ret = GST_FLOW_OK;
 
   if (hlsdemux->current_key)
     gst_hls_demux_decrypt_end (hlsdemux);
@@ -558,20 +609,24 @@
       ": %" G_GSIZE_FORMAT, gst_adapter_available (stream->adapter));
   gst_adapter_clear (stream->adapter);
 
-  /* pending buffer is only used for encrypted streams */
   if (stream->last_ret == GST_FLOW_OK) {
     if (hlsdemux->pending_buffer) {
-      GstMapInfo info;
-      gsize unpadded_size;
+      if (hlsdemux->current_key) {
+        GstMapInfo info;
+        gssize unpadded_size;
 
-      /* Handle pkcs7 unpadding here */
-      gst_buffer_map (hlsdemux->pending_buffer, &info, GST_MAP_READ);
-      unpadded_size = info.size - info.data[info.size - 1];
-      gst_buffer_unmap (hlsdemux->pending_buffer, &info);
+        /* Handle pkcs7 unpadding here */
+        gst_buffer_map (hlsdemux->pending_buffer, &info, GST_MAP_READ);
+        unpadded_size = info.size - info.data[info.size - 1];
+        gst_buffer_unmap (hlsdemux->pending_buffer, &info);
 
-      gst_buffer_resize (hlsdemux->pending_buffer, 0, unpadded_size);
+        gst_buffer_resize (hlsdemux->pending_buffer, 0, unpadded_size);
+      }
 
-      gst_adaptive_demux_stream_push_buffer (stream, hlsdemux->pending_buffer);
+      ret =
+          gst_hls_demux_handle_buffer (demux, stream, hlsdemux->pending_buffer,
+          TRUE);
+      hlsdemux->pending_buffer = NULL;
     }
   } else {
     if (hlsdemux->pending_buffer)
@@ -579,8 +634,10 @@
     hlsdemux->pending_buffer = NULL;
   }
 
-  return gst_adaptive_demux_stream_advance_fragment (demux, stream,
-      stream->fragment.duration);
+  if (ret == GST_FLOW_OK || ret == GST_FLOW_NOT_LINKED)
+    return gst_adaptive_demux_stream_advance_fragment (demux, stream,
+        stream->fragment.duration);
+  return ret;
 }
 
 static GstFlowReturn
@@ -625,59 +682,7 @@
     }
   }
 
-  if (G_UNLIKELY (hlsdemux->do_typefind && buffer != NULL)) {
-    GstCaps *caps = NULL;
-    GstMapInfo info;
-    guint buffer_size;
-    GstTypeFindProbability prob = GST_TYPE_FIND_NONE;
-
-    gst_buffer_map (buffer, &info, GST_MAP_READ);
-    buffer_size = info.size;
-
-    /* Typefind could miss if buffer is too small. In this case we
-     * will retry later */
-    if (buffer_size >= (2 * 1024)) {
-      caps =
-          gst_type_find_helper_for_data (GST_OBJECT_CAST (hlsdemux), info.data,
-          info.size, &prob);
-    }
-    gst_buffer_unmap (buffer, &info);
-
-    if (G_UNLIKELY (!caps)) {
-      /* Only fail typefinding if we already a good amount of data
-       * and we still don't know the type */
-      if (buffer_size > (2 * 1024 * 1024)) {
-        GST_ELEMENT_ERROR (hlsdemux, STREAM, TYPE_NOT_FOUND,
-            ("Could not determine type of stream"), (NULL));
-        gst_buffer_unref (buffer);
-        return GST_FLOW_NOT_NEGOTIATED;
-      } else {
-        if (hlsdemux->pending_buffer)
-          hlsdemux->pending_buffer =
-              gst_buffer_append (buffer, hlsdemux->pending_buffer);
-        else
-          hlsdemux->pending_buffer = buffer;
-        return GST_FLOW_OK;
-      }
-    }
-
-    GST_DEBUG_OBJECT (hlsdemux, "Typefind result: %" GST_PTR_FORMAT " prob:%d",
-        caps, prob);
-
-    if (!hlsdemux->input_caps
-        || !gst_caps_is_equal (caps, hlsdemux->input_caps)) {
-      gst_caps_replace (&hlsdemux->input_caps, caps);
-      GST_INFO_OBJECT (demux, "Input source caps: %" GST_PTR_FORMAT,
-          hlsdemux->input_caps);
-    }
-    gst_adaptive_demux_stream_set_caps (stream, caps);
-    hlsdemux->do_typefind = FALSE;
-  }
-
-  if (buffer) {
-    return gst_adaptive_demux_stream_push_buffer (stream, buffer);
-  }
-  return GST_FLOW_OK;
+  return gst_hls_demux_handle_buffer (demux, stream, buffer, FALSE);
 }
 
 static gboolean
@@ -852,6 +857,7 @@
 gst_hls_demux_update_playlist (GstHLSDemux * demux, gboolean update,
     GError ** err)
 {
+  GstAdaptiveDemux *adaptive_demux = GST_ADAPTIVE_DEMUX (demux);
   GstFragment *download;
   GstBuffer *buf;
   gchar *playlist;
@@ -862,7 +868,7 @@
   uri = gst_m3u8_client_get_current_uri (demux->client);
   main_uri = gst_m3u8_client_get_uri (demux->client);
   download =
-      gst_uri_downloader_fetch_uri (demux->downloader, uri, main_uri,
+      gst_uri_downloader_fetch_uri (adaptive_demux->downloader, uri, main_uri,
       TRUE, TRUE, TRUE, err);
   g_free (main_uri);
   if (download == NULL) {
@@ -875,7 +881,7 @@
           "Updating playlist %s failed, attempt to refresh variant playlist %s",
           uri, main_uri);
       download =
-          gst_uri_downloader_fetch_uri (demux->downloader,
+          gst_uri_downloader_fetch_uri (adaptive_demux->downloader,
           main_uri, NULL, TRUE, TRUE, TRUE, &err2);
       g_free (main_uri);
       g_clear_error (&err2);
diff --git a/ext/hls/gsthlsdemux.h b/ext/hls/gsthlsdemux.h
index 77f7414..7acfead 100644
--- a/ext/hls/gsthlsdemux.h
+++ b/ext/hls/gsthlsdemux.h
@@ -27,7 +27,6 @@
 #include <gst/gst.h>
 #include "m3u8.h"
 #include "gstfragmented.h"
-#include <gst/uridownloader/gsturidownloader.h>
 #include <gst/adaptivedemux/gstadaptivedemux.h>
 #if defined(HAVE_OPENSSL)
 #include <openssl/evp.h>
@@ -68,7 +67,6 @@
   gint srcpad_counter;
 
   GstCaps *input_caps;
-  GstUriDownloader *downloader;
   gchar *uri;                   /* Original playlist URI */
   GstM3U8Client *client;        /* M3U8 client */
   gboolean do_typefind;         /* Whether we need to typefind the next buffer */
diff --git a/ext/hls/gsthlssink.c b/ext/hls/gsthlssink.c
index ea337ea..de5e84c 100644
--- a/ext/hls/gsthlssink.c
+++ b/ext/hls/gsthlssink.c
@@ -85,6 +85,8 @@
 static GstStateChangeReturn
 gst_hls_sink_change_state (GstElement * element, GstStateChange trans);
 static gboolean schedule_next_key_unit (GstHlsSink * sink);
+static GstFlowReturn gst_hls_sink_chain_list (GstPad * pad, GstObject * parent,
+    GstBufferList * list);
 
 static void
 gst_hls_sink_dispose (GObject * object)
@@ -180,6 +182,7 @@
       gst_hls_sink_ghost_event_probe, sink, NULL);
   gst_pad_add_probe (sink->ghostpad, GST_PAD_PROBE_TYPE_BUFFER,
       gst_hls_sink_ghost_buffer_probe, sink, NULL);
+  gst_pad_set_chain_list_function (sink->ghostpad, gst_hls_sink_chain_list);
 
   sink->location = g_strdup (DEFAULT_LOCATION);
   sink->playlist_location = g_strdup (DEFAULT_PLAYLIST_LOCATION);
@@ -250,6 +253,25 @@
 }
 
 static void
+gst_hls_sink_write_playlist (GstHlsSink * sink)
+{
+  char *playlist_content;
+  GError *error = NULL;
+
+  playlist_content = gst_m3u8_playlist_render (sink->playlist);
+  if (!g_file_set_contents (sink->playlist_location,
+          playlist_content, -1, &error)) {
+    GST_ERROR ("Failed to write playlist: %s", error->message);
+    GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
+        (("Failed to write playlist '%s'."), error->message), (NULL));
+    g_error_free (error);
+    error = NULL;
+  }
+  g_free (playlist_content);
+
+}
+
+static void
 gst_hls_sink_handle_message (GstBin * bin, GstMessage * message)
 {
   GstHlsSink *sink = GST_HLS_SINK_CAST (bin);
@@ -258,10 +280,8 @@
     case GST_MESSAGE_ELEMENT:
     {
       const char *filename;
-      char *playlist_content;
       GstClockTime running_time, duration;
       gboolean discont = FALSE;
-      GError *error = NULL;
       gchar *entry_location;
       const GstStructure *structure;
 
@@ -286,16 +306,8 @@
       gst_m3u8_playlist_add_entry (sink->playlist, entry_location,
           NULL, duration, sink->index, discont);
       g_free (entry_location);
-      playlist_content = gst_m3u8_playlist_render (sink->playlist);
-      if (!g_file_set_contents (sink->playlist_location,
-              playlist_content, -1, &error)) {
-        GST_ERROR ("Failed to write playlist: %s", error->message);
-        GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
-            (("Failed to write playlist '%s'."), error->message), (NULL));
-        g_error_free (error);
-        error = NULL;
-      }
-      g_free (playlist_content);
+
+      gst_hls_sink_write_playlist (sink);
 
       /* multifilesink is starting a new file. It means that upstream sent a key
        * unit and we can schedule the next key unit now.
@@ -310,6 +322,11 @@
       message = NULL;
       break;
     }
+    case GST_MESSAGE_EOS:{
+      sink->playlist->end_list = TRUE;
+      gst_hls_sink_write_playlist (sink);
+      break;
+    }
     default:
       break;
   }
@@ -499,6 +516,19 @@
   return res;
 }
 
+static void
+gst_hls_sink_check_schedule_next_key_unit (GstHlsSink * sink, GstBuffer * buf)
+{
+  GstClockTime timestamp;
+
+  timestamp = GST_BUFFER_TIMESTAMP (buf);
+  if (!GST_CLOCK_TIME_IS_VALID (timestamp))
+    return;
+
+  sink->last_running_time = gst_segment_to_running_time (&sink->segment,
+      GST_FORMAT_TIME, timestamp);
+  schedule_next_key_unit (sink);
+}
 
 static GstPadProbeReturn
 gst_hls_sink_ghost_buffer_probe (GstPad * pad, GstPadProbeInfo * info,
@@ -506,19 +536,45 @@
 {
   GstHlsSink *sink = GST_HLS_SINK_CAST (data);
   GstBuffer *buffer = gst_pad_probe_info_get_buffer (info);
-  GstClockTime timestamp;
 
-  timestamp = GST_BUFFER_TIMESTAMP (buffer);
-  if (sink->target_duration == 0 || !GST_CLOCK_TIME_IS_VALID (timestamp)
-      || sink->waiting_fku)
+  if (sink->target_duration == 0 || sink->waiting_fku)
     return GST_PAD_PROBE_OK;
 
-  sink->last_running_time = gst_segment_to_running_time (&sink->segment,
-      GST_FORMAT_TIME, timestamp);
-  schedule_next_key_unit (sink);
+  gst_hls_sink_check_schedule_next_key_unit (sink, buffer);
   return GST_PAD_PROBE_OK;
 }
 
+static GstFlowReturn
+gst_hls_sink_chain_list (GstPad * pad, GstObject * parent, GstBufferList * list)
+{
+  guint i, len;
+  GstBuffer *buffer;
+  GstFlowReturn ret;
+  GstHlsSink *sink = GST_HLS_SINK_CAST (parent);
+
+  if (sink->target_duration == 0 || sink->waiting_fku)
+    return gst_proxy_pad_chain_list_default (pad, parent, list);
+
+  GST_DEBUG_OBJECT (pad, "chaining each group in list as a merged buffer");
+
+  len = gst_buffer_list_length (list);
+
+  ret = GST_FLOW_OK;
+  for (i = 0; i < len; i++) {
+    buffer = gst_buffer_list_get (list, i);
+
+    if (!sink->waiting_fku)
+      gst_hls_sink_check_schedule_next_key_unit (sink, buffer);
+
+    ret = gst_pad_chain (pad, gst_buffer_ref (buffer));
+    if (ret != GST_FLOW_OK)
+      break;
+  }
+  gst_buffer_list_unref (list);
+
+  return ret;
+}
+
 gboolean
 gst_hls_sink_plugin_init (GstPlugin * plugin)
 {
diff --git a/ext/hls/m3u8.c b/ext/hls/m3u8.c
index 9645256..0d1f892 100755
--- a/ext/hls/m3u8.c
+++ b/ext/hls/m3u8.c
@@ -925,15 +925,16 @@
     }
 
     if (unmatched_lists != NULL) {
-      g_list_free (unmatched_lists);
+      GST_WARNING ("Unable to match all playlists");
 
-      /* We should attempt to handle the case where playlists are dropped/replaced,
-       * and possibly switch over to a comparable (not neccessarily identical)
-       * playlist.
-       */
-      GST_FIXME
-          ("Cannot update variant playlist, unable to match all playlists");
-      goto out;
+      for (list_entry = unmatched_lists; list_entry;
+          list_entry = list_entry->next) {
+        if (list_entry->data == self->current) {
+          GST_WARNING ("Unable to match current playlist");
+        }
+      }
+
+      g_list_free (unmatched_lists);
     }
 
     /* Switch out the variant playlist */
diff --git a/ext/libde265/libde265-dec.c b/ext/libde265/libde265-dec.c
index 0c530ae..a57bd5b 100644
--- a/ext/libde265/libde265-dec.c
+++ b/ext/libde265/libde265-dec.c
@@ -36,14 +36,62 @@
 #include "config.h"
 #endif
 
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+
+#include "libde265-dec.h"
+
+#if !GLIB_CHECK_VERSION(2, 36, 0)
+#include <stdio.h>
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#ifdef G_OS_WIN32
+#include <windows.h>
+#endif
+#define g_get_num_processors gst_g_get_num_processors
+static guint
+gst_g_get_num_processors (void)
+{
+  guint threads = 0;
 
-#include "libde265-dec.h"
+#if defined(_SC_NPROC_ONLN)
+  threads = sysconf (_SC_NPROC_ONLN);
+#elif defined(_SC_NPROCESSORS_ONLN)
+  threads = sysconf (_SC_NPROCESSORS_ONLN);
+#elif defined(G_OS_WIN32)
+  {
+    SYSTEM_INFO sysinfo;
+    DWORD_PTR process_cpus;
+    DWORD_PTR system_cpus;
+
+    /* This *never* fails, but doesn't take CPU affinity into account */
+    GetSystemInfo (&sysinfo);
+    threads = (int) sysinfo.dwNumberOfProcessors;
+
+    /* This *can* fail, but produces correct results if affinity mask is used,
+     * unlike the simpler code above.
+     */
+    if (GetProcessAffinityMask (GetCurrentProcess (),
+            &process_cpus, &system_cpus)) {
+      unsigned int count;
+
+      for (count = 0; process_cpus != 0; process_cpus >>= 1)
+        if (process_cpus & 1)
+          count++;
+    }
+  }
+#else
+#warning "Don't know how to get number of CPU cores, will use the default thread count"
+  threads = DEFAULT_THREAD_COUNT;
+#endif
+
+  if (threads > 0)
+    return threads;
+
+  return 1;
+}
+#endif /* !GLIB_CHECK_VERSION(2, 36, 0) */
 
 /* use two decoder threads if no information about
  * available CPU cores can be retrieved */
@@ -374,17 +422,8 @@
     return FALSE;
   }
   if (threads == 0) {
-#if defined(_SC_NPROC_ONLN)
-    threads = sysconf (_SC_NPROC_ONLN);
-#elif defined(_SC_NPROCESSORS_ONLN)
-    threads = sysconf (_SC_NPROCESSORS_ONLN);
-#else
-#warning "Don't know how to get number of CPU cores, will use the default thread count"
-    threads = DEFAULT_THREAD_COUNT;
-#endif
-    if (threads <= 0) {
-      threads = DEFAULT_THREAD_COUNT;
-    }
+    threads = g_get_num_processors ();
+
     /* NOTE: We start more threads than cores for now, as some threads
      * might get blocked while waiting for dependent data. Having more
      * threads increases decoding speed by about 10% */
@@ -601,8 +640,8 @@
             int nal_count;
             if (pos + 3 > size) {
               GST_ELEMENT_ERROR (decoder, STREAM, DECODE,
-                  ("Buffer underrun in extra header (%d >= %ld)", pos + 3,
-                      size), (NULL));
+                  ("Buffer underrun in extra header (%d >= %" G_GSIZE_FORMAT
+                      ")", pos + 3, size), (NULL));
               return FALSE;
             }
             /* ignore flags + NAL type (1 byte) */
@@ -612,14 +651,14 @@
               int nal_size;
               if (pos + 2 > size) {
                 GST_ELEMENT_ERROR (decoder, STREAM, DECODE,
-                    ("Buffer underrun in extra nal header (%d >= %ld)", pos + 2,
-                        size), (NULL));
+                    ("Buffer underrun in extra nal header (%d >= %"
+                        G_GSIZE_FORMAT ")", pos + 2, size), (NULL));
                 return FALSE;
               }
               nal_size = data[pos] << 8 | data[pos + 1];
               if (pos + 2 + nal_size > size) {
                 GST_ELEMENT_ERROR (decoder, STREAM, DECODE,
-                    ("Buffer underrun in extra nal (%d >= %ld)",
+                    ("Buffer underrun in extra nal (%d >= %" G_GSIZE_FORMAT ")",
                         pos + 2 + nal_size, size), (NULL));
                 return FALSE;
               }
diff --git a/ext/mpg123/Makefile.am b/ext/mpg123/Makefile.am
index 3acdfa4..6c96207 100644
--- a/ext/mpg123/Makefile.am
+++ b/ext/mpg123/Makefile.am
@@ -10,18 +10,3 @@
 libgstmpg123_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstmpg123audiodec.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstmpg123 -:SHARED libgstmpg123 \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstmpg123_la_SOURCES) \
-	 -:CPPFLAGS $(CPPFLAGS) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmpg123_la_CFLAGS) \
-	 -:LDFLAGS $(libgstmpg123_la_LDFLAGS) \
-	           $(libgstmpg123_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-@GST_API_VERSION@' \
-	> $@
diff --git a/ext/mpg123/Makefile.in b/ext/mpg123/Makefile.in
index 8f13897..7d53fb9 100644
--- a/ext/mpg123/Makefile.in
+++ b/ext/mpg123/Makefile.in
@@ -1073,21 +1073,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstmpg123 -:SHARED libgstmpg123 \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstmpg123_la_SOURCES) \
-	 -:CPPFLAGS $(CPPFLAGS) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmpg123_la_CFLAGS) \
-	 -:LDFLAGS $(libgstmpg123_la_LDFLAGS) \
-	           $(libgstmpg123_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-@GST_API_VERSION@' \
-	> $@
-
 # 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/ext/opencv/MotionCells.cpp b/ext/opencv/MotionCells.cpp
index 449fe24..eaa013f 100644
--- a/ext/opencv/MotionCells.cpp
+++ b/ext/opencv/MotionCells.cpp
@@ -54,6 +54,7 @@
 #include <math.h>
 #include <gst/gst.h>
 #include "MotionCells.h"
+#include <opencv2/imgproc/imgproc_c.h>
 
 MotionCells::MotionCells ()
 {
diff --git a/ext/opencv/MotionCells.h b/ext/opencv/MotionCells.h
index 5c6d131..41bb9c7 100644
--- a/ext/opencv/MotionCells.h
+++ b/ext/opencv/MotionCells.h
@@ -45,7 +45,7 @@
 #ifndef MOTIONCELLS_H_
 #define MOTIONCELLS_H_
 
-#include <cv.h>                 // includes OpenCV definitions
+#include <opencv2/core/core_c.h>
 #ifdef HAVE_HIGHGUI_H
 #include <highgui.h>            // includes highGUI definitions
 #endif
diff --git a/ext/opencv/gstcvdilate.c b/ext/opencv/gstcvdilate.c
index 3b55f45..da0713d 100644
--- a/ext/opencv/gstcvdilate.c
+++ b/ext/opencv/gstcvdilate.c
@@ -48,6 +48,7 @@
 #include <gst/gst.h>
 
 #include "gstcvdilate.h"
+#include <opencv2/imgproc/imgproc_c.h>
 
 GST_DEBUG_CATEGORY_STATIC (gst_cv_dilate_debug);
 #define GST_CAT_DEFAULT gst_cv_dilate_debug
diff --git a/ext/opencv/gstcvdilate.h b/ext/opencv/gstcvdilate.h
index 21c3fbf..fdacdd8 100644
--- a/ext/opencv/gstcvdilate.h
+++ b/ext/opencv/gstcvdilate.h
@@ -45,7 +45,7 @@
 #define __GST_CV_DILATE_H__
 
 #include <gst/gst.h>
-#include <cv.h>
+
 #include "gstcvdilateerode.h"
 
 G_BEGIN_DECLS
diff --git a/ext/opencv/gstcvdilateerode.h b/ext/opencv/gstcvdilateerode.h
index 20b55a6..94425f5 100644
--- a/ext/opencv/gstcvdilateerode.h
+++ b/ext/opencv/gstcvdilateerode.h
@@ -45,7 +45,7 @@
 #define __GST_CV_DILATE_ERODE_H__
 
 #include <gst/gst.h>
-#include <cv.h>
+
 #include <gstopencvvideofilter.h>
 
 G_BEGIN_DECLS
diff --git a/ext/opencv/gstcvequalizehist.c b/ext/opencv/gstcvequalizehist.c
index 5c6526a..7384df1 100644
--- a/ext/opencv/gstcvequalizehist.c
+++ b/ext/opencv/gstcvequalizehist.c
@@ -49,6 +49,7 @@
 
 #include "gstopencvutils.h"
 #include "gstcvequalizehist.h"
+#include <opencv2/imgproc/imgproc_c.h>
 
 GST_DEBUG_CATEGORY_STATIC (gst_cv_equalize_hist_debug);
 #define GST_CAT_DEFAULT gst_cv_equalize_hist_debug
diff --git a/ext/opencv/gstcvequalizehist.h b/ext/opencv/gstcvequalizehist.h
index 0be379d..d1d600d 100644
--- a/ext/opencv/gstcvequalizehist.h
+++ b/ext/opencv/gstcvequalizehist.h
@@ -45,7 +45,7 @@
 #define __GST_CV_EQUALIZE_HIST_H__
 
 #include <gst/gst.h>
-#include <cv.h>
+
 #include <gstopencvvideofilter.h>
 
 G_BEGIN_DECLS
diff --git a/ext/opencv/gstcverode.c b/ext/opencv/gstcverode.c
index a869a84..4c62624 100644
--- a/ext/opencv/gstcverode.c
+++ b/ext/opencv/gstcverode.c
@@ -48,6 +48,7 @@
 #include <gst/gst.h>
 
 #include "gstcverode.h"
+#include <opencv2/imgproc/imgproc_c.h>
 
 GST_DEBUG_CATEGORY_STATIC (gst_cv_erode_debug);
 #define GST_CAT_DEFAULT gst_cv_erode_debug
diff --git a/ext/opencv/gstcverode.h b/ext/opencv/gstcverode.h
index bc474f3..3f2944a 100644
--- a/ext/opencv/gstcverode.h
+++ b/ext/opencv/gstcverode.h
@@ -45,7 +45,7 @@
 #define __GST_CV_ERODE_H__
 
 #include <gst/gst.h>
-#include <cv.h>
+
 #include "gstcvdilateerode.h"
 
 G_BEGIN_DECLS
diff --git a/ext/opencv/gstcvlaplace.c b/ext/opencv/gstcvlaplace.c
index bd71ae6..5b95618 100644
--- a/ext/opencv/gstcvlaplace.c
+++ b/ext/opencv/gstcvlaplace.c
@@ -49,6 +49,7 @@
 
 #include "gstopencvutils.h"
 #include "gstcvlaplace.h"
+#include <opencv2/imgproc/imgproc_c.h>
 
 GST_DEBUG_CATEGORY_STATIC (gst_cv_laplace_debug);
 #define GST_CAT_DEFAULT gst_cv_laplace_debug
diff --git a/ext/opencv/gstcvlaplace.h b/ext/opencv/gstcvlaplace.h
index 93201e4..098b347 100644
--- a/ext/opencv/gstcvlaplace.h
+++ b/ext/opencv/gstcvlaplace.h
@@ -45,7 +45,7 @@
 #define __GST_CV_LAPLACE_H__
 
 #include <gst/gst.h>
-#include <cv.h>
+
 #include <gstopencvvideofilter.h>
 
 G_BEGIN_DECLS
diff --git a/ext/opencv/gstcvsmooth.c b/ext/opencv/gstcvsmooth.c
index ec36173..67f403e 100644
--- a/ext/opencv/gstcvsmooth.c
+++ b/ext/opencv/gstcvsmooth.c
@@ -49,6 +49,7 @@
 
 #include "gstopencvutils.h"
 #include "gstcvsmooth.h"
+#include <opencv2/imgproc/imgproc_c.h>
 
 GST_DEBUG_CATEGORY_STATIC (gst_cv_smooth_debug);
 #define GST_CAT_DEFAULT gst_cv_smooth_debug
diff --git a/ext/opencv/gstcvsmooth.h b/ext/opencv/gstcvsmooth.h
index 16521d9..9a62e91 100644
--- a/ext/opencv/gstcvsmooth.h
+++ b/ext/opencv/gstcvsmooth.h
@@ -45,7 +45,7 @@
 #define __GST_CV_SMOOTH_H__
 
 #include <gst/gst.h>
-#include <cv.h>
+
 #include <gstopencvvideofilter.h>
 
 G_BEGIN_DECLS
diff --git a/ext/opencv/gstcvsobel.c b/ext/opencv/gstcvsobel.c
index cd21189..1d9b151 100644
--- a/ext/opencv/gstcvsobel.c
+++ b/ext/opencv/gstcvsobel.c
@@ -49,6 +49,7 @@
 
 #include "gstopencvutils.h"
 #include "gstcvsobel.h"
+#include <opencv2/imgproc/imgproc_c.h>
 
 GST_DEBUG_CATEGORY_STATIC (gst_cv_sobel_debug);
 #define GST_CAT_DEFAULT gst_cv_sobel_debug
diff --git a/ext/opencv/gstcvsobel.h b/ext/opencv/gstcvsobel.h
index 55885d3..c6719a0 100644
--- a/ext/opencv/gstcvsobel.h
+++ b/ext/opencv/gstcvsobel.h
@@ -45,7 +45,7 @@
 #define __GST_CV_SOBEL_H__
 
 #include <gst/gst.h>
-#include <cv.h>
+
 #include <gstopencvvideofilter.h>
 
 G_BEGIN_DECLS
diff --git a/ext/opencv/gstdisparity.h b/ext/opencv/gstdisparity.h
index a1e0bdc..adbb9ae 100644
--- a/ext/opencv/gstdisparity.h
+++ b/ext/opencv/gstdisparity.h
@@ -45,7 +45,7 @@
 #define __GST_DISPARITY_H__
 
 #include <gst/gst.h>
-#include <cv.h>
+
 #include <opencv2/legacy/legacy.hpp>
 
 G_BEGIN_DECLS
diff --git a/ext/opencv/gstedgedetect.c b/ext/opencv/gstedgedetect.c
index bb85de4..14781bd 100644
--- a/ext/opencv/gstedgedetect.c
+++ b/ext/opencv/gstedgedetect.c
@@ -64,6 +64,7 @@
 
 #include "gstopencvutils.h"
 #include "gstedgedetect.h"
+#include <opencv2/imgproc/imgproc_c.h>
 
 GST_DEBUG_CATEGORY_STATIC (gst_edge_detect_debug);
 #define GST_CAT_DEFAULT gst_edge_detect_debug
diff --git a/ext/opencv/gstedgedetect.h b/ext/opencv/gstedgedetect.h
index 065dccf..23c95e6 100644
--- a/ext/opencv/gstedgedetect.h
+++ b/ext/opencv/gstedgedetect.h
@@ -47,7 +47,7 @@
 #define __GST_EDGE_DETECT_H__
 
 #include <gst/gst.h>
-#include <cv.h>
+#include <opencv2/core/core_c.h>
 
 G_BEGIN_DECLS
 /* #defines don't like whitespacey bits */
diff --git a/ext/opencv/gstfaceblur.c b/ext/opencv/gstfaceblur.c
index cadeaed..11d9145 100644
--- a/ext/opencv/gstfaceblur.c
+++ b/ext/opencv/gstfaceblur.c
@@ -65,6 +65,7 @@
 
 #include "gstopencvutils.h"
 #include "gstfaceblur.h"
+#include <opencv2/imgproc/imgproc_c.h>
 
 GST_DEBUG_CATEGORY_STATIC (gst_face_blur_debug);
 #define GST_CAT_DEFAULT gst_face_blur_debug
diff --git a/ext/opencv/gstfaceblur.h b/ext/opencv/gstfaceblur.h
index a6ee28e..23fa7fc 100644
--- a/ext/opencv/gstfaceblur.h
+++ b/ext/opencv/gstfaceblur.h
@@ -48,7 +48,7 @@
 #define __GST_FACE_BLUR_H__
 
 #include <gst/gst.h>
-#include <cv.h>
+#include <opencv2/core/version.hpp>
 
 #include "gstopencvvideofilter.h"
 
diff --git a/ext/opencv/gstfacedetect.c b/ext/opencv/gstfacedetect.c
index fa01268..0f9425b 100644
--- a/ext/opencv/gstfacedetect.c
+++ b/ext/opencv/gstfacedetect.c
@@ -81,6 +81,7 @@
 
 #include "gstopencvutils.h"
 #include "gstfacedetect.h"
+#include <opencv2/imgproc/imgproc_c.h>
 
 GST_DEBUG_CATEGORY_STATIC (gst_face_detect_debug);
 #define GST_CAT_DEFAULT gst_face_detect_debug
diff --git a/ext/opencv/gstfacedetect.h b/ext/opencv/gstfacedetect.h
index 090fb79..6db7033 100644
--- a/ext/opencv/gstfacedetect.h
+++ b/ext/opencv/gstfacedetect.h
@@ -49,7 +49,7 @@
 #define __GST_FACE_DETECT_H__
 
 #include <gst/gst.h>
-#include <cv.h>
+#include <opencv2/core/version.hpp>
 #include "gstopencvvideofilter.h"
 
 #if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2)
diff --git a/ext/opencv/gstgrabcut.cpp b/ext/opencv/gstgrabcut.cpp
index 8b57306..c9ff4f9 100644
--- a/ext/opencv/gstgrabcut.cpp
+++ b/ext/opencv/gstgrabcut.cpp
@@ -89,7 +89,9 @@
 extern "C"
 {
 #include <gst/video/gstvideometa.h>
+#include <opencv2/imgproc/imgproc_c.h>
 }
+#include <opencv2/imgproc/imgproc.hpp>
 GST_DEBUG_CATEGORY_STATIC (gst_grabcut_debug);
 #define GST_CAT_DEFAULT gst_grabcut_debug
 
diff --git a/ext/opencv/gstgrabcut.h b/ext/opencv/gstgrabcut.h
index ec7dc96..de988bb 100644
--- a/ext/opencv/gstgrabcut.h
+++ b/ext/opencv/gstgrabcut.h
@@ -47,8 +47,9 @@
 #include <gst/gst.h>
 #include <gst/video/video.h>
 #include <gst/video/gstvideofilter.h>
+#include <opencv2/core/core_c.h>
 
-#include <cv.h>
+
 
 G_BEGIN_DECLS
 /* #defines don't like whitespacey bits */
diff --git a/ext/opencv/gsthanddetect.c b/ext/opencv/gsthanddetect.c
index d01a42e..8c72b72 100644
--- a/ext/opencv/gsthanddetect.c
+++ b/ext/opencv/gsthanddetect.c
@@ -63,6 +63,7 @@
 /* element header */
 #include "gsthanddetect.h"
 #include "gstopencvutils.h"
+#include <opencv2/imgproc/imgproc_c.h>
 
 GST_DEBUG_CATEGORY_STATIC (gst_handdetect_debug);
 #define GST_CAT_DEFAULT gst_handdetect_debug
@@ -429,7 +430,7 @@
     if (filter->prev_r == NULL)
       filter->prev_r = &temp_r;
     /* Get the best FIST gesture */
-    for (i = 0; i < (hands ? hands->total : 0); i++) {
+    for (i = 0; i < hands->total; i++) {
       r = (CvRect *) cvGetSeqElem (hands, i);
       distance = (int) sqrt (pow ((r->x - filter->prev_r->x),
               2) + pow ((r->y - filter->prev_r->y), 2));
diff --git a/ext/opencv/gsthanddetect.h b/ext/opencv/gsthanddetect.h
index 129784f..e57f567 100644
--- a/ext/opencv/gsthanddetect.h
+++ b/ext/opencv/gsthanddetect.h
@@ -51,9 +51,13 @@
 
 #include "gstopencvvideofilter.h"
 /* opencv */
-#include <cv.h>
-#include <cxcore.h>
-#include <highgui.h>
+#include <opencv2/core/version.hpp>
+#ifdef HAVE_HIGHGUI_H
+#include <highgui.h>            // includes highGUI definitions
+#endif
+#ifdef HAVE_OPENCV2_HIGHGUI_HIGHGUI_C_H
+#include <opencv2/highgui/highgui_c.h>            // includes highGUI definitions
+#endif
 #if (CV_MAJOR_VERSION >= 2) && (CV_MINOR_VERSION >= 2)
 #include <opencv2/objdetect/objdetect.hpp>
 #endif
diff --git a/ext/opencv/gstmotioncells.h b/ext/opencv/gstmotioncells.h
index 6d4b123..08eed3e 100644
--- a/ext/opencv/gstmotioncells.h
+++ b/ext/opencv/gstmotioncells.h
@@ -46,7 +46,7 @@
 #define __GST_MOTIONCELLS_H__
 
 #include <gst/gst.h>
-#include <cv.h>
+#include <opencv2/core/core_c.h>
 
 G_BEGIN_DECLS
 /* #defines don't like whitespacey bits */
diff --git a/ext/opencv/gstopencvutils.c b/ext/opencv/gstopencvutils.c
index 6655b07..89901bf 100644
--- a/ext/opencv/gstopencvutils.c
+++ b/ext/opencv/gstopencvutils.c
@@ -24,6 +24,7 @@
 #endif
 
 #include "gstopencvutils.h"
+#include <opencv2/core/types_c.h>
 
 static gboolean
 gst_opencv_get_ipl_depth_and_channels (GstStructure * structure,
diff --git a/ext/opencv/gstopencvutils.h b/ext/opencv/gstopencvutils.h
index 82a2795..84123f1 100644
--- a/ext/opencv/gstopencvutils.h
+++ b/ext/opencv/gstopencvutils.h
@@ -29,7 +29,7 @@
 #include <gst/gst.h>
 #include <gst/video/video.h>
 
-#include <cv.h>
+
 
 gboolean
 gst_opencv_get_ipldepth (gint depth, gint bpp, gint * ipldepth);
diff --git a/ext/opencv/gstopencvvideofilter.h b/ext/opencv/gstopencvvideofilter.h
index fce3b32..7fbafe9 100644
--- a/ext/opencv/gstopencvvideofilter.h
+++ b/ext/opencv/gstopencvvideofilter.h
@@ -46,7 +46,7 @@
 
 #include <gst/gst.h>
 #include <gst/video/gstvideofilter.h>
-#include <cv.h>
+#include <opencv2/core/core_c.h>
 
 G_BEGIN_DECLS
 /* #defines don't like whitespacey bits */
diff --git a/ext/opencv/gstpyramidsegment.h b/ext/opencv/gstpyramidsegment.h
index 7d7bcf5..586ef2c 100644
--- a/ext/opencv/gstpyramidsegment.h
+++ b/ext/opencv/gstpyramidsegment.h
@@ -47,7 +47,7 @@
 #define __GST_PYRAMID_SEGMENT_H__
 
 #include <gst/gst.h>
-#include <cv.h>
+#include <opencv2/core/version.hpp>
 
 #if CV_MAJOR_VERSION * 100 + CV_MINOR_VERSION >= 204
 #include <opencv2/legacy/legacy.hpp>
diff --git a/ext/opencv/gstretinex.c b/ext/opencv/gstretinex.c
index 8c64b80..5bc112a 100644
--- a/ext/opencv/gstretinex.c
+++ b/ext/opencv/gstretinex.c
@@ -64,6 +64,7 @@
 
 #include <gst/gst.h>
 #include "gstretinex.h"
+#include <opencv2/imgproc/imgproc_c.h>
 
 GST_DEBUG_CATEGORY_STATIC (gst_retinex_debug);
 #define GST_CAT_DEFAULT gst_retinex_debug
diff --git a/ext/opencv/gstretinex.h b/ext/opencv/gstretinex.h
index 24a7c5e..c53d230 100644
--- a/ext/opencv/gstretinex.h
+++ b/ext/opencv/gstretinex.h
@@ -47,8 +47,8 @@
 #include <gst/gst.h>
 #include <gst/video/video.h>
 #include <gst/video/gstvideofilter.h>
+#include <opencv2/core/core_c.h>
 
-#include <cv.h>
 
 G_BEGIN_DECLS
 /* #defines don't like whitespacey bits */
diff --git a/ext/opencv/gstsegmentation.cpp b/ext/opencv/gstsegmentation.cpp
index ec03b80..79cbb49 100644
--- a/ext/opencv/gstsegmentation.cpp
+++ b/ext/opencv/gstsegmentation.cpp
@@ -94,6 +94,7 @@
 
 #include "gstsegmentation.h"
 #include <opencv2/video/background_segm.hpp>
+#include <opencv2/imgproc/imgproc_c.h>
 
 GST_DEBUG_CATEGORY_STATIC (gst_segmentation_debug);
 #define GST_CAT_DEFAULT gst_segmentation_debug
diff --git a/ext/opencv/gstsegmentation.h b/ext/opencv/gstsegmentation.h
index 0357770..9400853 100644
--- a/ext/opencv/gstsegmentation.h
+++ b/ext/opencv/gstsegmentation.h
@@ -46,8 +46,9 @@
 
 #include <gst/gst.h>
 #include <gst/video/gstvideofilter.h>
+#include <opencv2/core/core_c.h>
 
-#include <cv.h>
+
 
 G_BEGIN_DECLS
 /* #defines don't like whitespacey bits */
diff --git a/ext/opencv/gstskindetect.c b/ext/opencv/gstskindetect.c
index 9cd5633..caf38ec 100644
--- a/ext/opencv/gstskindetect.c
+++ b/ext/opencv/gstskindetect.c
@@ -62,6 +62,8 @@
 
 #include "gstopencvutils.h"
 #include "gstskindetect.h"
+#include <opencv2/imgproc/imgproc_c.h>
+#include <opencv2/legacy/compat.hpp>
 
 GST_DEBUG_CATEGORY_STATIC (gst_skin_detect_debug);
 #define GST_CAT_DEFAULT gst_skin_detect_debug
diff --git a/ext/opencv/gstskindetect.h b/ext/opencv/gstskindetect.h
index 9789834..910d22e 100644
--- a/ext/opencv/gstskindetect.h
+++ b/ext/opencv/gstskindetect.h
@@ -47,7 +47,7 @@
 #define __GST_SKIN_DETECT_H__
 
 #include <gst/gst.h>
-#include <cv.h>
+
 #include <gstopencvvideofilter.h>
 
 G_BEGIN_DECLS
diff --git a/ext/opencv/gsttemplatematch.c b/ext/opencv/gsttemplatematch.c
index 602dd8e..3c97841 100644
--- a/ext/opencv/gsttemplatematch.c
+++ b/ext/opencv/gsttemplatematch.c
@@ -66,6 +66,7 @@
 #include "../../gst-libs/gst/gst-i18n-plugin.h"
 #include "gstopencvutils.h"
 #include "gsttemplatematch.h"
+#include <opencv2/imgproc/imgproc_c.h>
 
 GST_DEBUG_CATEGORY_STATIC (gst_template_match_debug);
 #define GST_CAT_DEFAULT gst_template_match_debug
diff --git a/ext/opencv/gsttemplatematch.h b/ext/opencv/gsttemplatematch.h
index 6b67000..44d3d9c 100644
--- a/ext/opencv/gsttemplatematch.h
+++ b/ext/opencv/gsttemplatematch.h
@@ -47,7 +47,7 @@
 #define __GST_TEMPLATE_MATCH_H__
 
 #include <gst/gst.h>
-#include <cv.h>
+
 #ifdef HAVE_HIGHGUI_H
 #include <highgui.h>            // includes highGUI definitions
 #endif
diff --git a/ext/opencv/gsttextoverlay.h b/ext/opencv/gsttextoverlay.h
index cf59b35..1fe8d22 100644
--- a/ext/opencv/gsttextoverlay.h
+++ b/ext/opencv/gsttextoverlay.h
@@ -48,6 +48,7 @@
 
 #include <gst/gst.h>
 #include "gstopencvutils.h"
+#include <opencv2/core/core_c.h>
 G_BEGIN_DECLS
 
 /* #defines don't like whitespacey bits */
diff --git a/ext/openh264/gstopenh264enc.cpp b/ext/openh264/gstopenh264enc.cpp
index ebbe9b4..4461ae2 100644
--- a/ext/openh264/gstopenh264enc.cpp
+++ b/ext/openh264/gstopenh264enc.cpp
@@ -38,6 +38,7 @@
 #include <wels/codec_api.h>
 #include <wels/codec_app_def.h>
 #include <wels/codec_def.h>
+#include <wels/codec_ver.h>
 
 #define GST_OPENH264ENC_GET_PRIVATE(obj) \
     (G_TYPE_INSTANCE_GET_PRIVATE((obj), GST_TYPE_OPENH264ENC, GstOpenh264EncPrivate))
@@ -103,14 +104,14 @@
         "Deblocking on, except for slice boundaries", "not-slice-boundaries"},
     {0, NULL, NULL},
   };
-  static volatile GType id = 0;
+  static gsize id = 0;
 
-  if (g_once_init_enter ((gsize *) & id)) {
+  if (g_once_init_enter (& id)) {
     GType _id = g_enum_register_static ("GstOpenh264encDeblockingModes", types);
-    g_once_init_leave ((gsize *) & id, _id);
+    g_once_init_leave (& id, _id);
   }
 
-  return id;
+  return (GType) id;
 }
 
 #define GST_TYPE_OPENH264ENC_SLICE_MODE (gst_openh264enc_slice_mode_get_type ())
@@ -122,14 +123,34 @@
     {SM_AUTO_SLICE, "Number of slices equal to number of threads", "auto"},
     {0, NULL, NULL},
   };
-  static volatile GType id = 0;
+  static gsize id = 0;
 
-  if (g_once_init_enter ((gsize *) & id)) {
+  if (g_once_init_enter (& id)) {
     GType _id = g_enum_register_static ("GstOpenh264encSliceModes", types);
-    g_once_init_leave ((gsize *) & id, _id);
+    g_once_init_leave (& id, _id);
   }
 
-  return id;
+  return (GType) id;
+}
+
+#define GST_TYPE_OPENH264ENC_COMPLEXITY (gst_openh264enc_complexity_get_type ())
+static GType
+gst_openh264enc_complexity_get_type (void)
+{
+  static const GEnumValue types[] = {
+    {LOW_COMPLEXITY, "Low complexity / high speed encoding", "low"},
+    {MEDIUM_COMPLEXITY, "Medium complexity / medium speed encoding", "medium"},
+    {HIGH_COMPLEXITY, "High complexity / low speed encoding", "high"},
+    {0, NULL, NULL},
+  };
+  static gsize id = 0;
+
+  if (g_once_init_enter (& id)) {
+    GType _id = g_enum_register_static ("GstOpenh264encComplexity", types);
+    g_once_init_leave (& id, _id);
+  }
+
+  return (GType) id;
 }
 
 /* prototypes */
@@ -170,6 +191,7 @@
 #define DEFAULT_SCENE_CHANGE_DETECTION TRUE
 #define DEFAULT_SLICE_MODE      SM_FIXEDSLCNUM_SLICE
 #define DEFAULT_NUM_SLICES      1
+#define DEFAULT_COMPLEXITY      MEDIUM_COMPLEXITY
 
 enum
 {
@@ -188,6 +210,7 @@
   PROP_SCENE_CHANGE_DETECTION,
   PROP_SLICE_MODE,
   PROP_NUM_SLICES,
+  PROP_COMPLEXITY,
   N_PROPERTIES
 };
 
@@ -214,6 +237,7 @@
   gboolean scene_change_detection;
   SliceModeEnum slice_mode;
   guint num_slices;
+  ECOMPLEXITY_MODE complexity;
 };
 
 /* pad templates */
@@ -352,6 +376,11 @@
           "The number of slices (needs slice-mode=n-slices)",
           0, G_MAXUINT, DEFAULT_NUM_SLICES,
           (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_COMPLEXITY,
+      g_param_spec_enum ("complexity", "Complexity / quality / speed tradeoff", "Complexity",
+          GST_TYPE_OPENH264ENC_COMPLEXITY, DEFAULT_COMPLEXITY,
+          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
 }
 
 static void
@@ -379,6 +408,7 @@
   openh264enc->priv->slice_mode = DEFAULT_SLICE_MODE;
   openh264enc->priv->num_slices = DEFAULT_NUM_SLICES;
   openh264enc->priv->encoder = NULL;
+  openh264enc->priv->complexity = DEFAULT_COMPLEXITY;
   gst_openh264enc_set_usage_type (openh264enc, CAMERA_VIDEO_REAL_TIME);
   gst_openh264enc_set_rate_control (openh264enc, RC_QUALITY_MODE);
 }
@@ -485,6 +515,10 @@
       openh264enc->priv->num_slices = g_value_get_uint (value);
       break;
 
+    case PROP_COMPLEXITY:
+      openh264enc->priv->complexity = (ECOMPLEXITY_MODE) g_value_get_enum (value);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -556,6 +590,10 @@
       g_value_set_uint (value, openh264enc->priv->num_slices);
       break;
 
+    case PROP_COMPLEXITY:
+      g_value_set_enum (value, openh264enc->priv->complexity);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -674,6 +712,7 @@
   enc_params.iLtrMarkPeriod = 30;
   enc_params.iMultipleThreadIdc = openh264enc->priv->multi_thread;
   enc_params.bEnableDenoise = openh264enc->priv->enable_denoise;
+  enc_params.iComplexityMode = priv->complexity;
   enc_params.uiIntraPeriod = priv->gop_size;
   enc_params.bEnableBackgroundDetection =
       openh264enc->priv->background_detection;
@@ -682,7 +721,11 @@
       openh264enc->priv->scene_change_detection;
   enc_params.bEnableFrameSkip = openh264enc->priv->enable_frame_skip;
   enc_params.bEnableLongTermReference = 0;
+#if OPENH264_MINOR >= 4
+  enc_params.eSpsPpsIdStrategy = CONSTANT_ID;
+#else
   enc_params.bEnableSpsPpsIdAddition = 1;
+#endif
   enc_params.bPrefixNalAddingCtrl = 0;
   enc_params.fMaxFrameRate = fps_n * 1.0 / fps_d;
   enc_params.iLoopFilterDisableIdc = openh264enc->priv->deblocking_mode;
diff --git a/ext/opus/gstopusdec.c b/ext/opus/gstopusdec.c
index cfa711a..a634787 100644
--- a/ext/opus/gstopusdec.c
+++ b/ext/opus/gstopusdec.c
@@ -224,13 +224,11 @@
     caps = gst_caps_truncate (caps);
     caps = gst_caps_make_writable (caps);
     s = gst_caps_get_structure (caps, 0);
-    gst_structure_fixate_field_nearest_int (s, "rate", 48000);
+    gst_structure_fixate_field_nearest_int (s, "rate", dec->sample_rate);
     gst_structure_get_int (s, "rate", &dec->sample_rate);
     gst_structure_fixate_field_nearest_int (s, "channels", dec->n_channels);
     gst_structure_get_int (s, "channels", &dec->n_channels);
     gst_caps_unref (caps);
-  } else {
-    dec->sample_rate = 48000;
   }
 
   GST_INFO_OBJECT (dec, "Negotiated %d channels, %d Hz", dec->n_channels,
@@ -282,6 +280,7 @@
   }
 
   dec->n_channels = data[9];
+  dec->sample_rate = GST_READ_UINT32_LE (data + 12);
   dec->pre_skip = GST_READ_UINT16_LE (data + 10);
   dec->r128_gain = GST_READ_UINT16_LE (data + 16);
   dec->r128_gain_volume = gst_opus_dec_get_r128_volume (dec->r128_gain);
@@ -432,7 +431,9 @@
   samples = 120 * dec->sample_rate / 1000;
   packet_size = samples * dec->n_channels * 2;
 
-  outbuf = gst_buffer_new_and_alloc (packet_size);
+  outbuf =
+      gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER (dec),
+      packet_size);
   if (!outbuf) {
     goto buffer_failed;
   }
@@ -542,9 +543,22 @@
   gboolean ret = TRUE;
   GstStructure *s;
   const GValue *streamheader;
+  GstCaps *old_caps;
 
   GST_DEBUG_OBJECT (dec, "set_format: %" GST_PTR_FORMAT, caps);
 
+  if ((old_caps = gst_pad_get_current_caps (GST_AUDIO_DECODER_SINK_PAD (bdec)))) {
+    if (gst_caps_is_equal (caps, old_caps)) {
+      gst_caps_unref (old_caps);
+      GST_DEBUG_OBJECT (dec, "caps didn't change");
+      goto done;
+    }
+
+    GST_DEBUG_OBJECT (dec, "caps have changed, resetting decoder");
+    gst_opus_dec_reset (dec);
+    gst_caps_unref (old_caps);
+  }
+
   s = gst_caps_get_structure (caps, 0);
   if ((streamheader = gst_structure_get_value (s, "streamheader")) &&
       G_VALUE_HOLDS (streamheader, GST_TYPE_ARRAY) &&
@@ -570,6 +584,22 @@
         goto done;
       gst_buffer_replace (&dec->vorbiscomment, buf);
     }
+  } else {
+    /* defaults if not in the caps */
+    dec->n_channels = 2;
+    dec->sample_rate = 48000;
+
+    gst_structure_get_int (s, "channels", &dec->n_channels);
+    gst_structure_get_int (s, "rate", &dec->sample_rate);
+
+    /* default stereo mapping */
+    dec->channel_mapping_family = 0;
+    dec->channel_mapping[0] = 0;
+    dec->channel_mapping[1] = 1;
+    dec->n_streams = 1;
+    dec->n_stereo_streams = 1;
+
+    gst_opus_dec_negotiate (dec, NULL);
   }
 
 done:
diff --git a/ext/opus/gstopusdec.h b/ext/opus/gstopusdec.h
index 7248778..4a270fe 100644
--- a/ext/opus/gstopusdec.h
+++ b/ext/opus/gstopusdec.h
@@ -24,7 +24,7 @@
 
 #include <gst/gst.h>
 #include <gst/audio/gstaudiodecoder.h>
-#include <opus/opus_multistream.h>
+#include <opus_multistream.h>
 
 G_BEGIN_DECLS
 
diff --git a/ext/opus/gstopusenc.c b/ext/opus/gstopusenc.c
index cb3f276..4bac854 100644
--- a/ext/opus/gstopusenc.c
+++ b/ext/opus/gstopusenc.c
@@ -44,7 +44,7 @@
 #include <string.h>
 #include <time.h>
 #include <math.h>
-#include <opus/opus.h>
+#include <opus.h>
 
 #include <gst/gsttagsetter.h>
 #include <gst/audio/audio.h>
@@ -387,8 +387,6 @@
   GstOpusEnc *enc = GST_OPUS_ENC (benc);
 
   GST_DEBUG_OBJECT (enc, "start");
-  enc->tags = gst_tag_list_new_empty ();
-  enc->header_sent = FALSE;
   enc->encoded_samples = 0;
 
   return TRUE;
@@ -400,16 +398,10 @@
   GstOpusEnc *enc = GST_OPUS_ENC (benc);
 
   GST_DEBUG_OBJECT (enc, "stop");
-  enc->header_sent = FALSE;
   if (enc->state) {
     opus_multistream_encoder_destroy (enc->state);
     enc->state = NULL;
   }
-  gst_tag_list_unref (enc->tags);
-  enc->tags = NULL;
-  g_slist_foreach (enc->headers, (GFunc) gst_buffer_unref, NULL);
-  g_slist_free (enc->headers);
-  enc->headers = NULL;
   gst_tag_setter_reset_tags (GST_TAG_SETTER (enc));
 
   return TRUE;
@@ -701,6 +693,8 @@
 gst_opus_enc_setup (GstOpusEnc * enc)
 {
   int error = OPUS_OK;
+  GstCaps *caps;
+  gboolean ret;
 
 #ifndef GST_DISABLE_GST_DEBUG
   GST_DEBUG_OBJECT (enc,
@@ -740,7 +734,18 @@
 
   GST_LOG_OBJECT (enc, "we have frame size %d", enc->frame_size);
 
-  return TRUE;
+  gst_opus_header_create_caps (&caps, NULL, enc->n_channels,
+      enc->n_stereo_streams, enc->sample_rate, enc->channel_mapping_family,
+      enc->decoding_channel_mapping,
+      gst_tag_setter_get_tag_list (GST_TAG_SETTER (enc)));
+
+  /* negotiate with these caps */
+  GST_DEBUG_OBJECT (enc, "here are the caps: %" GST_PTR_FORMAT, caps);
+
+  ret = gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (enc), caps);
+  gst_caps_unref (caps);
+
+  return ret;
 
 encoder_creation_failed:
   GST_ERROR_OBJECT (enc, "Encoder creation failed");
@@ -913,7 +918,9 @@
 
   g_assert (size == bytes);
 
-  outbuf = gst_buffer_new_and_alloc (max_payload_size * enc->n_channels);
+  outbuf =
+      gst_audio_encoder_allocate_output_buffer (GST_AUDIO_ENCODER (enc),
+      max_payload_size * enc->n_channels);
   if (!outbuf)
     goto done;
 
@@ -970,29 +977,6 @@
 
   enc = GST_OPUS_ENC (benc);
   GST_DEBUG_OBJECT (enc, "handle_frame");
-
-  if (!enc->header_sent) {
-    GstCaps *caps;
-
-    g_slist_foreach (enc->headers, (GFunc) gst_buffer_unref, NULL);
-    g_slist_free (enc->headers);
-    enc->headers = NULL;
-
-    gst_opus_header_create_caps (&caps, &enc->headers, enc->n_channels,
-        enc->n_stereo_streams, enc->sample_rate, enc->channel_mapping_family,
-        enc->decoding_channel_mapping,
-        gst_tag_setter_get_tag_list (GST_TAG_SETTER (enc)));
-
-
-    /* negotiate with these caps */
-    GST_DEBUG_OBJECT (enc, "here are the caps: %" GST_PTR_FORMAT, caps);
-
-    gst_audio_encoder_set_output_format (benc, caps);
-    gst_caps_unref (caps);
-
-    enc->header_sent = TRUE;
-  }
-
   GST_DEBUG_OBJECT (enc, "received buffer %p of %" G_GSIZE_FORMAT " bytes", buf,
       buf ? gst_buffer_get_size (buf) : 0);
 
@@ -1037,6 +1021,7 @@
           ("constrained-vbr property is deprecated; use bitrate-type instead");
       g_value_set_boolean (value,
           enc->bitrate_type == BITRATE_TYPE_CONSTRAINED_VBR);
+      break;
     case PROP_BITRATE_TYPE:
       g_value_set_enum (value, enc->bitrate_type);
       break;
diff --git a/ext/opus/gstopusenc.h b/ext/opus/gstopusenc.h
index 4ff9610..43eaac8 100644
--- a/ext/opus/gstopusenc.h
+++ b/ext/opus/gstopusenc.h
@@ -27,7 +27,7 @@
 #include <gst/gst.h>
 #include <gst/audio/gstaudioencoder.h>
 
-#include <opus/opus_multistream.h>
+#include <opus_multistream.h>
 
 G_BEGIN_DECLS
 
@@ -79,13 +79,8 @@
   gint                  n_channels;
   gint                  sample_rate;
 
-  gboolean              header_sent;
   guint64               encoded_samples;
 
-  GSList                *headers;
-
-  GstTagList            *tags;
-
   guint8                channel_mapping_family;
   guint8                encoding_channel_mapping[256];
   guint8                decoding_channel_mapping[256];
diff --git a/ext/opus/gstopusheader.c b/ext/opus/gstopusheader.c
index d190cc2..1521c1c 100644
--- a/ext/opus/gstopusheader.c
+++ b/ext/opus/gstopusheader.c
@@ -157,17 +157,21 @@
     GstBuffer * buf1, GstBuffer * buf2)
 {
   int n_streams, family;
+  gint channels, rate;
   gboolean multistream;
   GstMapInfo map;
   guint8 *data;
 
   g_return_if_fail (caps);
-  g_return_if_fail (headers && !*headers);
+  g_return_if_fail (!headers || !*headers);
   g_return_if_fail (gst_buffer_get_size (buf1) >= 19);
 
   gst_buffer_map (buf1, &map, GST_MAP_READ);
   data = map.data;
 
+  channels = data[9];
+  rate = GST_READ_UINT32_LE (data + 12);
+
   /* work out the number of streams */
   family = data[18];
   if (family == 0) {
@@ -183,16 +187,27 @@
     }
   }
 
+  /* TODO: should probably also put the channel mapping into the caps too once
+   * we actually support multi channel, and pre-skip and other fields */
+
   gst_buffer_unmap (buf1, &map);
 
   /* mark and put on caps */
   multistream = n_streams > 1;
   *caps = gst_caps_new_simple ("audio/x-opus",
-      "multistream", G_TYPE_BOOLEAN, multistream, NULL);
+      "multistream", G_TYPE_BOOLEAN, multistream,
+      "channels", G_TYPE_INT, channels, NULL);
+
+  if (rate > 0) {
+    gst_caps_set_simple (*caps, "rate", G_TYPE_INT, rate, NULL);
+  }
+
   *caps = _gst_caps_set_buffer_array (*caps, "streamheader", buf1, buf2, NULL);
 
-  *headers = g_slist_prepend (*headers, gst_buffer_ref (buf2));
-  *headers = g_slist_prepend (*headers, gst_buffer_ref (buf1));
+  if (headers) {
+    *headers = g_slist_prepend (*headers, gst_buffer_ref (buf2));
+    *headers = g_slist_prepend (*headers, gst_buffer_ref (buf1));
+  }
 }
 
 void
@@ -203,7 +218,7 @@
   GstBuffer *buf1, *buf2;
 
   g_return_if_fail (caps);
-  g_return_if_fail (headers && !*headers);
+  g_return_if_fail (!headers || !*headers);
   g_return_if_fail (nchannels > 0);
   g_return_if_fail (sample_rate >= 0);  /* 0 -> unset */
   g_return_if_fail (channel_mapping_family == 0 || channel_mapping);
diff --git a/ext/opus/gstopusparse.c b/ext/opus/gstopusparse.c
index 8ede3a3..c8aba11 100644
--- a/ext/opus/gstopusparse.c
+++ b/ext/opus/gstopusparse.c
@@ -39,7 +39,7 @@
 #endif
 
 #include <string.h>
-#include <opus/opus.h>
+#include <opus.h>
 #include "gstopusheader.h"
 #include "gstopusparse.h"
 
diff --git a/ext/opus/gstrtpopusdepay.c b/ext/opus/gstrtpopusdepay.c
index 6bcdd12..af3237b 100644
--- a/ext/opus/gstrtpopusdepay.c
+++ b/ext/opus/gstrtpopusdepay.c
@@ -46,7 +46,7 @@
 GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("audio/x-opus")
+    GST_STATIC_CAPS ("audio/x-opus, multistream = (boolean) FALSE")
     );
 
 static GstBuffer *gst_rtp_opus_depay_process (GstRTPBaseDepayload * depayload,
@@ -92,9 +92,40 @@
 gst_rtp_opus_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
 {
   GstCaps *srccaps;
+  GstStructure *s;
   gboolean ret;
+  const gchar *sprop_stereo, *sprop_maxcapturerate;
 
-  srccaps = gst_caps_new_empty_simple ("audio/x-opus");
+  srccaps =
+      gst_caps_new_simple ("audio/x-opus", "multistream", G_TYPE_BOOLEAN, FALSE,
+      NULL);
+
+  s = gst_caps_get_structure (caps, 0);
+  if ((sprop_stereo = gst_structure_get_string (s, "sprop-stereo"))) {
+    if (strcmp (sprop_stereo, "0") == 0)
+      gst_caps_set_simple (srccaps, "channels", G_TYPE_INT, 1, NULL);
+    else if (strcmp (sprop_stereo, "1") == 0)
+      gst_caps_set_simple (srccaps, "channels", G_TYPE_INT, 2, NULL);
+    else
+      GST_WARNING_OBJECT (depayload, "Unknown sprop-stereo value '%s'",
+          sprop_stereo);
+  }
+
+  if ((sprop_maxcapturerate =
+          gst_structure_get_string (s, "sprop-maxcapturerate"))) {
+    gulong rate;
+    gchar *tailptr;
+
+    rate = strtoul (sprop_maxcapturerate, &tailptr, 10);
+    if (rate > INT_MAX || *tailptr != '\0') {
+      GST_WARNING_OBJECT (depayload,
+          "Failed to parse sprop-maxcapturerate value '%s'",
+          sprop_maxcapturerate);
+    } else {
+      gst_caps_set_simple (srccaps, "rate", G_TYPE_INT, rate, NULL);
+    }
+  }
+
   ret = gst_pad_set_caps (GST_RTP_BASE_DEPAYLOAD_SRCPAD (depayload), srccaps);
 
   GST_DEBUG_OBJECT (depayload,
diff --git a/ext/opus/gstrtpopuspay.c b/ext/opus/gstrtpopuspay.c
index d0f7b10..057c8d0 100644
--- a/ext/opus/gstrtpopuspay.c
+++ b/ext/opus/gstrtpopuspay.c
@@ -48,11 +48,14 @@
         "media = (string) \"audio\", "
         "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
         "clock-rate = (int) 48000, "
+        "encoding-params = (string) \"2\", "
         "encoding-name = (string) { \"OPUS\", \"X-GST-OPUS-DRAFT-SPITTKA-00\" }")
     );
 
 static gboolean gst_rtp_opus_pay_setcaps (GstRTPBasePayload * payload,
     GstCaps * caps);
+static GstCaps *gst_rtp_opus_pay_getcaps (GstRTPBasePayload * payload,
+    GstPad * pad, GstCaps * filter);
 static GstFlowReturn gst_rtp_opus_pay_handle_buffer (GstRTPBasePayload *
     payload, GstBuffer * buffer);
 
@@ -68,6 +71,7 @@
   element_class = GST_ELEMENT_CLASS (klass);
 
   gstbasertppayload_class->set_caps = gst_rtp_opus_pay_setcaps;
+  gstbasertppayload_class->get_caps = gst_rtp_opus_pay_getcaps;
   gstbasertppayload_class->handle_buffer = gst_rtp_opus_pay_handle_buffer;
 
   gst_element_class_add_pad_template (element_class,
@@ -97,6 +101,9 @@
   GstCaps *src_caps;
   GstStructure *s;
   char *encoding_name;
+  gint channels, rate;
+  const char *sprop_stereo = NULL;
+  char *sprop_maxcapturerate = NULL;
 
   src_caps = gst_pad_get_allowed_caps (GST_RTP_BASE_PAYLOAD_SRCPAD (payload));
   if (src_caps) {
@@ -110,10 +117,45 @@
     encoding_name = g_strdup ("X-GST-OPUS-DRAFT-SPITTKA-00");
   }
 
+  s = gst_caps_get_structure (caps, 0);
+  if (gst_structure_get_int (s, "channels", &channels)) {
+    if (channels > 2) {
+      GST_ERROR_OBJECT (payload,
+          "More than 2 channels with multistream=FALSE is invalid");
+      return FALSE;
+    } else if (channels == 2) {
+      sprop_stereo = "1";
+    } else {
+      sprop_stereo = "0";
+    }
+  }
+
+  if (gst_structure_get_int (s, "rate", &rate)) {
+    sprop_maxcapturerate = g_strdup_printf ("%d", rate);
+  }
+
   gst_rtp_base_payload_set_options (payload, "audio", FALSE,
       encoding_name, 48000);
   g_free (encoding_name);
-  res = gst_rtp_base_payload_set_outcaps (payload, NULL);
+
+  if (sprop_maxcapturerate && sprop_stereo) {
+    res =
+        gst_rtp_base_payload_set_outcaps (payload, "sprop-maxcapturerate",
+        G_TYPE_STRING, sprop_maxcapturerate, "sprop-stereo", G_TYPE_STRING,
+        sprop_stereo, NULL);
+  } else if (sprop_maxcapturerate) {
+    res =
+        gst_rtp_base_payload_set_outcaps (payload, "sprop-maxcapturerate",
+        G_TYPE_STRING, sprop_maxcapturerate, NULL);
+  } else if (sprop_stereo) {
+    res =
+        gst_rtp_base_payload_set_outcaps (payload, "sprop-stereo",
+        G_TYPE_STRING, sprop_stereo, NULL);
+  } else {
+    res = gst_rtp_base_payload_set_outcaps (payload, NULL);
+  }
+
+  g_free (sprop_maxcapturerate);
 
   return res;
 }
@@ -139,3 +181,62 @@
   /* Push out */
   return gst_rtp_base_payload_push (basepayload, outbuf);
 }
+
+static GstCaps *
+gst_rtp_opus_pay_getcaps (GstRTPBasePayload * payload,
+    GstPad * pad, GstCaps * filter)
+{
+  GstCaps *caps, *peercaps, *tcaps;
+  GstStructure *s;
+  const gchar *stereo;
+
+  if (pad == GST_RTP_BASE_PAYLOAD_SRCPAD (payload))
+    return
+        GST_RTP_BASE_PAYLOAD_CLASS (gst_rtp_opus_pay_parent_class)->get_caps
+        (payload, pad, filter);
+
+  tcaps = gst_pad_get_pad_template_caps (GST_RTP_BASE_PAYLOAD_SRCPAD (payload));
+  peercaps = gst_pad_peer_query_caps (GST_RTP_BASE_PAYLOAD_SRCPAD (payload),
+      tcaps);
+  gst_caps_unref (tcaps);
+  if (!peercaps)
+    return
+        GST_RTP_BASE_PAYLOAD_CLASS (gst_rtp_opus_pay_parent_class)->get_caps
+        (payload, pad, filter);
+
+  if (gst_caps_is_empty (peercaps))
+    return peercaps;
+
+  caps = gst_pad_get_pad_template_caps (GST_RTP_BASE_PAYLOAD_SINKPAD (payload));
+
+  s = gst_caps_get_structure (peercaps, 0);
+  stereo = gst_structure_get_string (s, "stereo");
+  if (stereo != NULL) {
+    caps = gst_caps_make_writable (caps);
+
+    if (!strcmp (stereo, "1")) {
+      GstCaps *caps2 = gst_caps_copy (caps);
+
+      gst_caps_set_simple (caps, "channels", G_TYPE_INT, 2, NULL);
+      gst_caps_set_simple (caps2, "channels", G_TYPE_INT, 1, NULL);
+      caps = gst_caps_merge (caps, caps2);
+    } else if (!strcmp (stereo, "0")) {
+      GstCaps *caps2 = gst_caps_copy (caps);
+
+      gst_caps_set_simple (caps, "channels", G_TYPE_INT, 1, NULL);
+      gst_caps_set_simple (caps2, "channels", G_TYPE_INT, 2, NULL);
+      caps = gst_caps_merge (caps, caps2);
+    }
+  }
+  gst_caps_unref (peercaps);
+
+  if (filter) {
+    GstCaps *tmp = gst_caps_intersect_full (caps, filter,
+        GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (caps);
+    caps = tmp;
+  }
+
+  GST_DEBUG_OBJECT (payload, "Returning caps: %" GST_PTR_FORMAT, caps);
+  return caps;
+}
diff --git a/ext/smoothstreaming/Makefile.am b/ext/smoothstreaming/Makefile.am
index 06c6796..5f331f3 100644
--- a/ext/smoothstreaming/Makefile.am
+++ b/ext/smoothstreaming/Makefile.am
@@ -19,18 +19,3 @@
 
 noinst_HEADERS = gstmssdemux.h \
 	gstmssmanifest.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstsmoothstreaming -:SHARED libgstsmoothstreaming \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstsmoothstreaming_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(CPPFLAGS) $(libgstsmoothstreaming_la_CFLAGS) \
-	 -:LDFLAGS $(libgstsmoothstreaming_la_LDFLAGS) \
-	           $(libgstsmoothstreaming_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
diff --git a/ext/smoothstreaming/Makefile.in b/ext/smoothstreaming/Makefile.in
index 1bf70fe..8a34871 100644
--- a/ext/smoothstreaming/Makefile.in
+++ b/ext/smoothstreaming/Makefile.in
@@ -1105,20 +1105,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstsmoothstreaming -:SHARED libgstsmoothstreaming \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstsmoothstreaming_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(CPPFLAGS) $(libgstsmoothstreaming_la_CFLAGS) \
-	 -:LDFLAGS $(libgstsmoothstreaming_la_LDFLAGS) \
-	           $(libgstsmoothstreaming_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/ext/smoothstreaming/gstmssdemux.c b/ext/smoothstreaming/gstmssdemux.c
index 90cfac1..8f10d7d 100644
--- a/ext/smoothstreaming/gstmssdemux.c
+++ b/ext/smoothstreaming/gstmssdemux.c
@@ -135,7 +135,8 @@
 static gint64
 gst_mss_demux_get_manifest_update_interval (GstAdaptiveDemux * demux);
 static GstFlowReturn
-gst_mss_demux_update_manifest (GstAdaptiveDemux * demux, GstBuffer * buffer);
+gst_mss_demux_update_manifest_data (GstAdaptiveDemux * demux,
+    GstBuffer * buffer);
 
 static void
 gst_mss_demux_class_init (GstMssDemuxClass * klass)
@@ -188,7 +189,8 @@
       gst_mss_demux_stream_select_bitrate;
   gstadaptivedemux_class->stream_update_fragment_info =
       gst_mss_demux_stream_update_fragment_info;
-  gstadaptivedemux_class->update_manifest = gst_mss_demux_update_manifest;
+  gstadaptivedemux_class->update_manifest_data =
+      gst_mss_demux_update_manifest_data;
 
   GST_DEBUG_CATEGORY_INIT (mssdemux_debug, "mssdemux", 0, "mssdemux plugin");
 }
@@ -546,7 +548,8 @@
 }
 
 static GstFlowReturn
-gst_mss_demux_update_manifest (GstAdaptiveDemux * demux, GstBuffer * buffer)
+gst_mss_demux_update_manifest_data (GstAdaptiveDemux * demux,
+    GstBuffer * buffer)
 {
   GstMssDemux *mssdemux = GST_MSS_DEMUX_CAST (demux);
 
diff --git a/ext/smoothstreaming/gstmssmanifest.c b/ext/smoothstreaming/gstmssmanifest.c
index 7254e4d..e92e3da 100644
--- a/ext/smoothstreaming/gstmssmanifest.c
+++ b/ext/smoothstreaming/gstmssmanifest.c
@@ -724,7 +724,8 @@
     gst_structure_set (structure, "rate", G_TYPE_INT, rate, NULL);
 
   if (q->bitrate)
-    gst_structure_set (structure, "bitrate", G_TYPE_INT, (int) q->bitrate, NULL);
+    gst_structure_set (structure, "bitrate", G_TYPE_INT, (int) q->bitrate,
+        NULL);
 
   if (codec_data)
     gst_structure_set (structure, "codec_data", GST_TYPE_BUFFER, codec_data,
diff --git a/ext/spandsp/gstspanplc.c b/ext/spandsp/gstspanplc.c
index c30c0d7..d3ff53f 100644
--- a/ext/spandsp/gstspanplc.c
+++ b/ext/spandsp/gstspanplc.c
@@ -188,8 +188,7 @@
   GstSpanPlc *plc = GST_SPAN_PLC (parent);
   GstMapInfo map;
 
-  if (plc->plc_state->missing_samples != 0)
-    buffer = gst_buffer_make_writable (buffer);
+  buffer = gst_buffer_make_writable (buffer);
   gst_buffer_map (buffer, &map, GST_MAP_READWRITE);
   plc_rx (plc->plc_state, (int16_t *) map.data, map.size / 2);
   gst_buffer_unmap (buffer, &map);
diff --git a/ext/srtp/gstsrtpdec.c b/ext/srtp/gstsrtpdec.c
index debff15..31999cb 100644
--- a/ext/srtp/gstsrtpdec.c
+++ b/ext/srtp/gstsrtpdec.c
@@ -142,6 +142,22 @@
   PROP_0
 };
 
+typedef struct _ValidateBufferItData
+{
+  GstSrtpDecSsrcStream **stream;
+  GstSrtpDec *filter;
+  guint32 *ssrc;
+  gboolean *is_rtcp;
+} ValidateBufferItData;
+
+typedef struct _DecodeBufferItData
+{
+  GstSrtpDec *filter;
+  GstPad *pad;
+  guint32 ssrc;
+  gboolean is_rtcp;
+} DecodeBufferItData;
+
 /* the capabilities of the inputs and outputs.
  *
  * describe the real formats here.
@@ -202,6 +218,11 @@
 static GstFlowReturn gst_srtp_dec_chain_rtcp (GstPad * pad,
     GstObject * parent, GstBuffer * buf);
 
+static GstFlowReturn gst_srtp_dec_chain_list_rtp (GstPad * pad,
+    GstObject * parent, GstBufferList * buf_list);
+static GstFlowReturn gst_srtp_dec_chain_list_rtcp (GstPad * pad,
+    GstObject * parent, GstBufferList * buf_list);
+
 static GstStateChangeReturn gst_srtp_dec_change_state (GstElement * element,
     GstStateChange transition);
 
@@ -347,6 +368,8 @@
       GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtp));
   gst_pad_set_chain_function (filter->rtp_sinkpad,
       GST_DEBUG_FUNCPTR (gst_srtp_dec_chain_rtp));
+  gst_pad_set_chain_list_function (filter->rtp_sinkpad,
+      GST_DEBUG_FUNCPTR (gst_srtp_dec_chain_list_rtp));
 
   filter->rtp_srcpad =
       gst_pad_new_from_static_template (&rtp_src_template, "rtp_src");
@@ -370,6 +393,8 @@
       GST_DEBUG_FUNCPTR (gst_srtp_dec_iterate_internal_links_rtcp));
   gst_pad_set_chain_function (filter->rtcp_sinkpad,
       GST_DEBUG_FUNCPTR (gst_srtp_dec_chain_rtcp));
+  gst_pad_set_chain_list_function (filter->rtcp_sinkpad,
+      GST_DEBUG_FUNCPTR (gst_srtp_dec_chain_list_rtcp));
 
   filter->rtcp_srcpad =
       gst_pad_new_from_static_template (&rtcp_src_template, "rtcp_src");
@@ -701,6 +726,9 @@
     else
       GST_WARNING_OBJECT (filter, "Could not set stream with SSRC %u", ssrc);
     gst_caps_unref (caps);
+  } else {
+    GST_WARNING_OBJECT (filter, "Could not get caps for stream with SSRC %u",
+        ssrc);
   }
 
   return stream;
@@ -768,6 +796,14 @@
       gst_event_unref (event);
       return ret;
     case GST_EVENT_SEGMENT:
+      /* Make sure to send a caps event downstream before the segment event,
+       * even if upstream didn't */
+      if (!gst_pad_has_current_caps (filter->rtp_srcpad)) {
+        GstCaps *caps = gst_caps_new_empty_simple ("application/x-rtp");
+
+        gst_pad_set_caps (filter->rtp_srcpad, caps);
+        gst_caps_unref (caps);
+      }
       filter->rtp_has_segment = TRUE;
       break;
     case GST_EVENT_FLUSH_STOP:
@@ -795,6 +831,14 @@
       gst_event_unref (event);
       return ret;
     case GST_EVENT_SEGMENT:
+      /* Make sure to send a caps event downstream before the segment event,
+       * even if upstream didn't */
+      if (!gst_pad_has_current_caps (filter->rtcp_srcpad)) {
+        GstCaps *caps = gst_caps_new_empty_simple ("application/x-rtcp");
+
+        gst_pad_set_caps (filter->rtcp_srcpad, caps);
+        gst_caps_unref (caps);
+      }
       filter->rtcp_has_segment = TRUE;
       break;
     case GST_EVENT_FLUSH_STOP:
@@ -1003,33 +1047,16 @@
 
 }
 
-static GstFlowReturn
-gst_srtp_dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf,
-    gboolean is_rtcp)
+/*
+ * This function should be called while holding the filter lock
+ */
+static gboolean
+gst_srtp_dec_decode_buffer (GstSrtpDec * filter, GstPad * pad, GstBuffer * buf,
+    gboolean is_rtcp, guint32 ssrc)
 {
-  GstSrtpDec *filter = GST_SRTP_DEC (parent);
-  GstPad *otherpad;
-  err_status_t err = err_status_ok;
-  GstSrtpDecSsrcStream *stream = NULL;
-  GstFlowReturn ret = GST_FLOW_OK;
-  gint size;
-  guint32 ssrc = 0;
   GstMapInfo map;
-
-  GST_OBJECT_LOCK (filter);
-
-  /* Check if this stream exists, if not create a new stream */
-
-  if (!(stream = validate_buffer (filter, buf, &ssrc, &is_rtcp))) {
-    GST_OBJECT_UNLOCK (filter);
-    GST_WARNING_OBJECT (filter, "Invalid buffer, dropping");
-    goto drop_buffer;
-  }
-
-  if (!STREAM_HAS_CRYPTO (stream)) {
-    GST_OBJECT_UNLOCK (filter);
-    goto push_out;
-  }
+  err_status_t err;
+  gint size;
 
   GST_LOG_OBJECT (pad, "Received %s buffer of size %" G_GSIZE_FORMAT
       " with SSRC = %u", is_rtcp ? "RTCP" : "RTP", gst_buffer_get_size (buf),
@@ -1038,11 +1065,11 @@
   /* Change buffer to remove protection */
   buf = gst_buffer_make_writable (buf);
 
-unprotect:
-
   gst_buffer_map (buf, &map, GST_MAP_READWRITE);
   size = map.size;
 
+unprotect:
+
   gst_srtp_init_event_reporter ();
 
   if (is_rtcp)
@@ -1074,8 +1101,6 @@
     err = srtp_unprotect (filter->session, map.data, &size);
   }
 
-  gst_buffer_unmap (buf, &map);
-
   GST_OBJECT_UNLOCK (filter);
 
   if (err != err_status_ok) {
@@ -1113,10 +1138,50 @@
         break;
     }
 
+    gst_buffer_unmap (buf, &map);
+
+    GST_OBJECT_LOCK (filter);
+    return FALSE;
+  }
+
+  gst_buffer_unmap (buf, &map);
+
+  gst_buffer_set_size (buf, size);
+
+  GST_OBJECT_LOCK (filter);
+  return TRUE;
+}
+
+static GstFlowReturn
+gst_srtp_dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf,
+    gboolean is_rtcp)
+{
+  GstSrtpDec *filter = GST_SRTP_DEC (parent);
+  GstPad *otherpad;
+  GstSrtpDecSsrcStream *stream = NULL;
+  GstFlowReturn ret = GST_FLOW_OK;
+  guint32 ssrc = 0;
+
+  GST_OBJECT_LOCK (filter);
+
+  /* Check if this stream exists, if not create a new stream */
+  if (!(stream = validate_buffer (filter, buf, &ssrc, &is_rtcp))) {
+    GST_OBJECT_UNLOCK (filter);
+    GST_WARNING_OBJECT (filter, "Invalid buffer, dropping");
     goto drop_buffer;
   }
 
-  gst_buffer_set_size (buf, size);
+  if (!STREAM_HAS_CRYPTO (stream)) {
+    GST_OBJECT_UNLOCK (filter);
+    goto push_out;
+  }
+
+  if (!gst_srtp_dec_decode_buffer (filter, pad, buf, is_rtcp, ssrc)) {
+    GST_OBJECT_UNLOCK (filter);
+    goto drop_buffer;
+  }
+
+  GST_OBJECT_UNLOCK (filter);
 
   /* If all is well, we may have reached soft limit */
   if (gst_srtp_get_soft_limit_reached ())
@@ -1147,6 +1212,107 @@
   return ret;
 }
 
+static gboolean
+validate_buffer_it (GstBuffer ** buffer, guint index, gpointer user_data)
+{
+  ValidateBufferItData *data = user_data;
+
+  if (!(*data->stream =
+          validate_buffer (data->filter, *buffer, data->ssrc, data->is_rtcp))) {
+    GST_WARNING_OBJECT (data->filter, "Invalid buffer, dropping");
+    gst_buffer_replace (buffer, NULL);
+  }
+
+  return TRUE;
+}
+
+static gboolean
+decode_buffer_it (GstBuffer ** buffer, guint index, gpointer user_data)
+{
+  DecodeBufferItData *data = user_data;
+
+  if (!gst_srtp_dec_decode_buffer (data->filter, data->pad, *buffer,
+          data->is_rtcp, data->ssrc)) {
+    GST_WARNING_OBJECT (data->filter, "Error decoding buffer, dropping");
+    gst_buffer_replace (buffer, NULL);
+  }
+
+  return TRUE;
+}
+
+static GstFlowReturn
+gst_srtp_dec_chain_list (GstPad * pad, GstObject * parent,
+    GstBufferList * buf_list, gboolean is_rtcp)
+{
+  GstSrtpDec *filter = GST_SRTP_DEC (parent);
+  GstPad *otherpad;
+  GstSrtpDecSsrcStream *stream = NULL;
+  GstFlowReturn ret = GST_FLOW_OK;
+  guint32 ssrc = 0;
+  ValidateBufferItData validate_data;
+  DecodeBufferItData decode_data;
+
+  validate_data.stream = &stream;
+  validate_data.filter = filter;
+  validate_data.ssrc = &ssrc;
+  validate_data.is_rtcp = &is_rtcp;
+
+  decode_data.filter = filter;
+  decode_data.pad = pad;
+
+  GST_OBJECT_LOCK (filter);
+
+  /* Check if this stream exists, if not create a new stream */
+  gst_buffer_list_foreach (buf_list, validate_buffer_it, &validate_data);
+
+  if (!gst_buffer_list_length (buf_list)) {
+    GST_OBJECT_LOCK (filter);
+    gst_buffer_list_unref (buf_list);
+    return GST_FLOW_OK;
+  }
+
+  if (!STREAM_HAS_CRYPTO (stream)) {
+    GST_OBJECT_UNLOCK (filter);
+    goto push_out;
+  }
+
+  decode_data.ssrc = ssrc;
+  decode_data.is_rtcp = is_rtcp;
+
+  gst_buffer_list_foreach (buf_list, decode_buffer_it, &decode_data);
+
+  GST_OBJECT_UNLOCK (filter);
+
+  if (!gst_buffer_list_length (buf_list)) {
+    gst_buffer_list_unref (buf_list);
+    return GST_FLOW_OK;
+  }
+
+  /* If all is well, we may have reached soft limit */
+  if (gst_srtp_get_soft_limit_reached ())
+    request_key_with_signal (filter, ssrc, SIGNAL_SOFT_LIMIT);
+
+push_out:
+  /* Push buffer list to source pad */
+  if (is_rtcp) {
+    otherpad = filter->rtcp_srcpad;
+    if (!filter->rtcp_has_segment)
+      gst_srtp_dec_push_early_events (filter, filter->rtcp_srcpad,
+          filter->rtp_srcpad, TRUE);
+  } else {
+    otherpad = filter->rtp_srcpad;
+    if (!filter->rtp_has_segment)
+      gst_srtp_dec_push_early_events (filter, filter->rtp_srcpad,
+          filter->rtcp_srcpad, FALSE);
+  }
+
+  GST_LOG_OBJECT (pad, "Pushing buffer chain of %d",
+      gst_buffer_list_length (buf_list));
+  ret = gst_pad_push_list (otherpad, buf_list);
+
+  return ret;
+}
+
 static GstFlowReturn
 gst_srtp_dec_chain_rtp (GstPad * pad, GstObject * parent, GstBuffer * buf)
 {
@@ -1159,6 +1325,21 @@
   return gst_srtp_dec_chain (pad, parent, buf, TRUE);
 }
 
+static GstFlowReturn
+gst_srtp_dec_chain_list_rtp (GstPad * pad, GstObject * parent,
+    GstBufferList * buf_list)
+{
+  return gst_srtp_dec_chain_list (pad, parent, buf_list, FALSE);
+}
+
+static GstFlowReturn
+gst_srtp_dec_chain_list_rtcp (GstPad * pad, GstObject * parent,
+    GstBufferList * buf_list)
+{
+  return gst_srtp_dec_chain_list (pad, parent, buf_list, TRUE);
+}
+
+
 static GstStateChangeReturn
 gst_srtp_dec_change_state (GstElement * element, GstStateChange transition)
 {
diff --git a/ext/srtp/gstsrtpenc.c b/ext/srtp/gstsrtpenc.c
index 20d3e36..8489da4 100644
--- a/ext/srtp/gstsrtpenc.c
+++ b/ext/srtp/gstsrtpenc.c
@@ -162,6 +162,20 @@
   PROP_ALLOW_REPEAT_TX
 };
 
+typedef struct ValidateBufferItData
+{
+  GstSrtpEnc *filter;
+  gboolean is_rtcp;
+} ValidateBufferItData;
+
+typedef struct ProcessBufferItData
+{
+  GstSrtpEnc *filter;
+  GstPad *pad;
+  GstBufferList *out_list;
+  gboolean is_rtcp;
+} ProcessBufferItData;
+
 /* the capabilities of the inputs and outputs.
  *
  * describe the real formats here.
@@ -219,6 +233,10 @@
     GstBuffer * buf);
 static GstFlowReturn gst_srtp_enc_chain_rtcp (GstPad * pad, GstObject * parent,
     GstBuffer * buf);
+static GstFlowReturn gst_srtp_enc_chain_list_rtp (GstPad * pad,
+    GstObject * parent, GstBufferList * buf);
+static GstFlowReturn gst_srtp_enc_chain_list_rtcp (GstPad * pad,
+    GstObject * parent, GstBufferList * buf);
 
 static gboolean gst_srtp_enc_sink_event_rtp (GstPad * pad, GstObject * parent,
     GstEvent * event);
@@ -389,6 +407,8 @@
 }
 
 /* Create stream
+ *
+ * Should be called with the filter locked
  */
 static err_status_t
 gst_srtp_enc_create_session (GstSrtpEnc * filter)
@@ -400,30 +420,26 @@
 
   memset (&policy, 0, sizeof (srtp_policy_t));
 
-  GST_OBJECT_LOCK (filter);
-
   if (HAS_CRYPTO (filter)) {
     guint expected;
     gsize keysize;
 
     if (filter->key == NULL) {
-      GST_OBJECT_UNLOCK (filter);
       GST_ELEMENT_ERROR (filter, LIBRARY, SETTINGS,
           ("Cipher is not NULL, key must be set"),
           ("Cipher is not NULL, key must be set"));
-      return FALSE;
+      return err_status_fail;
     }
 
     expected = max_cipher_key_size (filter);
     keysize = gst_buffer_get_size (filter->key);
 
     if (expected != keysize) {
-      GST_OBJECT_UNLOCK (filter);
       GST_ELEMENT_ERROR (filter, LIBRARY, SETTINGS,
           ("Master key size is wrong"),
           ("Expected master key of %d bytes, but received %" G_GSIZE_FORMAT
               " bytes", expected, keysize));
-      return FALSE;
+      return err_status_fail;
     }
   }
 
@@ -457,24 +473,26 @@
   if (HAS_CRYPTO (filter))
     gst_buffer_unmap (filter->key, &map);
 
-  GST_OBJECT_UNLOCK (filter);
-
   return ret;
 }
 
 /* Release ressources and set default values
  */
 static void
-gst_srtp_enc_reset (GstSrtpEnc * filter)
+gst_srtp_enc_reset_no_lock (GstSrtpEnc * filter)
 {
-  GST_OBJECT_LOCK (filter);
-
   if (!filter->first_session)
     srtp_dealloc (filter->session);
 
   filter->first_session = TRUE;
   filter->key_changed = FALSE;
+}
 
+static void
+gst_srtp_enc_reset (GstSrtpEnc * filter)
+{
+  GST_OBJECT_LOCK (filter);
+  gst_srtp_enc_reset_no_lock (filter);
   GST_OBJECT_UNLOCK (filter);
 }
 
@@ -509,6 +527,8 @@
       GST_DEBUG_FUNCPTR (gst_srtp_enc_iterate_internal_links_rtp));
   gst_pad_set_chain_function (sinkpad,
       GST_DEBUG_FUNCPTR (gst_srtp_enc_chain_rtp));
+  gst_pad_set_chain_list_function (sinkpad,
+      GST_DEBUG_FUNCPTR (gst_srtp_enc_chain_list_rtp));
   gst_pad_set_event_function (sinkpad,
       GST_DEBUG_FUNCPTR (gst_srtp_enc_sink_event_rtp));
   gst_pad_set_active (sinkpad, TRUE);
@@ -553,6 +573,8 @@
       GST_DEBUG_FUNCPTR (gst_srtp_enc_iterate_internal_links_rtcp));
   gst_pad_set_chain_function (sinkpad,
       GST_DEBUG_FUNCPTR (gst_srtp_enc_chain_rtcp));
+  gst_pad_set_chain_list_function (sinkpad,
+      GST_DEBUG_FUNCPTR (gst_srtp_enc_chain_list_rtcp));
   gst_pad_set_event_function (sinkpad,
       GST_DEBUG_FUNCPTR (gst_srtp_enc_sink_event_rtcp));
   gst_pad_set_active (sinkpad, TRUE);
@@ -948,27 +970,17 @@
   filter->key_changed = TRUE;
 }
 
-static GstFlowReturn
-gst_srtp_enc_chain (GstPad * pad, GstObject * parent, GstBuffer * buf,
+static gboolean
+gst_srtp_enc_check_buffer (GstSrtpEnc * filter, GstBuffer * buf,
     gboolean is_rtcp)
 {
-  GstSrtpEnc *filter = GST_SRTP_ENC (parent);
-  GstFlowReturn ret = GST_FLOW_OK;
-  GstPad *otherpad = NULL;
-  err_status_t err = err_status_ok;
-  gint size_max, size;
-  GstBuffer *bufout = NULL;
-  gboolean do_setcaps = FALSE;
-  GstMapInfo mapin, mapout;
-
   if (!is_rtcp) {
     GstRTPBuffer rtpbuf = GST_RTP_BUFFER_INIT;
 
     if (!gst_rtp_buffer_map (buf, GST_MAP_READ, &rtpbuf)) {
       GST_ELEMENT_ERROR (filter, STREAM, WRONG_TYPE, (NULL),
           ("Could not map RTP buffer"));
-      ret = GST_FLOW_ERROR;
-      goto out;
+      return FALSE;
     }
 
     gst_rtp_buffer_unmap (&rtpbuf);
@@ -978,61 +990,75 @@
     if (!gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcpbuf)) {
       GST_ELEMENT_ERROR (filter, STREAM, WRONG_TYPE, (NULL),
           ("Could not map RTCP buffer"));
-      ret = GST_FLOW_ERROR;
-      goto out;
+      return FALSE;
     }
     gst_rtcp_buffer_unmap (&rtcpbuf);
   }
 
-  do_setcaps = filter->key_changed;
-  if (filter->key_changed)
-    gst_srtp_enc_reset (filter);
+  return TRUE;
+}
+
+static GstFlowReturn
+gst_srtp_enc_check_set_caps (GstSrtpEnc * filter, GstPad * pad,
+    gboolean is_rtcp)
+{
+  gboolean do_setcaps = FALSE;
+
+  GST_OBJECT_LOCK (filter);
+
+  if (filter->key_changed) {
+    gst_srtp_enc_reset_no_lock (filter);
+    do_setcaps = TRUE;
+  }
+
   if (filter->first_session) {
     err_status_t status = gst_srtp_enc_create_session (filter);
+
     if (status != err_status_ok) {
+      GST_OBJECT_UNLOCK (filter);
       GST_ELEMENT_ERROR (filter, LIBRARY, INIT,
           ("Could not initialize SRTP encoder"),
           ("Failed to add stream to SRTP encoder (err: %d)", status));
-      ret = GST_FLOW_ERROR;
-      goto out;
+      return GST_FLOW_ERROR;
     }
   }
-  GST_OBJECT_LOCK (filter);
+
+  GST_OBJECT_UNLOCK (filter);
 
   /* Update source caps if asked */
   if (do_setcaps) {
     GstCaps *caps;
-    GST_OBJECT_UNLOCK (filter);
 
     caps = gst_pad_get_current_caps (pad);
     if (!gst_srtp_enc_sink_setcaps (pad, filter, caps, is_rtcp)) {
       gst_caps_unref (caps);
-      ret = GST_FLOW_NOT_NEGOTIATED;
-      goto out;
+      return GST_FLOW_NOT_NEGOTIATED;
     }
     gst_caps_unref (caps);
-
-    GST_OBJECT_LOCK (filter);
   }
 
-  if (!HAS_CRYPTO (filter)) {
-    GST_OBJECT_UNLOCK (filter);
-    otherpad = get_rtp_other_pad (pad);
-    return gst_pad_push (otherpad, buf);
-  }
+  return GST_FLOW_OK;
+}
 
+static GstBuffer *
+gst_srtp_enc_process_buffer (GstSrtpEnc * filter, GstPad * pad,
+    GstBuffer * buf, gboolean is_rtcp)
+{
+  gint size_max, size;
+  GstBuffer *bufout = NULL;
+  GstMapInfo mapout;
+  err_status_t err;
 
   /* Create a bigger buffer to add protection */
-  size_max = gst_buffer_get_size (buf) + SRTP_MAX_TRAILER_LEN + 10;
+  size = gst_buffer_get_size (buf);
+  size_max = size + SRTP_MAX_TRAILER_LEN + 10;
   bufout = gst_buffer_new_allocate (NULL, size_max, NULL);
 
-  gst_buffer_map (buf, &mapin, GST_MAP_READ);
   gst_buffer_map (bufout, &mapout, GST_MAP_READWRITE);
 
-  size = mapin.size;
-  memcpy (mapout.data, mapin.data, mapin.size);
+  gst_buffer_extract (buf, 0, mapout.data, size);
 
-  gst_buffer_unmap (buf, &mapin);
+  GST_OBJECT_LOCK (filter);
 
   gst_srtp_init_event_reporter ();
 
@@ -1041,18 +1067,67 @@
   else
     err = srtp_protect (filter->session, mapout.data, &size);
 
-  gst_buffer_unmap (bufout, &mapout);
-
   GST_OBJECT_UNLOCK (filter);
 
+  gst_buffer_unmap (bufout, &mapout);
+
   if (err == err_status_ok) {
     /* Buffer protected */
     gst_buffer_set_size (bufout, size);
     gst_buffer_copy_into (bufout, buf, GST_BUFFER_COPY_METADATA, 0, -1);
 
-    GST_LOG_OBJECT (pad, "Encing %s buffer of size %d",
+    GST_LOG_OBJECT (pad, "Encoding %s buffer of size %d",
         is_rtcp ? "RTCP" : "RTP", size);
 
+  } else if (err == err_status_key_expired) {
+
+    GST_ELEMENT_ERROR (GST_ELEMENT_CAST (filter), STREAM, ENCODE,
+        ("Key usage limit has been reached"),
+        ("Unable to protect buffer (hard key usage limit reached)"));
+    goto fail;
+
+  } else {
+    /* srtp_protect failed */
+    GST_ELEMENT_ERROR (filter, LIBRARY, FAILED, (NULL),
+        ("Unable to protect buffer (protect failed) code %d", err));
+    goto fail;
+  }
+
+  return bufout;
+
+fail:
+  gst_buffer_unref (bufout);
+  return NULL;
+}
+
+static GstFlowReturn
+gst_srtp_enc_chain (GstPad * pad, GstObject * parent, GstBuffer * buf,
+    gboolean is_rtcp)
+{
+  GstSrtpEnc *filter = GST_SRTP_ENC (parent);
+  GstFlowReturn ret = GST_FLOW_OK;
+  GstPad *otherpad;
+  GstBuffer *bufout = NULL;
+
+  if (!gst_srtp_enc_check_buffer (filter, buf, is_rtcp)) {
+    goto fail;
+  }
+
+  if ((ret = gst_srtp_enc_check_set_caps (filter, pad, is_rtcp)) != GST_FLOW_OK) {
+    goto out;
+  }
+
+  GST_OBJECT_LOCK (filter);
+
+  if (!HAS_CRYPTO (filter)) {
+    GST_OBJECT_UNLOCK (filter);
+    otherpad = get_rtp_other_pad (pad);
+    return gst_pad_push (otherpad, buf);
+  }
+
+  GST_OBJECT_UNLOCK (filter);
+
+  if ((bufout = gst_srtp_enc_process_buffer (filter, pad, buf, is_rtcp))) {
     /* Push buffer to source pad */
     otherpad = get_rtp_other_pad (pad);
     ret = gst_pad_push (otherpad, bufout);
@@ -1060,29 +1135,22 @@
 
     if (ret != GST_FLOW_OK)
       goto out;
-
-  } else if (err == err_status_key_expired) {
-
-    GST_ELEMENT_ERROR (GST_ELEMENT_CAST (filter), STREAM, ENCODE,
-        ("Key usage limit has been reached"),
-        ("Unable to protect buffer (hard key usage limit reached)"));
-    gst_buffer_unref (bufout);
-    goto fail;
-
   } else {
-    /* srtp_protect failed */
-    GST_ELEMENT_ERROR (filter, LIBRARY, FAILED, (NULL),
-        ("Unable to protect buffer (protect failed) code %d", err));
-    gst_buffer_unref (bufout);
     goto fail;
   }
 
+  GST_OBJECT_LOCK (filter);
+
   if (gst_srtp_get_soft_limit_reached ()) {
+    GST_OBJECT_UNLOCK (filter);
     g_signal_emit (filter, gst_srtp_enc_signals[SIGNAL_SOFT_LIMIT], 0);
+    GST_OBJECT_LOCK (filter);
     if (filter->random_key && !filter->key_changed)
       gst_srtp_enc_replace_random_key (filter);
   }
 
+  GST_OBJECT_UNLOCK (filter);
+
 out:
 
   gst_buffer_unref (buf);
@@ -1094,6 +1162,115 @@
   goto out;
 }
 
+static gboolean
+validate_buffer_it (GstBuffer ** buffer, guint index, gpointer user_data)
+{
+  ValidateBufferItData *data = user_data;
+
+  if (!gst_srtp_enc_check_buffer (data->filter, *buffer, data->is_rtcp)) {
+    GST_WARNING_OBJECT (data->filter, "Invalid buffer, dropping");
+    gst_buffer_replace (buffer, NULL);
+  }
+
+  return TRUE;
+}
+
+static gboolean
+process_buffer_it (GstBuffer ** buffer, guint index, gpointer user_data)
+{
+  ProcessBufferItData *data = user_data;
+  GstBuffer *bufout;
+
+  if ((bufout =
+          gst_srtp_enc_process_buffer (data->filter, data->pad, *buffer,
+              data->is_rtcp))) {
+    gst_buffer_list_add (data->out_list, bufout);
+  } else {
+    GST_WARNING_OBJECT (data->filter, "Error encoding buffer, dropping");
+  }
+
+  return TRUE;
+}
+
+static GstFlowReturn
+gst_srtp_enc_chain_list (GstPad * pad, GstObject * parent,
+    GstBufferList * buf_list, gboolean is_rtcp)
+{
+  GstSrtpEnc *filter = GST_SRTP_ENC (parent);
+  GstFlowReturn ret = GST_FLOW_OK;
+  GstPad *otherpad;
+  GstBufferList *out_list = NULL;
+  ValidateBufferItData validate_data;
+  ProcessBufferItData process_data;
+
+  validate_data.filter = filter;
+  validate_data.is_rtcp = is_rtcp;
+
+  GST_LOG_OBJECT (pad, "Buffer chain with list of %d",
+      gst_buffer_list_length (buf_list));
+
+  gst_buffer_list_foreach (buf_list, validate_buffer_it, &validate_data);
+
+  if (!gst_buffer_list_length (buf_list))
+    goto out;
+
+  if ((ret = gst_srtp_enc_check_set_caps (filter, pad, is_rtcp)) != GST_FLOW_OK)
+    goto out;
+
+  GST_OBJECT_LOCK (filter);
+
+  if (!HAS_CRYPTO (filter)) {
+    GST_OBJECT_UNLOCK (filter);
+    otherpad = get_rtp_other_pad (pad);
+    return gst_pad_push_list (otherpad, buf_list);
+  }
+
+  GST_OBJECT_UNLOCK (filter);
+
+  out_list = gst_buffer_list_new ();
+
+  process_data.filter = filter;
+  process_data.pad = pad;
+  process_data.is_rtcp = is_rtcp;
+  process_data.out_list = out_list;
+
+  gst_buffer_list_foreach (buf_list, process_buffer_it, &process_data);
+
+  if (!gst_buffer_list_length (out_list)) {
+    gst_buffer_list_unref (out_list);
+    ret = GST_FLOW_OK;
+    goto out;
+  }
+
+  /* Push buffer to source pad */
+  otherpad = get_rtp_other_pad (pad);
+  GST_LOG_OBJECT (pad, "Pushing buffer chain of %d",
+      gst_buffer_list_length (buf_list));
+  ret = gst_pad_push_list (otherpad, out_list);
+
+  if (ret != GST_FLOW_OK) {
+    goto out;
+  }
+
+  GST_OBJECT_LOCK (filter);
+
+  if (gst_srtp_get_soft_limit_reached ()) {
+    GST_OBJECT_UNLOCK (filter);
+    g_signal_emit (filter, gst_srtp_enc_signals[SIGNAL_SOFT_LIMIT], 0);
+    GST_OBJECT_LOCK (filter);
+    if (filter->random_key && !filter->key_changed)
+      gst_srtp_enc_replace_random_key (filter);
+  }
+
+  GST_OBJECT_UNLOCK (filter);
+
+out:
+
+  gst_buffer_list_unref (buf_list);
+
+  return ret;
+}
+
 static GstFlowReturn
 gst_srtp_enc_chain_rtp (GstPad * pad, GstObject * parent, GstBuffer * buf)
 {
@@ -1106,6 +1283,20 @@
   return gst_srtp_enc_chain (pad, parent, buf, TRUE);
 }
 
+static GstFlowReturn
+gst_srtp_enc_chain_list_rtp (GstPad * pad, GstObject * parent,
+    GstBufferList * buf_list)
+{
+  return gst_srtp_enc_chain_list (pad, parent, buf_list, FALSE);
+}
+
+static GstFlowReturn
+gst_srtp_enc_chain_list_rtcp (GstPad * pad, GstObject * parent,
+    GstBufferList * buf_list)
+{
+  return gst_srtp_enc_chain_list (pad, parent, buf_list, TRUE);
+}
+
 
 /* Change state
  */
@@ -1138,8 +1329,10 @@
             "RTCP authentication can't be NULL if encryption is not NULL.");
         return GST_STATE_CHANGE_FAILURE;
       }
+      GST_OBJECT_LOCK (filter);
       if (!filter->first_session)
-        gst_srtp_enc_reset (filter);
+        gst_srtp_enc_reset_no_lock (filter);
+      GST_OBJECT_UNLOCK (filter);
       break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
       break;
diff --git a/ext/x265/Makefile.am b/ext/x265/Makefile.am
index d2a8102..0f1e7f5 100644
--- a/ext/x265/Makefile.am
+++ b/ext/x265/Makefile.am
@@ -15,18 +15,3 @@
 libgstx265_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstx265enc.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstx265 -:SHARED libgstx265 \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstx265_la_SOURCES) \
-	 -:CPPFLAGS $(CPPFLAGS) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstx265_la_CFLAGS) -I'$$(GSTREAMER_AGGREGATE_TOP)/x265' \
-	 -:LDFLAGS $(libgstx265_la_LDFLAGS) \
-	           $(libgstx265_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/ext/x265/Makefile.in b/ext/x265/Makefile.in
index 712244b..0fadad9 100644
--- a/ext/x265/Makefile.in
+++ b/ext/x265/Makefile.in
@@ -1077,21 +1077,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstx265 -:SHARED libgstx265 \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstx265_la_SOURCES) \
-	 -:CPPFLAGS $(CPPFLAGS) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstx265_la_CFLAGS) -I'$$(GSTREAMER_AGGREGATE_TOP)/x265' \
-	 -:LDFLAGS $(libgstx265_la_LDFLAGS) \
-	           $(libgstx265_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst-libs/gst/adaptivedemux/Makefile.am b/gst-libs/gst/adaptivedemux/Makefile.am
index 7ef8990..be4baac 100644
--- a/gst-libs/gst/adaptivedemux/Makefile.am
+++ b/gst-libs/gst/adaptivedemux/Makefile.am
@@ -20,17 +20,3 @@
 	-lgstapp-$(GST_API_VERSION) $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(GST_LIBS)
 
 libgstadaptivedemux_@GST_API_VERSION@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
-
-Android.mk: Makefile.am
-	androgenizer -:PROJECT libgstadaptivedemux -:STATIC libgstadaptivedemux-@GST_API_VERSION@ \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstadaptivedemux_@GST_API_VERSION@_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(libgstadaptivedemux_@GST_API_VERSION@_la_CFLAGS) \
-	 -:LDFLAGS $(libgstadaptivedemux_@GST_API_VERSION@_la_LDFLAGS) \
-	           $(libgstadaptivedemux_@GST_API_VERSION@_la_LIBADD) \
-	           -ldl \
-	 -:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/adaptivedemux \
-	 -:HEADERS $(libgstadaptivedemuxinclude_HEADERS) \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-	> $@
diff --git a/gst-libs/gst/adaptivedemux/Makefile.in b/gst-libs/gst/adaptivedemux/Makefile.in
index b6ef985..9949cfa 100644
--- a/gst-libs/gst/adaptivedemux/Makefile.in
+++ b/gst-libs/gst/adaptivedemux/Makefile.in
@@ -1082,20 +1082,6 @@
 	tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES
 
 
-Android.mk: Makefile.am
-	androgenizer -:PROJECT libgstadaptivedemux -:STATIC libgstadaptivedemux-@GST_API_VERSION@ \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstadaptivedemux_@GST_API_VERSION@_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(libgstadaptivedemux_@GST_API_VERSION@_la_CFLAGS) \
-	 -:LDFLAGS $(libgstadaptivedemux_@GST_API_VERSION@_la_LDFLAGS) \
-	           $(libgstadaptivedemux_@GST_API_VERSION@_la_LIBADD) \
-	           -ldl \
-	 -:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/adaptivedemux \
-	 -:HEADERS $(libgstadaptivedemuxinclude_HEADERS) \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-	> $@
-
 # 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/gst-libs/gst/adaptivedemux/gstadaptivedemux.c b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c
index cf4a317..655e03e 100644
--- a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c
+++ b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c
@@ -75,7 +75,6 @@
 #include "gstadaptivedemux.h"
 #include "gst/gst-i18n-plugin.h"
 #include <gst/base/gstadapter.h>
-#include <gst/uridownloader/gsturidownloader.h>
 
 GST_DEBUG_CATEGORY (adaptivedemux_debug);
 #define GST_CAT_DEFAULT adaptivedemux_debug
@@ -107,7 +106,7 @@
 struct _GstAdaptiveDemuxPrivate
 {
   GstAdapter *input_adapter;
-  GstBuffer *manifest_buffer;
+  gboolean have_manifest;
 
   GstUriDownloader *downloader;
 
@@ -168,6 +167,8 @@
     GstAdaptiveDemuxStream * stream);
 static GstFlowReturn gst_adaptive_demux_update_manifest (GstAdaptiveDemux *
     demux);
+static GstFlowReturn
+gst_adaptive_demux_update_manifest_default (GstAdaptiveDemux * demux);
 static gboolean gst_adaptive_demux_has_next_period (GstAdaptiveDemux * demux);
 static void gst_adaptive_demux_advance_period (GstAdaptiveDemux * demux);
 
@@ -315,6 +316,7 @@
 
   klass->data_received = gst_adaptive_demux_stream_data_received_default;
   klass->finish_fragment = gst_adaptive_demux_stream_finish_fragment_default;
+  klass->update_manifest = gst_adaptive_demux_update_manifest_default;
 }
 
 static void
@@ -328,7 +330,7 @@
 
   demux->priv = GST_ADAPTIVE_DEMUX_GET_PRIVATE (demux);
   demux->priv->input_adapter = gst_adapter_new ();
-  demux->priv->downloader = gst_uri_downloader_new ();
+  demux->downloader = gst_uri_downloader_new ();
   demux->stream_struct_size = sizeof (GstAdaptiveDemuxStream);
 
   gst_segment_init (&demux->segment, GST_FORMAT_TIME);
@@ -372,7 +374,7 @@
   GST_DEBUG_OBJECT (object, "finalize");
 
   g_object_unref (priv->input_adapter);
-  g_object_unref (priv->downloader);
+  g_object_unref (demux->downloader);
 
   g_mutex_clear (&priv->updates_timed_lock);
   g_cond_clear (&priv->updates_timed_cond);
@@ -420,6 +422,7 @@
       gboolean query_res;
       gboolean ret = TRUE;
       gsize available;
+      GstBuffer *manifest_buffer;
 
       demux_class = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
       available = gst_adapter_available (demux->priv->input_adapter);
@@ -461,16 +464,19 @@
       gst_query_unref (query);
 
       /* Let the subclass parse the manifest */
-      demux->priv->manifest_buffer =
+      manifest_buffer =
           gst_adapter_take_buffer (demux->priv->input_adapter, available);
-      if (!demux_class->process_manifest (demux, demux->priv->manifest_buffer)) {
+      if (!demux_class->process_manifest (demux, manifest_buffer)) {
         /* In most cases, this will happen if we set a wrong url in the
          * source element and we have received the 404 HTML response instead of
          * the manifest */
         GST_ELEMENT_ERROR (demux, STREAM, DECODE, ("Invalid manifest."),
             (NULL));
         ret = FALSE;
+      } else {
+        demux->priv->have_manifest = TRUE;
       }
+      gst_buffer_unref (manifest_buffer);
 
       gst_element_post_message (GST_ELEMENT_CAST (demux),
           gst_message_new_element (GST_OBJECT_CAST (demux),
@@ -553,7 +559,7 @@
   GList *iter;
 
   gst_adaptive_demux_stop_tasks (demux);
-  gst_uri_downloader_reset (demux->priv->downloader);
+  gst_uri_downloader_reset (demux->downloader);
 
   if (klass->reset)
     klass->reset (demux);
@@ -579,10 +585,7 @@
   demux->manifest_base_uri = NULL;
 
   gst_adapter_clear (demux->priv->input_adapter);
-  if (demux->priv->manifest_buffer) {
-    gst_buffer_unref (demux->priv->manifest_buffer);
-    demux->priv->manifest_buffer = NULL;
-  }
+  demux->priv->have_manifest = FALSE;
 
   gst_segment_init (&demux->segment, GST_FORMAT_TIME);
 
@@ -1102,7 +1105,8 @@
 
       GST_MANIFEST_LOCK (demux);
       gst_query_parse_duration (query, &fmt, NULL);
-      if (fmt == GST_FORMAT_TIME && demux->priv->manifest_buffer != NULL) {
+      if (fmt == GST_FORMAT_TIME && demux->priv->have_manifest
+          && !gst_adaptive_demux_is_live (demux)) {
         duration = demux_class->get_duration (demux);
 
         if (GST_CLOCK_TIME_IS_VALID (duration) && duration > 0) {
@@ -1116,13 +1120,7 @@
       break;
     }
     case GST_QUERY_LATENCY:{
-      gboolean live = FALSE;
-
-      GST_MANIFEST_LOCK (demux);
-      live = demux->priv->manifest_buffer && gst_adaptive_demux_is_live (demux);
-      GST_MANIFEST_UNLOCK (demux);
-
-      gst_query_set_latency (query, live, 0, -1);
+      gst_query_set_latency (query, FALSE, 0, -1);
       ret = TRUE;
       break;
     }
@@ -1132,8 +1130,10 @@
       gint64 start = 0;
 
       GST_MANIFEST_LOCK (demux);
-      if (demux->priv->manifest_buffer == NULL) {
+      if (!demux->priv->have_manifest) {
         GST_MANIFEST_UNLOCK (demux);
+        GST_INFO_OBJECT (demux,
+            "Don't have manifest yet, can't answer seeking query");
         return FALSE;           /* can't answer without manifest */
       }
 
@@ -1212,7 +1212,7 @@
   g_cond_broadcast (&demux->manifest_cond);
   GST_MANIFEST_UNLOCK (demux);
 
-  gst_uri_downloader_cancel (demux->priv->downloader);
+  gst_uri_downloader_cancel (demux->downloader);
   for (iter = demux->streams; iter; iter = g_list_next (iter)) {
     GstAdaptiveDemuxStream *stream = iter->data;
 
@@ -1974,38 +1974,27 @@
     GST_DEBUG_OBJECT (stream->pad,
         "Activating stream due to reconfigure event");
 
-    cur = stream->segment.position;
+    cur = ts = stream->segment.position;
 
     if (gst_pad_peer_query_position (stream->pad, GST_FORMAT_TIME, &pos)) {
       ts = (GstClockTime) pos;
       GST_DEBUG_OBJECT (demux, "Downstream position: %"
           GST_TIME_FORMAT, GST_TIME_ARGS (ts));
     } else {
-      gboolean have_pos = FALSE;
-
       /* query other pads as some faulty element in the pad's branch might
        * reject position queries. This should be better than using the
        * demux segment position that can be much ahead */
       for (GList * iter = demux->streams; iter != NULL;
           iter = g_list_next (iter)) {
-        GstAdaptiveDemuxStream *cur_stream = iter->data;
+        GstAdaptiveDemuxStream *cur_stream = (GstAdaptiveDemuxStream *)iter->data;
 
-        have_pos =
-            gst_pad_peer_query_position (cur_stream->pad, GST_FORMAT_TIME,
-            &pos);
-        if (have_pos) {
+        if (gst_pad_peer_query_position (cur_stream->pad, GST_FORMAT_TIME, &pos)) {
           ts = (GstClockTime) pos;
           GST_DEBUG_OBJECT (stream->pad, "Downstream position: %"
               GST_TIME_FORMAT, GST_TIME_ARGS (ts));
           break;
         }
       }
-
-      if (!have_pos) {
-        ts = stream->segment.position;
-        GST_DEBUG_OBJECT (stream->pad, "Downstream position query failed, "
-            "failling back to looking at other pads");
-      }
     }
 
     /* we might have already pushed this data */
@@ -2267,7 +2256,8 @@
             g_get_monotonic_time () +
             klass->get_manifest_update_interval (demux);
       } else {
-        GST_ERROR_OBJECT (demux, "Could not update playlist");
+        GST_ELEMENT_ERROR (demux, STREAM, FAILED,
+            (_("Internal data stream error.")), ("Could not update playlist"));
         goto error;
       }
     } else {
@@ -2291,7 +2281,7 @@
 error:
   {
     GST_DEBUG_OBJECT (demux, "Stopped updates task because of error");
-    gst_adaptive_demux_stop_tasks (demux);
+    gst_task_stop (demux->priv->updates_task);
   }
 }
 
@@ -2395,7 +2385,13 @@
 
   if (GST_CLOCK_TIME_IS_VALID (duration))
     stream->segment.position += duration;
-  ret = klass->stream_advance_fragment (stream);
+
+  if (gst_adaptive_demux_is_live (demux)
+      || gst_adaptive_demux_stream_has_next_fragment (demux, stream)) {
+    ret = klass->stream_advance_fragment (stream);
+  } else {
+    ret = GST_FLOW_EOS;
+  }
 
   stream->download_start_time = stream->download_chunk_start_time =
       g_get_monotonic_time ();
@@ -2464,17 +2460,16 @@
 }
 
 static GstFlowReturn
-gst_adaptive_demux_update_manifest (GstAdaptiveDemux * demux)
+gst_adaptive_demux_update_manifest_default (GstAdaptiveDemux * demux)
 {
   GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
   GstFragment *download;
   GstBuffer *buffer;
   GstFlowReturn ret;
 
-  download = gst_uri_downloader_fetch_uri (demux->priv->downloader,
+  download = gst_uri_downloader_fetch_uri (demux->downloader,
       demux->manifest_uri, NULL, TRUE, TRUE, TRUE, NULL);
   if (download) {
-
     GST_MANIFEST_LOCK (demux);
     g_free (demux->manifest_uri);
     g_free (demux->manifest_base_uri);
@@ -2488,31 +2483,11 @@
 
     buffer = gst_fragment_get_buffer (download);
     g_object_unref (download);
-    ret = klass->update_manifest (demux, buffer);
-    if (ret == GST_FLOW_OK) {
-      GstClockTime duration;
-      gst_buffer_unref (demux->priv->manifest_buffer);
-      demux->priv->manifest_buffer = buffer;
-
-      /* Send an updated duration message */
-      duration = klass->get_duration (demux);
-
-      GST_MANIFEST_UNLOCK (demux);
-      if (duration != GST_CLOCK_TIME_NONE) {
-        GST_DEBUG_OBJECT (demux,
-            "Sending duration message : %" GST_TIME_FORMAT,
-            GST_TIME_ARGS (duration));
-        gst_element_post_message (GST_ELEMENT (demux),
-            gst_message_new_duration_changed (GST_OBJECT (demux)));
-      } else {
-        GST_DEBUG_OBJECT (demux,
-            "Duration unknown, can not send the duration message");
-      }
-    } else {
-      GST_MANIFEST_UNLOCK (demux);
-      gst_buffer_unref (buffer);
-      /* Should the manifest uri vars be reverted to original values? */
-    }
+    ret = klass->update_manifest_data (demux, buffer);
+    gst_buffer_unref (buffer);
+    GST_MANIFEST_UNLOCK (demux);
+    /* FIXME: Should the manifest uri vars be reverted to original
+     * values if updating fails? */
   } else {
     ret = GST_FLOW_NOT_LINKED;
   }
@@ -2520,6 +2495,35 @@
   return ret;
 }
 
+static GstFlowReturn
+gst_adaptive_demux_update_manifest (GstAdaptiveDemux * demux)
+{
+  GstAdaptiveDemuxClass *klass = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
+  GstFlowReturn ret;
+
+  ret = klass->update_manifest (demux);
+
+  if (ret == GST_FLOW_OK) {
+    GstClockTime duration;
+    GST_MANIFEST_LOCK (demux);
+    /* Send an updated duration message */
+    duration = klass->get_duration (demux);
+    GST_MANIFEST_UNLOCK (demux);
+    if (duration != GST_CLOCK_TIME_NONE) {
+      GST_DEBUG_OBJECT (demux,
+          "Sending duration message : %" GST_TIME_FORMAT,
+          GST_TIME_ARGS (duration));
+      gst_element_post_message (GST_ELEMENT (demux),
+          gst_message_new_duration_changed (GST_OBJECT (demux)));
+    } else {
+      GST_DEBUG_OBJECT (demux,
+          "Duration unknown, can not send the duration message");
+    }
+  }
+
+  return ret;
+}
+
 void
 gst_adaptive_demux_stream_fragment_clear (GstAdaptiveDemuxStreamFragment * f)
 {
diff --git a/gst-libs/gst/adaptivedemux/gstadaptivedemux.h b/gst-libs/gst/adaptivedemux/gstadaptivedemux.h
index 36e20ef..9303a84 100644
--- a/gst-libs/gst/adaptivedemux/gstadaptivedemux.h
+++ b/gst-libs/gst/adaptivedemux/gstadaptivedemux.h
@@ -24,6 +24,7 @@
 
 #include <gst/gst.h>
 #include <gst/base/gstadapter.h>
+#include <gst/uridownloader/gsturidownloader.h>
 
 G_BEGIN_DECLS
 
@@ -176,7 +177,7 @@
   /*< protected >*/
   GstPad         *sinkpad;
 
-  GstAdaptiveDemuxPrivate *priv;
+  GstUriDownloader *downloader;
 
   GList *streams;
   GList *next_streams;
@@ -198,6 +199,9 @@
 
   gboolean have_group_id;
   guint group_id;
+
+  /* < private > */
+  GstAdaptiveDemuxPrivate *priv;
 };
 
 /**
@@ -233,9 +237,23 @@
    * Returns: the update interval in microseconds
    */
   gint64        (*get_manifest_update_interval) (GstAdaptiveDemux * demux);
+
   /**
    * update_manifest:
    * @demux: #GstAdaptiveDemux
+   *
+   * During live streaming, this will be called for the subclass to update its
+   * manifest with the new version. By default it fetches the manifest URI
+   * and passes it to GstAdaptiveDemux::update_manifest_data().
+   *
+   * Returns: #GST_FLOW_OK is all succeeded, #GST_FLOW_EOS if the stream ended
+   *          or #GST_FLOW_ERROR if an error happened
+   */
+  GstFlowReturn (*update_manifest) (GstAdaptiveDemux * demux);
+
+  /**
+   * update_manifest_data:
+   * @demux: #GstAdaptiveDemux
    * @buf: Downloaded manifest data
    *
    * During live streaming, this will be called for the subclass to update its
@@ -244,7 +262,7 @@
    * Returns: #GST_FLOW_OK is all succeeded, #GST_FLOW_EOS if the stream ended
    *          or #GST_FLOW_ERROR if an error happened
    */
-  GstFlowReturn (*update_manifest) (GstAdaptiveDemux * demux, GstBuffer * buf);
+  GstFlowReturn (*update_manifest_data) (GstAdaptiveDemux * demux, GstBuffer * buf);
 
   gboolean      (*is_live)          (GstAdaptiveDemux * demux);
   GstClockTime  (*get_duration)     (GstAdaptiveDemux * demux);
diff --git a/gst-libs/gst/base/gstaggregator.c b/gst-libs/gst/base/gstaggregator.c
index 788c84a..4370ac2 100644
--- a/gst-libs/gst/base/gstaggregator.c
+++ b/gst-libs/gst/base/gstaggregator.c
@@ -54,6 +54,12 @@
  *    subclass, it should instead return GST_FLOW_EOS in its aggregate
  *    implementation.
  *  </para></listitem>
+ *  <listitem><para>
+ *    Note that the aggregator logic regarding gap event handling is to turn
+ *    these into gap buffers with matching PTS and duration. It will also
+ *    flag these buffers with GST_BUFFER_FLAG_GAP and GST_BUFFER_FLAG_DROPPABLE
+ *    to ease their identification and subsequent processing.
+ *  </para></listitem>
  * </itemizedlist>
  */
 
@@ -87,6 +93,8 @@
  */
 
 
+static GstClockTime gst_aggregator_get_latency_unlocked (GstAggregator * self);
+
 GST_DEBUG_CATEGORY_STATIC (aggregator_debug);
 #define GST_CAT_DEFAULT aggregator_debug
 
@@ -109,16 +117,16 @@
 
 
 #define PAD_WAIT_EVENT(pad)   G_STMT_START {                            \
-  GST_LOG_OBJECT (pad, "Waiting for EVENT on thread %p",                \
+  GST_LOG_OBJECT (pad, "Waiting for buffer to be consumed thread %p",   \
         g_thread_self());                                               \
   g_cond_wait(&(((GstAggregatorPad* )pad)->priv->event_cond),           \
       (&((GstAggregatorPad*)pad)->priv->lock));                         \
-  GST_LOG_OBJECT (pad, "DONE Waiting for EVENT on thread %p",           \
+  GST_LOG_OBJECT (pad, "DONE Waiting for buffer to be consumed on thread %p", \
         g_thread_self());                                               \
   } G_STMT_END
 
 #define PAD_BROADCAST_EVENT(pad) G_STMT_START {                        \
-  GST_LOG_OBJECT (pad, "Signaling EVENT from thread %p",               \
+  GST_LOG_OBJECT (pad, "Signaling buffer consumed from thread %p",     \
         g_thread_self());                                              \
   g_cond_broadcast(&(((GstAggregatorPad* )pad)->priv->event_cond));    \
   } G_STMT_END
@@ -174,10 +182,8 @@
 
 struct _GstAggregatorPadPrivate
 {
-  /* To always be used atomically */
-  gboolean flushing;
-
   /* Following fields are protected by the PAD_LOCK */
+  GstFlowReturn flow_return;
   gboolean pending_flush_start;
   gboolean pending_flush_stop;
   gboolean pending_eos;
@@ -199,8 +205,9 @@
   GstAggregatorPadClass *klass = GST_AGGREGATOR_PAD_GET_CLASS (aggpad);
 
   PAD_LOCK (aggpad);
+  aggpad->priv->pending_eos = FALSE;
   aggpad->priv->eos = FALSE;
-  aggpad->priv->flushing = FALSE;
+  aggpad->priv->flow_return = GST_FLOW_OK;
   PAD_UNLOCK (aggpad);
 
   if (klass->flush)
@@ -229,16 +236,16 @@
   gboolean flush_seeking;
   gboolean pending_flush_start;
   gboolean send_eos;            /* protected by srcpad stream lock */
-  GstFlowReturn flow_return;
 
   GstCaps *srccaps;             /* protected by the srcpad stream lock */
 
   GstTagList *tags;
   gboolean tags_changed;
 
-  gboolean latency_live;        /* protected by src_lock */
-  GstClockTime latency_min;     /* protected by src_lock */
-  GstClockTime latency_max;     /* protected by src_lock */
+  gboolean peer_latency_live;   /* protected by src_lock */
+  GstClockTime peer_latency_min;        /* protected by src_lock */
+  GstClockTime peer_latency_max;        /* protected by src_lock */
+  gboolean has_peer_latency;
 
   GstClockTime sub_latency_min; /* protected by src_lock */
   GstClockTime sub_latency_max; /* protected by src_lock */
@@ -397,7 +404,6 @@
 gst_aggregator_reset_flow_values (GstAggregator * self)
 {
   GST_OBJECT_LOCK (self);
-  self->priv->flow_return = GST_FLOW_FLUSHING;
   self->priv->send_stream_start = TRUE;
   self->priv->send_segment = TRUE;
   gst_segment_init (&self->segment, GST_FORMAT_TIME);
@@ -535,15 +541,15 @@
 static gboolean
 gst_aggregator_wait_and_check (GstAggregator * self, gboolean * timeout)
 {
-  GstClockTime latency_max, latency_min;
+  GstClockTime latency;
   GstClockTime start;
-  gboolean live, res;
+  gboolean res;
 
   *timeout = FALSE;
 
   SRC_LOCK (self);
 
-  gst_aggregator_get_latency_unlocked (self, &live, &latency_min, &latency_max);
+  latency = gst_aggregator_get_latency_unlocked (self);
 
   if (gst_aggregator_check_pads_ready (self)) {
     GST_DEBUG_OBJECT (self, "all pads have data");
@@ -561,8 +567,9 @@
 
   start = gst_aggregator_get_next_time (self);
 
-  if (!live || !GST_IS_CLOCK (GST_ELEMENT_CLOCK (self))
-      || !GST_CLOCK_TIME_IS_VALID (start)) {
+  if (!GST_CLOCK_TIME_IS_VALID (latency) ||
+      !GST_IS_CLOCK (GST_ELEMENT_CLOCK (self)) ||
+      !GST_CLOCK_TIME_IS_VALID (start)) {
     /* We wake up here when something happened, and below
      * then check if we're ready now. If we return FALSE,
      * we will be directly called again.
@@ -585,15 +592,14 @@
     GST_OBJECT_UNLOCK (self);
 
     time = base_time + start;
-    time += latency_min;
+    time += latency;
 
     GST_DEBUG_OBJECT (self, "possibly waiting for clock to reach %"
         GST_TIME_FORMAT " (base %" GST_TIME_FORMAT " start %" GST_TIME_FORMAT
-        " latency max %" GST_TIME_FORMAT " latency min %" GST_TIME_FORMAT
-        " current %" GST_TIME_FORMAT ")", GST_TIME_ARGS (time),
+        " latency %" GST_TIME_FORMAT " current %" GST_TIME_FORMAT ")",
+        GST_TIME_ARGS (time),
         GST_TIME_ARGS (GST_ELEMENT_CAST (self)->base_time),
-        GST_TIME_ARGS (start), GST_TIME_ARGS (latency_max),
-        GST_TIME_ARGS (latency_min),
+        GST_TIME_ARGS (start), GST_TIME_ARGS (latency),
         GST_TIME_ARGS (gst_clock_get_time (clock)));
 
 
@@ -630,6 +636,20 @@
 }
 
 static void
+gst_aggregator_pad_set_flushing (GstAggregatorPad * aggpad,
+    GstFlowReturn flow_return)
+{
+  PAD_LOCK (aggpad);
+  if (flow_return == GST_FLOW_NOT_LINKED)
+    aggpad->priv->flow_return = MIN (flow_return, aggpad->priv->flow_return);
+  else
+    aggpad->priv->flow_return = flow_return;
+  gst_buffer_replace (&aggpad->priv->buffer, NULL);
+  PAD_BROADCAST_EVENT (aggpad);
+  PAD_UNLOCK (aggpad);
+}
+
+static void
 gst_aggregator_aggregate_func (GstAggregator * self)
 {
   GstAggregatorPrivate *priv = self->priv;
@@ -653,10 +673,12 @@
     flow_return = klass->aggregate (self, timeout);
 
     GST_OBJECT_LOCK (self);
-    if (flow_return == GST_FLOW_FLUSHING && priv->flush_seeking)
-      priv->flow_return = GST_FLOW_OK;
-    else
-      priv->flow_return = flow_return;
+    if (flow_return == GST_FLOW_FLUSHING && priv->flush_seeking) {
+      /* We don't want to set the pads to flushing, but we want to
+       * stop the thread, so just break here */
+      GST_OBJECT_UNLOCK (self);
+      break;
+    }
     GST_OBJECT_UNLOCK (self);
 
     if (flow_return == GST_FLOW_EOS) {
@@ -665,8 +687,18 @@
 
     GST_LOG_OBJECT (self, "flow return is %s", gst_flow_get_name (flow_return));
 
-    if (flow_return != GST_FLOW_OK)
+    if (flow_return != GST_FLOW_OK) {
+      GList *item;
+
+      GST_OBJECT_LOCK (self);
+      for (item = GST_ELEMENT (self)->sinkpads; item; item = item->next) {
+        GstAggregatorPad *aggpad = GST_AGGREGATOR_PAD (item->data);
+
+        gst_aggregator_pad_set_flushing (aggpad, flow_return);
+      }
+      GST_OBJECT_UNLOCK (self);
       break;
+    }
   }
 
   /* Pause the task here, the only ways to get here are:
@@ -690,7 +722,6 @@
   self->priv->send_segment = TRUE;
   self->priv->send_eos = TRUE;
   self->priv->srccaps = NULL;
-  self->priv->flow_return = GST_FLOW_OK;
 
   klass = GST_AGGREGATOR_GET_CLASS (self);
 
@@ -794,10 +825,7 @@
   GstAggregatorPrivate *priv = self->priv;
   GstAggregatorPadPrivate *padpriv = aggpad->priv;
 
-  g_atomic_int_set (&aggpad->priv->flushing, TRUE);
-
-  /*  Remove pad buffer and wake up the streaming thread */
-  gst_aggregator_pad_drop_buffer (aggpad);
+  gst_aggregator_pad_set_flushing (aggpad, GST_FLOW_FLUSHING);
 
   PAD_FLUSH_LOCK (aggpad);
   PAD_LOCK (aggpad);
@@ -818,7 +846,6 @@
 
       GST_INFO_OBJECT (self, "Flushing, pausing srcpad task");
       gst_aggregator_stop_srcpad_task (self, event);
-      priv->flow_return = GST_FLOW_OK;
 
       GST_INFO_OBJECT (self, "Getting STREAM_LOCK while seeking");
       GST_PAD_STREAM_LOCK (self->srcpad);
@@ -925,9 +952,23 @@
     }
     case GST_EVENT_GAP:
     {
-      /* FIXME: need API to handle GAP events properly */
-      GST_FIXME_OBJECT (self, "implement support for GAP events");
-      /* don't forward GAP events downstream */
+      GstClockTime pts;
+      GstClockTime duration;
+      GstBuffer *gapbuf;
+
+      gst_event_parse_gap (event, &pts, &duration);
+      gapbuf = gst_buffer_new ();
+
+      GST_BUFFER_PTS (gapbuf) = pts;
+      GST_BUFFER_DURATION (gapbuf) = duration;
+      GST_BUFFER_FLAG_SET (gapbuf, GST_BUFFER_FLAG_GAP);
+      GST_BUFFER_FLAG_SET (gapbuf, GST_BUFFER_FLAG_DROPPABLE);
+
+      if (gst_pad_chain (pad, gapbuf) != GST_FLOW_OK) {
+        GST_WARNING_OBJECT (self, "Failed to chain gap buffer");
+        res = FALSE;
+      }
+
       goto eat;
     }
     case GST_EVENT_TAG:
@@ -987,6 +1028,10 @@
   else
     result = TRUE;
 
+  agg->priv->has_peer_latency = FALSE;
+  agg->priv->peer_latency_live = FALSE;
+  agg->priv->peer_latency_min = agg->priv->peer_latency_max = FALSE;
+
   if (agg->priv->tags)
     gst_tag_list_unref (agg->priv->tags);
   agg->priv->tags = NULL;
@@ -1046,14 +1091,12 @@
 gst_aggregator_release_pad (GstElement * element, GstPad * pad)
 {
   GstAggregator *self = GST_AGGREGATOR (element);
-
   GstAggregatorPad *aggpad = GST_AGGREGATOR_PAD (pad);
 
   GST_INFO_OBJECT (pad, "Removing pad");
 
   SRC_LOCK (self);
-  g_atomic_int_set (&aggpad->priv->flushing, TRUE);
-  gst_aggregator_pad_drop_buffer (aggpad);
+  gst_aggregator_pad_set_flushing (aggpad, GST_FLOW_FLUSHING);
   gst_element_remove_pad (element, pad);
 
   SRC_BROADCAST (self);
@@ -1110,8 +1153,10 @@
   return GST_PAD (agg_pad);
 }
 
+/* Must be called with SRC_LOCK held */
+
 static gboolean
-gst_aggregator_query_latency (GstAggregator * self, GstQuery * query)
+gst_aggregator_query_latency_unlocked (GstAggregator * self, GstQuery * query)
 {
   gboolean query_ret, live;
   GstClockTime our_latency, min, max;
@@ -1125,13 +1170,11 @@
 
   gst_query_parse_latency (query, &live, &min, &max);
 
-  SRC_LOCK (self);
   our_latency = self->priv->latency;
 
   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (min))) {
     GST_ERROR_OBJECT (self, "Invalid minimum latency %" GST_TIME_FORMAT
         ". Please file a bug at " PACKAGE_BUGREPORT ".", GST_TIME_ARGS (min));
-    SRC_UNLOCK (self);
     return FALSE;
   }
 
@@ -1140,13 +1183,13 @@
         ("Impossible to configure latency: max %" GST_TIME_FORMAT " < min %"
             GST_TIME_FORMAT ". Add queues or other buffering elements.",
             GST_TIME_ARGS (max), GST_TIME_ARGS (min)));
-    SRC_UNLOCK (self);
     return FALSE;
   }
 
-  self->priv->latency_live = live;
-  self->priv->latency_min = min;
-  self->priv->latency_max = max;
+  self->priv->peer_latency_live = live;
+  self->priv->peer_latency_min = min;
+  self->priv->peer_latency_max = max;
+  self->priv->has_peer_latency = TRUE;
 
   /* add our own */
   min += our_latency;
@@ -1160,7 +1203,7 @@
   if (live && min > max) {
     GST_ELEMENT_WARNING (self, CORE, NEGOTIATION,
         ("%s", "Latency too big"),
-        ("The requested latency value is too big for the current pipeline.  "
+        ("The requested latency value is too big for the current pipeline. "
             "Limiting to %" G_GINT64_FORMAT, max));
     min = max;
     /* FIXME: This could in theory become negative, but in
@@ -1170,7 +1213,6 @@
   }
 
   SRC_BROADCAST (self);
-  SRC_UNLOCK (self);
 
   GST_DEBUG_OBJECT (self, "configured latency live:%s min:%" G_GINT64_FORMAT
       " max:%" G_GINT64_FORMAT, live ? "true" : "false", min, max);
@@ -1180,47 +1222,63 @@
   return query_ret;
 }
 
-/**
- * gst_aggregator_get_latency_unlocked:
- * @self: a #GstAggregator
- * @live: (out) (allow-none): whether @self is live
- * @min_latency: (out) (allow-none): the configured minimum latency of @self
- * @max_latency: (out) (allow-none): the configured maximum latency of @self
+/*
+ * MUST be called with the src_lock held.
  *
- * Retreives the latency values reported by @self in response to the latency
- * query.
+ * See  gst_aggregator_get_latency() for doc
+ */
+static GstClockTime
+gst_aggregator_get_latency_unlocked (GstAggregator * self)
+{
+  GstClockTime latency;
+
+  g_return_val_if_fail (GST_IS_AGGREGATOR (self), 0);
+
+  if (!self->priv->has_peer_latency) {
+    GstQuery *query = gst_query_new_latency ();
+    gboolean ret;
+
+    ret = gst_aggregator_query_latency_unlocked (self, query);
+    gst_query_unref (query);
+    if (!ret)
+      return GST_CLOCK_TIME_NONE;
+  }
+
+  if (!self->priv->has_peer_latency || !self->priv->peer_latency_live)
+    return GST_CLOCK_TIME_NONE;
+
+  /* latency_min is never GST_CLOCK_TIME_NONE by construction */
+  latency = self->priv->peer_latency_min;
+
+  /* add our own */
+  latency += self->priv->latency;
+  latency += self->priv->sub_latency_min;
+
+  return latency;
+}
+
+/**
+ * gst_aggregator_get_latency:
+ * @self: a #GstAggregator
+ *
+ * Retrieves the latency values reported by @self in response to the latency
+ * query, or %GST_CLOCK_TIME_NONE if there is not live source connected and the element
+ * will not wait for the clock.
  *
  * Typically only called by subclasses.
  *
- * MUST be called with the src_lock held.
+ * Returns: The latency or %GST_CLOCK_TIME_NONE if the element does not sync
  */
-void
-gst_aggregator_get_latency_unlocked (GstAggregator * self, gboolean * live,
-    GstClockTime * min_latency, GstClockTime * max_latency)
+GstClockTime
+gst_aggregator_get_latency (GstAggregator * self)
 {
-  GstClockTime min, max;
+  GstClockTime ret;
 
-  g_return_if_fail (GST_IS_AGGREGATOR (self));
+  SRC_LOCK (self);
+  ret = gst_aggregator_get_latency_unlocked (self);
+  SRC_UNLOCK (self);
 
-  /* latency_min is never GST_CLOCK_TIME_NONE by construction */
-  min = self->priv->latency_min;
-  max = self->priv->latency_max;
-
-  /* add our own */
-  min += self->priv->latency;
-  min += self->priv->sub_latency_min;
-  if (GST_CLOCK_TIME_IS_VALID (max)
-      && GST_CLOCK_TIME_IS_VALID (self->priv->sub_latency_max))
-    max += self->priv->sub_latency_max;
-  else
-    max = GST_CLOCK_TIME_NONE;
-
-  if (live)
-    *live = self->priv->latency_live;
-  if (min_latency)
-    *min_latency = min;
-  if (max_latency)
-    *max_latency = max;
+  return ret;
 }
 
 static gboolean
@@ -1271,17 +1329,17 @@
       gst_query_set_seeking (query, format, FALSE, 0, -1);
       res = TRUE;
 
-      goto discard;
+      break;
     }
     case GST_QUERY_LATENCY:
-      return gst_aggregator_query_latency (self, query);
-    default:
+      SRC_LOCK (self);
+      res = gst_aggregator_query_latency_unlocked (self, query);
+      SRC_UNLOCK (self);
       break;
+    default:
+      return gst_pad_query_default (self->srcpad, GST_OBJECT (self), query);
   }
 
-  return gst_pad_query_default (self->srcpad, GST_OBJECT (self), query);
-
-discard:
   return res;
 }
 
@@ -1549,9 +1607,9 @@
   g_return_if_fail (GST_CLOCK_TIME_IS_VALID (latency));
 
   SRC_LOCK (self);
-  if (self->priv->latency_live) {
-    min = self->priv->latency_min;
-    max = self->priv->latency_max;
+  if (self->priv->peer_latency_live) {
+    min = self->priv->peer_latency_min;
+    max = self->priv->peer_latency_max;
     /* add our own */
     min += latency;
     min += self->priv->sub_latency_min;
@@ -1707,9 +1765,10 @@
   priv->padcount = -1;
   priv->tags_changed = FALSE;
 
-  self->priv->latency_live = FALSE;
-  self->priv->latency_min = self->priv->sub_latency_min = 0;
-  self->priv->latency_max = self->priv->sub_latency_max = 0;
+  self->priv->peer_latency_live = FALSE;
+  self->priv->peer_latency_min = self->priv->sub_latency_min = 0;
+  self->priv->peer_latency_max = self->priv->sub_latency_max = 0;
+  self->priv->has_peer_latency = FALSE;
   gst_aggregator_reset_flow_values (self);
 
   self->srcpad = gst_pad_new_from_template (pad_template, "src");
@@ -1762,7 +1821,6 @@
 {
   GstBuffer *actual_buf = buffer;
   GstAggregator *self = GST_AGGREGATOR (object);
-  GstAggregatorPrivate *priv = self->priv;
   GstAggregatorPad *aggpad = GST_AGGREGATOR_PAD (pad);
   GstAggregatorClass *aggclass = GST_AGGREGATOR_GET_CLASS (object);
   GstFlowReturn flow_return;
@@ -1771,23 +1829,23 @@
 
   PAD_FLUSH_LOCK (aggpad);
 
-  if (g_atomic_int_get (&aggpad->priv->flushing) == TRUE)
+  PAD_LOCK (aggpad);
+  flow_return = aggpad->priv->flow_return;
+  if (flow_return != GST_FLOW_OK)
     goto flushing;
 
-  PAD_LOCK (aggpad);
   if (aggpad->priv->pending_eos == TRUE)
     goto eos;
 
-  while (aggpad->priv->buffer
-      && g_atomic_int_get (&aggpad->priv->flushing) == FALSE) {
-    GST_DEBUG_OBJECT (aggpad, "Waiting for buffer to be consumed");
+  while (aggpad->priv->buffer && aggpad->priv->flow_return == GST_FLOW_OK)
     PAD_WAIT_EVENT (aggpad);
-  }
-  PAD_UNLOCK (aggpad);
 
-  if (g_atomic_int_get (&aggpad->priv->flushing) == TRUE)
+  flow_return = aggpad->priv->flow_return;
+  if (flow_return != GST_FLOW_OK)
     goto flushing;
 
+  PAD_UNLOCK (aggpad);
+
   if (aggclass->clip) {
     aggclass->clip (self, aggpad, buffer, &actual_buf);
   }
@@ -1797,6 +1855,9 @@
   if (aggpad->priv->buffer)
     gst_buffer_unref (aggpad->priv->buffer);
   aggpad->priv->buffer = actual_buf;
+
+  flow_return = aggpad->priv->flow_return;
+
   PAD_UNLOCK (aggpad);
   PAD_FLUSH_UNLOCK (aggpad);
 
@@ -1805,19 +1866,17 @@
 
   GST_DEBUG_OBJECT (aggpad, "Done chaining");
 
-  GST_OBJECT_LOCK (self);
-  flow_return = priv->flow_return;
-  GST_OBJECT_UNLOCK (self);
-
   return flow_return;
 
 flushing:
+  PAD_UNLOCK (aggpad);
   PAD_FLUSH_UNLOCK (aggpad);
 
   gst_buffer_unref (buffer);
-  GST_DEBUG_OBJECT (aggpad, "We are flushing");
+  GST_DEBUG_OBJECT (aggpad, "Pad is %s, dropping buffer",
+      gst_flow_get_name (flow_return));
 
-  return GST_FLOW_FLUSHING;
+  return flow_return;
 
 eos:
   PAD_UNLOCK (aggpad);
@@ -1839,27 +1898,22 @@
   if (GST_QUERY_IS_SERIALIZED (query)) {
     PAD_LOCK (aggpad);
 
-    if (g_atomic_int_get (&aggpad->priv->flushing) == TRUE) {
-      PAD_UNLOCK (aggpad);
-      goto flushing;
-    }
-
-    while (aggpad->priv->buffer
-        && g_atomic_int_get (&aggpad->priv->flushing) == FALSE) {
-      GST_DEBUG_OBJECT (aggpad, "Waiting for buffer to be consumed");
+    while (aggpad->priv->buffer && aggpad->priv->flow_return == GST_FLOW_OK)
       PAD_WAIT_EVENT (aggpad);
-    }
-    PAD_UNLOCK (aggpad);
 
-    if (g_atomic_int_get (&aggpad->priv->flushing) == TRUE)
+    if (aggpad->priv->flow_return != GST_FLOW_OK)
       goto flushing;
+
+    PAD_UNLOCK (aggpad);
   }
 
   return klass->sink_query (GST_AGGREGATOR (parent),
       GST_AGGREGATOR_PAD (pad), query);
 
 flushing:
-  GST_DEBUG_OBJECT (aggpad, "Pad is flushing, dropping query");
+  GST_DEBUG_OBJECT (aggpad, "Pad is %s, dropping query",
+      gst_flow_get_name (aggpad->priv->flow_return));
+  PAD_UNLOCK (aggpad);
   return FALSE;
 }
 
@@ -1874,29 +1928,24 @@
       && GST_EVENT_TYPE (event) != GST_EVENT_SEGMENT_DONE) {
     PAD_LOCK (aggpad);
 
-    if (g_atomic_int_get (&aggpad->priv->flushing) == TRUE
-        && GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_STOP) {
-      PAD_UNLOCK (aggpad);
-      goto flushing;
-    }
 
-    while (aggpad->priv->buffer
-        && g_atomic_int_get (&aggpad->priv->flushing) == FALSE) {
-      GST_DEBUG_OBJECT (aggpad, "Waiting for buffer to be consumed");
+    while (aggpad->priv->buffer && aggpad->priv->flow_return == GST_FLOW_OK)
       PAD_WAIT_EVENT (aggpad);
-    }
-    PAD_UNLOCK (aggpad);
 
-    if (g_atomic_int_get (&aggpad->priv->flushing) == TRUE
+    if (aggpad->priv->flow_return != GST_FLOW_OK
         && GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_STOP)
       goto flushing;
+
+    PAD_UNLOCK (aggpad);
   }
 
   return klass->sink_event (GST_AGGREGATOR (parent),
       GST_AGGREGATOR_PAD (pad), event);
 
 flushing:
-  GST_DEBUG_OBJECT (aggpad, "Pad is flushing, dropping event");
+  GST_DEBUG_OBJECT (aggpad, "Pad is %s, dropping event",
+      gst_flow_get_name (aggpad->priv->flow_return));
+  PAD_UNLOCK (aggpad);
   if (GST_EVENT_IS_STICKY (event))
     gst_pad_store_sticky_event (pad, event);
   gst_event_unref (event);
@@ -1910,14 +1959,10 @@
   GstAggregatorPad *aggpad = GST_AGGREGATOR_PAD (pad);
 
   if (active == FALSE) {
-    PAD_LOCK (aggpad);
-    g_atomic_int_set (&aggpad->priv->flushing, TRUE);
-    gst_buffer_replace (&aggpad->priv->buffer, NULL);
-    PAD_BROADCAST_EVENT (aggpad);
-    PAD_UNLOCK (aggpad);
+    gst_aggregator_pad_set_flushing (aggpad, GST_FLOW_FLUSHING);
   } else {
     PAD_LOCK (aggpad);
-    g_atomic_int_set (&aggpad->priv->flushing, FALSE);
+    aggpad->priv->flow_return = GST_FLOW_OK;
     PAD_BROADCAST_EVENT (aggpad);
     PAD_UNLOCK (aggpad);
   }
diff --git a/gst-libs/gst/base/gstaggregator.h b/gst-libs/gst/base/gstaggregator.h
index a4ebdd7..dce567b 100644
--- a/gst-libs/gst/base/gstaggregator.h
+++ b/gst-libs/gst/base/gstaggregator.h
@@ -271,10 +271,7 @@
                                                     GstAggregatorPadForeachFunc      func,
                                                     gpointer                         user_data);
 
-void     gst_aggregator_get_latency_unlocked       (GstAggregator                 *  self,
-                                                    gboolean                      *  live,
-                                                    GstClockTime                  *  min,
-                                                    GstClockTime                  *  max);
+GstClockTime  gst_aggregator_get_latency           (GstAggregator                 *  self);
 
 G_END_DECLS
 
diff --git a/gst-libs/gst/basecamerabinsrc/Makefile.am b/gst-libs/gst/basecamerabinsrc/Makefile.am
index 51f10ba..64126e3 100644
--- a/gst-libs/gst/basecamerabinsrc/Makefile.am
+++ b/gst-libs/gst/basecamerabinsrc/Makefile.am
@@ -23,17 +23,3 @@
 	-lgstapp-$(GST_API_VERSION) $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(GST_LIBS)
 
 libgstbasecamerabinsrc_@GST_API_VERSION@_la_LDFLAGS = $(GST_LIB_LDFLAGS) $(GST_ALL_LDFLAGS) $(GST_LT_LDFLAGS)
-
-Android.mk: Makefile.am
-	androgenizer -:PROJECT libgstbasecamerabinsrc -:STATIC libgstbasecamerabinsrc-@GST_API_VERSION@ \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstbasecamerabinsrc_@GST_API_VERSION@_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(libgstbasecamerabinsrc_@GST_API_VERSION@_la_CFLAGS) \
-	 -:LDFLAGS $(libgstbasecamerabinsrc_@GST_API_VERSION@_la_LDFLAGS) \
-	           $(libgstbasecamerabinsrc_@GST_API_VERSION@_la_LIBADD) \
-	           -ldl \
-	 -:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/basecamerabinsrc \
-	 -:HEADERS $(libgstbasecamerabinsrcinclude_HEADERS) \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-	> $@
diff --git a/gst-libs/gst/basecamerabinsrc/Makefile.in b/gst-libs/gst/basecamerabinsrc/Makefile.in
index 5c32e65..d9c75c2 100644
--- a/gst-libs/gst/basecamerabinsrc/Makefile.in
+++ b/gst-libs/gst/basecamerabinsrc/Makefile.in
@@ -1068,20 +1068,6 @@
 	uninstall-libgstbasecamerabinsrc_@GST_API_VERSION@includeHEADERS
 
 
-Android.mk: Makefile.am
-	androgenizer -:PROJECT libgstbasecamerabinsrc -:STATIC libgstbasecamerabinsrc-@GST_API_VERSION@ \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstbasecamerabinsrc_@GST_API_VERSION@_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(libgstbasecamerabinsrc_@GST_API_VERSION@_la_CFLAGS) \
-	 -:LDFLAGS $(libgstbasecamerabinsrc_@GST_API_VERSION@_la_LDFLAGS) \
-	           $(libgstbasecamerabinsrc_@GST_API_VERSION@_la_LIBADD) \
-	           -ldl \
-	 -:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/basecamerabinsrc \
-	 -:HEADERS $(libgstbasecamerabinsrcinclude_HEADERS) \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-	> $@
-
 # 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/gst-libs/gst/codecparsers/Makefile.am b/gst-libs/gst/codecparsers/Makefile.am
index eff6e83..8f2abb9 100644
--- a/gst-libs/gst/codecparsers/Makefile.am
+++ b/gst-libs/gst/codecparsers/Makefile.am
@@ -35,19 +35,3 @@
 	$(GST_LT_LDFLAGS)
 
 EXTRA_DIST = dboolhuff.LICENSE dboolhuff.PATENTS dboolhuff.AUTHORS
-
-Android.mk:  $(BUILT_SOURCES) Makefile.am
-	androgenizer -:PROJECT libgstcodecparsers -:STATIC libgstcodecparsers-@GST_API_VERSION@ \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstcodecparsers_@GST_API_VERSION@_la_SOURCES) \
-         $(built_sources) \
-	 -:CFLAGS $(DEFS) $(libgstcodecparsers_@GST_API_VERSION@_la_CFLAGS) \
-	 -:LDFLAGS $(libgstcodecparsers_@GST_API_VERSION@_la_LDFLAGS) \
-	           $(libgstcodecparsers@GST_API_VERSION@_la_LIBADD) \
-	           -ldl \
-	 -:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/codecparsers \
-	 -:HEADERS $(libgstcodecparsersinclude_HEADERS) \
-         $(built_headers) \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-	> $@
diff --git a/gst-libs/gst/codecparsers/Makefile.in b/gst-libs/gst/codecparsers/Makefile.in
index 738a4f8..aa9d1e8 100644
--- a/gst-libs/gst/codecparsers/Makefile.in
+++ b/gst-libs/gst/codecparsers/Makefile.in
@@ -1227,22 +1227,6 @@
 	uninstall-libgstcodecparsers_@GST_API_VERSION@includeHEADERS
 
 
-Android.mk:  $(BUILT_SOURCES) Makefile.am
-	androgenizer -:PROJECT libgstcodecparsers -:STATIC libgstcodecparsers-@GST_API_VERSION@ \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstcodecparsers_@GST_API_VERSION@_la_SOURCES) \
-         $(built_sources) \
-	 -:CFLAGS $(DEFS) $(libgstcodecparsers_@GST_API_VERSION@_la_CFLAGS) \
-	 -:LDFLAGS $(libgstcodecparsers_@GST_API_VERSION@_la_LDFLAGS) \
-	           $(libgstcodecparsers@GST_API_VERSION@_la_LIBADD) \
-	           -ldl \
-	 -:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/codecparsers \
-	 -:HEADERS $(libgstcodecparsersinclude_HEADERS) \
-         $(built_headers) \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-	> $@
-
 # 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/gst-libs/gst/codecparsers/gsth265parser.c b/gst-libs/gst/codecparsers/gsth265parser.c
index 083b278..563fedf 100644
--- a/gst-libs/gst/codecparsers/gsth265parser.c
+++ b/gst-libs/gst/codecparsers/gsth265parser.c
@@ -131,6 +131,24 @@
   54, 71, 71, 91
 };
 
+static const guint8 zigzag_4x4[16] = {
+  0, 1, 4, 8,
+  5, 2, 3, 6,
+  9, 12, 13, 10,
+  7, 11, 14, 15,
+};
+
+static const guint8 zigzag_8x8[64] = {
+  0, 1, 8, 16, 9, 2, 3, 10,
+  17, 24, 32, 25, 18, 11, 4, 5,
+  12, 19, 26, 33, 40, 48, 41, 34,
+  27, 20, 13, 6, 7, 14, 21, 28,
+  35, 42, 49, 56, 57, 50, 43, 36,
+  29, 22, 15, 23, 30, 37, 44, 51,
+  58, 59, 52, 45, 38, 31, 39, 46,
+  53, 60, 61, 54, 47, 55, 62, 63
+};
+
 typedef struct
 {
   guint par_n, par_d;
@@ -747,9 +765,6 @@
       READ_UINT8 (nr, used_by_curr_pic_flag[j], 1);
       if (!used_by_curr_pic_flag[j])
         READ_UINT8 (nr, use_delta_flag[j], 1);
-
-      if (used_by_curr_pic_flag[j] || use_delta_flag[j])
-        stRPS->NumDeltaPocs++;
     }
 
     /* 7-47: calcuate NumNegativePics, DeltaPocS0 and UsedByCurrPicS0 */
@@ -839,9 +854,11 @@
       }
     }
 
-    /* 7-57 */
-    stRPS->NumDeltaPocs = stRPS->NumPositivePics + stRPS->NumNegativePics;
   }
+
+  /* 7-57 */
+  stRPS->NumDeltaPocs = stRPS->NumPositivePics + stRPS->NumNegativePics;
+
   return TRUE;
 
 error:
@@ -1222,7 +1239,7 @@
 
   if (nalu->type == GST_H265_NAL_EOS || nalu->type == GST_H265_NAL_EOB) {
     GST_DEBUG ("end-of-seq or end-of-stream nal found");
-    nalu->size = 0;
+    nalu->size = 2;
     return GST_H265_PARSER_OK;
   }
 
@@ -1252,7 +1269,7 @@
       gst_h265_parser_identify_nalu_unchecked (parser, data, offset, size,
       nalu);
 
-  if (res != GST_H265_PARSER_OK || nalu->size == 0)
+  if (res != GST_H265_PARSER_OK || nalu->size == 2)
     goto beach;
 
   off2 = scan_for_start_codes (data + nalu->offset, size - nalu->offset);
@@ -1269,7 +1286,7 @@
     off2--;
 
   nalu->size = off2;
-  if (nalu->size < 2)
+  if (nalu->size < 3)
     return GST_H265_PARSER_BROKEN_DATA;
 
   GST_DEBUG ("Complete nal found. Off: %d, Size: %d", nalu->offset, nalu->size);
@@ -1547,6 +1564,8 @@
   GstH265VPS *vps;
   guint8 vps_id;
   guint i;
+  guint subwc[] = { 1, 2, 2, 1, 1 };
+  guint subhc[] = { 1, 2, 1, 1, 1 };
   GstH265VUIParams *vui = NULL;
 
   INITIALIZE_DEBUG_CATEGORY;
@@ -1696,7 +1715,20 @@
     goto error;
   }
 
-  /* ToDo: Add crop_rectangle dimensions */
+  if (sps->conformance_window_flag) {
+    const guint crop_unit_x = subwc[sps->chroma_format_idc];
+    const guint crop_unit_y = subhc[sps->chroma_format_idc];
+
+    sps->crop_rect_width = sps->width -
+        (sps->conf_win_left_offset + sps->conf_win_right_offset) * crop_unit_x;
+    sps->crop_rect_height = sps->height -
+        (sps->conf_win_top_offset + sps->conf_win_bottom_offset) * crop_unit_y;
+    sps->crop_rect_x = sps->conf_win_left_offset * crop_unit_x;
+    sps->crop_rect_y = sps->conf_win_top_offset * crop_unit_y;
+
+    GST_LOG ("crop_rectangle x=%u y=%u width=%u, height=%u", sps->crop_rect_x,
+        sps->crop_rect_y, sps->crop_rect_width, sps->crop_rect_height);
+  }
 
   sps->fps_num = 0;
   sps->fps_den = 1;
@@ -1804,8 +1836,8 @@
   READ_UINT8 (&nr, pps->entropy_coding_sync_enabled_flag, 1);
 
   if (pps->tiles_enabled_flag) {
-    READ_UE_ALLOWED (&nr, pps->num_tile_columns_minus1, 1, 19);
-    READ_UE_ALLOWED (&nr, pps->num_tile_rows_minus1, 1, 21);
+    READ_UE_ALLOWED (&nr, pps->num_tile_columns_minus1, 0, 19);
+    READ_UE_ALLOWED (&nr, pps->num_tile_rows_minus1, 0, 21);
 
     READ_UINT8 (&nr, pps->uniform_spacing_flag, 1);
     if (!pps->uniform_spacing_flag) {
@@ -2075,24 +2107,25 @@
             pps->num_ref_idx_l1_default_active_minus1;
       }
 
+      /* calculate NumPocTotalCurr */
+      if (slice->short_term_ref_pic_set_sps_flag)
+        CurrRpsIdx = slice->short_term_ref_pic_set_idx;
+      else
+        CurrRpsIdx = sps->num_short_term_ref_pic_sets;
+      stRPS = &sps->short_term_ref_pic_set[CurrRpsIdx];
+      for (i = 0; i < stRPS->NumNegativePics; i++)
+        if (stRPS->UsedByCurrPicS0[i])
+          NumPocTotalCurr++;
+      for (i = 0; i < stRPS->NumPositivePics; i++)
+        if (stRPS->UsedByCurrPicS1[i])
+          NumPocTotalCurr++;
+      for (i = 0;
+          i < (slice->num_long_term_sps + slice->num_long_term_pics); i++)
+        if (UsedByCurrPicLt[i])
+          NumPocTotalCurr++;
+      slice->NumPocTotalCurr = NumPocTotalCurr;
+
       if (pps->lists_modification_present_flag) {
-        /* calculate NumPocTotalCurr */
-        if (slice->short_term_ref_pic_set_sps_flag)
-          CurrRpsIdx = slice->short_term_ref_pic_set_idx;
-        else
-          CurrRpsIdx = sps->num_short_term_ref_pic_sets;
-        stRPS = &sps->short_term_ref_pic_set[CurrRpsIdx];
-        for (i = 0; i < stRPS->NumNegativePics; i++)
-          if (stRPS->UsedByCurrPicS0[i])
-            NumPocTotalCurr++;
-        for (i = 0; i < stRPS->NumPositivePics; i++)
-          if (stRPS->UsedByCurrPicS1[i])
-            NumPocTotalCurr++;
-        for (i = 0;
-            i < (slice->num_long_term_sps + slice->num_long_term_pics); i++)
-          if (UsedByCurrPicLt[i])
-            NumPocTotalCurr++;
-        slice->NumPocTotalCurr = NumPocTotalCurr;
         if (NumPocTotalCurr > 1)
           if (!gst_h265_slice_parse_ref_pic_list_modification (slice, &nr,
                   NumPocTotalCurr))
@@ -2185,6 +2218,14 @@
         goto error;
   }
 
+  /* Skip the byte alignment bits */
+  if (!nal_reader_skip (&nr, 1))
+    goto error;
+  while (!nal_reader_is_byte_aligned (&nr)) {
+    if (!nal_reader_skip (&nr, 1))
+      goto error;
+  }
+
   slice->header_size = nal_reader_get_pos (&nr);
   slice->n_emulation_prevention_bytes = nal_reader_get_epb_count (&nr);
 
@@ -2198,68 +2239,106 @@
   return GST_H265_PARSER_ERROR;
 }
 
-/**
- * gst_h265_parser_parse_sei:
- * @parser: a #GstH265Parser
- * @nalu: The #GST_H265_NAL_SEI #GstH265NalUnit to parse
- * @sei: The #GstH265SEIMessage to fill.
- *
- * Parses @data, and fills the @sei structures.
- * The resulting @sei  structure shall be deallocated with
- * gst_h265_sei_free() when it is no longer needed
- *
- * Returns: a #GstH265ParserResult
- */
-GstH265ParserResult
-gst_h265_parser_parse_sei (GstH265Parser * parser,
-    GstH265NalUnit * nalu, GstH265SEIMessage * sei)
+static gboolean
+nal_reader_has_more_data_in_payload (NalReader * nr,
+    guint32 payload_start_pos_bit, guint32 payloadSize)
 {
-  NalReader nr;
+  if (nal_reader_is_byte_aligned (nr) &&
+      (nal_reader_get_pos (nr) == (payload_start_pos_bit + 8 * payloadSize)))
+    return FALSE;
+
+  return TRUE;
+}
+
+static GstH265ParserResult
+gst_h265_parser_parse_sei_message (GstH265Parser * parser,
+    guint8 nal_type, NalReader * nr, GstH265SEIMessage * sei)
+{
   guint32 payloadSize;
   guint8 payload_type_byte, payload_size_byte;
-#ifndef GST_DISABLE_GST_DEBUG
   guint remaining, payload_size;
-#endif
-  GstH265ParserResult res;
+  guint32 payload_start_pos_bit;
+  GstH265ParserResult res = GST_H265_PARSER_OK;
+
   GST_DEBUG ("parsing \"Sei message\"");
-  nal_reader_init (&nr, nalu->data + nalu->offset + 1, nalu->size - 1);
-  /* init */
-  memset (sei, 0, sizeof (*sei));
+
   sei->payloadType = 0;
   do {
-    READ_UINT8 (&nr, payload_type_byte, 8);
+    READ_UINT8 (nr, payload_type_byte, 8);
     sei->payloadType += payload_type_byte;
   } while (payload_type_byte == 0xff);
   payloadSize = 0;
   do {
-    READ_UINT8 (&nr, payload_size_byte, 8);
+    READ_UINT8 (nr, payload_size_byte, 8);
     payloadSize += payload_size_byte;
   }
   while (payload_size_byte == 0xff);
-#ifndef GST_DISABLE_GST_DEBUG
-  remaining = nal_reader_get_remaining (&nr) * 8;
-  payload_size = payloadSize < remaining ? payloadSize : remaining;
+
+  remaining = nal_reader_get_remaining (nr);
+  payload_size = payloadSize * 8 < remaining ? payloadSize * 8 : remaining;
+
+  payload_start_pos_bit = nal_reader_get_pos (nr);
   GST_DEBUG
       ("SEI message received: payloadType  %u, payloadSize = %u bytes",
       sei->payloadType, payload_size);
-#endif
-  if (sei->payloadType == GST_H265_SEI_BUF_PERIOD) {
-    /* size not set; might depend on emulation_prevention_three_byte */
-    res = gst_h265_parser_parse_buffering_period (parser,
-        &sei->payload.buffering_period, &nr);
-  } else if (sei->payloadType == GST_H265_SEI_PIC_TIMING) {
-    /* size not set; might depend on emulation_prevention_three_byte */
-    res = gst_h265_parser_parse_pic_timing (parser,
-        &sei->payload.pic_timing, &nr);
-  } else
-    res = GST_H265_PARSER_OK;
+
+  if (nal_type == GST_H265_NAL_PREFIX_SEI) {
+    switch (sei->payloadType) {
+      case GST_H265_SEI_BUF_PERIOD:
+        /* size not set; might depend on emulation_prevention_three_byte */
+        res = gst_h265_parser_parse_buffering_period (parser,
+            &sei->payload.buffering_period, nr);
+        break;
+      case GST_H265_SEI_PIC_TIMING:
+        /* size not set; might depend on emulation_prevention_three_byte */
+        res = gst_h265_parser_parse_pic_timing (parser,
+            &sei->payload.pic_timing, nr);
+        break;
+      default:
+        /* Just consume payloadSize bytes, which does not account for
+           emulation prevention bytes */
+        if (!nal_reader_skip_long (nr, payload_size))
+          goto error;
+        res = GST_H265_PARSER_OK;
+        break;
+    }
+  } else if (nal_type == GST_H265_NAL_SUFFIX_SEI) {
+    switch (sei->payloadType) {
+      default:
+        /* Just consume payloadSize bytes, which does not account for
+           emulation prevention bytes */
+        if (!nal_reader_skip_long (nr, payload_size))
+          goto error;
+        res = GST_H265_PARSER_OK;
+        break;
+    }
+  }
+
+  /* Not parsing the reserved_payload_extension, but it shouldn't be
+   * an issue because of 1: There shall not be any reserved_payload_extension
+   * present in bitstreams conforming to the specification.2. Even though
+   * it is present, the size will be less than total PayloadSize since the
+   * size of reserved_payload_extension is supposed to be
+   * 8 * payloadSize - nEarlierBits - nPayloadZeroBits -1 which means the
+   * the current implementation will still skip all unnecessary bits correctly.
+   * In theory, we can have a more optimized implementation by skipping the
+   * data left in PayLoadSize without out individually checking for each bits,
+   * since the totoal size will be always less than payloadSize*/
+  if (nal_reader_has_more_data_in_payload (nr, payload_start_pos_bit,
+          payloadSize)) {
+    /* Skip the byte alignment bits */
+    if (!nal_reader_skip (nr, 1))
+      goto error;
+    while (!nal_reader_is_byte_aligned (nr)) {
+      if (!nal_reader_skip (nr, 1))
+        goto error;
+    }
+  }
 
   return res;
 
 error:
   GST_WARNING ("error parsing \"Sei message\"");
-  gst_h265_sei_free (sei);
-
   return GST_H265_PARSER_ERROR;
 }
 
@@ -2377,3 +2456,139 @@
     pic_timing->du_cpb_removal_delay_increment_minus1 = 0;
   }
 }
+
+/**
+ * gst_h265_parser_parse_sei:
+ * @nalparser: a #GstH265Parser
+ * @nalu: The #GST_H265_NAL_SEI #GstH265NalUnit to parse
+ * @messages: The GArray of #GstH265SEIMessage to fill. The caller must free it when done.
+ *
+ * Parses @data, create and fills the @messages array.
+ *
+ * Returns: a #GstH265ParserResult
+ */
+GstH265ParserResult
+gst_h265_parser_parse_sei (GstH265Parser * nalparser, GstH265NalUnit * nalu,
+    GArray ** messages)
+{
+  NalReader nr;
+  GstH265SEIMessage sei;
+  GstH265ParserResult res;
+
+  GST_DEBUG ("parsing SEI nal");
+  nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
+      nalu->size - nalu->header_bytes);
+  *messages = g_array_new (FALSE, FALSE, sizeof (GstH265SEIMessage));
+  g_array_set_clear_func (*messages, (GDestroyNotify) gst_h265_sei_free);
+
+  do {
+    res = gst_h265_parser_parse_sei_message (nalparser, nalu->type, &nr, &sei);
+    if (res == GST_H265_PARSER_OK)
+      g_array_append_val (*messages, sei);
+    else
+      break;
+  } while (nal_reader_has_more_data (&nr));
+
+  return res;
+}
+
+
+/**
+ * gst_h265_quant_matrix_4x4_get_zigzag_from_raster:
+ * @out_quant: (out): The resulting quantization matrix
+ * @quant: The source quantization matrix
+ *
+ * Converts quantization matrix @quant from raster scan order to
+ * zigzag scan order and store the resulting factors into @out_quant.
+ *
+ * Note: it is an error to pass the same table in both @quant and
+ * @out_quant arguments.
+ *
+ * Since: 1.6
+ */
+void
+gst_h265_quant_matrix_4x4_get_zigzag_from_raster (guint8 out_quant[16],
+    const guint8 quant[16])
+{
+  guint i;
+
+  g_return_if_fail (out_quant != quant);
+
+  for (i = 0; i < 16; i++)
+    out_quant[i] = quant[zigzag_4x4[i]];
+}
+
+/**
+ * gst_h265_quant_matrix_4x4_get_raster_from_zigzag:
+ * @out_quant: (out): The resulting quantization matrix
+ * @quant: The source quantization matrix
+ *
+ * Converts quantization matrix @quant from zigzag scan order to
+ * raster scan order and store the resulting factors into @out_quant.
+ *
+ * Note: it is an error to pass the same table in both @quant and
+ * @out_quant arguments.
+ *
+ * Since: 1.6
+ */
+void
+gst_h265_quant_matrix_4x4_get_raster_from_zigzag (guint8 out_quant[16],
+    const guint8 quant[16])
+{
+  guint i;
+
+  g_return_if_fail (out_quant != quant);
+
+  for (i = 0; i < 16; i++)
+    out_quant[zigzag_4x4[i]] = quant[i];
+}
+
+/**
+ * gst_h265_quant_matrix_8x8_get_zigzag_from_raster:
+ * @out_quant: (out): The resulting quantization matrix
+ * @quant: The source quantization matrix
+ *
+ * Converts quantization matrix @quant from raster scan order to
+ * zigzag scan order and store the resulting factors into @out_quant.
+ *
+ * Note: it is an error to pass the same table in both @quant and
+ * @out_quant arguments.
+ *
+ * Since: 1.6
+ */
+void
+gst_h265_quant_matrix_8x8_get_zigzag_from_raster (guint8 out_quant[64],
+    const guint8 quant[64])
+{
+  guint i;
+
+  g_return_if_fail (out_quant != quant);
+
+  for (i = 0; i < 64; i++)
+    out_quant[i] = quant[zigzag_8x8[i]];
+}
+
+/**
+ * gst_h265_quant_matrix_8x8_get_raster_from_zigzag:
+ * @out_quant: (out): The resulting quantization matrix
+ * @quant: The source quantization matrix
+ *
+ * Converts quantization matrix @quant from zigzag scan order to
+ * raster scan order and store the resulting factors into @out_quant.
+ *
+ * Note: it is an error to pass the same table in both @quant and
+ * @out_quant arguments.
+ *
+ * Since: 1.6
+ */
+void
+gst_h265_quant_matrix_8x8_get_raster_from_zigzag (guint8 out_quant[64],
+    const guint8 quant[64])
+{
+  guint i;
+
+  g_return_if_fail (out_quant != quant);
+
+  for (i = 0; i < 64; i++)
+    out_quant[zigzag_8x8[i]] = quant[i];
+}
diff --git a/gst-libs/gst/codecparsers/gsth265parser.h b/gst-libs/gst/codecparsers/gsth265parser.h
index 883b7b2..9f42625 100644
--- a/gst-libs/gst/codecparsers/gsth265parser.h
+++ b/gst-libs/gst/codecparsers/gsth265parser.h
@@ -763,6 +763,8 @@
   /* calculated values */
   guint8 chroma_array_type;
   gint width, height;
+  gint crop_rect_width, crop_rect_height;
+  gint crop_rect_x, crop_rect_y;
   gint fps_num, fps_den;
   gboolean valid;
 };
@@ -1035,7 +1037,7 @@
 
 GstH265ParserResult gst_h265_parser_parse_sei       (GstH265Parser   * parser,
                                                      GstH265NalUnit  * nalu,
-                                                     GstH265SEIMessage * sei);
+                                                     GArray **messages);
 
 void                gst_h265_parser_free            (GstH265Parser  * parser);
 
@@ -1061,5 +1063,26 @@
 
 void                gst_h265_sei_free       (GstH265SEIMessage * sei);
 
+void    gst_h265_quant_matrix_4x4_get_zigzag_from_raster (guint8 out_quant[16],
+                                                          const guint8 quant[16]);
+
+void    gst_h265_quant_matrix_4x4_get_raster_from_zigzag (guint8 out_quant[16],
+                                                          const guint8 quant[16]);
+
+void    gst_h265_quant_matrix_8x8_get_zigzag_from_raster (guint8 out_quant[64],
+                                                          const guint8 quant[64]);
+
+void    gst_h265_quant_matrix_8x8_get_raster_from_zigzag (guint8 out_quant[64],
+                                                          const guint8 quant[64]);
+
+#define gst_h265_quant_matrix_16x16_get_zigzag_from_raster \
+        gst_h265_quant_matrix_8x8_get_zigzag_from_raster
+#define gst_h265_quant_matrix_16x16_get_raster_from_zigzag \
+        gst_h265_quant_matrix_8x8_get_raster_from_zigzag
+#define gst_h265_quant_matrix_32x32_get_zigzag_from_raster \
+        gst_h265_quant_matrix_8x8_get_zigzag_from_raster
+#define gst_h265_quant_matrix_32x32_get_raster_from_zigzag \
+        gst_h265_quant_matrix_8x8_get_raster_from_zigzag
+
 G_END_DECLS
 #endif
diff --git a/gst-libs/gst/gl/Makefile.am b/gst-libs/gst/gl/Makefile.am
index fcf318d..8f5f115 100644
--- a/gst-libs/gst/gl/Makefile.am
+++ b/gst-libs/gst/gl/Makefile.am
@@ -126,7 +126,7 @@
 gir_sources=$(patsubst %,$(srcdir)/%, $(libgstgl_@GST_API_VERSION@_la_SOURCES))
 
 GstGL-@GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libgstgl-@GST_API_VERSION@.la
-	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
+	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" GI_SCANNER_DISABLE_CACHE=yes\
 		GST_PLUGIN_SYSTEM_PATH_1_0="" GST_PLUGIN_PATH_1_0="" GST_REGISTRY_UPDATE=no \
 		$(INTROSPECTION_SCANNER) -v --namespace GstGL \
 		--nsversion=@GST_API_VERSION@ \
diff --git a/gst-libs/gst/gl/Makefile.in b/gst-libs/gst/gl/Makefile.in
index 4200a7a..3ce5d1b 100644
--- a/gst-libs/gst/gl/Makefile.in
+++ b/gst-libs/gst/gl/Makefile.in
@@ -1541,7 +1541,7 @@
 
 
 @HAVE_INTROSPECTION_TRUE@GstGL-@GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libgstgl-@GST_API_VERSION@.la
-@HAVE_INTROSPECTION_TRUE@	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
+@HAVE_INTROSPECTION_TRUE@	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" GI_SCANNER_DISABLE_CACHE=yes\
 @HAVE_INTROSPECTION_TRUE@		GST_PLUGIN_SYSTEM_PATH_1_0="" GST_PLUGIN_PATH_1_0="" GST_REGISTRY_UPDATE=no \
 @HAVE_INTROSPECTION_TRUE@		$(INTROSPECTION_SCANNER) -v --namespace GstGL \
 @HAVE_INTROSPECTION_TRUE@		--nsversion=@GST_API_VERSION@ \
diff --git a/gst-libs/gst/gl/dispmanx/gstglwindow_dispmanx_egl.c b/gst-libs/gst/gl/dispmanx/gstglwindow_dispmanx_egl.c
index ca5411a..0adbfb6 100644
--- a/gst-libs/gst/gl/dispmanx/gstglwindow_dispmanx_egl.c
+++ b/gst-libs/gst/gl/dispmanx/gstglwindow_dispmanx_egl.c
@@ -29,18 +29,31 @@
 
 #include "gstglwindow_dispmanx_egl.h"
 
+
+#ifndef ELEMENT_CHANGE_LAYER
+/* copied from interface/vmcs_host/vc_vchi_dispmanx.h of userland.git */
+#define ELEMENT_CHANGE_LAYER          (1<<0)
+#define ELEMENT_CHANGE_OPACITY        (1<<1)
+#define ELEMENT_CHANGE_DEST_RECT      (1<<2)
+#define ELEMENT_CHANGE_SRC_RECT       (1<<3)
+#define ELEMENT_CHANGE_MASK_RESOURCE  (1<<4)
+#define ELEMENT_CHANGE_TRANSFORM      (1<<5)
+#endif
+
 #define GST_CAT_DEFAULT gst_gl_window_debug
 
 #define gst_gl_window_dispmanx_egl_parent_class parent_class
 G_DEFINE_TYPE (GstGLWindowDispmanxEGL, gst_gl_window_dispmanx_egl,
     GST_GL_TYPE_WINDOW);
 
+static void gst_gl_window_dispmanx_egl_finalize (GObject * object);
 static guintptr gst_gl_window_dispmanx_egl_get_window_handle (GstGLWindow *
     window);
 static void gst_gl_window_dispmanx_egl_set_window_handle (GstGLWindow * window,
     guintptr handle);
 static void gst_gl_window_dispmanx_egl_set_preferred_size (GstGLWindow * window,
     gint width, gint height);
+static void gst_gl_window_dispmanx_egl_show (GstGLWindow * window);
 static void gst_gl_window_dispmanx_egl_draw (GstGLWindow * window);
 static void gst_gl_window_dispmanx_egl_run (GstGLWindow * window);
 static void gst_gl_window_dispmanx_egl_quit (GstGLWindow * window);
@@ -53,17 +66,19 @@
 
 
 static void window_resize (GstGLWindowDispmanxEGL * window_egl, guint width,
-    guint height);
+    guint height, gboolean visible);
 
 static void
 gst_gl_window_dispmanx_egl_class_init (GstGLWindowDispmanxEGLClass * klass)
 {
   GstGLWindowClass *window_class = (GstGLWindowClass *) klass;
+  GObjectClass *gobject_class = (GObjectClass *) klass;
 
   window_class->get_window_handle =
       GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_get_window_handle);
   window_class->set_window_handle =
       GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_set_window_handle);
+  window_class->show = GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_show);
   window_class->draw_unlocked =
       GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_draw);
   window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_draw);
@@ -77,11 +92,26 @@
       GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_get_display);
   window_class->set_preferred_size =
       GST_DEBUG_FUNCPTR (gst_gl_window_dispmanx_egl_set_preferred_size);
+
+  gobject_class->finalize = gst_gl_window_dispmanx_egl_finalize;
 }
 
 static void
-gst_gl_window_dispmanx_egl_init (GstGLWindowDispmanxEGL * window)
+gst_gl_window_dispmanx_egl_init (GstGLWindowDispmanxEGL * window_egl)
 {
+  window_egl->main_context = g_main_context_new ();
+  window_egl->loop = g_main_loop_new (window_egl->main_context, FALSE);
+}
+
+static void
+gst_gl_window_dispmanx_egl_finalize (GObject * object)
+{
+  GstGLWindowDispmanxEGL *window_egl = GST_GL_WINDOW_DISPMANX_EGL (object);
+
+  g_main_loop_unref (window_egl->loop);
+  g_main_context_unref (window_egl->main_context);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
 /* Must be called in the gl thread */
@@ -96,6 +126,7 @@
 
   window->egldisplay = EGL_DEFAULT_DISPLAY;
 
+  window->visible = FALSE;
   window->display = 0;
   window->dp_width = 0;
   window->dp_height = 0;
@@ -140,16 +171,18 @@
   GST_DEBUG ("Got display size: %dx%d\n", window_egl->dp_width,
       window_egl->dp_height);
 
+  window_egl->native.element = 0;
+
+  return TRUE;
+}
+
+gboolean
+gst_gl_window_dispmanx_egl_create_window (GstGLWindowDispmanxEGL * window_egl)
+{
   window_egl->native.width = 0;
   window_egl->native.height = 0;
   window_egl->display = vc_dispmanx_display_open (0);
-  window_egl->native.element = 0;
-
-  window_egl->main_context = g_main_context_new ();
-  window_egl->loop = g_main_loop_new (window_egl->main_context, FALSE);
-
-  window_resize (window_egl, 16, 16);
-
+  window_resize (window_egl, 16, 16, FALSE);
   return TRUE;
 }
 
@@ -221,7 +254,11 @@
 static guintptr
 gst_gl_window_dispmanx_egl_get_window_handle (GstGLWindow * window)
 {
-  return (guintptr) & GST_GL_WINDOW_DISPMANX_EGL (window)->native;
+  GstGLWindowDispmanxEGL *window_egl;
+  window_egl = GST_GL_WINDOW_DISPMANX_EGL (window);
+  if (window_egl->native.element)
+    return (guintptr) & window_egl->native;
+  return 0;
 }
 
 static void
@@ -231,27 +268,32 @@
 }
 
 static void
-gst_gl_window_dispmanx_egl_set_preferred_size (GstGLWindow * window, gint width, gint height)
+gst_gl_window_dispmanx_egl_set_preferred_size (GstGLWindow * window, gint width,
+    gint height)
 {
   GstGLWindowDispmanxEGL *window_egl = GST_GL_WINDOW_DISPMANX_EGL (window);
 
+  GST_DEBUG_OBJECT (window, "set preferred size to %dx%d", width, height);
   window_egl->preferred_width = width;
   window_egl->preferred_height = height;
 }
 
 static void
-window_resize (GstGLWindowDispmanxEGL * window_egl, guint width, guint height)
+window_resize (GstGLWindowDispmanxEGL * window_egl, guint width, guint height,
+    gboolean visible)
 {
-  GST_DEBUG ("resizing window from %ux%u to %ux%u",
-      window_egl->native.width, window_egl->native.height, width, height);
+  GST_DEBUG ("resizing %s window from %ux%u to %ux%u",
+      visible ? "visible" : "invisible", window_egl->native.width,
+      window_egl->native.height, width, height);
 
   if (window_egl->display) {
     VC_RECT_T dst_rect;
     VC_RECT_T src_rect;
     GstVideoRectangle src, dst, res;
     DISPMANX_UPDATE_HANDLE_T dispman_update;
+    uint32_t opacity = visible ? 255 : 0;
     VC_DISPMANX_ALPHA_T alpha =
-        { DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, 255, 0 };
+        { DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, opacity, 0 };
 
     /* Center width*height frame inside dp_width*dp_height */
     src.w = width;
@@ -275,9 +317,12 @@
     dispman_update = vc_dispmanx_update_start (0);
 
     if (window_egl->native.element) {
+      uint32_t change_flags =
+          ELEMENT_CHANGE_OPACITY | ELEMENT_CHANGE_DEST_RECT |
+          ELEMENT_CHANGE_SRC_RECT;
       vc_dispmanx_element_change_attributes (dispman_update,
-          window_egl->native.element, 0x00000110, 0, 0, &dst_rect, &src_rect, 0,
-          0);
+          window_egl->native.element, change_flags, 0, opacity, &dst_rect,
+          &src_rect, 0, 0);
     } else {
       window_egl->native.element = vc_dispmanx_element_add (dispman_update,
           window_egl->display, 0, &dst_rect, 0, &src_rect,
@@ -296,6 +341,17 @@
 }
 
 static void
+gst_gl_window_dispmanx_egl_show (GstGLWindow * window)
+{
+  GstGLWindowDispmanxEGL *window_egl = GST_GL_WINDOW_DISPMANX_EGL (window);
+
+  if (!window_egl->visible) {
+    window_resize (window_egl, window_egl->preferred_width, window_egl->preferred_height, TRUE);
+    window_egl->visible = TRUE;
+  }
+}
+
+static void
 draw_cb (gpointer data)
 {
   GstGLWindowDispmanxEGL *window_egl = data;
@@ -303,13 +359,6 @@
   GstGLContext *context = gst_gl_window_get_context (window);
   GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);
 
-  if (window_egl->native.width != window_egl->preferred_width
-      || window_egl->native.height != window_egl->preferred_height) {
-    GST_DEBUG ("dimensions don't match, attempting resize");
-    window_resize (window_egl, window_egl->preferred_width,
-        window_egl->preferred_height);
-  }
-
   if (window->draw)
     window->draw (window->draw_data);
 
diff --git a/gst-libs/gst/gl/dispmanx/gstglwindow_dispmanx_egl.h b/gst-libs/gst/gl/dispmanx/gstglwindow_dispmanx_egl.h
index f8a6817..1572bd5 100644
--- a/gst-libs/gst/gl/dispmanx/gstglwindow_dispmanx_egl.h
+++ b/gst-libs/gst/gl/dispmanx/gstglwindow_dispmanx_egl.h
@@ -54,6 +54,8 @@
   GMainContext *main_context;
   GMainLoop *loop;
 
+  gboolean visible;
+
   gpointer _reserved[GST_PADDING];
 };
 
@@ -68,6 +70,7 @@
 GType gst_gl_window_dispmanx_egl_get_type     (void);
 
 GstGLWindowDispmanxEGL * gst_gl_window_dispmanx_egl_new  (void);
+gboolean gst_gl_window_dispmanx_egl_create_window (GstGLWindowDispmanxEGL * window_egl);
 
 G_END_DECLS
 
diff --git a/gst-libs/gst/gl/eagl/gstglcontext_eagl.h b/gst-libs/gst/gl/eagl/gstglcontext_eagl.h
index b621b35..c8997ff 100644
--- a/gst-libs/gst/gl/eagl/gstglcontext_eagl.h
+++ b/gst-libs/gst/gl/eagl/gstglcontext_eagl.h
@@ -59,6 +59,7 @@
 
 GstGLContextEagl * gst_gl_context_eagl_new (void);
 
+void gst_gl_context_eagl_update_layer (GstGLContext * context);
 void gst_gl_context_eagl_resize (GstGLContextEagl * eagl_context);
 void gst_gl_context_eagl_prepare_draw (GstGLContextEagl * context);
 void gst_gl_context_eagl_finish_draw (GstGLContextEagl * context);
diff --git a/gst-libs/gst/gl/eagl/gstglcontext_eagl.m b/gst-libs/gst/gl/eagl/gstglcontext_eagl.m
index e01fa62..9fb29e6 100644
--- a/gst-libs/gst/gl/eagl/gstglcontext_eagl.m
+++ b/gst-libs/gst/gl/eagl/gstglcontext_eagl.m
@@ -115,108 +115,13 @@
       height);
 }
 
-static gboolean
-gst_gl_context_eagl_create_context (GstGLContext * context, GstGLAPI gl_api,
-    GstGLContext * other_context, GError ** error)
-{
-  GstGLContextEagl *context_eagl = GST_GL_CONTEXT_EAGL (context);
-  GstGLContextEaglPrivate *priv = context_eagl->priv;
-  GstGLWindow *window = gst_gl_context_get_window (context);
-  UIView *window_handle = nil;
-
-  dispatch_sync (dispatch_get_main_queue (), ^{
-    if (other_context) {
-      EAGLContext *external_gl_context = (EAGLContext *)
-          gst_gl_context_get_gl_context (other_context);
-      EAGLSharegroup *share_group = [external_gl_context sharegroup];
-
-      priv->eagl_context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2 sharegroup:share_group];
-      [share_group release];
-    } else {
-      priv->eagl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
-    }
-  });
-
-  if (window)
-    window_handle = (UIView *) gst_gl_window_get_window_handle (window);
-
-  if (window_handle) {
-    __block GLuint framebuffer;
-    __block GLuint color_renderbuffer;
-    __block GLuint depth_renderbuffer;
-    __block GLint width;
-    __block GLint height;
-    __block CAEAGLLayer *eagl_layer;
-    GLenum status;
-
-    dispatch_sync (dispatch_get_main_queue (), ^{
-          eagl_layer = (CAEAGLLayer *)[window_handle layer];
-          [EAGLContext setCurrentContext:priv->eagl_context];
-
-          /* Allocate framebuffer */
-          glGenFramebuffers (1, &framebuffer);
-          glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
-          /* Allocate color render buffer */
-          glGenRenderbuffers (1, &color_renderbuffer);
-          glBindRenderbuffer (GL_RENDERBUFFER, color_renderbuffer);
-          [priv->eagl_context renderbufferStorage: GL_RENDERBUFFER fromDrawable:eagl_layer];
-          glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-              GL_RENDERBUFFER, color_renderbuffer);
-          /* Get renderbuffer width/height */
-          glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH,
-              &width);
-          glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT,
-              &height);
-          /* allocate depth render buffer */
-          glGenRenderbuffers (1, &depth_renderbuffer);
-          glBindRenderbuffer (GL_RENDERBUFFER, depth_renderbuffer);
-          glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width,
-              height);
-          glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-              GL_RENDERBUFFER, depth_renderbuffer);
-          [EAGLContext setCurrentContext:nil];
-    });
-
-    [EAGLContext setCurrentContext:priv->eagl_context];
-
-    glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
-    /* check creation status */
-    status = glCheckFramebufferStatus (GL_FRAMEBUFFER);
-    if (status != GL_FRAMEBUFFER_COMPLETE) {
-      GST_ERROR ("Failed to make complete framebuffer object %x", status);
-      if (window)
-        gst_object_unref (window);
-      return FALSE;
-    }
-    glBindFramebuffer (GL_FRAMEBUFFER, 0);
-
-    priv->eagl_layer = eagl_layer;
-    priv->framebuffer = framebuffer;
-    priv->color_renderbuffer = color_renderbuffer;
-    priv->depth_renderbuffer = depth_renderbuffer;
-  } else {
-    priv->eagl_layer = NULL;
-    priv->framebuffer = 0;
-    priv->color_renderbuffer = 0;
-    priv->depth_renderbuffer = 0;
-  }
-
-  if (window)
-    gst_object_unref (window);
-
-  return TRUE;
-}
-
 static void
-gst_gl_context_eagl_destroy_context (GstGLContext * context)
+gst_gl_context_eagl_release_layer (GstGLContext * context)
 {
   GstGLContextEagl *context_eagl;
 
   context_eagl = GST_GL_CONTEXT_EAGL (context);
 
-  if (!context_eagl->priv->eagl_context)
-    return;
-
   if (context_eagl->priv->eagl_layer) {
     gst_gl_context_eagl_activate (context, TRUE);
 
@@ -233,6 +138,127 @@
     context_eagl->priv->eagl_layer = nil;
     gst_gl_context_eagl_activate (context, FALSE);
   }
+}
+
+void
+gst_gl_context_eagl_update_layer (GstGLContext * context)
+{
+  __block GLuint framebuffer;
+  __block GLuint color_renderbuffer;
+  __block GLuint depth_renderbuffer;
+  __block GLint width;
+  __block GLint height;
+  __block CAEAGLLayer *eagl_layer;
+  GLenum status;
+  GstGLContextEagl *context_eagl = GST_GL_CONTEXT_EAGL (context);
+  GstGLContextEaglPrivate *priv = context_eagl->priv;
+  UIView *window_handle = nil;
+  GstGLWindow *window = gst_gl_context_get_window (context);
+  if (window)
+    window_handle = (UIView *) gst_gl_window_get_window_handle (window);
+
+  if (!window_handle) {
+    GST_INFO_OBJECT (context, "window handle not set yet, not updating layer");
+    goto out;
+  }
+
+  GST_INFO_OBJECT (context, "updating layer, frame %fx%f",
+      window_handle.frame.size.width, window_handle.frame.size.height);
+
+  if (priv->eagl_layer)
+    gst_gl_context_eagl_release_layer (context);
+
+  dispatch_sync (dispatch_get_main_queue (), ^{
+      eagl_layer = (CAEAGLLayer *)[window_handle layer];
+      [EAGLContext setCurrentContext:priv->eagl_context];
+
+      /* Allocate framebuffer */
+      glGenFramebuffers (1, &framebuffer);
+      glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
+      /* Allocate color render buffer */
+      glGenRenderbuffers (1, &color_renderbuffer);
+      glBindRenderbuffer (GL_RENDERBUFFER, color_renderbuffer);
+      [priv->eagl_context renderbufferStorage: GL_RENDERBUFFER fromDrawable:eagl_layer];
+      glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+          GL_RENDERBUFFER, color_renderbuffer);
+      /* Get renderbuffer width/height */
+      glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH,
+          &width);
+      glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT,
+          &height);
+      /* allocate depth render buffer */
+      glGenRenderbuffers (1, &depth_renderbuffer);
+      glBindRenderbuffer (GL_RENDERBUFFER, depth_renderbuffer);
+      glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width,
+          height);
+      glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+          GL_RENDERBUFFER, depth_renderbuffer);
+      [EAGLContext setCurrentContext:nil];
+  });
+
+  [EAGLContext setCurrentContext:priv->eagl_context];
+
+  glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
+  /* check creation status */
+  status = glCheckFramebufferStatus (GL_FRAMEBUFFER);
+  if (status != GL_FRAMEBUFFER_COMPLETE) {
+    GST_ERROR ("Failed to make complete framebuffer object %x", status);
+    goto out;
+  }
+  glBindFramebuffer (GL_FRAMEBUFFER, 0);
+
+  priv->eagl_layer = eagl_layer;
+  priv->framebuffer = framebuffer;
+  priv->color_renderbuffer = color_renderbuffer;
+  priv->depth_renderbuffer = depth_renderbuffer;
+
+out:
+  if (window)
+    gst_object_unref (window);
+}
+
+static gboolean
+gst_gl_context_eagl_create_context (GstGLContext * context, GstGLAPI gl_api,
+    GstGLContext * other_context, GError ** error)
+{
+  GstGLContextEagl *context_eagl = GST_GL_CONTEXT_EAGL (context);
+  GstGLContextEaglPrivate *priv = context_eagl->priv;
+
+  dispatch_sync (dispatch_get_main_queue (), ^{
+    if (other_context) {
+      EAGLContext *external_gl_context = (EAGLContext *)
+          gst_gl_context_get_gl_context (other_context);
+      EAGLSharegroup *share_group = [external_gl_context sharegroup];
+
+      priv->eagl_context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2 sharegroup:share_group];
+      [share_group release];
+    } else {
+      priv->eagl_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+    }
+  });
+  
+  priv->eagl_layer = NULL;
+  priv->framebuffer = 0;
+  priv->color_renderbuffer = 0;
+  priv->depth_renderbuffer = 0;
+
+  GST_INFO_OBJECT (context, "context created, updating layer");
+  gst_gl_context_eagl_update_layer (context);
+
+  return TRUE;
+}
+
+static void
+gst_gl_context_eagl_destroy_context (GstGLContext * context)
+{
+  GstGLContextEagl *context_eagl;
+
+  context_eagl = GST_GL_CONTEXT_EAGL (context);
+
+  if (!context_eagl->priv->eagl_context)
+    return;
+
+  gst_gl_context_eagl_release_layer (context);
 
   [context_eagl->priv->eagl_context release];
   context_eagl->priv->eagl_context = nil;
diff --git a/gst-libs/gst/gl/eagl/gstglwindow_eagl.m b/gst-libs/gst/gl/eagl/gstglwindow_eagl.m
index f1fc8b8..e1d06fd 100644
--- a/gst-libs/gst/gl/eagl/gstglwindow_eagl.m
+++ b/gst-libs/gst/gl/eagl/gstglwindow_eagl.m
@@ -139,10 +139,14 @@
 gst_gl_window_eagl_set_window_handle (GstGLWindow * window, guintptr handle)
 {
   GstGLWindowEagl *window_eagl;
+  GstGLContext *context;
 
   window_eagl = GST_GL_WINDOW_EAGL (window);
+  context = gst_gl_window_get_context (window);
 
   window_eagl->priv->view = (UIView *) handle;
+  GST_INFO_OBJECT (context, "handle set, updating layer");
+  gst_gl_context_eagl_update_layer (context);
 }
 
 static gboolean
diff --git a/gst-libs/gst/gl/egl/gstglcontext_egl.c b/gst-libs/gst/gl/egl/gstglcontext_egl.c
index 28c2359..f1fb70f 100644
--- a/gst-libs/gst/gl/egl/gstglcontext_egl.c
+++ b/gst-libs/gst/gl/egl/gstglcontext_egl.c
@@ -37,6 +37,9 @@
 #if GST_GL_HAVE_WINDOW_WIN32
 #include "../win32/gstglwindow_win32.h"
 #endif
+#if GST_GL_HAVE_WINDOW_DISPMANX
+#include "../dispmanx/gstglwindow_dispmanx_egl.h"
+#endif
 
 #define GST_CAT_DEFAULT gst_gl_context_debug
 
@@ -181,16 +184,19 @@
   else
     config_attrib[i++] = EGL_OPENGL_BIT;
 #if defined(USE_EGL_RPI) && GST_GL_HAVE_WINDOW_WAYLAND
-  /* The configurations r=5 g=6 b=5 seems to be buggy whereas
+  /* The configurations with a=0 seems to be buggy whereas
    * it works when using dispmanx directly */
-  config_attrib[i++] = EGL_BUFFER_SIZE;
-  config_attrib[i++] = 24;
-  /* same with a=0 */
   config_attrib[i++] = EGL_ALPHA_SIZE;
   config_attrib[i++] = 1;
 #endif
   config_attrib[i++] = EGL_DEPTH_SIZE;
   config_attrib[i++] = 16;
+  config_attrib[i++] = EGL_RED_SIZE;
+  config_attrib[i++] = 1;
+  config_attrib[i++] = EGL_GREEN_SIZE;
+  config_attrib[i++] = 1;
+  config_attrib[i++] = EGL_BLUE_SIZE;
+  config_attrib[i++] = 1;
   config_attrib[i++] = EGL_NONE;
 
   if (eglChooseConfig (egl->egl_display, config_attrib,
@@ -392,6 +398,12 @@
       gst_gl_window_win32_create_window ((GstGLWindowWin32 *) context->window);
     }
 #endif
+#if GST_GL_HAVE_WINDOW_DISPMANX
+    if (GST_GL_IS_WINDOW_DISPMANX_EGL (context->window)) {
+      gst_gl_window_dispmanx_egl_create_window ((GstGLWindowDispmanxEGL *)
+          context->window);
+    }
+#endif
   }
 
   if (window)
@@ -514,13 +526,25 @@
           "Handle changed (have:%p, now:%p), switching surface",
           (void *) egl->window_handle, (void *) handle);
       if (egl->egl_surface) {
-        eglDestroySurface (egl->egl_display, egl->egl_surface);
+        result = eglDestroySurface (egl->egl_display, egl->egl_surface);
         egl->egl_surface = EGL_NO_SURFACE;
+        if (!result) {
+          GST_ERROR_OBJECT (context, "Failed to destroy old window surface: %s",
+              gst_gl_context_egl_get_error_string ());
+          goto done;
+        }
       }
       egl->egl_surface =
           eglCreateWindowSurface (egl->egl_display, egl->egl_config, handle,
           NULL);
       egl->window_handle = handle;
+
+      if (egl->egl_surface == EGL_NO_SURFACE) {
+        GST_ERROR_OBJECT (context, "Failed to create window surface: %s",
+            gst_gl_context_egl_get_error_string ());
+        result = FALSE;
+        goto done;
+      }
     }
     result = eglMakeCurrent (egl->egl_display, egl->egl_surface,
         egl->egl_surface, egl->egl_context);
@@ -528,6 +552,13 @@
     result = eglMakeCurrent (egl->egl_display, EGL_NO_SURFACE,
         EGL_NO_SURFACE, EGL_NO_CONTEXT);
 
+  if (!result) {
+    GST_ERROR_OBJECT (context,
+        "Failed to bind context to the current rendering thread: %s",
+        gst_gl_context_egl_get_error_string ());
+  }
+
+done:
   return result;
 }
 
diff --git a/gst-libs/gst/gl/gstglbasefilter.c b/gst-libs/gst/gl/gstglbasefilter.c
index e61d7f7..0b49e09 100644
--- a/gst-libs/gst/gl/gstglbasefilter.c
+++ b/gst-libs/gst/gl/gstglbasefilter.c
@@ -273,16 +273,6 @@
     gst_object_unref (filter->context);
     filter->context = NULL;
   }
-
-  if (filter->display) {
-    gst_object_unref (filter->display);
-    filter->display = NULL;
-  }
-
-  if (filter->priv->other_context) {
-    gst_object_unref (filter->priv->other_context);
-    filter->priv->other_context = NULL;
-  }
 }
 
 static gboolean
@@ -334,6 +324,7 @@
   _find_local_gl_context (filter);
 
   if (!filter->context) {
+    GST_OBJECT_LOCK (filter->display);
     do {
       if (filter->context)
         gst_object_unref (filter->context);
@@ -342,11 +333,15 @@
           gst_gl_display_get_gl_context_for_thread (filter->display, NULL);
       if (!filter->context) {
         filter->context = gst_gl_context_new (filter->display);
+        if (!filter->context)
+          goto context_null_error;
+
         if (!gst_gl_context_create (filter->context,
                 filter->priv->other_context, &error))
           goto context_error;
       }
     } while (!gst_gl_display_add_context (filter->display, filter->context));
+    GST_OBJECT_UNLOCK (filter->display);
   }
 
   gst_gl_context_thread_add (filter->context, gst_gl_base_filter_gl_start,
@@ -362,6 +357,12 @@
         (NULL));
     return FALSE;
   }
+context_null_error:
+  {
+    GST_ELEMENT_ERROR (trans, RESOURCE, FAILED,
+        ("Failed to create context."), (NULL));
+    return FALSE;
+  }
 error:
   {
     GST_ELEMENT_ERROR (trans, LIBRARY, INIT,
@@ -407,6 +408,17 @@
     return ret;
 
   switch (transition) {
+    case GST_STATE_CHANGE_READY_TO_NULL:
+      if (filter->priv->other_context) {
+        gst_object_unref (filter->priv->other_context);
+        filter->priv->other_context = NULL;
+      }
+
+      if (filter->display) {
+        gst_object_unref (filter->display);
+        filter->display = NULL;
+      }
+      break;
     default:
       break;
   }
diff --git a/gst-libs/gst/gl/gstglbufferpool.c b/gst-libs/gst/gl/gstglbufferpool.c
index 6dd496c..78c6a77 100644
--- a/gst-libs/gst/gl/gstglbufferpool.c
+++ b/gst-libs/gst/gl/gstglbufferpool.c
@@ -326,7 +326,7 @@
 
 /**
  * gst_gl_buffer_pool_new:
- * @display: the #GstGLDisplay to use
+ * @context: the #GstGLContext to use
  *
  * Returns: a #GstBufferPool that allocates buffers with #GstGLMemory
  */
diff --git a/gst-libs/gst/gl/gstglcolorconvert.c b/gst-libs/gst/gl/gstglcolorconvert.c
index 86906bb..4f56da7 100644
--- a/gst-libs/gst/gl/gstglcolorconvert.c
+++ b/gst-libs/gst/gl/gstglcolorconvert.c
@@ -575,6 +575,35 @@
 }
 
 static gboolean
+_gst_gl_color_convert_can_passthrough (GstVideoInfo * in, GstVideoInfo * out)
+{
+  gint i;
+
+  if (GST_VIDEO_INFO_FORMAT (in) != GST_VIDEO_INFO_FORMAT (out))
+    return FALSE;
+  if (GST_VIDEO_INFO_WIDTH (in) != GST_VIDEO_INFO_WIDTH (out))
+    return FALSE;
+  if (GST_VIDEO_INFO_HEIGHT (in) != GST_VIDEO_INFO_HEIGHT (out))
+    return FALSE;
+  if (GST_VIDEO_INFO_SIZE (in) != GST_VIDEO_INFO_SIZE (out))
+    return FALSE;
+
+  for (i = 0; i < in->finfo->n_planes; i++) {
+    if (in->stride[i] != out->stride[i])
+      return FALSE;
+    if (in->offset[i] != out->offset[i])
+      return FALSE;
+  }
+
+  if (!gst_video_colorimetry_is_equal (&in->colorimetry, &out->colorimetry))
+    return FALSE;
+  if (in->chroma_site != out->chroma_site)
+    return FALSE;
+
+  return TRUE;
+}
+
+static gboolean
 _gst_gl_color_convert_set_caps_unlocked (GstGLColorConvert * convert,
     GstCaps * in_caps, GstCaps * out_caps)
 {
@@ -619,14 +648,27 @@
   convert->out_info = out_info;
   convert->initted = FALSE;
 
+  /* If input and output are identical, pass through directly */
+  convert->passthrough =
+      _gst_gl_color_convert_can_passthrough (&in_info, &out_info);
+#ifndef GST_DISABLE_GST_DEBUG
+  if (G_UNLIKELY (convert->passthrough))
+    GST_DEBUG_OBJECT (convert,
+        "Configuring passthrough mode for same in/out caps");
+  else {
+    GST_DEBUG_OBJECT (convert, "Color converting %" GST_PTR_FORMAT
+        " to %" GST_PTR_FORMAT, in_caps, out_caps);
+  }
+#endif
+
   return TRUE;
 }
 
 /**
  * gst_gl_color_convert_set_caps:
  * @convert: a #GstGLColorConvert
- * @in_info: input #GstVideoInfo
- * @out_info: output #GstVideoInfo
+ * @in_caps: input #GstCaps
+ * @out_caps: output #GstCaps
  *
  * Initializes @convert with the information required for conversion.
  */
@@ -732,7 +774,7 @@
   g_return_val_if_fail (convert != NULL, FALSE);
   g_return_val_if_fail (inbuf, FALSE);
 
-  if (gst_video_info_is_equal (&convert->in_info, &convert->out_info))
+  if (G_UNLIKELY (convert->passthrough))
     return gst_buffer_ref (inbuf);
 
   convert->inbuf = inbuf;
@@ -896,13 +938,13 @@
   GstVideoFormat out_format = GST_VIDEO_INFO_FORMAT (&convert->out_info);
   const gchar *out_format_str = gst_video_format_to_string (out_format);
   gchar *pixel_order = _RGB_pixel_order ("rgba", out_format_str);
-#if GST_GL_HAVE_PLATFORM_EAGL
-  gboolean texture_rg = FALSE;
-#else
   gboolean texture_rg =
       gst_gl_context_check_feature (convert->context, "GL_EXT_texture_rg")
-      || gst_gl_context_check_feature (convert->context, "GL_ARB_texture_rg");
-#endif
+      || gst_gl_context_check_gl_version (convert->context, GST_GL_API_GLES2, 3,
+      0)
+      || gst_gl_context_check_feature (convert->context, "GL_ARB_texture_rg")
+      || gst_gl_context_check_gl_version (convert->context, GST_GL_API_OPENGL3,
+      3, 0);
   gboolean apple_ycbcr = gst_gl_context_check_feature (convert->context,
       "GL_APPLE_ycbcr_422");
   gboolean in_tex_rectangular = FALSE;
@@ -1134,13 +1176,13 @@
   GstVideoFormat out_format = GST_VIDEO_INFO_FORMAT (&convert->out_info);
   const gchar *out_format_str = gst_video_format_to_string (out_format);
   gchar *pixel_order = _RGB_pixel_order ("rgba", out_format_str);
-#if GST_GL_HAVE_PLATFORM_EAGL
-  gboolean texture_rg = FALSE;
-#else
   gboolean texture_rg =
       gst_gl_context_check_feature (convert->context, "GL_EXT_texture_rg")
-      || gst_gl_context_check_feature (convert->context, "GL_ARB_texture_rg");
-#endif
+      || gst_gl_context_check_gl_version (convert->context, GST_GL_API_GLES2, 3,
+      0)
+      || gst_gl_context_check_feature (convert->context, "GL_ARB_texture_rg")
+      || gst_gl_context_check_gl_version (convert->context, GST_GL_API_OPENGL3,
+      3, 0);
 
   info->in_n_textures = 1;
   info->out_n_textures = 1;
diff --git a/gst-libs/gst/gl/gstglcolorconvert.h b/gst-libs/gst/gl/gstglcolorconvert.h
index 748ac90..4aa8985 100644
--- a/gst-libs/gst/gl/gstglcolorconvert.h
+++ b/gst-libs/gst/gl/gstglcolorconvert.h
@@ -53,6 +53,7 @@
   GstVideoInfo     out_info;
 
   gboolean         initted;
+  gboolean         passthrough;
 
   GstBuffer *    inbuf;
   GstBuffer *    outbuf;
diff --git a/gst-libs/gst/gl/gstglcontext.c b/gst-libs/gst/gl/gstglcontext.c
index d05169f..18e527e 100644
--- a/gst-libs/gst/gl/gstglcontext.c
+++ b/gst-libs/gst/gl/gstglcontext.c
@@ -449,7 +449,6 @@
 
 /**
  * gst_gl_context_get_current_gl_api:
- * @context_type: a #GstGLPlatform specifying the type of context to retreive
  * @major: (out): (allow-none): the major version
  * @minor: (out): (allow-none): the minor version
  *
@@ -1217,7 +1216,7 @@
   context_class = GST_GL_CONTEXT_GET_CLASS (context);
   window_class = GST_GL_WINDOW_GET_CLASS (context->window);
 
-  display_api = gst_gl_display_get_gl_api (context->priv->display);
+  display_api = gst_gl_display_get_gl_api_unlocked (context->priv->display);
   if (display_api == GST_GL_API_NONE) {
     g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API,
         "Cannot create context with satisfying requested apis "
diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c
index 89f22ea..a049af4 100644
--- a/gst-libs/gst/gl/gstgldisplay.c
+++ b/gst-libs/gst/gl/gstgldisplay.c
@@ -214,6 +214,7 @@
 /**
  * gst_gl_display_filter_gl_api:
  * @display: a #GstGLDisplay
+ * @gl_api: a #GstGLAPI to filter with
  *
  * limit the use of OpenGL to the requested @gl_api.  This is intended to allow
  * application and elements to request a specific set of OpenGL API's based on
@@ -236,6 +237,14 @@
   GST_OBJECT_UNLOCK (display);
 }
 
+GstGLAPI
+gst_gl_display_get_gl_api_unlocked (GstGLDisplay * display)
+{
+  g_return_val_if_fail (GST_IS_GL_DISPLAY (display), GST_GL_API_NONE);
+
+  return display->priv->gl_api;
+}
+
 /**
  * gst_gl_display_get_gl_api:
  * @display: a #GstGLDisplay
@@ -371,6 +380,8 @@
  *
  * Returns: (transfer full): the #GstGLContext current on @thread or %NULL
  *
+ * Must be called with the object lock held.
+ *
  * Since: 1.6
  */
 GstGLContext *
@@ -381,11 +392,9 @@
 
   g_return_val_if_fail (GST_IS_GL_DISPLAY (display), NULL);
 
-  GST_OBJECT_LOCK (display);
   context = _get_gl_context_for_thread_unlocked (display, thread);
   GST_DEBUG_OBJECT (display, "returning context %" GST_PTR_FORMAT " for thread "
       "%p", context, thread);
-  GST_OBJECT_UNLOCK (display);
 
   return context;
 }
@@ -429,6 +438,8 @@
  * Returns: whether @context was successfully added. %FALSE may be returned
  * if there already exists another context for @context's active thread.
  *
+ * Must be called with the object lock held.
+ *
  * Since: 1.6
  */
 gboolean
@@ -447,11 +458,10 @@
   g_assert (context_display == display);
   gst_object_unref (context_display);
 
-  GST_OBJECT_LOCK (display);
-
   thread = gst_gl_context_get_thread (context);
   if (thread) {
     collision = _get_gl_context_for_thread_unlocked (display, thread);
+    g_thread_unref (thread);
     if (_check_collision (context, collision)) {
       ret = FALSE;
       goto out;
@@ -469,7 +479,6 @@
 
   GST_DEBUG_OBJECT (display, "%ssuccessfully inserted context %" GST_PTR_FORMAT,
       ret ? "" : "un", context);
-  GST_OBJECT_UNLOCK (display);
 
   return ret;
 }
diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h
index d50b463..a9c1433 100644
--- a/gst-libs/gst/gl/gstgldisplay.h
+++ b/gst-libs/gst/gl/gstgldisplay.h
@@ -86,6 +86,7 @@
 void             gst_gl_display_filter_gl_api          (GstGLDisplay * display,
                                                         GstGLAPI api);
 GstGLAPI         gst_gl_display_get_gl_api             (GstGLDisplay * display);
+GstGLAPI         gst_gl_display_get_gl_api_unlocked    (GstGLDisplay * display);
 
 #define GST_GL_DISPLAY_CONTEXT_TYPE "gst.gl.GLDisplay"
 void     gst_context_set_gl_display (GstContext * context, GstGLDisplay * display);
diff --git a/gst-libs/gst/gl/gstgldownload.c b/gst-libs/gst/gl/gstgldownload.c
index d5b35c3..1ae49b8 100644
--- a/gst-libs/gst/gl/gstgldownload.c
+++ b/gst-libs/gst/gl/gstgldownload.c
@@ -151,9 +151,7 @@
 /**
  * gst_gl_download_set_format:
  * @download: a #GstGLDownload
- * @v_format: a #GstVideoFormat
- * @out_width: the width to download to
- * @out_height: the height to download to
+ * @out_info: a #GstVideoInfo
  *
  * Initializes @download with the information required for download.
  */
diff --git a/gst-libs/gst/gl/gstglfilter.c b/gst-libs/gst/gl/gstglfilter.c
index cf95d1c..169ded9 100644
--- a/gst-libs/gst/gl/gstglfilter.c
+++ b/gst-libs/gst/gl/gstglfilter.c
@@ -75,7 +75,6 @@
 static GstCaps *gst_gl_filter_fixate_caps (GstBaseTransform * bt,
     GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
 static void gst_gl_filter_reset (GstGLFilter * filter);
-static gboolean gst_gl_filter_start (GstBaseTransform * bt);
 static gboolean gst_gl_filter_stop (GstBaseTransform * bt);
 static gboolean gst_gl_filter_get_unit_size (GstBaseTransform * trans,
     GstCaps * caps, gsize * size);
@@ -106,7 +105,6 @@
       gst_gl_filter_transform_caps;
   GST_BASE_TRANSFORM_CLASS (klass)->fixate_caps = gst_gl_filter_fixate_caps;
   GST_BASE_TRANSFORM_CLASS (klass)->transform = gst_gl_filter_transform;
-  GST_BASE_TRANSFORM_CLASS (klass)->start = gst_gl_filter_start;
   GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_filter_stop;
   GST_BASE_TRANSFORM_CLASS (klass)->set_caps = gst_gl_filter_set_caps;
   GST_BASE_TRANSFORM_CLASS (klass)->propose_allocation =
@@ -165,25 +163,9 @@
 }
 
 static gboolean
-gst_gl_filter_start (GstBaseTransform * bt)
-{
-  GstGLFilter *filter = GST_GL_FILTER (bt);
-  GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
-
-  if (filter_class->onStart)
-    filter_class->onStart (filter);
-
-  return GST_BASE_TRANSFORM_CLASS (parent_class)->start (bt);
-}
-
-static gboolean
 gst_gl_filter_stop (GstBaseTransform * bt)
 {
   GstGLFilter *filter = GST_GL_FILTER (bt);
-  GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
-
-  if (filter_class->onStop)
-    filter_class->onStop (filter);
 
   gst_gl_filter_reset (filter);
 
@@ -215,8 +197,8 @@
   if (filter_class->display_init_cb)
     filter_class->display_init_cb (filter);
 
-  if (filter_class->onInitFBO) {
-    if (!filter_class->onInitFBO (filter))
+  if (filter_class->init_fbo) {
+    if (!filter_class->init_fbo (filter))
       goto error;
   }
 
diff --git a/gst-libs/gst/gl/gstglfilter.h b/gst-libs/gst/gl/gstglfilter.h
index fcca308..a5caf32 100644
--- a/gst-libs/gst/gl/gstglfilter.h
+++ b/gst-libs/gst/gl/gstglfilter.h
@@ -90,10 +90,7 @@
  *          Note: If @filter exists, then @filter_texture is not run
  * @filter_texture: given @in_tex, transform it into @out_tex.  Not used
  *                  if @filter exists
- * @onInitFBO: perform initialization when the Framebuffer object is created
- * @onStart: called when element activates see also #GstBaseTransform
- * @onStop: called when the element deactivates e also #GstBaseTransform
- * @onReset: called on inizialation and after @onStop
+ * @init_fbo: perform initialization when the Framebuffer object is created
  * @display_init_cb: execute arbitrary gl code on start
  * @display_reset_cb: execute arbitrary gl code at stop
  */
@@ -104,11 +101,7 @@
   gboolean (*set_caps)          (GstGLFilter* filter, GstCaps* incaps, GstCaps* outcaps);
   gboolean (*filter)            (GstGLFilter *filter, GstBuffer *inbuf, GstBuffer *outbuf);
   gboolean (*filter_texture)    (GstGLFilter *filter, guint in_tex, guint out_tex);
-  gboolean (*onInitFBO)         (GstGLFilter *filter);
-
-  void (*onStart)               (GstGLFilter *filter);
-  void (*onStop)                (GstGLFilter *filter);
-  void (*onReset)               (GstGLFilter *filter);
+  gboolean (*init_fbo)          (GstGLFilter *filter);
 
   /* useful to init and cleanup custom gl resources */
   void (*display_init_cb)       (GstGLFilter *filter);
diff --git a/gst-libs/gst/gl/gstglmemory.c b/gst-libs/gst/gl/gstglmemory.c
index 397d216..254e617 100644
--- a/gst-libs/gst/gl/gstglmemory.c
+++ b/gst-libs/gst/gl/gstglmemory.c
@@ -219,15 +219,11 @@
 gst_gl_texture_type_from_format (GstGLContext * context,
     GstVideoFormat v_format, guint plane)
 {
-#if GST_GL_HAVE_PLATFORM_EAGL
-  gboolean texture_rg = FALSE;
-#else
   gboolean texture_rg =
       gst_gl_context_check_feature (context, "GL_EXT_texture_rg")
       || gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0)
       || gst_gl_context_check_feature (context, "GL_ARB_texture_rg")
       || gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 0);
-#endif
   guint n_plane_components;
 
   switch (v_format) {
@@ -1073,7 +1069,6 @@
 
     if (dest == NULL) {
       GST_WARNING ("Could not copy GL Memory");
-      gst_memory_unref ((GstMemory *) dest);
       goto done;
     }
 
@@ -1407,7 +1402,7 @@
 /**
  * gst_gl_memory_setup_buffer:
  * @context: a #GstGLContext
- * @param: a #GstAllocationParams
+ * @params: a #GstAllocationParams
  * @info: a #GstVideoInfo
  * @valign: the #GstVideoAlignment applied to @info
  * @buffer: a #GstBuffer
diff --git a/gst-libs/gst/gl/gstglmemory.h b/gst-libs/gst/gl/gstglmemory.h
index 87033c0..28db0a4 100644
--- a/gst-libs/gst/gl/gstglmemory.h
+++ b/gst-libs/gst/gl/gstglmemory.h
@@ -109,6 +109,10 @@
 };
 
 #define GST_CAPS_FEATURE_MEMORY_GL_MEMORY "memory:GLMemory"
+#define GST_GL_MEMORY_VIDEO_FORMATS_STR \
+    "{ RGBA, BGRA, RGBx, BGRx, ARGB, ABGR, xRGB, xBGR, RGB, BGR, RGB16, BGR16, " \
+    "AYUV, I420, YV12, NV12, NV21, YUY2, UYVY, Y41B, Y42B, Y444, " \
+    "GRAY8, GRAY16_LE, GRAY16_BE }"
 
 /**
  * GST_GL_MEMORY_ALLOCATOR:
diff --git a/gst-libs/gst/gl/gstglsyncmeta.c b/gst-libs/gst/gl/gstglsyncmeta.c
index 1391a6d..db48f02 100644
--- a/gst-libs/gst/gl/gstglsyncmeta.c
+++ b/gst-libs/gst/gl/gstglsyncmeta.c
@@ -195,7 +195,7 @@
   if (g_once_init_enter (&meta_info)) {
     const GstMetaInfo *meta =
         gst_meta_register (GST_GL_SYNC_META_API_TYPE, "GstGLSyncMeta",
-        sizeof (GstVideoMeta), (GstMetaInitFunction) _gst_gl_sync_meta_init,
+        sizeof (GstGLSyncMeta), (GstMetaInitFunction) _gst_gl_sync_meta_init,
         (GstMetaFreeFunction) _gst_gl_sync_meta_free,
         _gst_gl_sync_meta_transform);
     g_once_init_leave (&meta_info, meta);
diff --git a/gst-libs/gst/gl/gstglupload.c b/gst-libs/gst/gl/gstglupload.c
index 635477f..3415f8f 100644
--- a/gst-libs/gst/gl/gstglupload.c
+++ b/gst-libs/gst/gl/gstglupload.c
@@ -97,6 +97,8 @@
   const gchar *name;
   GstGLUploadMethodFlags flags;
 
+  GstStaticCaps *input_template_caps;
+
     gpointer (*new) (GstGLUpload * upload);
   GstCaps *(*transform_caps) (GstGLContext * context,
       GstPadDirection direction, GstCaps * caps);
@@ -274,9 +276,15 @@
   g_free (impl);
 }
 
+
+static GstStaticCaps _gl_memory_upload_caps =
+GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
+    (GST_CAPS_FEATURE_MEMORY_GL_MEMORY, GST_GL_MEMORY_VIDEO_FORMATS_STR));
+
 static const UploadMethod _gl_memory_upload = {
   "GLMemory",
   METHOD_FLAG_CAN_SHARE_CONTEXT,
+  &_gl_memory_upload_caps,
   &_gl_memory_upload_new,
   &_gl_memory_upload_transform_caps,
   &_gl_memory_upload_accept,
@@ -442,9 +450,14 @@
   g_free (impl);
 }
 
+static GstStaticCaps _egl_image_upload_caps =
+GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
+    (GST_CAPS_FEATURE_MEMORY_EGL_IMAGE, "RGBA"));
+
 static const UploadMethod _egl_image_upload = {
   "EGLImage",
   0,
+  &_egl_image_upload_caps,
   &_egl_image_upload_new,
   &_egl_image_upload_transform_caps,
   &_egl_image_upload_accept,
@@ -648,9 +661,14 @@
   g_free (upload);
 }
 
+static GstStaticCaps _upload_meta_upload_caps =
+GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
+    (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, "RGBA"));
+
 static const UploadMethod _upload_meta_upload = {
   "UploadMeta",
   METHOD_FLAG_CAN_SHARE_CONTEXT,
+  &_upload_meta_upload_caps,
   &_upload_meta_upload_new,
   &_upload_meta_upload_transform_caps,
   &_upload_meta_upload_accept,
@@ -777,9 +795,13 @@
   g_free (raw);
 }
 
+static GstStaticCaps _raw_data_upload_caps =
+GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_GL_MEMORY_VIDEO_FORMATS_STR));
+
 static const UploadMethod _raw_data_upload = {
   "Raw Data",
   0,
+  &_raw_data_upload_caps,
   &_raw_data_upload_new,
   &_raw_data_upload_transform_caps,
   &_raw_data_upload_accept,
@@ -796,6 +818,30 @@
   &_upload_meta_upload, &_raw_data_upload
 };
 
+static GMutex upload_global_lock;
+
+GstCaps *
+gst_gl_upload_get_input_template_caps (void)
+{
+  GstCaps *ret = NULL;
+  gint i;
+
+  g_mutex_lock (&upload_global_lock);
+
+  /* FIXME: cache this and invalidate on changes to upload_methods */
+  for (i = 0; i < G_N_ELEMENTS (upload_methods); i++) {
+    GstCaps *template =
+        gst_static_caps_get (upload_methods[i]->input_template_caps);
+    ret = ret == NULL ? template : gst_caps_merge (ret, template);
+  }
+
+  ret = gst_caps_simplify (ret);
+
+  g_mutex_unlock (&upload_global_lock);
+
+  return ret;
+}
+
 #define DEBUG_INIT \
   GST_DEBUG_CATEGORY_INIT (gst_gl_upload_debug, "glupload", 0, "upload");
 
@@ -984,8 +1030,8 @@
 /**
  * gst_gl_upload_get_caps:
  * @upload: a #GstGLUpload
- * @in_caps: (transfer full): (allow-none): (out): the input #GstCaps
- * @ou_caps: (transfer full): (allow-none): (out): the output #GstCaps
+ * @in_caps: (transfer full) (allow-none) (out): the input #GstCaps
+ * @out_caps: (transfer full) (allow-none) (out): the output #GstCaps
  *
  * Returns: (transfer none): The #GstCaps set by gst_gl_upload_set_caps()
  */
diff --git a/gst-libs/gst/gl/gstglupload.h b/gst-libs/gst/gl/gstglupload.h
index 8652891..5bc4346 100644
--- a/gst-libs/gst/gl/gstglupload.h
+++ b/gst-libs/gst/gl/gstglupload.h
@@ -78,6 +78,8 @@
   GstObjectClass object_class;
 };
 
+GstCaps *     gst_gl_upload_get_input_template_caps (void);
+
 GstGLUpload * gst_gl_upload_new                    (GstGLContext * context);
 
 GstCaps *     gst_gl_upload_transform_caps         (GstGLContext * context,
diff --git a/gst-libs/gst/gl/gstglwindow.c b/gst-libs/gst/gl/gstglwindow.c
index 984033a..42de9ab 100644
--- a/gst-libs/gst/gl/gstglwindow.c
+++ b/gst-libs/gst/gl/gstglwindow.c
@@ -87,7 +87,6 @@
 
 struct _GstGLWindowPrivate
 {
-  GThread *gl_thread;
   GThread *navigation_thread;
 
   gboolean alive;
@@ -301,12 +300,28 @@
 {
   GstGLContext *context = gst_gl_window_get_context (data->window);
   GstGLWindowClass *window_class = GST_GL_WINDOW_GET_CLASS (data->window);
+  GThread *thread = NULL;
 
-  gst_gl_context_activate (context, FALSE);
+  /* deactivate if necessary */
+  if (context) {
+    thread = gst_gl_context_get_thread (context);
+    if (thread) {
+      /* This is only thread safe iff the context thread == g_thread_self() */
+      g_assert (thread == g_thread_self ());
+      gst_gl_context_activate (context, FALSE);
+    }
+  }
+
   window_class->set_window_handle (data->window, data->handle);
-  gst_gl_context_activate (context, TRUE);
 
-  gst_object_unref (context);
+  /* reactivate */
+  if (context && thread)
+    gst_gl_context_activate (context, TRUE);
+
+  if (context)
+    gst_object_unref (context);
+  if (thread)
+    g_thread_unref (thread);
 }
 
 static void
diff --git a/gst-libs/gst/insertbin/Makefile.am b/gst-libs/gst/insertbin/Makefile.am
index 6379a0b..09eb97c 100644
--- a/gst-libs/gst/insertbin/Makefile.am
+++ b/gst-libs/gst/insertbin/Makefile.am
@@ -29,7 +29,7 @@
 gir_sources+=$(patsubst %,$(builddir)/%, $(built_sources))
 
 GstInsertBin-@GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libgstinsertbin-@GST_API_VERSION@.la
-	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
+	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)"  GI_SCANNER_DISABLE_CACHE=yes\
 		GST_PLUGIN_SYSTEM_PATH_1_0="" GST_PLUGIN_PATH_1_0="" GST_REGISTRY_UPDATE=no \
 		$(INTROSPECTION_SCANNER) -v --namespace GstInsertBin \
 		--nsversion=@GST_API_VERSION@ \
@@ -73,19 +73,3 @@
 
 CLEANFILES = $(BUILT_GIRSOURCES) $(typelibs_DATA)
 endif
-
-Android.mk:  $(BUILT_SOURCES) Makefile.am
-	androgenizer -:PROJECT libgstinsertbin -:STATIC libgstinsertbin-@GST_API_VERSION@ \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstinsertbin_@GST_API_VERSION@_la_SOURCES) \
-         $(built_sources) \
-	 -:CFLAGS $(DEFS) $(libgstinsertbin_@GST_API_VERSION@_la_CFLAGS) \
-	 -:LDFLAGS $(libgstinsertbin_@GST_API_VERSION@_la_LDFLAGS) \
-	           $(libgstinsertbin@GST_API_VERSION@_la_LIBADD) \
-	           -ldl \
-	 -:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/insertbin \
-	 -:HEADERS $(libgstinsertbininclude_HEADERS) \
-         $(built_headers) \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-	> $@
diff --git a/gst-libs/gst/insertbin/Makefile.in b/gst-libs/gst/insertbin/Makefile.in
index 714cb43..1a93810 100644
--- a/gst-libs/gst/insertbin/Makefile.in
+++ b/gst-libs/gst/insertbin/Makefile.in
@@ -1111,7 +1111,7 @@
 
 
 @HAVE_INTROSPECTION_TRUE@GstInsertBin-@GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libgstinsertbin-@GST_API_VERSION@.la
-@HAVE_INTROSPECTION_TRUE@	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
+@HAVE_INTROSPECTION_TRUE@	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)"  GI_SCANNER_DISABLE_CACHE=yes\
 @HAVE_INTROSPECTION_TRUE@		GST_PLUGIN_SYSTEM_PATH_1_0="" GST_PLUGIN_PATH_1_0="" GST_REGISTRY_UPDATE=no \
 @HAVE_INTROSPECTION_TRUE@		$(INTROSPECTION_SCANNER) -v --namespace GstInsertBin \
 @HAVE_INTROSPECTION_TRUE@		--nsversion=@GST_API_VERSION@ \
@@ -1144,22 +1144,6 @@
 @HAVE_INTROSPECTION_TRUE@		--includedir=`PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" $(PKG_CONFIG) --variable=girdir gstreamer-base-@GST_API_VERSION@` \
 @HAVE_INTROSPECTION_TRUE@		$(INTROSPECTION_COMPILER_OPTS) $< -o $(@F)
 
-Android.mk:  $(BUILT_SOURCES) Makefile.am
-	androgenizer -:PROJECT libgstinsertbin -:STATIC libgstinsertbin-@GST_API_VERSION@ \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstinsertbin_@GST_API_VERSION@_la_SOURCES) \
-         $(built_sources) \
-	 -:CFLAGS $(DEFS) $(libgstinsertbin_@GST_API_VERSION@_la_CFLAGS) \
-	 -:LDFLAGS $(libgstinsertbin_@GST_API_VERSION@_la_LDFLAGS) \
-	           $(libgstinsertbin@GST_API_VERSION@_la_LIBADD) \
-	           -ldl \
-	 -:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/insertbin \
-	 -:HEADERS $(libgstinsertbininclude_HEADERS) \
-         $(built_headers) \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-	> $@
-
 # 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/gst-libs/gst/interfaces/Makefile.am b/gst-libs/gst/interfaces/Makefile.am
index 6401a83..e66ab82 100644
--- a/gst-libs/gst/interfaces/Makefile.am
+++ b/gst-libs/gst/interfaces/Makefile.am
@@ -43,19 +43,3 @@
 CLEANFILES = $(BUILT_SOURCES)
 
 include $(top_srcdir)/common/gst-glib-gen.mak
-
-Android.mk:  $(BUILT_SOURCES) Makefile.am
-	androgenizer -:PROJECT libgstphotography -:STATIC libgstphotography-@GST_API_VERSION@ \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstphotography_@GST_API_VERSION@_la_SOURCES) \
-         $(built_sources) \
-	 -:CFLAGS $(DEFS) $(libgstphotography_@GST_API_VERSION@_la_CFLAGS) \
-	 -:LDFLAGS $(libgstphotography_@GST_API_VERSION@_la_LDFLAGS) \
-	           $(libgstphotography_@GST_API_VERSION@_la_LIBADD) \
-	           -ldl \
-	 -:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/photography \
-	 -:HEADERS $(libgstphotographyinclude_HEADERS) \
-         $(built_headers) \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-	> $@
diff --git a/gst-libs/gst/interfaces/Makefile.in b/gst-libs/gst/interfaces/Makefile.in
index b17b882..3ae266c 100644
--- a/gst-libs/gst/interfaces/Makefile.in
+++ b/gst-libs/gst/interfaces/Makefile.in
@@ -1222,22 +1222,6 @@
 .deps/%-enumtypes.Plo:
 	@touch $@
 
-Android.mk:  $(BUILT_SOURCES) Makefile.am
-	androgenizer -:PROJECT libgstphotography -:STATIC libgstphotography-@GST_API_VERSION@ \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstphotography_@GST_API_VERSION@_la_SOURCES) \
-         $(built_sources) \
-	 -:CFLAGS $(DEFS) $(libgstphotography_@GST_API_VERSION@_la_CFLAGS) \
-	 -:LDFLAGS $(libgstphotography_@GST_API_VERSION@_la_LDFLAGS) \
-	           $(libgstphotography_@GST_API_VERSION@_la_LIBADD) \
-	           -ldl \
-	 -:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/photography \
-	 -:HEADERS $(libgstphotographyinclude_HEADERS) \
-         $(built_headers) \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-	> $@
-
 # 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/gst-libs/gst/mpegts/Makefile.am b/gst-libs/gst/mpegts/Makefile.am
index 0cee304..2511d49 100644
--- a/gst-libs/gst/mpegts/Makefile.am
+++ b/gst-libs/gst/mpegts/Makefile.am
@@ -63,7 +63,7 @@
 gir_sources+=$(patsubst %,$(builddir)/%, $(built_sources))
 
 GstMpegts-@GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libgstmpegts-@GST_API_VERSION@.la
-	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
+	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)"  GI_SCANNER_DISABLE_CACHE=yes\
 		GST_PLUGIN_SYSTEM_PATH_1_0="" GST_PLUGIN_PATH_1_0="" GST_REGISTRY_UPDATE=no \
 		$(INTROSPECTION_SCANNER) -v --namespace GstMpegts \
 		--nsversion=@GST_API_VERSION@ \
@@ -109,20 +109,4 @@
 CLEANFILES += $(BUILT_GIRSOURCES) $(typelibs_DATA)
 endif
 
-Android.mk:  $(BUILT_SOURCES) Makefile.am
-	androgenizer -:PROJECT libgstmpegts -:STATIC libgstmpegts-@GST_API_VERSION@ \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstmpegts_@GST_API_VERSION@_la_SOURCES) \
-         $(built_sources) \
-	 -:CFLAGS $(DEFS) $(libgstmpegts_@GST_API_VERSION@_la_CFLAGS) \
-	 -:LDFLAGS $(libgstmpegts_@GST_API_VERSION@_la_LDFLAGS) \
-	           $(libgstmpegts@GST_API_VERSION@_la_LIBADD) \
-	           -ldl \
-	 -:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/mpegts \
-	 -:HEADERS $(libgstmpegtsinclude_HEADERS) \
-         $(built_headers) \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-	> $@
-
 include $(top_srcdir)/common/gst-glib-gen.mak
diff --git a/gst-libs/gst/mpegts/Makefile.in b/gst-libs/gst/mpegts/Makefile.in
index a0207c7..b0a4b04 100644
--- a/gst-libs/gst/mpegts/Makefile.in
+++ b/gst-libs/gst/mpegts/Makefile.in
@@ -1301,7 +1301,7 @@
 
 
 @HAVE_INTROSPECTION_TRUE@GstMpegts-@GST_API_VERSION@.gir: $(INTROSPECTION_SCANNER) libgstmpegts-@GST_API_VERSION@.la
-@HAVE_INTROSPECTION_TRUE@	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" \
+@HAVE_INTROSPECTION_TRUE@	$(AM_V_GEN)PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)"  GI_SCANNER_DISABLE_CACHE=yes\
 @HAVE_INTROSPECTION_TRUE@		GST_PLUGIN_SYSTEM_PATH_1_0="" GST_PLUGIN_PATH_1_0="" GST_REGISTRY_UPDATE=no \
 @HAVE_INTROSPECTION_TRUE@		$(INTROSPECTION_SCANNER) -v --namespace GstMpegts \
 @HAVE_INTROSPECTION_TRUE@		--nsversion=@GST_API_VERSION@ \
@@ -1335,22 +1335,6 @@
 @HAVE_INTROSPECTION_TRUE@		--includedir=`PKG_CONFIG_PATH="$(GST_PKG_CONFIG_PATH)" $(PKG_CONFIG) --variable=girdir gstreamer-base-@GST_API_VERSION@` \
 @HAVE_INTROSPECTION_TRUE@		$(INTROSPECTION_COMPILER_OPTS) $< -o $(@F)
 
-Android.mk:  $(BUILT_SOURCES) Makefile.am
-	androgenizer -:PROJECT libgstmpegts -:STATIC libgstmpegts-@GST_API_VERSION@ \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstmpegts_@GST_API_VERSION@_la_SOURCES) \
-         $(built_sources) \
-	 -:CFLAGS $(DEFS) $(libgstmpegts_@GST_API_VERSION@_la_CFLAGS) \
-	 -:LDFLAGS $(libgstmpegts_@GST_API_VERSION@_la_LDFLAGS) \
-	           $(libgstmpegts@GST_API_VERSION@_la_LIBADD) \
-	           -ldl \
-	 -:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/mpegts \
-	 -:HEADERS $(libgstmpegtsinclude_HEADERS) \
-         $(built_headers) \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-	> $@
-
 # these are all the rules generating the relevant files
 $(glib_gen_basename)-marshal.h: $(glib_gen_basename)-marshal.list
 	$(AM_V_GEN)$(GLIB_GENMARSHAL) --header --prefix=$(glib_gen_prefix)_marshal $^ > $(glib_gen_basename)-marshal.h.tmp && \
diff --git a/gst-libs/gst/uridownloader/Makefile.am b/gst-libs/gst/uridownloader/Makefile.am
index a63f2ac..91b5187 100644
--- a/gst-libs/gst/uridownloader/Makefile.am
+++ b/gst-libs/gst/uridownloader/Makefile.am
@@ -22,19 +22,3 @@
 	$(GST_LIB_LDFLAGS) \
 	$(GST_ALL_LDFLAGS) \
 	$(GST_LT_LDFLAGS)
-
-Android.mk:  $(BUILT_SOURCES) Makefile.am
-	androgenizer -:PROJECT libgsturidownloader -:STATIC libgsturidownloader-@GST_API_VERSION@ \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgsturidownloader_@GST_API_VERSION@_la_SOURCES) \
-         $(built_sources) \
-	 -:CFLAGS $(DEFS) $(libgsturidownloader_@GST_API_VERSION@_la_CFLAGS) \
-	 -:LDFLAGS $(libgsturidownloader_@GST_API_VERSION@_la_LDFLAGS) \
-	           $(libgsturidownloader@GST_API_VERSION@_la_LIBADD) \
-	           -ldl \
-	 -:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/uridownloader \
-	 -:HEADERS $(libgsturidownloaderinclude_HEADERS) \
-         $(built_headers) \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-	> $@
diff --git a/gst-libs/gst/uridownloader/Makefile.in b/gst-libs/gst/uridownloader/Makefile.in
index f63ea01..1dafcbc 100644
--- a/gst-libs/gst/uridownloader/Makefile.in
+++ b/gst-libs/gst/uridownloader/Makefile.in
@@ -1058,22 +1058,6 @@
 	uninstall-libgsturidownloader_@GST_API_VERSION@includeHEADERS
 
 
-Android.mk:  $(BUILT_SOURCES) Makefile.am
-	androgenizer -:PROJECT libgsturidownloader -:STATIC libgsturidownloader-@GST_API_VERSION@ \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgsturidownloader_@GST_API_VERSION@_la_SOURCES) \
-         $(built_sources) \
-	 -:CFLAGS $(DEFS) $(libgsturidownloader_@GST_API_VERSION@_la_CFLAGS) \
-	 -:LDFLAGS $(libgsturidownloader_@GST_API_VERSION@_la_LDFLAGS) \
-	           $(libgsturidownloader@GST_API_VERSION@_la_LIBADD) \
-	           -ldl \
-	 -:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/uridownloader \
-	 -:HEADERS $(libgsturidownloaderinclude_HEADERS) \
-         $(built_headers) \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-	> $@
-
 # 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/gst-libs/gst/video/gstvideoaggregator.c b/gst-libs/gst/video/gstvideoaggregator.c
index 24ab93f..965aafc 100644
--- a/gst-libs/gst/video/gstvideoaggregator.c
+++ b/gst-libs/gst/video/gstvideoaggregator.c
@@ -734,10 +734,11 @@
 
       gst_caps_unref (caps);
       gst_caps_unref (peercaps);
-      caps = tmp;
+      caps = tmp;               /* pass ownership */
       if (gst_caps_is_empty (caps)) {
         GST_DEBUG_OBJECT (vagg, "empty caps");
         ret = FALSE;
+        gst_caps_unref (caps);
         goto done;
       }
 
@@ -880,9 +881,11 @@
       GST_TIME_FORMAT, proportion, (diff < 0) ? "-" : "",
       GST_TIME_ARGS (ABS (diff)), GST_TIME_ARGS (timestamp));
 
+  live =
+      GST_CLOCK_TIME_IS_VALID (gst_aggregator_get_latency (GST_AGGREGATOR
+          (vagg)));
+
   GST_OBJECT_LOCK (vagg);
-  gst_aggregator_get_latency_unlocked (GST_AGGREGATOR (vagg), &live, NULL,
-      NULL);
 
   vagg->priv->proportion = proportion;
   if (G_LIKELY (timestamp != GST_CLOCK_TIME_NONE)) {
@@ -988,16 +991,6 @@
       vinfo = &pad->info;
 
       /* FIXME: Make all this work with negative rates */
-
-      if ((start_time < GST_BUFFER_TIMESTAMP (buf))
-          || (pad->buffer && start_time < GST_BUFFER_TIMESTAMP (pad->buffer))) {
-        GST_DEBUG_OBJECT (pad, "Buffer from the past, dropping");
-        gst_buffer_unref (buf);
-        gst_aggregator_pad_drop_buffer (bpad);
-        need_more_data = TRUE;
-        continue;
-      }
-
       end_time = GST_BUFFER_DURATION (buf);
 
       if (end_time == -1) {
@@ -1006,8 +999,14 @@
             gst_segment_to_running_time (&segment, GST_FORMAT_TIME, start_time);
 
         if (start_time >= output_end_time) {
-          GST_DEBUG_OBJECT (pad, "buffer duration is -1, start_time >= "
-              "output_end_time.  Keeping previous buffer");
+          if (pad->buffer) {
+            GST_DEBUG_OBJECT (pad, "buffer duration is -1, start_time >= "
+                "output_end_time. Keeping previous buffer");
+          } else {
+            GST_DEBUG_OBJECT (pad, "buffer duration is -1, start_time >= "
+                "output_end_time. No previous buffer, need more data");
+            need_more_data = TRUE;
+          }
           gst_buffer_unref (buf);
           continue;
         } else if (start_time < output_start_time) {
diff --git a/gst-libs/gst/video/gstvideoaggregatorpad.h b/gst-libs/gst/video/gstvideoaggregatorpad.h
index 8fd061b..1839740 100644
--- a/gst-libs/gst/video/gstvideoaggregatorpad.h
+++ b/gst-libs/gst/video/gstvideoaggregatorpad.h
@@ -61,6 +61,12 @@
   GstVideoInfo info;
 
   GstBuffer *buffer;
+  /* The caps on the pad may not match the buffer above because of two reasons:
+   * 1) When caps change, the info above will get updated, but the buffer might
+   *    not since it might be pending on the GstAggregatorPad
+   * 2) We might reject the new buffer in fill_queues() and reuse a previous
+   *    buffer which has older GstVideoInfo
+   * Hence, we need to maintain a GstVideoInfo for mapping buffers separately */
   GstVideoInfo buffer_vinfo;
 
   GstVideoFrame *aggregated_frame;
diff --git a/gst-plugins-bad.spec b/gst-plugins-bad.spec
index 9d57408..b59173f 100644
--- a/gst-plugins-bad.spec
+++ b/gst-plugins-bad.spec
@@ -7,7 +7,7 @@
 Summary: GStreamer streaming media framework "bad" plug-ins
 Name: %{gstreamer}-plugins-bad
 Version: 1.5.0.1
-Release: 0.20150316.190059.gst
+Release: 0.20150513.130001.gst
 # The freeze and nfs plugins are LGPLv2 (only)
 License: LGPLv2+ and LGPLv2
 Group: Applications/Multimedia
diff --git a/gst/adpcmdec/Makefile.am b/gst/adpcmdec/Makefile.am
index 62cb951..ffefcec 100644
--- a/gst/adpcmdec/Makefile.am
+++ b/gst/adpcmdec/Makefile.am
@@ -11,17 +11,3 @@
 	$(GST_BASE_LIBS) $(GST_LIBS)
 libgstadpcmdec_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstadpcmdec_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstadpcmdec -:SHARED libgstadpcmdec \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstadpcmdec_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstadpcmdec_la_CFLAGS) \
-	 -:LDFLAGS $(libgstadpcmdec_la_LDFLAGS) \
-	           $(libgstadpcmdec_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/adpcmdec/Makefile.in b/gst/adpcmdec/Makefile.in
index 00ccfee..caa0344 100644
--- a/gst/adpcmdec/Makefile.in
+++ b/gst/adpcmdec/Makefile.in
@@ -1072,20 +1072,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstadpcmdec -:SHARED libgstadpcmdec \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstadpcmdec_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstadpcmdec_la_CFLAGS) \
-	 -:LDFLAGS $(libgstadpcmdec_la_LDFLAGS) \
-	           $(libgstadpcmdec_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/adpcmenc/Makefile.am b/gst/adpcmenc/Makefile.am
index faf3b4a..e53c645 100644
--- a/gst/adpcmenc/Makefile.am
+++ b/gst/adpcmenc/Makefile.am
@@ -10,17 +10,3 @@
 	$(GST_LIBS)
 libgstadpcmenc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstadpcmenc_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstadpcmenc -:SHARED libgstadpcmenc \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstadpcmenc_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstadpcmenc_la_CFLAGS) \
-	 -:LDFLAGS $(libgstadpcmenc_la_LDFLAGS) \
-	           $(libgstadpcmenc_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/adpcmenc/Makefile.in b/gst/adpcmenc/Makefile.in
index c80443a..9c0171b 100644
--- a/gst/adpcmenc/Makefile.in
+++ b/gst/adpcmenc/Makefile.in
@@ -1071,20 +1071,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstadpcmenc -:SHARED libgstadpcmenc \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstadpcmenc_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstadpcmenc_la_CFLAGS) \
-	 -:LDFLAGS $(libgstadpcmenc_la_LDFLAGS) \
-	           $(libgstadpcmenc_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/adpcmenc/adpcmenc.c b/gst/adpcmenc/adpcmenc.c
index 7a8faab..36d336c 100644
--- a/gst/adpcmenc/adpcmenc.c
+++ b/gst/adpcmenc/adpcmenc.c
@@ -84,9 +84,9 @@
 
 enum adpcm_properties
 {
-  ARG_0,
-  ARG_BLOCK_SIZE,
-  ARG_LAYOUT
+  PROP_0,
+  PROP_BLOCK_SIZE,
+  PROP_LAYOUT
 };
 
 enum adpcm_layout
@@ -200,10 +200,10 @@
   ADPCMEnc *enc = GST_ADPCM_ENC (object);
 
   switch (prop_id) {
-    case ARG_BLOCK_SIZE:
+    case PROP_BLOCK_SIZE:
       enc->blocksize = g_value_get_int (value);
       break;
-    case ARG_LAYOUT:
+    case PROP_LAYOUT:
       enc->layout = g_value_get_enum (value);
       break;
     default:
@@ -219,10 +219,10 @@
   ADPCMEnc *enc = GST_ADPCM_ENC (object);
 
   switch (prop_id) {
-    case ARG_BLOCK_SIZE:
+    case PROP_BLOCK_SIZE:
       g_value_set_int (value, enc->blocksize);
       break;
-    case ARG_LAYOUT:
+    case PROP_LAYOUT:
       g_value_set_enum (value, enc->layout);
       break;
     default:
@@ -450,13 +450,13 @@
   base_class->set_format = GST_DEBUG_FUNCPTR (adpcmenc_set_format);
   base_class->handle_frame = GST_DEBUG_FUNCPTR (adpcmenc_handle_frame);
 
-  g_object_class_install_property (gobjectclass, ARG_LAYOUT,
+  g_object_class_install_property (gobjectclass, PROP_LAYOUT,
       g_param_spec_enum ("layout", "Layout",
           "Layout for output stream",
           GST_TYPE_ADPCMENC_LAYOUT, DEFAULT_ADPCM_LAYOUT,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  g_object_class_install_property (gobjectclass, ARG_BLOCK_SIZE,
+  g_object_class_install_property (gobjectclass, PROP_BLOCK_SIZE,
       g_param_spec_int ("blockalign", "Block Align",
           "Block size for output stream",
           MIN_ADPCM_BLOCK_SIZE, MAX_ADPCM_BLOCK_SIZE,
diff --git a/gst/aiff/Makefile.am b/gst/aiff/Makefile.am
index c1d1e48..ebe4230 100644
--- a/gst/aiff/Makefile.am
+++ b/gst/aiff/Makefile.am
@@ -1,5 +1,7 @@
 plugin_LTLIBRARIES = libgstaiff.la
 
+noinst_HEADERS = aiffmux.h aiffparse.h
+
 libgstaiff_la_SOURCES = aiff.c aiffmux.c aiffparse.c
 libgstaiff_la_CFLAGS = \
 	$(GST_PLUGINS_BAD_CFLAGS) \
@@ -12,19 +14,3 @@
 	$(LIBM)
 libgstaiff_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstaiff_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-noinst_HEADERS = aiffmux.h aiffparse.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstaiff -:SHARED libgstaiff \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstaiff_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstaiff_la_CFLAGS) \
-	 -:LDFLAGS $(libgstaiff_la_LDFLAGS) \
-	           $(libgstaiff_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/aiff/Makefile.in b/gst/aiff/Makefile.in
index a123f54..9ae881d 100644
--- a/gst/aiff/Makefile.in
+++ b/gst/aiff/Makefile.in
@@ -736,6 +736,7 @@
 top_srcdir = @top_srcdir@
 wayland_scanner = @wayland_scanner@
 plugin_LTLIBRARIES = libgstaiff.la
+noinst_HEADERS = aiffmux.h aiffparse.h
 libgstaiff_la_SOURCES = aiff.c aiffmux.c aiffparse.c
 libgstaiff_la_CFLAGS = \
 	$(GST_PLUGINS_BAD_CFLAGS) \
@@ -750,7 +751,6 @@
 
 libgstaiff_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstaiff_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-noinst_HEADERS = aiffmux.h aiffparse.h
 all: all-am
 
 .SUFFIXES:
@@ -1093,20 +1093,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstaiff -:SHARED libgstaiff \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstaiff_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstaiff_la_CFLAGS) \
-	 -:LDFLAGS $(libgstaiff_la_LDFLAGS) \
-	           $(libgstaiff_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/asfmux/Makefile.am b/gst/asfmux/Makefile.am
index ded6048..27656f1 100644
--- a/gst/asfmux/Makefile.am
+++ b/gst/asfmux/Makefile.am
@@ -22,18 +22,3 @@
                  gstasfobjects.h \
                  gstasfparse.h \
                  gstrtpasfpay.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstasfmux -:SHARED libgstasfmux \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstasfmux_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstasfmux_la_CFLAGS) \
-	 -:LDFLAGS $(libgstasfmux_la_LDFLAGS) \
-	           $(libgstasfmux_la_LIBADD) \
-						 $(libgstasfmux_la_LIBTOOLFLAGS) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/asfmux/Makefile.in b/gst/asfmux/Makefile.in
index 0ff4f01..353107a 100644
--- a/gst/asfmux/Makefile.in
+++ b/gst/asfmux/Makefile.in
@@ -1122,21 +1122,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstasfmux -:SHARED libgstasfmux \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstasfmux_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstasfmux_la_CFLAGS) \
-	 -:LDFLAGS $(libgstasfmux_la_LDFLAGS) \
-	           $(libgstasfmux_la_LIBADD) \
-						 $(libgstasfmux_la_LIBTOOLFLAGS) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/asfmux/gstasfmux.c b/gst/asfmux/gstasfmux.c
index 8bcf0a0..7614de5 100644
--- a/gst/asfmux/gstasfmux.c
+++ b/gst/asfmux/gstasfmux.c
@@ -61,7 +61,7 @@
  * Client (receiver)
  * |[
  * gst-launch udpsrc port=3333 ! "caps_from_rtpasfpay_at_sender" \
- * ! rtpasfdepay ! decodebin2 name=d ! queue \
+ * ! rtpasfdepay ! decodebin name=d ! queue \
  * ! videoconvert ! autovideosink \
  * d. ! queue ! audioconvert ! autoaudiosink
  * ]|
diff --git a/gst/audiofxbad/Makefile.am b/gst/audiofxbad/Makefile.am
index 65aa6bb..b483deb 100644
--- a/gst/audiofxbad/Makefile.am
+++ b/gst/audiofxbad/Makefile.am
@@ -11,18 +11,3 @@
 	$(GST_BASE_LIBS)  $(GST_LIBS) $(LIBM)
 libgstaudiofxbad_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstaudiofxbad_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT audiofxbad -:SHARED audiofxbad \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstaudiofxbad_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstaudiofxbad_la_CFLAGS) \
-	 -:LDFLAGS $(libgstaudiofxbad_la_LDFLAGS) \
-	           $(libgstaudiofxbad_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-1.0' \
-	> $@
-
diff --git a/gst/audiofxbad/Makefile.in b/gst/audiofxbad/Makefile.in
index 5b8284e..dd5e581 100644
--- a/gst/audiofxbad/Makefile.in
+++ b/gst/audiofxbad/Makefile.in
@@ -1082,20 +1082,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT audiofxbad -:SHARED audiofxbad \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstaudiofxbad_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstaudiofxbad_la_CFLAGS) \
-	 -:LDFLAGS $(libgstaudiofxbad_la_LDFLAGS) \
-	           $(libgstaudiofxbad_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-1.0' \
-	> $@
-
 # 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/gst/audiomixer/gstaudioaggregator.c b/gst/audiomixer/gstaudioaggregator.c
index b526350..eb2fb1e 100644
--- a/gst/audiomixer/gstaudioaggregator.c
+++ b/gst/audiomixer/gstaudioaggregator.c
@@ -616,9 +616,13 @@
 gst_audio_aggregator_set_sink_caps (GstAudioAggregator * aagg,
     GstAudioAggregatorPad * pad, GstCaps * caps)
 {
+  gboolean valid;
+
   GST_OBJECT_LOCK (pad);
-  gst_audio_info_from_caps (&pad->info, caps);
+  valid = gst_audio_info_from_caps (&pad->info, caps);
   GST_OBJECT_UNLOCK (pad);
+
+  g_assert (valid);
 }
 
 
diff --git a/gst/audiomixer/gstaudiomixer.c b/gst/audiomixer/gstaudiomixer.c
index 40ede84..f0e8f66 100644
--- a/gst/audiomixer/gstaudiomixer.c
+++ b/gst/audiomixer/gstaudiomixer.c
@@ -350,11 +350,12 @@
 gst_audiomixer_setcaps (GstAudioMixer * audiomixer, GstPad * pad,
     GstCaps * orig_caps)
 {
+  GstAggregator *agg = GST_AGGREGATOR (audiomixer);
   GstAudioAggregator *aagg = GST_AUDIO_AGGREGATOR (audiomixer);
   GstCaps *caps;
   GstAudioInfo info;
   GstStructure *s;
-  gint channels;
+  gint channels = 0;
   gboolean ret;
 
   caps = gst_caps_copy (orig_caps);
@@ -367,6 +368,31 @@
   if (!gst_audio_info_from_caps (&info, caps))
     goto invalid_format;
 
+  if (channels == 1) {
+    GstCaps *filter;
+    GstCaps *downstream_caps;
+
+    if (audiomixer->filter_caps)
+      filter = gst_caps_intersect_full (caps, audiomixer->filter_caps,
+          GST_CAPS_INTERSECT_FIRST);
+    else
+      filter = gst_caps_ref (caps);
+
+    downstream_caps = gst_pad_peer_query_caps (agg->srcpad, filter);
+    gst_caps_unref (filter);
+
+    if (downstream_caps) {
+      gst_caps_unref (caps);
+      caps = downstream_caps;
+
+      if (gst_caps_is_empty (caps)) {
+        gst_caps_unref (caps);
+        return FALSE;
+      }
+      caps = gst_caps_fixate (caps);
+    }
+  }
+
   GST_OBJECT_LOCK (audiomixer);
   /* don't allow reconfiguration for now; there's still a race between the
    * different upstream threads doing query_caps + accept_caps + sending
diff --git a/gst/audiovisualizers/Makefile.am b/gst/audiovisualizers/Makefile.am
index a26a1ed..a669900 100644
--- a/gst/audiovisualizers/Makefile.am
+++ b/gst/audiovisualizers/Makefile.am
@@ -19,18 +19,3 @@
 
 noinst_HEADERS = gstaudiovisualizer.h gstdrawhelpers.h \
 	gstspacescope.h gstspectrascope.h gstsynaescope.h gstwavescope.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT audiovisualizers -:SHARED audiovisualizers \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstaudiovisualizers_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstaudiovisualizers_la_CFLAGS) \
-	 -:LDFLAGS $(libgstaudiovisualizers_la_LDFLAGS) \
-	           $(libgstaudiovisualizers_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
diff --git a/gst/audiovisualizers/Makefile.in b/gst/audiovisualizers/Makefile.in
index b6f458a..42a11f9 100644
--- a/gst/audiovisualizers/Makefile.in
+++ b/gst/audiovisualizers/Makefile.in
@@ -1131,20 +1131,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT audiovisualizers -:SHARED audiovisualizers \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstaudiovisualizers_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstaudiovisualizers_la_CFLAGS) \
-	 -:LDFLAGS $(libgstaudiovisualizers_la_LDFLAGS) \
-	           $(libgstaudiovisualizers_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/audiovisualizers/gstaudiovisualizer.c b/gst/audiovisualizers/gstaudiovisualizer.c
index 0352787..ee09e39 100644
--- a/gst/audiovisualizers/gstaudiovisualizer.c
+++ b/gst/audiovisualizers/gstaudiovisualizer.c
@@ -3,19 +3,20 @@
  *
  * gstaudiovisualizer.h: base class for audio visualisation elements
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ * 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:gstaudiovisualizer
diff --git a/gst/audiovisualizers/gstaudiovisualizer.h b/gst/audiovisualizers/gstaudiovisualizer.h
index f7c6dd8..90c36c4 100644
--- a/gst/audiovisualizers/gstaudiovisualizer.h
+++ b/gst/audiovisualizers/gstaudiovisualizer.h
@@ -3,19 +3,20 @@
  *
  * gstaudiovisualizer.c: base class for audio visualisation elements
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ * 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_VISUALIZER_H__
diff --git a/gst/audiovisualizers/gstdrawhelpers.h b/gst/audiovisualizers/gstdrawhelpers.h
index d5bd724..15220ac 100644
--- a/gst/audiovisualizers/gstdrawhelpers.h
+++ b/gst/audiovisualizers/gstdrawhelpers.h
@@ -3,19 +3,20 @@
  *
  * gstdrawhelpers.h: simple drawing helpers
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ * 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.
  */
  
 /* FIXME: add versions that don't ignore alpha */
diff --git a/gst/audiovisualizers/gstspacescope.c b/gst/audiovisualizers/gstspacescope.c
index 246b8f5..b0828a8 100644
--- a/gst/audiovisualizers/gstspacescope.c
+++ b/gst/audiovisualizers/gstspacescope.c
@@ -3,19 +3,20 @@
  *
  * gstspacescope.c: simple stereo visualizer
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ * 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-spacescope
diff --git a/gst/audiovisualizers/gstspacescope.h b/gst/audiovisualizers/gstspacescope.h
index 7717c77..a305ab5 100644
--- a/gst/audiovisualizers/gstspacescope.h
+++ b/gst/audiovisualizers/gstspacescope.h
@@ -3,22 +3,22 @@
  *
  * gstspacescope.h: simple stereo visualizer
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ * 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_SPACE_SCOPE_H__
 #define __GST_SPACE_SCOPE_H__
 
@@ -59,4 +59,4 @@
 gboolean gst_space_scope_plugin_init (GstPlugin * plugin);
 
 G_END_DECLS
-#endif /* __GST_SPACE_SCOPE_H__ */
\ No newline at end of file
+#endif /* __GST_SPACE_SCOPE_H__ */
diff --git a/gst/audiovisualizers/gstspectrascope.c b/gst/audiovisualizers/gstspectrascope.c
index 1267854..ff43cfd 100644
--- a/gst/audiovisualizers/gstspectrascope.c
+++ b/gst/audiovisualizers/gstspectrascope.c
@@ -3,19 +3,21 @@
  *
  * gstspectrascope.c: frequency spectrum scope
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ * 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-spectrascope
diff --git a/gst/audiovisualizers/gstspectrascope.h b/gst/audiovisualizers/gstspectrascope.h
index 678e79a..0b21d08 100644
--- a/gst/audiovisualizers/gstspectrascope.h
+++ b/gst/audiovisualizers/gstspectrascope.h
@@ -3,22 +3,22 @@
  *
  * gstspectrascope.h: simple oscilloscope
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ * 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_SPECTRA_SCOPE_H__
 #define __GST_SPECTRA_SCOPE_H__
 
@@ -51,4 +51,4 @@
 gboolean gst_spectra_scope_plugin_init (GstPlugin * plugin);
 
 G_END_DECLS
-#endif /* __GST_SPECTRA_SCOPE_H__ */
\ No newline at end of file
+#endif /* __GST_SPECTRA_SCOPE_H__ */
diff --git a/gst/audiovisualizers/gstsynaescope.c b/gst/audiovisualizers/gstsynaescope.c
index 909dddd..23d15f0 100644
--- a/gst/audiovisualizers/gstsynaescope.c
+++ b/gst/audiovisualizers/gstsynaescope.c
@@ -3,19 +3,20 @@
  *
  * gstsynaescope.c: frequency spectrum scope
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ * 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-synaescope
diff --git a/gst/audiovisualizers/gstsynaescope.h b/gst/audiovisualizers/gstsynaescope.h
index 827fd55..a3148ed 100644
--- a/gst/audiovisualizers/gstsynaescope.h
+++ b/gst/audiovisualizers/gstsynaescope.h
@@ -3,22 +3,22 @@
  *
  * gstsynaescope.h: simple oscilloscope
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ * 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_SYNAE_SCOPE_H__
 #define __GST_SYNAE_SCOPE_H__
 
@@ -55,4 +55,4 @@
 gboolean gst_synae_scope_plugin_init (GstPlugin * plugin);
 
 G_END_DECLS
-#endif /* __GST_SYNAE_SCOPE_H__ */
\ No newline at end of file
+#endif /* __GST_SYNAE_SCOPE_H__ */
diff --git a/gst/audiovisualizers/gstwavescope.c b/gst/audiovisualizers/gstwavescope.c
index cd21abd..b87d05c 100644
--- a/gst/audiovisualizers/gstwavescope.c
+++ b/gst/audiovisualizers/gstwavescope.c
@@ -3,19 +3,20 @@
  *
  * gstwavescope.c: simple oscilloscope
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ * 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-wavescope
diff --git a/gst/audiovisualizers/gstwavescope.h b/gst/audiovisualizers/gstwavescope.h
index e4652eb..087f179 100644
--- a/gst/audiovisualizers/gstwavescope.h
+++ b/gst/audiovisualizers/gstwavescope.h
@@ -3,22 +3,22 @@
  *
  * gstwavescope.h: simple oscilloscope
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ * 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_WAVE_SCOPE_H__
 #define __GST_WAVE_SCOPE_H__
 
@@ -56,4 +56,4 @@
 gboolean gst_wave_scope_plugin_init (GstPlugin * plugin);
 
 G_END_DECLS
-#endif /* __GST_WAVE_SCOPE_H__ */
\ No newline at end of file
+#endif /* __GST_WAVE_SCOPE_H__ */
diff --git a/gst/audiovisualizers/plugin.c b/gst/audiovisualizers/plugin.c
index a21d65a..b93f491 100644
--- a/gst/audiovisualizers/plugin.c
+++ b/gst/audiovisualizers/plugin.c
@@ -3,19 +3,20 @@
  *
  * plugin.c: scopes plugin
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ * 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
@@ -44,4 +45,4 @@
     GST_VERSION_MINOR,
     audiovisualizers,
     "Creates video visualizations of audio input",
-    plugin_init, VERSION, "GPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
+    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/gst/autoconvert/Makefile.am b/gst/autoconvert/Makefile.am
index 35f73eb..1e3c5fb 100644
--- a/gst/autoconvert/Makefile.am
+++ b/gst/autoconvert/Makefile.am
@@ -8,17 +8,3 @@
 libgstautoconvert_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstautoconvert.h gstautovideoconvert.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstautoconvert -:SHARED libgstautoconvert \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstautoconvert_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstautoconvert_la_CFLAGS) \
-	 -:LDFLAGS $(libgstautoconvert_la_LDFLAGS) \
-	           $(libgstautoconvert_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/autoconvert/Makefile.in b/gst/autoconvert/Makefile.in
index bdaddb7..7d93e7b 100644
--- a/gst/autoconvert/Makefile.in
+++ b/gst/autoconvert/Makefile.in
@@ -1085,20 +1085,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstautoconvert -:SHARED libgstautoconvert \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstautoconvert_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstautoconvert_la_CFLAGS) \
-	 -:LDFLAGS $(libgstautoconvert_la_LDFLAGS) \
-	           $(libgstautoconvert_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/bayer/Makefile.am b/gst/bayer/Makefile.am
index 3754dab..4814251 100644
--- a/gst/bayer/Makefile.am
+++ b/gst/bayer/Makefile.am
@@ -20,20 +20,3 @@
 libgstbayer_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstbayer_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 nodist_libgstbayer_la_SOURCES = $(ORC_NODIST_SOURCES)
-
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstbayer -:SHARED libgstbayer \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstbayer_la_SOURCES) \
-               $(nodist_libgstbayer_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstbayer_la_CFLAGS) \
-	 -:LDFLAGS $(libgstbayer_la_LDFLAGS) \
-	           $(libgstbayer_la_LIBADD) \
-	           $(libgstbayer_la_LIBTOOLFLAGS) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/bayer/Makefile.in b/gst/bayer/Makefile.in
index 80f9fae..c838d77 100644
--- a/gst/bayer/Makefile.in
+++ b/gst/bayer/Makefile.in
@@ -1183,22 +1183,6 @@
 	cp -p tmp-orc.c $(distdir)/$(ORC_SOURCE)-dist.c
 	cp -p $(ORC_SOURCE).h $(distdir)/$(ORC_SOURCE)-dist.h
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstbayer -:SHARED libgstbayer \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstbayer_la_SOURCES) \
-               $(nodist_libgstbayer_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstbayer_la_CFLAGS) \
-	 -:LDFLAGS $(libgstbayer_la_LDFLAGS) \
-	           $(libgstbayer_la_LIBADD) \
-	           $(libgstbayer_la_LIBTOOLFLAGS) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/bayer/gstbayerorc-dist.c b/gst/bayer/gstbayerorc-dist.c
index af75511..c9afb6a 100644
--- a/gst/bayer/gstbayerorc-dist.c
+++ b/gst/bayer/gstbayerorc-dist.c
@@ -336,7 +336,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 34, 98, 97, 121, 101, 114, 95, 111, 114, 99, 95, 104, 111, 114,
         105, 122, 95, 117, 112, 115, 97, 109, 112, 108, 101, 95, 117, 110, 97,
-            108,
+        108,
         105, 103, 110, 101, 100, 11, 2, 2, 11, 2, 2, 12, 2, 2, 14, 4,
         1, 0, 0, 0, 20, 2, 20, 1, 20, 1, 20, 1, 20, 1, 199, 34,
         33, 4, 83, 32, 4, 16, 199, 36, 35, 32, 39, 36, 34, 36, 196, 0,
diff --git a/gst/camerabin2/Makefile.am b/gst/camerabin2/Makefile.am
index db7d8c0..9254f7c 100644
--- a/gst/camerabin2/Makefile.am
+++ b/gst/camerabin2/Makefile.am
@@ -1,6 +1,7 @@
 plugin_LTLIBRARIES = libgstcamerabin2.la
 
 libgstcamerabin2_la_SOURCES = gstviewfinderbin.c \
+				gstdigitalzoom.c \
 				camerabingeneral.c \
 				gstwrappercamerabinsrc.c \
 				gstcamerabin2.c \
@@ -23,21 +24,6 @@
 
 noinst_HEADERS = gstviewfinderbin.h \
 		camerabingeneral.h \
+		gstdigitalzoom.h \
 		gstwrappercamerabinsrc.h \
 		gstcamerabin2.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstcamerabin2 -:SHARED libgstcamerabin2 \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstcamerabin2_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstcamerabin2_la_CFLAGS) \
-	 -:LDFLAGS $(libgstcamerabin2_la_LDFLAGS) \
-	           $(libgstcamerabin2_la_LIBADD) \
-	           -ldl \
-	 -:LIBFILTER_STATIC gstphotography-@GST_API_VERSION@ \
-	          gstbasecamerabinsrc-@GST_API_VERSION@ \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/camerabin2/Makefile.in b/gst/camerabin2/Makefile.in
index e09c8ff..83fd3b0 100644
--- a/gst/camerabin2/Makefile.in
+++ b/gst/camerabin2/Makefile.in
@@ -160,6 +160,7 @@
 	$(am__DEPENDENCIES_1)
 am_libgstcamerabin2_la_OBJECTS =  \
 	libgstcamerabin2_la-gstviewfinderbin.lo \
+	libgstcamerabin2_la-gstdigitalzoom.lo \
 	libgstcamerabin2_la-camerabingeneral.lo \
 	libgstcamerabin2_la-gstwrappercamerabinsrc.lo \
 	libgstcamerabin2_la-gstcamerabin2.lo \
@@ -743,6 +744,7 @@
 wayland_scanner = @wayland_scanner@
 plugin_LTLIBRARIES = libgstcamerabin2.la
 libgstcamerabin2_la_SOURCES = gstviewfinderbin.c \
+				gstdigitalzoom.c \
 				camerabingeneral.c \
 				gstwrappercamerabinsrc.c \
 				gstcamerabin2.c \
@@ -764,6 +766,7 @@
 libgstcamerabin2_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 noinst_HEADERS = gstviewfinderbin.h \
 		camerabingeneral.h \
+		gstdigitalzoom.h \
 		gstwrappercamerabinsrc.h \
 		gstcamerabin2.h
 
@@ -848,6 +851,7 @@
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstcamerabin2_la-camerabingeneral.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstcamerabin2_la-gstcamerabin2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstcamerabin2_la-gstdigitalzoom.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstcamerabin2_la-gstplugin.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstcamerabin2_la-gstviewfinderbin.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstcamerabin2_la-gstwrappercamerabinsrc.Plo@am__quote@
@@ -883,6 +887,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 $(libgstcamerabin2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstcamerabin2_la_CFLAGS) $(CFLAGS) -c -o libgstcamerabin2_la-gstviewfinderbin.lo `test -f 'gstviewfinderbin.c' || echo '$(srcdir)/'`gstviewfinderbin.c
 
+libgstcamerabin2_la-gstdigitalzoom.lo: gstdigitalzoom.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstcamerabin2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstcamerabin2_la_CFLAGS) $(CFLAGS) -MT libgstcamerabin2_la-gstdigitalzoom.lo -MD -MP -MF $(DEPDIR)/libgstcamerabin2_la-gstdigitalzoom.Tpo -c -o libgstcamerabin2_la-gstdigitalzoom.lo `test -f 'gstdigitalzoom.c' || echo '$(srcdir)/'`gstdigitalzoom.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstcamerabin2_la-gstdigitalzoom.Tpo $(DEPDIR)/libgstcamerabin2_la-gstdigitalzoom.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gstdigitalzoom.c' object='libgstcamerabin2_la-gstdigitalzoom.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 $(libgstcamerabin2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstcamerabin2_la_CFLAGS) $(CFLAGS) -c -o libgstcamerabin2_la-gstdigitalzoom.lo `test -f 'gstdigitalzoom.c' || echo '$(srcdir)/'`gstdigitalzoom.c
+
 libgstcamerabin2_la-camerabingeneral.lo: camerabingeneral.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstcamerabin2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstcamerabin2_la_CFLAGS) $(CFLAGS) -MT libgstcamerabin2_la-camerabingeneral.lo -MD -MP -MF $(DEPDIR)/libgstcamerabin2_la-camerabingeneral.Tpo -c -o libgstcamerabin2_la-camerabingeneral.lo `test -f 'camerabingeneral.c' || echo '$(srcdir)/'`camerabingeneral.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstcamerabin2_la-camerabingeneral.Tpo $(DEPDIR)/libgstcamerabin2_la-camerabingeneral.Plo
@@ -1125,22 +1136,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstcamerabin2 -:SHARED libgstcamerabin2 \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstcamerabin2_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstcamerabin2_la_CFLAGS) \
-	 -:LDFLAGS $(libgstcamerabin2_la_LDFLAGS) \
-	           $(libgstcamerabin2_la_LIBADD) \
-	           -ldl \
-	 -:LIBFILTER_STATIC gstphotography-@GST_API_VERSION@ \
-	          gstbasecamerabinsrc-@GST_API_VERSION@ \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/camerabin2/gstdigitalzoom.c b/gst/camerabin2/gstdigitalzoom.c
new file mode 100644
index 0000000..20c01be
--- /dev/null
+++ b/gst/camerabin2/gstdigitalzoom.c
@@ -0,0 +1,387 @@
+/*
+ * GStreamer
+ * Copyright (C) 2015 Thiago Santos <thiagoss@osg.samsung.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-digitalzoom
+ *
+ * Does digital zooming by cropping and scaling an image.
+ *
+ * It is a bin that contains the internal pipeline:
+ * videocrop ! videoscale ! capsfilter
+ *
+ * It keeps monitoring the input caps and when it is set/updated
+ * the capsfilter gets set the same caps to guarantee that the same
+ * input resolution is provided as output.
+ *
+ * Exposes the 'zoom' property as a float to allow setting the amount
+ * of zoom desired. Zooming is done in the center.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <gst/gst-i18n-plugin.h>
+#include "gstdigitalzoom.h"
+
+enum
+{
+  PROP_0,
+  PROP_ZOOM
+};
+
+GST_DEBUG_CATEGORY (digital_zoom_debug);
+#define GST_CAT_DEFAULT digital_zoom_debug
+
+#define gst_digital_zoom_parent_class parent_class
+G_DEFINE_TYPE (GstDigitalZoom, gst_digital_zoom, GST_TYPE_BIN);
+
+static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS_ANY);
+
+static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS_ANY);
+
+static void
+gst_digital_zoom_update_crop (GstDigitalZoom * self, GstCaps * caps)
+{
+  gint w2_crop = 0, h2_crop = 0;
+  gint left = 0;
+  gint right = 0;
+  gint top = 0;
+  gint bottom = 0;
+  gint width, height;
+  gfloat zoom;
+  GstStructure *structure;
+
+  if (caps == NULL || gst_caps_is_any (caps)) {
+    g_object_set (self->capsfilter, "caps", NULL, NULL);
+    return;
+  }
+
+  structure = gst_caps_get_structure (caps, 0);
+  gst_structure_get (structure, "width", G_TYPE_INT, &width, "height",
+      G_TYPE_INT, &height, NULL);
+
+  zoom = self->zoom;
+
+  if (self->videocrop) {
+    /* Update capsfilters to apply the zoom */
+    GST_INFO_OBJECT (self, "zoom: %f, orig size: %dx%d", zoom, width, height);
+
+    if (zoom != 1.0) {
+      w2_crop = (width - (gint) (width * 1.0 / zoom)) / 2;
+      h2_crop = (height - (gint) (height * 1.0 / zoom)) / 2;
+
+      left += w2_crop;
+      right += w2_crop;
+      top += h2_crop;
+      bottom += h2_crop;
+
+      /* force number of pixels cropped from left to be even, to avoid slow code
+       * path on videoscale */
+      left &= 0xFFFE;
+    }
+
+    GST_INFO_OBJECT (self,
+        "sw cropping: left:%d, right:%d, top:%d, bottom:%d", left, right, top,
+        bottom);
+
+    g_object_set (self->videocrop, "left", left, "right", right, "top",
+        top, "bottom", bottom, NULL);
+  }
+}
+
+static void
+gst_digital_zoom_update_zoom (GstDigitalZoom * self)
+{
+  GstCaps *caps = NULL;
+
+  if (!self->elements_created)
+    return;
+
+  g_object_get (self->capsfilter, "caps", &caps, NULL);
+  if (caps) {
+    gst_digital_zoom_update_crop (self, caps);
+    gst_caps_unref (caps);
+  }
+}
+
+static void
+gst_digital_zoom_set_property (GObject * object,
+    guint prop_id, const GValue * value, GParamSpec * pspec)
+{
+  GstDigitalZoom *self = GST_DIGITAL_ZOOM_CAST (object);
+
+  switch (prop_id) {
+    case PROP_ZOOM:
+      self->zoom = g_value_get_float (value);
+      GST_DEBUG_OBJECT (self, "Setting zoom: %f", self->zoom);
+      gst_digital_zoom_update_zoom (self);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_digital_zoom_get_property (GObject * object,
+    guint prop_id, GValue * value, GParamSpec * pspec)
+{
+  GstDigitalZoom *self = GST_DIGITAL_ZOOM_CAST (object);
+
+  switch (prop_id) {
+    case PROP_ZOOM:
+      g_value_set_float (value, self->zoom);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
+      break;
+  }
+}
+
+static gboolean
+gst_digital_zoom_sink_query (GstPad * sink, GstObject * parent,
+    GstQuery * query)
+{
+  GstDigitalZoom *self = GST_DIGITAL_ZOOM_CAST (parent);
+  switch (GST_QUERY_TYPE (query)) {
+      /* for caps related queries we want to skip videocrop ! videoscale
+       * as the digital zoom preserves input dimensions */
+    case GST_QUERY_CAPS:
+    case GST_QUERY_ACCEPT_CAPS:
+      if (self->elements_created)
+        return gst_pad_peer_query (self->srcpad, query);
+      /* fall through */
+    default:
+      return gst_pad_query_default (sink, parent, query);
+  }
+}
+
+static gboolean
+gst_digital_zoom_src_query (GstPad * sink, GstObject * parent, GstQuery * query)
+{
+  GstDigitalZoom *self = GST_DIGITAL_ZOOM_CAST (parent);
+  switch (GST_QUERY_TYPE (query)) {
+      /* for caps related queries we want to skip videocrop ! videoscale
+       * as the digital zoom preserves input dimensions */
+    case GST_QUERY_CAPS:
+    case GST_QUERY_ACCEPT_CAPS:
+      if (self->elements_created)
+        return gst_pad_peer_query (self->sinkpad, query);
+      /* fall through */
+    default:
+      return gst_pad_query_default (sink, parent, query);
+  }
+}
+
+static gboolean
+gst_digital_zoom_sink_event (GstPad * sink, GstObject * parent,
+    GstEvent * event)
+{
+  gboolean ret;
+  gboolean is_caps;
+  GstDigitalZoom *self = GST_DIGITAL_ZOOM_CAST (parent);
+  GstCaps *old_caps = NULL;
+  GstCaps *caps = NULL;
+
+  is_caps = GST_EVENT_TYPE (event) == GST_EVENT_CAPS;
+
+  if (is_caps) {
+    gst_event_parse_caps (event, &caps);
+    g_object_get (self->capsfilter, "caps", &old_caps, NULL);
+    g_object_set (self->capsfilter, "caps", caps, NULL);
+    gst_digital_zoom_update_crop (self, caps);
+  }
+
+  ret = gst_pad_event_default (sink, parent, event);
+
+  if (is_caps) {
+    if (!ret) {
+      gst_digital_zoom_update_crop (self, old_caps);
+      g_object_set (self->capsfilter, "caps", old_caps, NULL);
+    }
+
+    if (old_caps)
+      gst_caps_unref (old_caps);
+  }
+
+  return ret;
+}
+
+static void
+gst_digital_zoom_dispose (GObject * object)
+{
+  GstDigitalZoom *self = GST_DIGITAL_ZOOM_CAST (object);
+
+  if (self->capsfilter_sinkpad) {
+    gst_object_unref (self->capsfilter_sinkpad);
+    self->capsfilter_sinkpad = NULL;
+  }
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gst_digital_zoom_init (GstDigitalZoom * self)
+{
+  GstPadTemplate *tmpl;
+
+  tmpl = gst_static_pad_template_get (&src_template);
+  self->srcpad = gst_ghost_pad_new_no_target_from_template ("src", tmpl);
+  gst_element_add_pad (GST_ELEMENT (self), self->srcpad);
+  gst_object_unref (tmpl);
+
+  tmpl = gst_static_pad_template_get (&sink_template);
+  self->sinkpad = gst_ghost_pad_new_no_target_from_template ("sink", tmpl);
+  gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);
+  gst_object_unref (tmpl);
+
+  gst_pad_set_event_function (self->sinkpad,
+      GST_DEBUG_FUNCPTR (gst_digital_zoom_sink_event));
+  gst_pad_set_query_function (self->sinkpad,
+      GST_DEBUG_FUNCPTR (gst_digital_zoom_sink_query));
+
+  gst_pad_set_query_function (self->srcpad,
+      GST_DEBUG_FUNCPTR (gst_digital_zoom_src_query));
+
+  self->zoom = 1;
+}
+
+static GstElement *
+zoom_create_element (GstDigitalZoom * self, const gchar * element_name,
+    const gchar * name)
+{
+  GstElement *element;
+  element = gst_element_factory_make (element_name, name);
+  if (element == NULL) {
+    GST_ELEMENT_ERROR (self, CORE, MISSING_PLUGIN,
+        (_("Missing element '%s' - check your GStreamer installation."),
+            element_name), (NULL));
+  }
+  return element;
+}
+
+static gboolean
+gst_digital_zoom_create_elements (GstDigitalZoom * self)
+{
+  GstPad *pad;
+
+  if (self->elements_created)
+    return TRUE;
+
+  self->videocrop = zoom_create_element (self, "videocrop", "zoom-videocrop");
+  if (self->videocrop == NULL)
+    return FALSE;
+  if (!gst_bin_add (GST_BIN_CAST (self), self->videocrop))
+    return FALSE;
+
+  self->videoscale =
+      zoom_create_element (self, "videoscale", "zoom-videoscale");
+  if (self->videoscale == NULL)
+    return FALSE;
+  if (!gst_bin_add (GST_BIN_CAST (self), self->videoscale))
+    return FALSE;
+
+  self->capsfilter =
+      zoom_create_element (self, "capsfilter", "zoom-capsfilter");
+  if (self->capsfilter == NULL)
+    return FALSE;
+  if (!gst_bin_add (GST_BIN_CAST (self), self->capsfilter))
+    return FALSE;
+
+  if (!gst_element_link_pads_full (self->videocrop, "src", self->videoscale,
+          "sink", GST_PAD_LINK_CHECK_CAPS))
+    return FALSE;
+  if (!gst_element_link_pads_full (self->videoscale, "src", self->capsfilter,
+          "sink", GST_PAD_LINK_CHECK_CAPS))
+    return FALSE;
+
+  pad = gst_element_get_static_pad (self->videocrop, "sink");
+  gst_ghost_pad_set_target (GST_GHOST_PAD (self->sinkpad), pad);
+  gst_object_unref (pad);
+
+  pad = gst_element_get_static_pad (self->capsfilter, "src");
+  gst_ghost_pad_set_target (GST_GHOST_PAD (self->srcpad), pad);
+  gst_object_unref (pad);
+
+  self->capsfilter_sinkpad =
+      gst_element_get_static_pad (self->capsfilter, "sink");
+
+  self->elements_created = TRUE;
+  return TRUE;
+}
+
+static GstStateChangeReturn
+gst_digital_zoom_change_state (GstElement * element, GstStateChange trans)
+{
+  GstDigitalZoom *self = GST_DIGITAL_ZOOM_CAST (element);
+
+  switch (trans) {
+    case GST_STATE_CHANGE_NULL_TO_READY:
+      if (!gst_digital_zoom_create_elements (self)) {
+        return GST_STATE_CHANGE_FAILURE;
+      }
+      break;
+    default:
+      break;
+  }
+
+  return GST_ELEMENT_CLASS (parent_class)->change_state (element, trans);
+}
+
+static void
+gst_digital_zoom_class_init (GstDigitalZoomClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gstelement_class = GST_ELEMENT_CLASS (klass);
+
+  gobject_class->dispose = gst_digital_zoom_dispose;
+  gobject_class->set_property = gst_digital_zoom_set_property;
+  gobject_class->get_property = gst_digital_zoom_get_property;
+
+  /* g_object_class_install_property .... */
+  g_object_class_install_property (gobject_class, PROP_ZOOM,
+      g_param_spec_float ("zoom", "Zoom",
+          "Digital zoom level to be used", 1.0, G_MAXFLOAT, 1.0,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  gstelement_class->change_state = gst_digital_zoom_change_state;
+
+  GST_DEBUG_CATEGORY_INIT (digital_zoom_debug, "digitalzoom",
+      0, "digital zoom");
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sink_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&src_template));
+
+  gst_element_class_set_static_metadata (gstelement_class,
+      "Digital zoom bin", "Generic/Video",
+      "Digital zoom bin", "Thiago Santos <thiagoss@osg.samsung.com>");
+}
diff --git a/gst/camerabin2/gstdigitalzoom.h b/gst/camerabin2/gstdigitalzoom.h
new file mode 100644
index 0000000..de7a300
--- /dev/null
+++ b/gst/camerabin2/gstdigitalzoom.h
@@ -0,0 +1,79 @@
+/*
+ * GStreamer
+ * Copyright (C) 2015 Thiago Santos <thiagoss@osg.samsung.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_DIGITAL_ZOOM_H__
+#define __GST_DIGITAL_ZOOM_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_DIGITAL_ZOOM \
+  (gst_digital_zoom_get_type())
+#define GST_DIGITAL_ZOOM(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DIGITAL_ZOOM,GstDigitalZoom))
+#define GST_DIGITAL_ZOOM_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DIGITAL_ZOOM,GstDigitalZoomClass))
+#define GST_IS_DIGITAL_ZOOM(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DIGITAL_ZOOM))
+#define GST_IS_DIGITAL_ZOOM_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DIGITAL_ZOOM))
+#define GST_DIGITAL_ZOOM_CAST(d) ((GstDigitalZoom *)(d))
+
+GType gst_digital_zoom_get_type (void);
+
+typedef struct _GstDigitalZoom GstDigitalZoom;
+typedef struct _GstDigitalZoomClass GstDigitalZoomClass;
+
+/**
+ * GstDigitalZoom:
+ *
+ */
+struct _GstDigitalZoom
+{
+  GstBin parent;
+
+  GstPad *srcpad;
+  GstPad *sinkpad;
+
+  gboolean elements_created;
+  GstElement *videocrop;
+  GstElement *videoscale;
+  GstElement *capsfilter;
+
+  GstPad *capsfilter_sinkpad;
+
+  gfloat zoom;
+};
+
+
+/**
+ * GstDigitalZoomClass:
+ *
+ */
+struct _GstDigitalZoomClass
+{
+  GstBinClass parent;
+};
+
+G_END_DECLS
+
+#endif /* __GST_DIGITAL_ZOOM_H__ */
diff --git a/gst/camerabin2/gstwrappercamerabinsrc.c b/gst/camerabin2/gstwrappercamerabinsrc.c
index 25643f3..40d7858 100644
--- a/gst/camerabin2/gstwrappercamerabinsrc.c
+++ b/gst/camerabin2/gstwrappercamerabinsrc.c
@@ -32,8 +32,10 @@
 #endif
 
 #include <gst/interfaces/photography.h>
+#include <gst/gst-i18n-plugin.h>
 
 #include "gstwrappercamerabinsrc.h"
+#include "gstdigitalzoom.h"
 #include "camerabingeneral.h"
 
 enum
@@ -76,13 +78,17 @@
 {
   GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (object);
 
-  if (self->outsel_imgpad) {
-    gst_object_unref (self->outsel_imgpad);
-    self->outsel_imgpad = NULL;
+  if (self->src_pad) {
+    gst_object_unref (self->src_pad);
+    self->src_pad = NULL;
   }
-  if (self->outsel_vidpad) {
-    gst_object_unref (self->outsel_vidpad);
-    self->outsel_vidpad = NULL;
+  if (self->video_tee_sink) {
+    gst_object_unref (self->video_tee_sink);
+    self->video_tee_sink = NULL;
+  }
+  if (self->video_tee_vf_pad) {
+    gst_object_unref (self->video_tee_vf_pad);
+    self->video_tee_vf_pad = NULL;
   }
   if (self->app_vid_src) {
     gst_object_unref (self->app_vid_src);
@@ -172,6 +178,15 @@
 }
 
 static void
+gst_wrapper_camera_bin_src_reset_src_zoom (GstWrapperCameraBinSrc * self)
+{
+  if (self->src_crop) {
+    g_object_set (self->src_crop, "top", 0, "left", 0, "bottom", 0, "right", 0,
+        NULL);
+  }
+}
+
+static void
 gst_wrapper_camera_bin_reset_video_src_caps (GstWrapperCameraBinSrc * self,
     GstCaps * new_filter_caps)
 {
@@ -182,7 +197,7 @@
     gboolean ret = FALSE;
 
     /* After pipe was negotiated src_filter do not have any filter caps.
-     * In this situation we should compare neogotiated caps on capsfilter pad
+     * In this situation we should compare negotiated caps on capsfilter pad
      * with requested range of caps. If one of this caps intersect,
      * then we can avoid reseting.
      */
@@ -215,6 +230,20 @@
   }
 }
 
+static void
+gst_wrapper_camera_bin_src_set_output (GstWrapperCameraBinSrc * self,
+    GstPad * old_pad, GstPad * output_pad)
+{
+  GstQuery *drain = gst_query_new_drain ();
+  gst_pad_peer_query (self->src_pad, drain);
+  gst_query_unref (drain);
+
+  if (old_pad)
+    gst_ghost_pad_set_target (GST_GHOST_PAD (old_pad), NULL);
+  if (output_pad)
+    gst_ghost_pad_set_target (GST_GHOST_PAD (output_pad), self->src_pad);
+}
+
 /**
  * gst_wrapper_camera_bin_src_imgsrc_probe:
  *
@@ -251,7 +280,15 @@
     gst_sample_unref (sample);
 
     if (self->image_capture_count == 0) {
+      GstCaps *anycaps = gst_caps_new_any ();
+
+      /* Get back to viewfinder */
+      gst_wrapper_camera_bin_src_reset_src_zoom (self);
+      gst_wrapper_camera_bin_reset_video_src_caps (self, anycaps);
+      gst_wrapper_camera_bin_src_set_output (self, self->imgsrc, self->vfsrc);
       gst_base_camera_src_finish_capture (camerasrc);
+
+      gst_caps_unref (anycaps);
     }
   }
   g_mutex_unlock (&camerasrc->capturing_mutex);
@@ -261,7 +298,7 @@
 /**
  * gst_wrapper_camera_bin_src_vidsrc_probe:
  *
- * Buffer probe called before sending each buffer to image queue.
+ * Buffer probe called before sending each buffer to video queue.
  */
 static GstPadProbeReturn
 gst_wrapper_camera_bin_src_vidsrc_probe (GstPad * pad, GstPadProbeInfo * info,
@@ -325,6 +362,9 @@
       GST_WARNING_OBJECT (camerasrc, "No peer pad for vidsrc");
     }
     self->video_rec_status = GST_VIDEO_RECORDING_STATUS_DONE;
+
+    gst_pad_unlink (self->src_pad, self->video_tee_sink);
+    gst_wrapper_camera_bin_src_set_output (self, self->vfsrc, self->vfsrc);
     gst_base_camera_src_finish_capture (camerasrc);
   } else {
     ret = GST_PAD_PROBE_OK;
@@ -333,27 +373,6 @@
   return ret;
 }
 
-static GstPadProbeReturn
-gst_wrapper_camera_src_src_event_probe (GstPad * pad, GstPadProbeInfo * info,
-    gpointer udata)
-{
-  GstPadProbeReturn ret = GST_PAD_PROBE_OK;
-  GstWrapperCameraBinSrc *self = udata;
-  GstEvent *evt = GST_EVENT (info->data);
-
-  switch (GST_EVENT_TYPE (evt)) {
-    case GST_EVENT_SEGMENT:
-      if (self->drop_newseg) {
-        ret = GST_PAD_PROBE_DROP;
-        self->drop_newseg = FALSE;
-      }
-      break;
-    default:
-      break;
-  }
-  return ret;
-}
-
 static void
 gst_wrapper_camera_bin_src_caps_cb (GstPad * pad, GParamSpec * pspec,
     gpointer user_data)
@@ -381,20 +400,6 @@
   /* Update zoom */
   gst_base_camera_src_setup_zoom (bcamsrc);
 
-  /* Update post-zoom capsfilter */
-  if (self->src_zoom_filter) {
-    GstCaps *filtercaps;
-
-    g_object_get (G_OBJECT (self->src_zoom_filter), "caps", &filtercaps, NULL);
-
-    if (caps != filtercaps && (caps == NULL || filtercaps == NULL ||
-            !gst_caps_is_equal (filtercaps, caps)))
-      g_object_set (G_OBJECT (self->src_zoom_filter), "caps", caps, NULL);
-
-    if (filtercaps)
-      gst_caps_unref (filtercaps);
-  }
-
   if (caps)
     gst_caps_unref (caps);
 };
@@ -409,14 +414,12 @@
   g_object_notify (G_OBJECT (bcamsrc), "max-zoom");
 }
 
-
 static gboolean
 gst_wrapper_camera_bin_src_src_event (GstPad * pad, GstObject * parent,
     GstEvent * event)
 {
   gboolean ret = TRUE;
   GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (parent);
-  GstPad *upstream_pad = NULL;
 
   GST_DEBUG_OBJECT (self, "Handling event %p %" GST_PTR_FORMAT, event, event);
 
@@ -435,24 +438,10 @@
       }
       break;
     default:
+      ret = gst_pad_event_default (pad, parent, event);
       break;
   }
 
-  if (pad == self->imgsrc) {
-    upstream_pad = self->outsel_imgpad;
-  } else if (pad == self->vidsrc) {
-    upstream_pad = self->outsel_vidpad;
-  }
-
-  if (upstream_pad) {
-    ret = gst_pad_send_event (upstream_pad, event);
-  } else {
-    GST_WARNING_OBJECT (self, "Event caught that doesn't have an upstream pad -"
-        "this shouldn't be possible!");
-    gst_event_unref (event);
-    ret = FALSE;
-  }
-
   return ret;
 }
 
@@ -467,7 +456,6 @@
 {
   GstBin *cbin = GST_BIN_CAST (self);
   GstBaseCameraSrc *bcamsrc = GST_BASE_CAMERA_SRC_CAST (self);
-  GstElement *videoconvert;
 
   if (self->src_vid_src && self->src_vid_src == self->app_vid_src) {
     GST_DEBUG_OBJECT (self, "No need to change current videosrc");
@@ -499,21 +487,19 @@
               self->app_vid_src, "autovideosrc", DEFAULT_VIDEOSRC,
               "camerasrc-real-src"))) {
     self->src_vid_src = NULL;
-    return FALSE;
+    goto fail;
   }
 
   if (!gst_bin_add (cbin, self->src_vid_src)) {
-    return FALSE;
+    goto fail;
   }
 
   /* check if we already have the next element to link to */
-  videoconvert = gst_bin_get_by_name (cbin, "src-videoconvert");
-  if (videoconvert) {
-    if (!gst_element_link_pads (self->src_vid_src, "src", videoconvert, "sink")) {
-      gst_object_unref (videoconvert);
-      return FALSE;
+  if (self->src_crop) {
+    if (!gst_element_link_pads (self->src_vid_src, "src", self->src_crop,
+            "sink")) {
+      goto fail;
     }
-    gst_object_unref (videoconvert);
   }
 
   /* we listen for changes to max-zoom in the video src so that
@@ -524,17 +510,12 @@
         (GCallback) gst_wrapper_camera_bin_src_max_zoom_cb, bcamsrc);
   }
 
-  /* add a buffer probe to the src elemento to drop EOS from READY->NULL */
-  {
-    GstPad *pad;
-    pad = gst_element_get_static_pad (self->src_vid_src, "src");
-
-    self->src_event_probe_id =
-        gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
-        gst_wrapper_camera_src_src_event_probe, self, NULL);
-    gst_object_unref (pad);
-  }
   return TRUE;
+
+fail:
+  if (self->src_vid_src)
+    gst_element_set_state (self->src_vid_src, GST_STATE_NULL);
+  return FALSE;
 }
 
 /**
@@ -543,11 +524,7 @@
  *
  * This function creates and links the elements of the camerasrc bin
  * videosrc ! cspconv ! srcfilter ! cspconv ! capsfilter ! crop ! scale ! \
- * capsfilter ! tee name=t
- *    t. ! ... (viewfinder pad)
- *    t. ! output-selector name=outsel
- *        outsel. ! (image pad)
- *        outsel. ! (video pad)
+ * capsfilter
  *
  * Returns: TRUE, if elements were successfully created, FALSE otherwise
  */
@@ -556,13 +533,12 @@
 {
   GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (bcamsrc);
   GstBin *cbin = GST_BIN (bcamsrc);
-  GstElement *tee;
   GstElement *filter_csp;
   GstElement *src_csp;
   GstElement *capsfilter;
+  GstElement *video_recording_tee;
   gboolean ret = FALSE;
-  GstPad *vf_pad;
-  GstPad *tee_capture_pad;
+  GstPad *tee_pad;
 
   /* checks and adds a new video src if needed */
   if (!check_and_replace_src (self))
@@ -572,6 +548,11 @@
 
     GST_DEBUG_OBJECT (self, "constructing pipeline");
 
+    if (!(self->src_crop =
+            gst_camerabin_create_and_add_element (cbin, "videocrop",
+                "src-crop")))
+      goto done;
+
     if (!gst_camerabin_create_and_add_element (cbin, "videoconvert",
             "src-videoconvert"))
       goto done;
@@ -598,77 +579,41 @@
     g_signal_connect (self->srcfilter_pad, "notify::caps",
         G_CALLBACK (gst_wrapper_camera_bin_src_caps_cb), self);
 
-    if (!(self->src_zoom_crop =
-            gst_camerabin_create_and_add_element (cbin, "videocrop",
-                "zoom-crop")))
+    if (!(self->digitalzoom = g_object_new (GST_TYPE_DIGITAL_ZOOM, NULL))) {
+      GST_ELEMENT_ERROR (self, CORE, MISSING_PLUGIN,
+          (_("Digitalzoom element cound't be created")), (NULL));
+
       goto done;
-    if (!(self->src_zoom_scale =
-            gst_camerabin_create_and_add_element (cbin, "videoscale",
-                "zoom-scale")))
-      goto done;
-    if (!(self->src_zoom_filter =
-            gst_camerabin_create_and_add_element (cbin, "capsfilter",
-                "zoom-capsfilter")))
+    }
+    if (!gst_camerabin_add_element_full (GST_BIN_CAST (self), NULL,
+            self->digitalzoom, "sink"))
       goto done;
 
-    if (!(tee =
-            gst_camerabin_create_and_add_element (cbin, "tee",
-                "camerasrc-tee")))
-      goto done;
+    /* keep a 'tee' element that has 2 source pads, one is linked to the
+     * vidsrc pad and the other is linked as needed to the viewfinder
+     * when video recording is hapenning */
+    video_recording_tee = gst_element_factory_make ("tee", "video_rec_tee");
+    gst_bin_add (GST_BIN_CAST (self), video_recording_tee);     /* TODO check returns */
+    self->video_tee_vf_pad =
+        gst_element_get_request_pad (video_recording_tee, "src_%u");
+    self->video_tee_sink =
+        gst_element_get_static_pad (video_recording_tee, "sink");
+    tee_pad = gst_element_get_request_pad (video_recording_tee, "src_%u");
+    gst_ghost_pad_set_target (GST_GHOST_PAD (self->vidsrc), tee_pad);
+    gst_object_unref (tee_pad);
 
     /* viewfinder pad */
-    vf_pad = gst_element_get_request_pad (tee, "src_%u");
-    g_object_set (tee, "alloc-pad", vf_pad, NULL);
-    gst_ghost_pad_set_target (GST_GHOST_PAD (self->vfsrc), vf_pad);
-    gst_object_unref (vf_pad);
-
-    /* image/video pad from tee */
-    tee_capture_pad = gst_element_get_request_pad (tee, "src_%u");
-
-    self->output_selector =
-        gst_element_factory_make ("output-selector", "outsel");
-    g_object_set (self->output_selector, "pad-negotiation-mode", 2, NULL);
-    gst_bin_add (GST_BIN (self), self->output_selector);
-    {
-      GstPad *pad = gst_element_get_static_pad (self->output_selector, "sink");
-
-      /* check return TODO */
-      gst_pad_link (tee_capture_pad, pad);
-      gst_object_unref (pad);
-    }
-    gst_object_unref (tee_capture_pad);
-
-    /* Create the 2 output pads for video and image */
-    self->outsel_vidpad =
-        gst_element_get_request_pad (self->output_selector, "src_%u");
-    self->outsel_imgpad =
-        gst_element_get_request_pad (self->output_selector, "src_%u");
-
-    g_assert (self->outsel_vidpad != NULL);
-    g_assert (self->outsel_imgpad != NULL);
-
-    gst_pad_add_probe (self->outsel_imgpad, GST_PAD_PROBE_TYPE_BUFFER,
-        gst_wrapper_camera_bin_src_imgsrc_probe, self, NULL);
-    gst_pad_add_probe (self->outsel_vidpad, GST_PAD_PROBE_TYPE_BUFFER,
-        gst_wrapper_camera_bin_src_vidsrc_probe, self, NULL);
-    gst_ghost_pad_set_target (GST_GHOST_PAD (self->imgsrc),
-        self->outsel_imgpad);
-    gst_ghost_pad_set_target (GST_GHOST_PAD (self->vidsrc),
-        self->outsel_vidpad);
-
-    if (bcamsrc->mode == MODE_IMAGE) {
-      g_object_set (self->output_selector, "active-pad", self->outsel_imgpad,
-          NULL);
-    } else {
-      g_object_set (self->output_selector, "active-pad", self->outsel_vidpad,
-          NULL);
-    }
-
-
+    self->src_pad = gst_element_get_static_pad (self->digitalzoom, "src");
+    gst_ghost_pad_set_target (GST_GHOST_PAD (self->vfsrc), self->src_pad);
 
     gst_pad_set_active (self->vfsrc, TRUE);
     gst_pad_set_active (self->imgsrc, TRUE);    /* XXX ??? */
     gst_pad_set_active (self->vidsrc, TRUE);    /* XXX ??? */
+
+    gst_pad_add_probe (self->imgsrc, GST_PAD_PROBE_TYPE_BUFFER,
+        gst_wrapper_camera_bin_src_imgsrc_probe, self, NULL);
+    gst_pad_add_probe (self->video_tee_sink, GST_PAD_PROBE_TYPE_BUFFER,
+        gst_wrapper_camera_bin_src_vidsrc_probe, self, NULL);
   }
 
   /* Do this even if pipeline is constructed */
@@ -712,19 +657,6 @@
   return ret;
 }
 
-static gboolean
-copy_missing_fields (GQuark field_id, const GValue * value, gpointer user_data)
-{
-  GstStructure *st = (GstStructure *) user_data;
-  const GValue *val = gst_structure_id_get_value (st, field_id);
-
-  if (G_UNLIKELY (val == NULL)) {
-    gst_structure_id_set_value (st, field_id, value);
-  }
-
-  return TRUE;
-}
-
 /**
  * adapt_image_capture:
  * @self: camerasrc object
@@ -738,11 +670,9 @@
 static void
 adapt_image_capture (GstWrapperCameraBinSrc * self, GstCaps * in_caps)
 {
-  GstBaseCameraSrc *bcamsrc = GST_BASE_CAMERA_SRC (self);
-  GstStructure *in_st, *new_st, *req_st;
+  GstStructure *in_st, *req_st;
   gint in_width = 0, in_height = 0, req_width = 0, req_height = 0, crop = 0;
   gdouble ratio_w, ratio_h;
-  GstCaps *filter_caps = NULL;
 
   GST_LOG_OBJECT (self, "in caps: %" GST_PTR_FORMAT, in_caps);
   GST_LOG_OBJECT (self, "requested caps: %" GST_PTR_FORMAT,
@@ -759,63 +689,34 @@
   GST_INFO_OBJECT (self, "we requested %dx%d, and got %dx%d", req_width,
       req_height, in_width, in_height);
 
-  new_st = gst_structure_copy (req_st);
-  /* If new fields have been added, we need to copy them */
-  gst_structure_foreach (in_st, copy_missing_fields, new_st);
-
-  gst_structure_set (new_st, "width", G_TYPE_INT, in_width, "height",
-      G_TYPE_INT, in_height, NULL);
-
-  GST_LOG_OBJECT (self, "new image capture caps: %" GST_PTR_FORMAT, new_st);
-
   /* Crop if requested aspect ratio differs from incoming frame aspect ratio */
-  if (self->src_zoom_crop) {
+  if (self->src_crop) {
+    gint base_crop_top = 0, base_crop_bottom = 0;
+    gint base_crop_left = 0, base_crop_right = 0;
 
     ratio_w = (gdouble) in_width / req_width;
     ratio_h = (gdouble) in_height / req_height;
 
     if (ratio_w < ratio_h) {
       crop = in_height - (req_height * ratio_w);
-      self->base_crop_top = crop / 2;
-      self->base_crop_bottom = crop / 2;
+      base_crop_top = crop / 2;
+      base_crop_bottom = crop / 2;
     } else {
       crop = in_width - (req_width * ratio_h);
-      self->base_crop_left = crop / 2;
-      self->base_crop_right += crop / 2;
+      base_crop_left = crop / 2;
+      base_crop_right += crop / 2;
     }
 
     GST_INFO_OBJECT (self,
         "setting base crop: left:%d, right:%d, top:%d, bottom:%d",
-        self->base_crop_left, self->base_crop_right, self->base_crop_top,
-        self->base_crop_bottom);
-    g_object_set (G_OBJECT (self->src_zoom_crop),
-        "top", self->base_crop_top,
-        "bottom", self->base_crop_bottom,
-        "left", self->base_crop_left, "right", self->base_crop_right, NULL);
+        base_crop_left, base_crop_right, base_crop_top, base_crop_bottom);
+    g_object_set (G_OBJECT (self->src_crop),
+        "top", base_crop_top, "bottom", base_crop_bottom,
+        "left", base_crop_left, "right", base_crop_right, NULL);
   }
 
   /* Update capsfilters */
-  if (self->image_capture_caps) {
-    gst_caps_unref (self->image_capture_caps);
-  }
-  self->image_capture_caps = gst_caps_new_full (new_st, NULL);
   set_capsfilter_caps (self, self->image_capture_caps);
-
-  /* Adjust the capsfilter before crop and videoscale elements if necessary */
-  if (in_width == bcamsrc->width && in_height == bcamsrc->height) {
-    GST_DEBUG_OBJECT (self, "no adaptation with resolution needed");
-  } else {
-    GST_DEBUG_OBJECT (self,
-        "changing %" GST_PTR_FORMAT " from %dx%d to %dx%d", self->src_filter,
-        bcamsrc->width, bcamsrc->height, in_width, in_height);
-    /* Apply the width and height to filter caps */
-    g_object_get (G_OBJECT (self->src_filter), "caps", &filter_caps, NULL);
-    filter_caps = gst_caps_make_writable (filter_caps);
-    gst_caps_set_simple (filter_caps, "width", G_TYPE_INT, in_width, "height",
-        G_TYPE_INT, in_height, NULL);
-    g_object_set (G_OBJECT (self->src_filter), "caps", filter_caps, NULL);
-    gst_caps_unref (filter_caps);
-  }
 }
 
 /**
@@ -833,83 +734,101 @@
   GST_INFO_OBJECT (self, "image capture prepared");
 
   /* It is possible we are about to get something else that we requested */
-  if (!gst_caps_is_equal (self->image_capture_caps, caps)) {
+  if (!gst_caps_can_intersect (self->image_capture_caps, caps)) {
     adapt_image_capture (self, caps);
   } else {
     set_capsfilter_caps (self, self->image_capture_caps);
   }
 }
 
-/**
- *
- */
-static gboolean
-start_image_capture (GstWrapperCameraBinSrc * self)
+static GstPadProbeReturn
+start_image_capture (GstPad * pad, GstPadProbeInfo * info, gpointer udata)
 {
+  GstWrapperCameraBinSrc *self = udata;
   GstBaseCameraSrc *bcamsrc = GST_BASE_CAMERA_SRC (self);
   GstPhotography *photography =
       (GstPhotography *) gst_bin_get_by_interface (GST_BIN_CAST (bcamsrc),
       GST_TYPE_PHOTOGRAPHY);
-  gboolean ret = FALSE;
   GstCaps *caps;
 
   GST_DEBUG_OBJECT (self, "Starting image capture");
 
-  /* V4L2 source will not close the device until all buffers have came
-   * back. Draining the pipeline, will ensure it's properly closed, and that
-   * setting it back to PLAYING will work. */
+  /* unlink from the viewfinder, link to the imagesrc pad to wait for
+   * the buffer to pass */
+  gst_wrapper_camera_bin_src_set_output (self, self->vfsrc, self->imgsrc);
+
   if (self->image_renegotiate) {
-    GstPad *pad, *peer;
-
-    g_mutex_unlock (&bcamsrc->capturing_mutex);
-    pad = gst_element_get_static_pad (self->src_vid_src, "src");
-    peer = gst_pad_get_peer (pad);
-    gst_object_unref (pad);
-    gst_pad_query (peer, gst_query_new_drain ());
-    gst_object_unref (peer);
-
     self->image_renegotiate = FALSE;
 
-    gst_element_set_state (self->src_vid_src, GST_STATE_READY);
-
     /* clean capsfilter caps so they don't interfere here */
     g_object_set (self->src_filter, "caps", NULL, NULL);
-    if (self->src_zoom_filter)
-      g_object_set (self->src_zoom_filter, "caps", NULL, NULL);
 
     caps = gst_pad_get_allowed_caps (self->imgsrc);
-
     gst_caps_replace (&self->image_capture_caps, caps);
     gst_caps_unref (caps);
 
-    /* FIXME - do we need to update basecamerasrc width/height somehow here?
-     * if not, i think we need to do something about _when_ they get updated
-     * to be sure that set_element_zoom doesn't use the wrong values */
-
     /* We caught this event in the src pad event handler and now we want to
      * actually push it upstream */
-    gst_pad_send_event (self->outsel_imgpad, gst_event_new_reconfigure ());
-    g_mutex_lock (&bcamsrc->capturing_mutex);
+    gst_pad_mark_reconfigure (pad);
   }
 
   if (photography) {
-    gst_element_set_state (self->src_vid_src, GST_STATE_PLAYING);
     GST_DEBUG_OBJECT (self, "prepare image capture caps %" GST_PTR_FORMAT,
         self->image_capture_caps);
-    ret = gst_photography_prepare_for_capture (photography,
-        (GstPhotographyCapturePrepared) img_capture_prepared,
-        self->image_capture_caps, self);
+    if (!gst_photography_prepare_for_capture (photography,
+            (GstPhotographyCapturePrepared) img_capture_prepared,
+            self->image_capture_caps, self)) {
+      GST_ELEMENT_ERROR (self, CORE, NEGOTIATION,
+          ("Failed to prepare image capture"),
+          ("Prepare capture call didn't succeed for the given caps"));
+      self->image_capture_count = 0;
+    }
     gst_object_unref (photography);
   } else {
-    g_mutex_unlock (&bcamsrc->capturing_mutex);
     gst_wrapper_camera_bin_reset_video_src_caps (self,
         self->image_capture_caps);
-    g_mutex_lock (&bcamsrc->capturing_mutex);
-    ret = TRUE;
-    gst_element_set_state (self->src_vid_src, GST_STATE_PLAYING);
   }
 
-  return ret;
+  self->image_capture_probe = 0;
+  return GST_PAD_PROBE_REMOVE;
+}
+
+static GstPadProbeReturn
+start_video_capture (GstPad * pad, GstPadProbeInfo * info, gpointer udata)
+{
+  GstWrapperCameraBinSrc *self = udata;
+  GstCaps *caps;
+
+  GST_DEBUG_OBJECT (self, "Starting video capture");
+
+  if (self->video_renegotiate) {
+    GstCaps *anycaps = gst_caps_new_any ();
+    gst_wrapper_camera_bin_reset_video_src_caps (self, anycaps);
+    gst_caps_unref (anycaps);
+
+    /* clean capsfilter caps so they don't interfere here */
+    g_object_set (self->src_filter, "caps", NULL, NULL);
+  }
+
+  /* unlink from the viewfinder, link to the imagesrc pad, wait for
+   * the buffer to pass */
+  gst_wrapper_camera_bin_src_set_output (self, self->vfsrc, NULL);
+  gst_pad_link (self->src_pad, self->video_tee_sink);
+  gst_ghost_pad_set_target (GST_GHOST_PAD (self->vfsrc),
+      self->video_tee_vf_pad);
+
+  if (self->video_renegotiate) {
+    GST_DEBUG_OBJECT (self, "Getting allowed videosrc caps");
+    caps = gst_pad_get_allowed_caps (self->vidsrc);
+    GST_DEBUG_OBJECT (self, "Video src caps %" GST_PTR_FORMAT, caps);
+
+    self->video_renegotiate = FALSE;
+    gst_wrapper_camera_bin_reset_video_src_caps (self, caps);
+    gst_caps_unref (caps);
+  }
+  self->video_capture_probe = 0;
+
+  return GST_PAD_PROBE_REMOVE;
 }
 
 static gboolean
@@ -921,16 +840,10 @@
       GST_TYPE_PHOTOGRAPHY);
   GstWrapperCameraBinSrc *self = GST_WRAPPER_CAMERA_BIN_SRC (bcamsrc);
 
-  if (self->output_selector) {
-    if (mode == MODE_IMAGE) {
-      self->image_renegotiate = TRUE;
-      g_object_set (self->output_selector, "active-pad", self->outsel_imgpad,
-          NULL);
-    } else {
-      self->video_renegotiate = TRUE;
-      g_object_set (self->output_selector, "active-pad", self->outsel_vidpad,
-          NULL);
-    }
+  if (mode == MODE_IMAGE) {
+    self->image_renegotiate = TRUE;
+  } else {
+    self->video_renegotiate = TRUE;
   }
   self->mode = mode;
 
@@ -962,54 +875,6 @@
   return ret;
 }
 
-static gboolean
-set_element_zoom (GstWrapperCameraBinSrc * self, gfloat zoom)
-{
-  gboolean ret = FALSE;
-  GstBaseCameraSrc *bcamsrc = GST_BASE_CAMERA_SRC (self);
-  gint w2_crop = 0, h2_crop = 0;
-  GstPad *pad_zoom_sink = NULL;
-  gint left = self->base_crop_left;
-  gint right = self->base_crop_right;
-  gint top = self->base_crop_top;
-  gint bottom = self->base_crop_bottom;
-
-  if (self->src_zoom_crop) {
-    /* Update capsfilters to apply the zoom */
-    GST_INFO_OBJECT (self, "zoom: %f, orig size: %dx%d", zoom,
-        bcamsrc->width, bcamsrc->height);
-
-    if (zoom != ZOOM_1X) {
-      w2_crop = (bcamsrc->width - (gint) (bcamsrc->width * ZOOM_1X / zoom)) / 2;
-      h2_crop =
-          (bcamsrc->height - (gint) (bcamsrc->height * ZOOM_1X / zoom)) / 2;
-
-      left += w2_crop;
-      right += w2_crop;
-      top += h2_crop;
-      bottom += h2_crop;
-
-      /* force number of pixels cropped from left to be even, to avoid slow code
-       * path on videoscale */
-      left &= 0xFFFE;
-    }
-
-    pad_zoom_sink = gst_element_get_static_pad (self->src_zoom_crop, "sink");
-
-    GST_INFO_OBJECT (self,
-        "sw cropping: left:%d, right:%d, top:%d, bottom:%d", left, right, top,
-        bottom);
-
-    GST_PAD_STREAM_LOCK (pad_zoom_sink);
-    g_object_set (self->src_zoom_crop, "left", left, "right", right, "top",
-        top, "bottom", bottom, NULL);
-    GST_PAD_STREAM_UNLOCK (pad_zoom_sink);
-    gst_object_unref (pad_zoom_sink);
-    ret = TRUE;
-  }
-  return ret;
-}
-
 static void
 gst_wrapper_camera_bin_src_set_zoom (GstBaseCameraSrc * bcamsrc, gfloat zoom)
 {
@@ -1018,12 +883,11 @@
   GST_INFO_OBJECT (self, "setting zoom %f", zoom);
 
   if (set_videosrc_zoom (self, zoom)) {
-    set_element_zoom (self, ZOOM_1X);
+    g_object_set (self->digitalzoom, "zoom", (gfloat) 1.0, NULL);
     GST_INFO_OBJECT (self, "zoom set using videosrc");
-  } else if (set_element_zoom (self, zoom)) {
-    GST_INFO_OBJECT (self, "zoom set using gst elements");
   } else {
-    GST_INFO_OBJECT (self, "setting zoom failed");
+    GST_INFO_OBJECT (self, "zoom set using digitalzoom");
+    g_object_set (self->digitalzoom, "zoom", zoom, NULL);
   }
 }
 
@@ -1038,7 +902,7 @@
 static void
 update_aspect_filter (GstWrapperCameraBinSrc * self, GstCaps * new_caps)
 {
-  // XXX why not instead add a preserve-aspect-ratio property to videoscale?
+  /* XXX why not instead add a preserve-aspect-ratio property to videoscale? */
 #if 0
   if (camera->flags & GST_CAMERABIN_FLAG_VIEWFINDER_SCALE) {
     GstCaps *sink_caps, *ar_caps;
@@ -1134,8 +998,6 @@
 
   /* Update capsfilters */
   g_object_set (G_OBJECT (self->src_filter), "caps", new_caps, NULL);
-  if (self->src_zoom_filter)
-    g_object_set (G_OBJECT (self->src_zoom_filter), "caps", new_caps, NULL);
   update_aspect_filter (self, new_caps);
   GST_INFO_OBJECT (self, "updated");
 }
@@ -1144,44 +1006,31 @@
 gst_wrapper_camera_bin_src_start_capture (GstBaseCameraSrc * camerasrc)
 {
   GstWrapperCameraBinSrc *src = GST_WRAPPER_CAMERA_BIN_SRC (camerasrc);
+  GstPad *pad;
+  gboolean ret = TRUE;
+
+  pad = gst_element_get_static_pad (src->src_vid_src, "src");
 
   /* TODO should we access this directly? Maybe a macro is better? */
   if (src->mode == MODE_IMAGE) {
-    start_image_capture (src);
     src->image_capture_count = 1;
+
+    src->image_capture_probe =
+        gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_IDLE, start_image_capture,
+        src, NULL);
   } else if (src->mode == MODE_VIDEO) {
-    GstCaps *caps = NULL;
-
-    if (src->video_renegotiate) {
-      GstCaps *anycaps = gst_caps_new_any ();
-      g_mutex_unlock (&camerasrc->capturing_mutex);
-      gst_wrapper_camera_bin_reset_video_src_caps (src, anycaps);
-      g_mutex_lock (&camerasrc->capturing_mutex);
-
-      /* clean capsfilter caps so they don't interfere here */
-      g_object_set (src->src_filter, "caps", NULL, NULL);
-      if (src->src_zoom_filter)
-        g_object_set (src->src_zoom_filter, "caps", NULL, NULL);
-
-      GST_DEBUG_OBJECT (src, "Getting allowed videosrc caps");
-      caps = gst_pad_get_allowed_caps (src->vidsrc);
-      GST_DEBUG_OBJECT (src, "Video src caps %" GST_PTR_FORMAT, caps);
-
-      src->video_renegotiate = FALSE;
-      g_mutex_unlock (&camerasrc->capturing_mutex);
-      gst_wrapper_camera_bin_reset_video_src_caps (src, caps);
-      g_mutex_lock (&camerasrc->capturing_mutex);
-      gst_caps_unref (caps);
-      gst_caps_unref (anycaps);
-    }
     if (src->video_rec_status == GST_VIDEO_RECORDING_STATUS_DONE) {
       src->video_rec_status = GST_VIDEO_RECORDING_STATUS_STARTING;
+      src->video_capture_probe =
+          gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_IDLE, start_video_capture,
+          src, NULL);
     }
   } else {
     g_assert_not_reached ();
-    return FALSE;
+    ret = FALSE;
   }
-  return TRUE;
+  gst_object_unref (pad);
+  return ret;
 }
 
 static void
@@ -1200,7 +1049,7 @@
       src->video_rec_status = GST_VIDEO_RECORDING_STATUS_FINISHING;
     }
   } else {
-    src->image_capture_count = 0;
+    /* TODO check what happens when we try to stop a image capture */
   }
 }
 
@@ -1220,7 +1069,6 @@
     case GST_STATE_CHANGE_PAUSED_TO_READY:
       self->video_renegotiate = TRUE;
       self->image_renegotiate = TRUE;
-      self->drop_newseg = FALSE;
       break;
     case GST_STATE_CHANGE_READY_TO_NULL:
       break;
diff --git a/gst/camerabin2/gstwrappercamerabinsrc.h b/gst/camerabin2/gstwrappercamerabinsrc.h
index 68be6c5..90ab0cc 100644
--- a/gst/camerabin2/gstwrappercamerabinsrc.h
+++ b/gst/camerabin2/gstwrappercamerabinsrc.h
@@ -78,21 +78,21 @@
   GstElement *src_vid_src;
   GstElement *video_filter;
   GstElement *src_filter;
-  GstElement *src_zoom_crop;
-  GstElement *src_zoom_scale;
-  GstElement *src_zoom_filter;
-  GstElement *output_selector;
+  GstElement *digitalzoom;
+
+  /* Pad from our last element that is linked
+   * with the output pads */
+  GstPad *src_pad;
+
+  GstPad *video_tee_vf_pad;
+  GstPad *video_tee_sink;
 
   gboolean elements_created;
 
   gulong src_event_probe_id;
   gulong src_max_zoom_signal_id;
-
-  GstPad *outsel_imgpad;
-  GstPad *outsel_vidpad;
-
-  /* For changing caps without losing timestamps */
-  gboolean drop_newseg;
+  gulong image_capture_probe;
+  gulong video_capture_probe;
 
   /* Application configurable elements */
   GstElement *app_vid_src;
@@ -101,12 +101,9 @@
   /* Caps that videosrc supports */
   GstCaps *allowed_caps;
 
-  /* Optional base crop for frames. Used to crop frames e.g.
-     due to wrong aspect ratio, before the crop related to zooming. */
-  gint base_crop_top;
-  gint base_crop_bottom;
-  gint base_crop_left;
-  gint base_crop_right;
+  /* Optional crop for frames. Used to crop frames e.g.
+     due to wrong aspect ratio. Done before the crop related to zooming. */
+  GstElement *src_crop;
 
   /* Caps applied to capsfilters when in view finder mode */
   GstCaps *view_finder_caps;
diff --git a/gst/cdxaparse/Makefile.am b/gst/cdxaparse/Makefile.am
index 673e87a..0a69ec7 100644
--- a/gst/cdxaparse/Makefile.am
+++ b/gst/cdxaparse/Makefile.am
@@ -22,17 +22,3 @@
 
 libgstcdxaparse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstcdxaparse_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstcdxaparse -:SHARED libgstcdxaparse \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstcdxaparse_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstcdxaparse_la_CFLAGS) \
-	 -:LDFLAGS $(libgstcdxaparse_la_LDFLAGS) \
-	           $(libgstcdxaparse_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
\ No newline at end of file
diff --git a/gst/cdxaparse/Makefile.in b/gst/cdxaparse/Makefile.in
index b536e8a..705314d 100644
--- a/gst/cdxaparse/Makefile.in
+++ b/gst/cdxaparse/Makefile.in
@@ -1091,20 +1091,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstcdxaparse -:SHARED libgstcdxaparse \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstcdxaparse_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstcdxaparse_la_CFLAGS) \
-	 -:LDFLAGS $(libgstcdxaparse_la_LDFLAGS) \
-	           $(libgstcdxaparse_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/coloreffects/Makefile.am b/gst/coloreffects/Makefile.am
index 1b75db7..eb8a758 100644
--- a/gst/coloreffects/Makefile.am
+++ b/gst/coloreffects/Makefile.am
@@ -16,17 +16,3 @@
 libgstcoloreffects_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstcoloreffects.h gstchromahold.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstcoloreffects -:SHARED libgstcoloreffects \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstcoloreffects_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstcoloreffects_la_CFLAGS) \
-	 -:LDFLAGS $(libgstcoloreffects_la_LDFLAGS) \
-	           $(libgstcoloreffects_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/coloreffects/Makefile.in b/gst/coloreffects/Makefile.in
index 64abf6b..30fa319 100644
--- a/gst/coloreffects/Makefile.in
+++ b/gst/coloreffects/Makefile.in
@@ -1097,20 +1097,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstcoloreffects -:SHARED libgstcoloreffects \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstcoloreffects_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstcoloreffects_la_CFLAGS) \
-	 -:LDFLAGS $(libgstcoloreffects_la_LDFLAGS) \
-	           $(libgstcoloreffects_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/coloreffects/gstchromahold.c b/gst/coloreffects/gstchromahold.c
index f4dd9ed..fa5709d 100644
--- a/gst/coloreffects/gstchromahold.c
+++ b/gst/coloreffects/gstchromahold.c
@@ -59,8 +59,7 @@
   PROP_TARGET_R,
   PROP_TARGET_G,
   PROP_TARGET_B,
-  PROP_TOLERANCE,
-  PROP_LAST
+  PROP_TOLERANCE
 };
 
 static GstStaticPadTemplate gst_chroma_hold_src_template =
diff --git a/gst/compositor/compositor.c b/gst/compositor/compositor.c
index ef71d84..a970729 100644
--- a/gst/compositor/compositor.c
+++ b/gst/compositor/compositor.c
@@ -296,6 +296,17 @@
   return TRUE;
 }
 
+/* Test whether rectangle2 contains rectangle 1 (geometrically) */
+static gboolean
+is_rectangle_contained (GstVideoRectangle rect1, GstVideoRectangle rect2)
+{
+  if ((rect2.x <= rect1.x) && (rect2.y <= rect1.y) &&
+      ((rect2.x + rect2.w) >= (rect1.x + rect1.w)) &&
+      ((rect2.y + rect2.h) >= (rect1.y + rect1.h)))
+    return TRUE;
+  return FALSE;
+}
+
 static gboolean
 gst_compositor_pad_prepare_frame (GstVideoAggregatorPad * pad,
     GstVideoAggregator * vagg)
@@ -307,32 +318,40 @@
   GstVideoFrame *frame;
   static GstAllocationParams params = { 0, 15, 0, 0, };
   gint width, height;
+  gboolean frame_obscured = FALSE;
+  GList *l;
+  /* The rectangle representing this frame, clamped to the video's boundaries.
+   * Due to the clamping, this is different from the frame width/height above. */
+  GstVideoRectangle frame_rect;
 
   if (!pad->buffer)
     return TRUE;
 
-  frame = g_slice_new0 (GstVideoFrame);
-
-  if (!gst_video_frame_map (frame, &pad->buffer_vinfo, pad->buffer,
-          GST_MAP_READ)) {
-    GST_WARNING_OBJECT (vagg, "Could not map input buffer");
-    return FALSE;
-  }
-
+  /* There's three types of width/height here:
+   * 1. GST_VIDEO_FRAME_WIDTH/HEIGHT:
+   *     The frame width/height (same as pad->buffer_vinfo.height/width;
+   *     see gst_video_frame_map())
+   * 2. cpad->width/height:
+   *     The optional pad property for scaling the frame (if zero, the video is
+   *     left unscaled)
+   * 3. conversion_info.width/height:
+   *     Equal to cpad->width/height if it's set, otherwise it's the pad
+   *     width/height. See ->set_info()
+   * */
   if (cpad->width > 0)
     width = cpad->width;
   else
-    width = GST_VIDEO_FRAME_WIDTH (frame);
+    width = GST_VIDEO_INFO_WIDTH (&pad->buffer_vinfo);
 
   if (cpad->height > 0)
     height = cpad->height;
   else
-    height = GST_VIDEO_FRAME_HEIGHT (frame);
+    height = GST_VIDEO_INFO_HEIGHT (&pad->buffer_vinfo);
 
   /* The only thing that can change here is the width
    * and height, otherwise set_info would've been called */
-  if (cpad->conversion_info.width != width ||
-      cpad->conversion_info.height != height) {
+  if (GST_VIDEO_INFO_WIDTH (&cpad->conversion_info) != width ||
+      GST_VIDEO_INFO_HEIGHT (&cpad->conversion_info) != height) {
     gchar *colorimetry, *wanted_colorimetry;
     const gchar *chroma, *wanted_chroma;
 
@@ -344,20 +363,21 @@
       gst_video_converter_free (cpad->convert);
     cpad->convert = NULL;
 
-    colorimetry = gst_video_colorimetry_to_string (&frame->info.colorimetry);
-    chroma = gst_video_chroma_to_string (frame->info.chroma_site);
+    colorimetry =
+        gst_video_colorimetry_to_string (&pad->buffer_vinfo.colorimetry);
+    chroma = gst_video_chroma_to_string (pad->buffer_vinfo.chroma_site);
 
     wanted_colorimetry =
         gst_video_colorimetry_to_string (&cpad->conversion_info.colorimetry);
     wanted_chroma =
         gst_video_chroma_to_string (cpad->conversion_info.chroma_site);
 
-    if (GST_VIDEO_INFO_FORMAT (&frame->info) !=
+    if (GST_VIDEO_INFO_FORMAT (&pad->buffer_vinfo) !=
         GST_VIDEO_INFO_FORMAT (&cpad->conversion_info)
         || g_strcmp0 (colorimetry, wanted_colorimetry)
         || g_strcmp0 (chroma, wanted_chroma)
-        || width != GST_VIDEO_FRAME_WIDTH (frame)
-        || height != GST_VIDEO_FRAME_HEIGHT (frame)) {
+        || width != GST_VIDEO_INFO_WIDTH (&pad->buffer_vinfo)
+        || height != GST_VIDEO_INFO_HEIGHT (&pad->buffer_vinfo)) {
       GstVideoInfo tmp_info;
 
       gst_video_info_set_format (&tmp_info, cpad->conversion_info.finfo->format,
@@ -372,40 +392,98 @@
       tmp_info.interlace_mode = cpad->conversion_info.interlace_mode;
 
       GST_DEBUG_OBJECT (pad, "This pad will be converted from %d to %d",
-          GST_VIDEO_INFO_FORMAT (&frame->info),
+          GST_VIDEO_INFO_FORMAT (&pad->buffer_vinfo),
           GST_VIDEO_INFO_FORMAT (&tmp_info));
-      cpad->convert = gst_video_converter_new (&frame->info, &tmp_info, NULL);
+      cpad->convert =
+          gst_video_converter_new (&pad->buffer_vinfo, &tmp_info, NULL);
       cpad->conversion_info = tmp_info;
 
       if (!cpad->convert) {
         GST_WARNING_OBJECT (pad, "No path found for conversion");
         g_free (colorimetry);
         g_free (wanted_colorimetry);
-        gst_video_frame_unmap (frame);
-        g_slice_free (GstVideoFrame, frame);
         return FALSE;
       }
     } else {
-      cpad->conversion_info.width = width;
-      cpad->conversion_info.height = height;
+      GST_VIDEO_INFO_WIDTH (&cpad->conversion_info) = width;
+      GST_VIDEO_INFO_HEIGHT (&cpad->conversion_info) = height;
     }
 
     g_free (colorimetry);
     g_free (wanted_colorimetry);
   }
 
+  /* Clamp the x/y coordinates of this frame to the video boundaries to cover
+   * the case where (say, with negative xpos/ypos) the non-obscured portion of
+   * the frame could be outside the bounds of the video itself and hence not
+   * visible at all */
+  frame_rect.x = CLAMP (cpad->xpos, 0, GST_VIDEO_INFO_WIDTH (&vagg->info));
+  frame_rect.y = CLAMP (cpad->ypos, 0, GST_VIDEO_INFO_HEIGHT (&vagg->info));
+  /* Clamp the width/height to the frame boundaries as well */
+  frame_rect.w =
+      MAX (GST_VIDEO_INFO_WIDTH (&cpad->conversion_info) - frame_rect.x, 0);
+  frame_rect.h =
+      MAX (GST_VIDEO_INFO_HEIGHT (&cpad->conversion_info) - frame_rect.y, 0);
+
+  GST_OBJECT_LOCK (vagg);
+  /* Check if this frame is obscured by a higher-zorder frame
+   * TODO: Also skip a frame if it's obscured by a combination of
+   * higher-zorder frames */
+  for (l = g_list_find (GST_ELEMENT (vagg)->sinkpads, pad)->next; l;
+      l = l->next) {
+    GstVideoRectangle frame2_rect;
+    GstVideoAggregatorPad *pad2 = l->data;
+    GstCompositorPad *cpad2 = GST_COMPOSITOR_PAD (pad2);
+
+    /* We don't need to clamp the coords of the second rectangle */
+    frame2_rect.x = cpad2->xpos;
+    frame2_rect.y = cpad2->ypos;
+    /* This is effectively what set_info and the above conversion
+     * code do to calculate the desired width/height */
+    frame2_rect.w = cpad2->width ? cpad2->width :
+        GST_VIDEO_INFO_WIDTH (&cpad2->conversion_info);
+    frame2_rect.h = cpad2->height ? cpad2->height :
+        GST_VIDEO_INFO_HEIGHT (&cpad2->conversion_info);
+
+    /* Check if there's a buffer to be aggregated, ensure it can't have an alpha
+     * channel, then check opacity and frame boundaries */
+    if (pad2->buffer && cpad2->alpha == 1.0 &&
+        !GST_VIDEO_INFO_HAS_ALPHA (&pad2->info) &&
+        is_rectangle_contained (frame_rect, frame2_rect)) {
+      frame_obscured = TRUE;
+      GST_DEBUG_OBJECT (pad, "Obscured by %s, skipping frame",
+          GST_PAD_NAME (pad2));
+      break;
+    }
+  }
+  GST_OBJECT_UNLOCK (vagg);
+
+  if (frame_obscured) {
+    converted_frame = NULL;
+    goto done;
+  }
+
   if (cpad->alpha == 0.0) {
     GST_DEBUG_OBJECT (vagg, "Pad has alpha 0.0, not converting frame");
     converted_frame = NULL;
-    gst_video_frame_unmap (frame);
-    g_slice_free (GstVideoFrame, frame);
-  } else if (cpad->convert) {
+    goto done;
+  }
+
+  frame = g_slice_new0 (GstVideoFrame);
+
+  if (!gst_video_frame_map (frame, &pad->buffer_vinfo, pad->buffer,
+          GST_MAP_READ)) {
+    GST_WARNING_OBJECT (vagg, "Could not map input buffer");
+    return FALSE;
+  }
+
+  if (cpad->convert) {
     gint converted_size;
 
     converted_frame = g_slice_new0 (GstVideoFrame);
 
     /* We wait until here to set the conversion infos, in case vagg->info changed */
-    converted_size = cpad->conversion_info.size;
+    converted_size = GST_VIDEO_INFO_SIZE (&cpad->conversion_info);
     outsize = GST_VIDEO_INFO_SIZE (&vagg->info);
     converted_size = converted_size > outsize ? converted_size : outsize;
     converted_buf = gst_buffer_new_allocate (NULL, converted_size, &params);
@@ -428,6 +506,7 @@
     converted_frame = frame;
   }
 
+done:
   pad->aggregated_frame = converted_frame;
 
   return TRUE;
@@ -808,6 +887,8 @@
   outframe = &out_frame;
   /* default to blending */
   composite = self->blend;
+  /* TODO: If the frames to be composited completely obscure the background,
+   * don't bother drawing the background at all. */
   switch (self->background) {
     case COMPOSITOR_BACKGROUND_CHECKER:
       self->fill_checker (outframe);
diff --git a/gst/dataurisrc/Makefile.am b/gst/dataurisrc/Makefile.am
index 37c8db3..37601ac 100644
--- a/gst/dataurisrc/Makefile.am
+++ b/gst/dataurisrc/Makefile.am
@@ -6,17 +6,3 @@
 libgstdataurisrc_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS)
 libgstdataurisrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstdataurisrc_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstdataurisrc -:SHARED libgstdataurisrc \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstdataurisrc_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstdataurisrc_la_CFLAGS) \
-	 -:LDFLAGS $(libgstdataurisrc_la_LDFLAGS) \
-	           $(libgstdataurisrc_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
\ No newline at end of file
diff --git a/gst/dataurisrc/Makefile.in b/gst/dataurisrc/Makefile.in
index 8b1e1bf..3c31645 100644
--- a/gst/dataurisrc/Makefile.in
+++ b/gst/dataurisrc/Makefile.in
@@ -1064,20 +1064,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstdataurisrc -:SHARED libgstdataurisrc \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstdataurisrc_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstdataurisrc_la_CFLAGS) \
-	 -:LDFLAGS $(libgstdataurisrc_la_LDFLAGS) \
-	           $(libgstdataurisrc_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/debugutils/Makefile.am b/gst/debugutils/Makefile.am
index c7dd343..94b0ef5 100644
--- a/gst/debugutils/Makefile.am
+++ b/gst/debugutils/Makefile.am
@@ -37,17 +37,3 @@
 libgstdebugutilsbad_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = fpsdisplaysink.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstdebugutils -:SHARED libgstdebugutils \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstdebugutils_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstdebugutils_la_CFLAGS) \
-	 -:LDFLAGS $(libgstdebugutils_la_LDFLAGS) \
-	           $(libgstdebugutils_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/debugutils/Makefile.in b/gst/debugutils/Makefile.in
index 9bb83ae..644fde8 100644
--- a/gst/debugutils/Makefile.in
+++ b/gst/debugutils/Makefile.in
@@ -1212,20 +1212,6 @@
 .deps/%-enumtypes.Plo:
 	@touch $@
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstdebugutils -:SHARED libgstdebugutils \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstdebugutils_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstdebugutils_la_CFLAGS) \
-	 -:LDFLAGS $(libgstdebugutils_la_LDFLAGS) \
-	           $(libgstdebugutils_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/debugutils/fpsdisplaysink.c b/gst/debugutils/fpsdisplaysink.c
index 1970baf..0708bc0 100644
--- a/gst/debugutils/fpsdisplaysink.c
+++ b/gst/debugutils/fpsdisplaysink.c
@@ -27,7 +27,7 @@
  * |[
  * gst-launch videotestsrc ! fpsdisplaysink
  * gst-launch videotestsrc ! fpsdisplaysink text-overlay=false
- * gst-launch filesrc location=video.avi ! decodebin2 name=d ! queue ! fpsdisplaysink d. ! queue ! fakesink sync=true
+ * gst-launch filesrc location=video.avi ! decodebin name=d ! queue ! fpsdisplaysink d. ! queue ! fakesink sync=true
  * gst-launch playbin uri=file:///path/to/video.avi video-sink="fpsdisplaysink" audio-sink=fakesink
  * ]|
  * </refsect2>
@@ -435,11 +435,7 @@
     g_free (self->last_message);
     self->last_message = g_strdup (fps_message);
     GST_OBJECT_UNLOCK (self);
-#if !GLIB_CHECK_VERSION(2,26,0)
-    g_object_notify ((GObject *) self, "last-message");
-#else
     g_object_notify_by_pspec ((GObject *) self, pspec_last_message);
-#endif
   }
 
   self->last_frames_rendered = frames_rendered;
@@ -521,11 +517,7 @@
     g_free (self->last_message);
     self->last_message = str;
     GST_OBJECT_UNLOCK (self);
-#if !GLIB_CHECK_VERSION(2,26,0)
-    g_object_notify ((GObject *) self, "last-message");
-#else
     g_object_notify_by_pspec ((GObject *) self, pspec_last_message);
-#endif
   }
 
   GST_OBJECT_LOCK (self);
diff --git a/gst/debugutils/gstcompare.c b/gst/debugutils/gstcompare.c
index 5de2f9d..3d52615 100644
--- a/gst/debugutils/gstcompare.c
+++ b/gst/debugutils/gstcompare.c
@@ -91,8 +91,7 @@
   PROP_OFFSET_TS,
   PROP_METHOD,
   PROP_THRESHOLD,
-  PROP_UPPER,
-  PROP_LAST
+  PROP_UPPER
 };
 
 #define DEFAULT_META             GST_BUFFER_COPY_ALL
diff --git a/gst/dvbsuboverlay/Makefile.am b/gst/dvbsuboverlay/Makefile.am
index 5f5c806..7993253 100644
--- a/gst/dvbsuboverlay/Makefile.am
+++ b/gst/dvbsuboverlay/Makefile.am
@@ -8,17 +8,3 @@
 libgstdvbsuboverlay_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstdvbsuboverlay.h dvb-sub.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstdvbsuboverlay -:SHARED libgstdvbsuboverlay \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstdvbsuboverlay_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstdvbsuboverlay_la_CFLAGS) \
-	 -:LDFLAGS $(libgstdvbsuboverlay_la_LDFLAGS) \
-	           $(libgstdvbsuboverlay_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/dvbsuboverlay/Makefile.in b/gst/dvbsuboverlay/Makefile.in
index ca741da..4c1b439 100644
--- a/gst/dvbsuboverlay/Makefile.in
+++ b/gst/dvbsuboverlay/Makefile.in
@@ -1076,20 +1076,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstdvbsuboverlay -:SHARED libgstdvbsuboverlay \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstdvbsuboverlay_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstdvbsuboverlay_la_CFLAGS) \
-	 -:LDFLAGS $(libgstdvbsuboverlay_la_LDFLAGS) \
-	           $(libgstdvbsuboverlay_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/dvdspu/Makefile.am b/gst/dvdspu/Makefile.am
index e28daeb..d7d48a5 100644
--- a/gst/dvdspu/Makefile.am
+++ b/gst/dvdspu/Makefile.am
@@ -12,17 +12,3 @@
 noinst_HEADERS = gstdvdspu.h gstspu-pgs.h gstspu-vobsub.h gstspu-common.h
 
 EXTRA_DIST = Notes.txt
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstdvdspu -:SHARED libgstdvdspu \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstdvdspu_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstdvdspu_la_CFLAGS) \
-	 -:LDFLAGS $(libgstdvdspu_la_LDFLAGS) \
-	           $(libgstdvdspu_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/dvdspu/Makefile.in b/gst/dvdspu/Makefile.in
index b2efeb1..ec94499 100644
--- a/gst/dvdspu/Makefile.in
+++ b/gst/dvdspu/Makefile.in
@@ -1106,20 +1106,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstdvdspu -:SHARED libgstdvdspu \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstdvdspu_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstdvdspu_la_CFLAGS) \
-	 -:LDFLAGS $(libgstdvdspu_la_LDFLAGS) \
-	           $(libgstdvdspu_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/festival/Makefile.am b/gst/festival/Makefile.am
index 16ed287..91ab9ae 100644
--- a/gst/festival/Makefile.am
+++ b/gst/festival/Makefile.am
@@ -10,18 +10,4 @@
 libgstfestival_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstfestival_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
-noinst_HEADERS = gstfestival.h 
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstfestival -:SHARED libgstfestival \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstfestival_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstfestival_la_CFLAGS) \
-	 -:LDFLAGS $(libgstfestival_la_LDFLAGS) \
-	           $(libgstfestival_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-1.0' \
-	> $@
+noinst_HEADERS = gstfestival.h
diff --git a/gst/festival/Makefile.in b/gst/festival/Makefile.in
index 6411e59..6163904 100644
--- a/gst/festival/Makefile.in
+++ b/gst/festival/Makefile.in
@@ -744,7 +744,7 @@
 
 libgstfestival_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstfestival_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-noinst_HEADERS = gstfestival.h 
+noinst_HEADERS = gstfestival.h
 all: all-am
 
 .SUFFIXES:
@@ -1071,20 +1071,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstfestival -:SHARED libgstfestival \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstfestival_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstfestival_la_CFLAGS) \
-	 -:LDFLAGS $(libgstfestival_la_LDFLAGS) \
-	           $(libgstfestival_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-1.0' \
-	> $@
-
 # 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/gst/festival/gstfestival.c b/gst/festival/gstfestival.c
index 7c4b88f..cb2d1cb 100644
--- a/gst/festival/gstfestival.c
+++ b/gst/festival/gstfestival.c
@@ -142,7 +142,7 @@
 
 enum
 {
-  ARG_0
+  PROP_0
       /* FILL ME */
 };
 
diff --git a/gst/fieldanalysis/gstfieldanalysis.c b/gst/fieldanalysis/gstfieldanalysis.c
index 8631d74..b7ffd87 100644
--- a/gst/fieldanalysis/gstfieldanalysis.c
+++ b/gst/fieldanalysis/gstfieldanalysis.c
@@ -259,7 +259,7 @@
           DEFAULT_SPATIAL_THRESH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (gobject_class, PROP_BLOCK_WIDTH,
       g_param_spec_uint64 ("block-width", "Block width",
-          "Block width for windowed comb detection", 0, G_MAXUINT64,
+          "Block width for windowed comb detection", 1, G_MAXUINT64,
           DEFAULT_BLOCK_WIDTH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (gobject_class, PROP_BLOCK_HEIGHT,
       g_param_spec_uint64 ("block-height", "Block height",
diff --git a/gst/fieldanalysis/gstfieldanalysisorc-dist.c b/gst/fieldanalysis/gstfieldanalysisorc-dist.c
index 7d00a73..1ae0143 100644
--- a/gst/fieldanalysis/gstfieldanalysisorc-dist.c
+++ b/gst/fieldanalysis/gstfieldanalysisorc-dist.c
@@ -283,7 +283,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 44, 102, 105, 101, 108, 100, 97, 110, 97, 108, 121, 115, 105, 115,
         95, 111, 114, 99, 95, 115, 97, 109, 101, 95, 112, 97, 114, 105, 116,
-            121,
+        121,
         95, 115, 97, 100, 95, 112, 108, 97, 110, 97, 114, 95, 121, 117, 118, 12,
         1, 1, 12, 1, 1, 13, 4, 16, 4, 20, 2, 20, 2, 20, 4, 20,
         4, 150, 32, 4, 150, 33, 5, 98, 32, 32, 33, 69, 32, 32, 154, 34,
@@ -466,9 +466,9 @@
       static const orc_uint8 bc[] = {
         1, 9, 44, 102, 105, 101, 108, 100, 97, 110, 97, 108, 121, 115, 105, 115,
         95, 111, 114, 99, 95, 115, 97, 109, 101, 95, 112, 97, 114, 105, 116,
-            121,
+        121,
         95, 115, 115, 100, 95, 112, 108, 97, 110, 97, 114, 95, 121, 117, 118,
-            12,
+        12,
         1, 1, 12, 1, 1, 13, 4, 16, 4, 20, 2, 20, 2, 20, 4, 20,
         4, 150, 32, 4, 150, 33, 5, 98, 32, 32, 33, 176, 34, 32, 32, 111,
         35, 34, 24, 106, 34, 34, 35, 181, 12, 34, 2, 0,
@@ -758,7 +758,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 46, 102, 105, 101, 108, 100, 97, 110, 97, 108, 121, 115, 105, 115,
         95, 111, 114, 99, 95, 115, 97, 109, 101, 95, 112, 97, 114, 105, 116,
-            121,
+        121,
         95, 51, 95, 116, 97, 112, 95, 112, 108, 97, 110, 97, 114, 95, 121, 117,
         118, 12, 1, 1, 12, 1, 1, 12, 1, 1, 12, 1, 1, 12, 1, 1,
         12, 1, 1, 13, 4, 14, 2, 2, 0, 0, 0, 16, 4, 20, 2, 20,
@@ -1085,7 +1085,7 @@
       static const orc_uint8 bc[] = {
         1, 9, 50, 102, 105, 101, 108, 100, 97, 110, 97, 108, 121, 115, 105, 115,
         95, 111, 114, 99, 95, 111, 112, 112, 111, 115, 105, 116, 101, 95, 112,
-            97,
+        97,
         114, 105, 116, 121, 95, 53, 95, 116, 97, 112, 95, 112, 108, 97, 110, 97,
         114, 95, 121, 117, 118, 12, 1, 1, 12, 1, 1, 12, 1, 1, 12, 1,
         1, 12, 1, 1, 13, 4, 14, 2, 2, 0, 0, 0, 14, 2, 3, 0,
diff --git a/gst/freeverb/Makefile.am b/gst/freeverb/Makefile.am
index 76ca1da..11d0fb4 100644
--- a/gst/freeverb/Makefile.am
+++ b/gst/freeverb/Makefile.am
@@ -23,17 +23,3 @@
 preset_DATA = GstFreeverb.prs
 
 EXTRA_DIST = $(preset_DATA)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstfreeverb -:SHARED libgstfreeverb \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstfreeverb_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstfreeverb_la_CFLAGS) \
-	 -:LDFLAGS $(libgstfreeverb_la_LDFLAGS) \
-	           $(libgstfreeverb_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/freeverb/Makefile.in b/gst/freeverb/Makefile.in
index 6ac9047..290a042 100644
--- a/gst/freeverb/Makefile.in
+++ b/gst/freeverb/Makefile.in
@@ -1109,20 +1109,6 @@
 	uninstall-am uninstall-pluginLTLIBRARIES uninstall-presetDATA
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstfreeverb -:SHARED libgstfreeverb \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstfreeverb_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstfreeverb_la_CFLAGS) \
-	 -:LDFLAGS $(libgstfreeverb_la_LDFLAGS) \
-	           $(libgstfreeverb_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/frei0r/Makefile.am b/gst/frei0r/Makefile.am
index ba0e7f5..b9f1776 100644
--- a/gst/frei0r/Makefile.am
+++ b/gst/frei0r/Makefile.am
@@ -13,17 +13,3 @@
 libgstfrei0r_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstfrei0r.h gstfrei0rfilter.h gstfrei0rsrc.h gstfrei0rmixer.h frei0r.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstfrei0r -:SHARED libgstfrei0r \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstfrei0r_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstfrei0r_la_CFLAGS) \
-	 -:LDFLAGS $(libgstfrei0r_la_LDFLAGS) \
-	           $(libgstfrei0r_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/frei0r/Makefile.in b/gst/frei0r/Makefile.in
index 496bbc1..9b92614 100644
--- a/gst/frei0r/Makefile.in
+++ b/gst/frei0r/Makefile.in
@@ -1102,20 +1102,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstfrei0r -:SHARED libgstfrei0r \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstfrei0r_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstfrei0r_la_CFLAGS) \
-	 -:LDFLAGS $(libgstfrei0r_la_LDFLAGS) \
-	           $(libgstfrei0r_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/gaudieffects/Makefile.am b/gst/gaudieffects/Makefile.am
index d25794c..87089cd 100644
--- a/gst/gaudieffects/Makefile.am
+++ b/gst/gaudieffects/Makefile.am
@@ -40,17 +40,3 @@
         gstsolarize.h
 
 EXTRA_SCRIPTS = blur-example.py  burn-example.py
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstgaudieffects -:SHARED libgstgaudieffects \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstgaudieffects_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstgaudieffects_la_CFLAGS) \
-	 -:LDFLAGS $(libgstgaudieffects_la_LDFLAGS) \
-	           $(libgstgaudieffects_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/gaudieffects/Makefile.in b/gst/gaudieffects/Makefile.in
index b5c6aee..8e992c8 100644
--- a/gst/gaudieffects/Makefile.in
+++ b/gst/gaudieffects/Makefile.in
@@ -1252,20 +1252,6 @@
 	cp -p tmp-orc.c $(distdir)/$(ORC_SOURCE)-dist.c
 	cp -p $(ORC_SOURCE).h $(distdir)/$(ORC_SOURCE)-dist.h
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstgaudieffects -:SHARED libgstgaudieffects \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstgaudieffects_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstgaudieffects_la_CFLAGS) \
-	 -:LDFLAGS $(libgstgaudieffects_la_LDFLAGS) \
-	           $(libgstgaudieffects_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/gaudieffects/gstburn.c b/gst/gaudieffects/gstburn.c
index eb4b0c5..c82c8af 100644
--- a/gst/gaudieffects/gstburn.c
+++ b/gst/gaudieffects/gstburn.c
@@ -1,6 +1,6 @@
 /*
  * GStreamer
- * Copyright (C) >2010-2012> Luis de Bethencourt <luis@debethencourt.com>
+ * Copyright (C) <2010-2015> Luis de Bethencourt <luis@debethencourt.com>
  *
  * Burn - curve adjustment video effect.
  * Based on Pete Warden's FreeFrame plugin with the same name.
@@ -91,7 +91,6 @@
 {
   PROP_0 = 0,
   PROP_ADJUSTMENT,
-  PROP_SILENT
 };
 
 /* Initializations */
@@ -153,10 +152,6 @@
           "Adjustment parameter", 0, 256, DEFAULT_ADJUSTMENT,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
 
-  g_object_class_install_property (gobject_class, PROP_SILENT,
-      g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
-          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
   vfilter_class->transform_frame = GST_DEBUG_FUNCPTR (gst_burn_transform_frame);
 }
 
@@ -169,7 +164,6 @@
 gst_burn_init (GstBurn * filter)
 {
   filter->adjustment = DEFAULT_ADJUSTMENT;
-  filter->silent = FALSE;
 }
 
 static void
@@ -179,9 +173,6 @@
   GstBurn *filter = GST_BURN (object);
 
   switch (prop_id) {
-    case PROP_SILENT:
-      filter->silent = g_value_get_boolean (value);
-      break;
     case PROP_ADJUSTMENT:
       filter->adjustment = g_value_get_uint (value);
       break;
@@ -199,9 +190,6 @@
 
   GST_OBJECT_LOCK (filter);
   switch (prop_id) {
-    case PROP_SILENT:
-      g_value_set_boolean (value, filter->silent);
-      break;
     case PROP_ADJUSTMENT:
       g_value_set_uint (value, filter->adjustment);
       break;
@@ -226,7 +214,7 @@
     GstVideoFrame * in_frame, GstVideoFrame * out_frame)
 {
   GstBurn *filter = GST_BURN (vfilter);
-  gint video_size, adjustment, width, height;
+  gint video_size, adjustment;
   guint32 *src, *dest;
   GstClockTime timestamp;
   gint64 stream_time;
@@ -234,10 +222,8 @@
   src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
   dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
 
-  width = GST_VIDEO_FRAME_WIDTH (in_frame);
-  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
-
-  video_size = width * height;
+  video_size = GST_VIDEO_FRAME_WIDTH (in_frame) *
+      GST_VIDEO_FRAME_HEIGHT (in_frame);
 
   /* GstController: update the properties */
   timestamp = GST_BUFFER_TIMESTAMP (in_frame->buffer);
diff --git a/gst/gaudieffects/gstburn.h b/gst/gaudieffects/gstburn.h
index e263ae2..5f563f8 100644
--- a/gst/gaudieffects/gstburn.h
+++ b/gst/gaudieffects/gstburn.h
@@ -53,7 +53,6 @@
 
 G_BEGIN_DECLS
 
-/* #defines don't like whitespacey bits */
 #define GST_TYPE_BURN \
   (gst_burn_get_type())
 #define GST_BURN(obj) \
@@ -73,9 +72,7 @@
   GstVideoFilter videofilter;
 
   /* < private > */
-
   gint adjustment;
-  gboolean silent;
 };
 
 struct _GstBurnClass
diff --git a/gst/gaudieffects/gstchromium.c b/gst/gaudieffects/gstchromium.c
index d3c9780..8daca3a 100644
--- a/gst/gaudieffects/gstchromium.c
+++ b/gst/gaudieffects/gstchromium.c
@@ -1,6 +1,6 @@
 /*
  * GStreamer
- * Copyright (C) <2010-2012> Luis de Bethencourt <luis@debethencourt.com>
+ * Copyright (C) <2010> Luis de Bethencourt <luis@debethencourt.com>
  *
  * Chromium - burning chrome video effect.
  * Based on Pete Warden's FreeFrame plugin with the same name.
@@ -90,7 +90,6 @@
   PROP_0 = 0,
   PROP_EDGE_A,
   PROP_EDGE_B,
-  PROP_SILENT
 };
 
 /* Initializations */
@@ -172,10 +171,6 @@
           "Second edge parameter", 0, 256, DEFAULT_EDGE_B,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
 
-  g_object_class_install_property (gobject_class, PROP_SILENT,
-      g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
-          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
   vfilter_class->transform_frame =
       GST_DEBUG_FUNCPTR (gst_chromium_transform_frame);
 }
@@ -190,7 +185,6 @@
 {
   filter->edge_a = DEFAULT_EDGE_A;
   filter->edge_b = DEFAULT_EDGE_B;
-  filter->silent = FALSE;
 
   setup_cos_table ();
 }
@@ -202,9 +196,6 @@
   GstChromium *filter = GST_CHROMIUM (object);
 
   switch (prop_id) {
-    case PROP_SILENT:
-      filter->silent = g_value_get_boolean (value);
-      break;
     case PROP_EDGE_A:
       filter->edge_a = g_value_get_uint (value);
       break;
@@ -225,9 +216,6 @@
 
   GST_OBJECT_LOCK (filter);
   switch (prop_id) {
-    case PROP_SILENT:
-      g_value_set_boolean (value, filter->silent);
-      break;
     case PROP_EDGE_A:
       g_value_set_uint (value, filter->edge_a);
       break;
@@ -255,7 +243,7 @@
     GstVideoFrame * in_frame, GstVideoFrame * out_frame)
 {
   GstChromium *filter = GST_CHROMIUM (vfilter);
-  gint video_size, edge_a, edge_b, width, height;
+  gint video_size, edge_a, edge_b;
   guint32 *src, *dest;
   GstClockTime timestamp;
   gint64 stream_time;
@@ -263,9 +251,6 @@
   src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
   dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
 
-  width = GST_VIDEO_FRAME_WIDTH (in_frame);
-  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
-
   /* GstController: update the properties */
   timestamp = GST_BUFFER_TIMESTAMP (in_frame->buffer);
   stream_time =
@@ -283,7 +268,8 @@
   edge_b = filter->edge_b;
   GST_OBJECT_UNLOCK (filter);
 
-  video_size = width * height;
+  video_size = GST_VIDEO_FRAME_WIDTH (in_frame) *
+      GST_VIDEO_FRAME_HEIGHT (in_frame);
   transform (src, dest, video_size, edge_a, edge_b);
 
   return GST_FLOW_OK;
@@ -358,7 +344,6 @@
     green = CLAMP (green, 0, 255);
     blue = CLAMP (blue, 0, 255);
 
-
     *dest++ = (red << 16) | (green << 8) | blue;
   }
 }
diff --git a/gst/gaudieffects/gstchromium.h b/gst/gaudieffects/gstchromium.h
index 144e53f..4d54e2a 100644
--- a/gst/gaudieffects/gstchromium.h
+++ b/gst/gaudieffects/gstchromium.h
@@ -71,7 +71,6 @@
 
   /* < private > */
   gint edge_a, edge_b;
-  gboolean silent;
 };
 
 struct GstChromiumClass
diff --git a/gst/gaudieffects/gstdilate.c b/gst/gaudieffects/gstdilate.c
index 8c3c013..98fa053 100644
--- a/gst/gaudieffects/gstdilate.c
+++ b/gst/gaudieffects/gstdilate.c
@@ -1,6 +1,6 @@
 /*
  * GStreamer
- * Copyright (C) <2010-2012> Luis de Bethencourt <luis@debethencourt.com>
+ * Copyright (C) <2010-2015> Luis de Bethencourt <luis@debethencourt.com>
  *
  * Dilate - dilated eye video effect.
  * Based on Pete Warden's FreeFrame plugin with the same name.
@@ -89,7 +89,6 @@
 {
   PROP_0,
   PROP_ERODE,
-  PROP_SILENT
 };
 
 /* Initializations */
@@ -154,10 +153,6 @@
       g_param_spec_boolean ("erode", "Erode", "Erode parameter", FALSE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
 
-  g_object_class_install_property (gobject_class, PROP_SILENT,
-      g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
-          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
   vfilter_class->transform_frame =
       GST_DEBUG_FUNCPTR (gst_dilate_transform_frame);
 }
@@ -171,7 +166,6 @@
 gst_dilate_init (GstDilate * filter)
 {
   filter->erode = DEFAULT_ERODE;
-  filter->silent = FALSE;
 }
 
 static void
@@ -181,9 +175,6 @@
   GstDilate *filter = GST_DILATE (object);
 
   switch (prop_id) {
-    case PROP_SILENT:
-      filter->silent = g_value_get_boolean (value);
-      break;
     case PROP_ERODE:
       filter->erode = g_value_get_boolean (value);
       break;
@@ -201,9 +192,6 @@
 
   GST_OBJECT_LOCK (filter);
   switch (prop_id) {
-    case PROP_SILENT:
-      g_value_set_boolean (value, filter->silent);
-      break;
     case PROP_ERODE:
       g_value_set_boolean (value, filter->erode);
       break;
@@ -305,120 +293,63 @@
   guint32 *down;
   guint32 *right;
 
-  if (erode) {
+  while (src != src_end) {
+    guint32 *src_line_start = src;
+    guint32 *src_line_end = src + width;
 
-    while (src != src_end) {
-      guint32 *src_line_start = src;
-      guint32 *src_line_end = src + width;
-      while (src != src_line_end) {
-
-        up = src - width;
-        if (up < src) {
-          up = src;
-        }
-
-        left = src - 1;
-        if (left < src_line_start) {
-          left = src;
-        }
-
-        down = src + width;
-        if (down >= src_end) {
-          down = src;
-        }
-
-        right = src + 1;
-        if (right >= src_line_end) {
-          right = src;
-        }
-
-        *dest = *src;
-        out_luminance = get_luminance (*src);
-
-        down_luminance = get_luminance (*down);
-        if (down_luminance < out_luminance) {
-          *dest = *down;
-          out_luminance = down_luminance;
-        }
-
-        right_luminance = get_luminance (*right);
-        if (right_luminance < out_luminance) {
-          *dest = *right;
-          out_luminance = right_luminance;
-        }
-
-        up_luminance = get_luminance (*up);
-        if (up_luminance < out_luminance) {
-          *dest = *up;
-          out_luminance = up_luminance;
-        }
-
-        left_luminance = get_luminance (*left);
-        if (left_luminance < out_luminance) {
-          *dest = *left;
-        }
-
-        src += 1;
-        dest += 1;
+    while (src != src_line_end) {
+      up = src - width;
+      if (up < src) {
+        up = src;
       }
-    }
 
-  } else {
-
-    while (src != src_end) {
-      guint32 *src_line_start = src;
-      guint32 *src_line_end = src + width;
-      while (src != src_line_end) {
-
-        up = src - width;
-        if (up < src) {
-          up = src;
-        }
-
-        left = src - 1;
-        if (left < src_line_start) {
-          left = src;
-        }
-
-        down = src + width;
-        if (down >= src_end) {
-          down = src;
-        }
-
-        right = src + 1;
-        if (right >= src_line_end) {
-          right = src;
-        }
-
-        *dest = *src;
-        out_luminance = get_luminance (*src);
-
-        down_luminance = get_luminance (*down);
-        if (down_luminance > out_luminance) {
-          *dest = *down;
-          out_luminance = down_luminance;
-        }
-
-        right_luminance = get_luminance (*right);
-        if (right_luminance > out_luminance) {
-          *dest = *right;
-          out_luminance = right_luminance;
-        }
-
-        up_luminance = get_luminance (*up);
-        if (up_luminance > out_luminance) {
-          *dest = *up;
-          out_luminance = up_luminance;
-        }
-
-        left_luminance = get_luminance (*left);
-        if (left_luminance > out_luminance) {
-          *dest = *left;
-        }
-
-        src += 1;
-        dest += 1;
+      left = src - 1;
+      if (left < src_line_start) {
+        left = src;
       }
+
+      down = src + width;
+      if (down >= src_end) {
+        down = src;
+      }
+
+      right = src + 1;
+      if (right >= src_line_end) {
+        right = src;
+      }
+
+      *dest = *src;
+      out_luminance = get_luminance (*src);
+
+      down_luminance = get_luminance (*down);
+      if ((erode && down_luminance < out_luminance) ||
+          (!erode && down_luminance > out_luminance)) {
+        *dest = *down;
+        out_luminance = down_luminance;
+      }
+
+      right_luminance = get_luminance (*right);
+      if ((erode && right_luminance < out_luminance) ||
+          (!erode && right_luminance > out_luminance)) {
+        *dest = *right;
+        out_luminance = right_luminance;
+      }
+
+      up_luminance = get_luminance (*up);
+      if ((erode && up_luminance < out_luminance) ||
+          (!erode && up_luminance > out_luminance)) {
+        *dest = *up;
+        out_luminance = up_luminance;
+      }
+
+      left_luminance = get_luminance (*left);
+      if ((erode && left_luminance < out_luminance) ||
+          (!erode && left_luminance > out_luminance)) {
+        *dest = *left;
+      }
+
+      src += 1;
+      dest += 1;
     }
   }
 }
diff --git a/gst/gaudieffects/gstdilate.h b/gst/gaudieffects/gstdilate.h
index 4285363..afb0901 100644
--- a/gst/gaudieffects/gstdilate.h
+++ b/gst/gaudieffects/gstdilate.h
@@ -53,7 +53,6 @@
 
 G_BEGIN_DECLS
 
-/* #defines don't like whitespacey bits */
 #define GST_TYPE_DILATE \
   (gst_dilate_get_type())
 #define GST_DILATE(obj) \
@@ -73,7 +72,6 @@
   GstVideoFilter videofilter;
 
   /* < private > */
-  gboolean silent;
   gboolean erode;
 };
 
diff --git a/gst/gaudieffects/gstdodge.c b/gst/gaudieffects/gstdodge.c
index efe8be1..8cf8c6e 100644
--- a/gst/gaudieffects/gstdodge.c
+++ b/gst/gaudieffects/gstdodge.c
@@ -1,6 +1,6 @@
 /*
  * GStreamer
- * Copyright (C) <2010-2012> Luis de Bethencourt <luis@debethencourt.com>
+ * Copyright (C) <2010-2015> Luis de Bethencourt <luis@debethencourt.com>
  *
  * Dodge - saturation video effect.
  * Based on Pete Warden's FreeFrame plugin with the same name.
@@ -88,7 +88,6 @@
 enum
 {
   PROP_0,
-  PROP_SILENT
 };
 
 /* Initializations */
@@ -145,10 +144,6 @@
   gobject_class->get_property = gst_dodge_get_property;
   gobject_class->finalize = gst_dodge_finalize;
 
-  g_object_class_install_property (gobject_class, PROP_SILENT,
-      g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
-          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
   vfilter_class->transform_frame =
       GST_DEBUG_FUNCPTR (gst_dodge_transform_frame);
 }
@@ -161,19 +156,13 @@
 static void
 gst_dodge_init (GstDodge * filter)
 {
-  filter->silent = FALSE;
 }
 
 static void
 gst_dodge_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
 {
-  GstDodge *filter = GST_DODGE (object);
-
   switch (prop_id) {
-    case PROP_SILENT:
-      filter->silent = g_value_get_boolean (value);
-      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -184,18 +173,11 @@
 gst_dodge_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec)
 {
-  GstDodge *filter = GST_DODGE (object);
-
-  GST_OBJECT_LOCK (filter);
   switch (prop_id) {
-    case PROP_SILENT:
-      g_value_set_boolean (value, filter->silent);
-      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
-  GST_OBJECT_UNLOCK (filter);
 }
 
 static void
@@ -213,7 +195,7 @@
 {
   GstDodge *filter = GST_DODGE (vfilter);
   guint32 *src, *dest;
-  gint video_size, width, height;
+  gint video_size;
 
   GstClockTime timestamp;
   gint64 stream_time;
@@ -221,9 +203,7 @@
   src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
   dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
 
-  width = GST_VIDEO_FRAME_WIDTH (in_frame);
-  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
-
+  /* GstController: update the properties */
   timestamp = GST_BUFFER_TIMESTAMP (in_frame->buffer);
   stream_time =
       gst_segment_to_stream_time (&GST_BASE_TRANSFORM (filter)->segment,
@@ -235,7 +215,8 @@
   if (GST_CLOCK_TIME_IS_VALID (stream_time))
     gst_object_sync_values (GST_OBJECT (filter), stream_time);
 
-  video_size = width * height;
+  video_size = GST_VIDEO_FRAME_WIDTH (in_frame) *
+      GST_VIDEO_FRAME_HEIGHT (in_frame);
 
   transform (src, dest, video_size);
 
diff --git a/gst/gaudieffects/gstdodge.h b/gst/gaudieffects/gstdodge.h
index 4be4251..64bf4d0 100644
--- a/gst/gaudieffects/gstdodge.h
+++ b/gst/gaudieffects/gstdodge.h
@@ -53,7 +53,6 @@
 
 G_BEGIN_DECLS
 
-/* #defines don't like whitespacey bits */
 #define GST_TYPE_DODGE \
   (gst_dodge_get_type())
 #define GST_DODGE(obj) \
@@ -71,10 +70,6 @@
 struct _GstDodge
 {
   GstVideoFilter videofilter;
-
-  /* < private > */
-
-  gboolean silent;
 };
 
 struct _GstDodgeClass
diff --git a/gst/gaudieffects/gstexclusion.c b/gst/gaudieffects/gstexclusion.c
index 240bf41..8f762ad 100644
--- a/gst/gaudieffects/gstexclusion.c
+++ b/gst/gaudieffects/gstexclusion.c
@@ -1,6 +1,6 @@
 /*
  * GStreamer
- * Copyright (C) <2010-2012> Luis de Bethencourt <luis@debethencourt.com>
+ * Copyright (C) <2010-2015> Luis de Bethencourt <luis@debethencourt.com>
  *
  * Exclusion - color exclusion video effect.
  * Based on Pete Warden's FreeFrame plugin with the same name.
@@ -88,7 +88,6 @@
 {
   PROP_0 = 0,
   PROP_FACTOR,
-  PROP_SILENT
 };
 
 /* Initializations */
@@ -155,10 +154,6 @@
           "Exclusion factor parameter", 0, 175, DEFAULT_FACTOR,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
 
-  g_object_class_install_property (gobject_class, PROP_SILENT,
-      g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
-          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
   vfilter_class->transform_frame =
       GST_DEBUG_FUNCPTR (gst_exclusion_transform_frame);
 }
@@ -172,7 +167,6 @@
 gst_exclusion_init (GstExclusion * filter)
 {
   filter->factor = DEFAULT_FACTOR;
-  filter->silent = FALSE;
 }
 
 static void
@@ -182,9 +176,6 @@
   GstExclusion *filter = GST_EXCLUSION (object);
 
   switch (prop_id) {
-    case PROP_SILENT:
-      filter->silent = g_value_get_boolean (value);
-      break;
     case PROP_FACTOR:
       filter->factor = g_value_get_uint (value);
       break;
@@ -202,9 +193,6 @@
 
   GST_OBJECT_LOCK (filter);
   switch (prop_id) {
-    case PROP_SILENT:
-      g_value_set_boolean (value, filter->silent);
-      break;
     case PROP_FACTOR:
       g_value_set_uint (value, filter->factor);
       break;
@@ -229,7 +217,7 @@
     GstVideoFrame * in_frame, GstVideoFrame * out_frame)
 {
   GstExclusion *filter = GST_EXCLUSION (vfilter);
-  gint video_size, factor, width, height;
+  gint video_size, factor;
   guint32 *src, *dest;
   GstClockTime timestamp;
   gint64 stream_time;
@@ -237,9 +225,6 @@
   src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
   dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
 
-  width = GST_VIDEO_FRAME_WIDTH (in_frame);
-  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
-
   /* GstController: update the properties */
   timestamp = GST_BUFFER_TIMESTAMP (in_frame->buffer);
   stream_time =
@@ -256,7 +241,8 @@
   factor = filter->factor;
   GST_OBJECT_UNLOCK (filter);
 
-  video_size = width * height;
+  video_size = GST_VIDEO_FRAME_WIDTH (in_frame) *
+      GST_VIDEO_FRAME_HEIGHT (in_frame);
   transform (src, dest, video_size, factor);
 
   return GST_FLOW_OK;
@@ -284,6 +270,9 @@
   guint32 in;
   gint x, red, green, blue;
 
+  if (G_UNLIKELY (factor == 0))
+    return;
+
   for (x = 0; x < video_area; x++) {
     in = *src++;
 
diff --git a/gst/gaudieffects/gstexclusion.h b/gst/gaudieffects/gstexclusion.h
index 84278ac..b910835 100644
--- a/gst/gaudieffects/gstexclusion.h
+++ b/gst/gaudieffects/gstexclusion.h
@@ -53,7 +53,6 @@
 
 G_BEGIN_DECLS
 
-/* #defines don't like whitespacey bits */
 #define GST_TYPE_EXCLUSION \
   (gst_exclusion_get_type())
 #define GST_EXCLUSION(obj) \
@@ -73,9 +72,7 @@
   GstVideoFilter videofilter;
 
   /* < private > */
-
   gint factor;
-  gboolean silent;
 };
 
 struct _GstExclusionClass
diff --git a/gst/gaudieffects/gstgaussblur.c b/gst/gaudieffects/gstgaussblur.c
index 2ba0ce8..bbf22b6 100644
--- a/gst/gaudieffects/gstgaussblur.c
+++ b/gst/gaudieffects/gstgaussblur.c
@@ -111,8 +111,7 @@
 enum
 {
   PROP_0,
-  PROP_SIGMA,
-  PROP_LAST
+  PROP_SIGMA
 };
 
 static gboolean make_gaussian_kernel (GstGaussianBlur * gb, float sigma);
@@ -249,7 +248,8 @@
   src = GST_VIDEO_FRAME_COMP_DATA (in_frame, 0);
   dest = GST_VIDEO_FRAME_COMP_DATA (out_frame, 0);
   gst_video_frame_copy (out_frame, in_frame);
-  gaussian_smooth (filter, src, dest);
+  if (filter->sigma != 0.0)
+    gaussian_smooth (filter, src, dest);
 
   return GST_FLOW_OK;
 }
diff --git a/gst/gaudieffects/gstsolarize.c b/gst/gaudieffects/gstsolarize.c
index 932c6cc..a45feb2 100644
--- a/gst/gaudieffects/gstsolarize.c
+++ b/gst/gaudieffects/gstsolarize.c
@@ -1,6 +1,6 @@
 /*
  * GStreamer
- * Copyright (C) <2010-2012> Luis de Bethencourt <luis@debethencourt.com>
+ * Copyright (C) <2010-2015> Luis de Bethencourt <luis@debethencourt.com>
  *
  * Solarize - curve adjustment video effect.
  * Based on Pete Warden's FreeFrame plugin with the same name.
@@ -88,7 +88,6 @@
   PROP_THRESHOLD,
   PROP_START,
   PROP_END,
-  PROP_SILENT
 };
 
 /* Initializations */
@@ -168,10 +167,6 @@
           "End parameter", 0, 256, DEFAULT_END,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
 
-  g_object_class_install_property (gobject_class, PROP_SILENT,
-      g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
-          FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
   vfilter_class->transform_frame =
       GST_DEBUG_FUNCPTR (gst_solarize_transform_frame);
 }
@@ -187,7 +182,6 @@
   filter->threshold = DEFAULT_THRESHOLD;
   filter->start = DEFAULT_START;
   filter->end = DEFAULT_END;
-  filter->silent = FALSE;
 }
 
 static void
@@ -197,9 +191,6 @@
   GstSolarize *filter = GST_SOLARIZE (object);
 
   switch (prop_id) {
-    case PROP_SILENT:
-      filter->silent = g_value_get_boolean (value);
-      break;
     case PROP_THRESHOLD:
       filter->threshold = g_value_get_uint (value);
       break;
@@ -223,9 +214,6 @@
 
   GST_OBJECT_LOCK (filter);
   switch (prop_id) {
-    case PROP_SILENT:
-      g_value_set_boolean (value, filter->silent);
-      break;
     case PROP_THRESHOLD:
       g_value_set_uint (value, filter->threshold);
       break;
@@ -256,7 +244,7 @@
     GstVideoFrame * in_frame, GstVideoFrame * out_frame)
 {
   GstSolarize *filter = GST_SOLARIZE (vfilter);
-  gint video_size, threshold, start, end, width, height;
+  gint video_size, threshold, start, end;
   guint32 *src, *dest;
   GstClockTime timestamp;
   gint64 stream_time;
@@ -264,9 +252,6 @@
   src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0);
   dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0);
 
-  width = GST_VIDEO_FRAME_WIDTH (in_frame);
-  height = GST_VIDEO_FRAME_HEIGHT (in_frame);
-
   /* GstController: update the properties */
   timestamp = GST_BUFFER_TIMESTAMP (in_frame->buffer);
   stream_time =
@@ -285,7 +270,9 @@
   end = filter->end;
   GST_OBJECT_UNLOCK (filter);
 
-  video_size = width * height;
+  video_size = GST_VIDEO_FRAME_WIDTH (in_frame) *
+      GST_VIDEO_FRAME_HEIGHT (in_frame);
+
   transform (src, dest, video_size, threshold, start, end);
 
   return GST_FLOW_OK;
@@ -313,26 +300,19 @@
 {
   guint32 in;
   guint32 color[3];
+  gint period = 1, up_length = 1, down_length = 1;
   gint x, c;
-  static const guint floor = 0;
+  gint param;
   static const guint ceiling = 255;
 
-  gint period, up_length, down_length, param;
+  if (end != start)
+    period = end - start;
 
-  period = end - start;
-  if (period == 0) {
-    period = 1;
-  }
+  if (threshold != start)
+    up_length = threshold - start;
 
-  up_length = threshold - start;
-  if (up_length == 0) {
-    up_length = 1;
-  }
-
-  down_length = end - threshold;
-  if (down_length == 0) {
-    down_length = 1;
-  }
+  if (threshold != end)
+    down_length = end - threshold;
 
   /* Loop through pixels. */
   for (x = 0; x < video_area; x++) {
@@ -352,12 +332,10 @@
       if (param < up_length) {
         color[c] = param * ceiling;
         color[c] /= up_length;
-        color[c] += floor;
       } else {
         color[c] = down_length - (param - up_length);
         color[c] *= ceiling;
         color[c] /= down_length;
-        color[c] += floor;
       }
     }
 
diff --git a/gst/gaudieffects/gstsolarize.h b/gst/gaudieffects/gstsolarize.h
index 5dbb76a..2390563 100644
--- a/gst/gaudieffects/gstsolarize.h
+++ b/gst/gaudieffects/gstsolarize.h
@@ -53,7 +53,6 @@
 
 G_BEGIN_DECLS
 
-/* #defines don't like whitespacey bits */
 #define GST_TYPE_SOLARIZE \
   (gst_solarize_get_type())
 #define GST_SOLARIZE(obj) \
@@ -73,9 +72,7 @@
   GstVideoFilter videofilter;
 
   /* < private > */
-
   gint threshold, start, end;
-  gboolean silent;
 };
 
 struct _GstSolarizeClass
diff --git a/gst/gdp/Makefile.am b/gst/gdp/Makefile.am
index 1e59eed..ef986f1 100644
--- a/gst/gdp/Makefile.am
+++ b/gst/gdp/Makefile.am
@@ -16,17 +16,3 @@
 	dp-private.h   \
 	gstgdppay.h    \
 	gstgdpdepay.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstgdp -:SHARED libgstgdp \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstgdp_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstgdp_la_CFLAGS) \
-	 -:LDFLAGS $(libgstgdp_la_LDFLAGS) \
-	           $(libgstgdp_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/gdp/Makefile.in b/gst/gdp/Makefile.in
index f883b1a..cd25136 100644
--- a/gst/gdp/Makefile.in
+++ b/gst/gdp/Makefile.in
@@ -1103,20 +1103,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstgdp -:SHARED libgstgdp \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstgdp_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstgdp_la_CFLAGS) \
-	 -:LDFLAGS $(libgstgdp_la_LDFLAGS) \
-	           $(libgstgdp_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/geometrictransform/Makefile.am b/gst/geometrictransform/Makefile.am
index df5f9e2..0bafe41 100644
--- a/gst/geometrictransform/Makefile.am
+++ b/gst/geometrictransform/Makefile.am
@@ -49,17 +49,3 @@
                  gstmirror.h \
                  gstfisheye.h \
                  gstperspective.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstgeometrictransform -:SHARED libgstgeometrictransform \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstgeometrictransform_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstgeometrictransform_la_CFLAGS) \
-	 -:LDFLAGS $(libgstgeometrictransform_la_LDFLAGS) \
-	           $(libgstgeometrictransform_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/geometrictransform/Makefile.in b/gst/geometrictransform/Makefile.in
index 10faea7..dd79e16 100644
--- a/gst/geometrictransform/Makefile.in
+++ b/gst/geometrictransform/Makefile.in
@@ -1287,20 +1287,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstgeometrictransform -:SHARED libgstgeometrictransform \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstgeometrictransform_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstgeometrictransform_la_CFLAGS) \
-	 -:LDFLAGS $(libgstgeometrictransform_la_LDFLAGS) \
-	           $(libgstgeometrictransform_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/hdvparse/Makefile.am b/gst/hdvparse/Makefile.am
index c3e05ea..ea9368a 100644
--- a/gst/hdvparse/Makefile.am
+++ b/gst/hdvparse/Makefile.am
@@ -10,17 +10,3 @@
 libgsthdvparse_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(LIBM)
 libgsthdvparse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgsthdvparse_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgsthdvparse -:SHARED libgsthdvparse \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgsthdvparse_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgsthdvparse_la_CFLAGS) \
-	 -:LDFLAGS $(libgsthdvparse_la_LDFLAGS) \
-	           $(libgsthdvparse_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
\ No newline at end of file
diff --git a/gst/hdvparse/Makefile.in b/gst/hdvparse/Makefile.in
index 43da119..7bb7bd9 100644
--- a/gst/hdvparse/Makefile.in
+++ b/gst/hdvparse/Makefile.in
@@ -1071,20 +1071,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgsthdvparse -:SHARED libgsthdvparse \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgsthdvparse_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgsthdvparse_la_CFLAGS) \
-	 -:LDFLAGS $(libgsthdvparse_la_LDFLAGS) \
-	           $(libgsthdvparse_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/id3tag/Makefile.am b/gst/id3tag/Makefile.am
index ae7ab97..f497b4a 100644
--- a/gst/id3tag/Makefile.am
+++ b/gst/id3tag/Makefile.am
@@ -16,17 +16,3 @@
 libgstid3tag_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstid3mux.h id3tag.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstid3tag -:SHARED libgstid3tag \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstid3tag_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstid3tag_la_CFLAGS) \
-	 -:LDFLAGS $(libgstid3tag_la_LDFLAGS) \
-	           $(libgstid3tag_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/id3tag/Makefile.in b/gst/id3tag/Makefile.in
index cbc1fa8..f60ef54 100644
--- a/gst/id3tag/Makefile.in
+++ b/gst/id3tag/Makefile.in
@@ -1085,20 +1085,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstid3tag -:SHARED libgstid3tag \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstid3tag_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstid3tag_la_CFLAGS) \
-	 -:LDFLAGS $(libgstid3tag_la_LDFLAGS) \
-	           $(libgstid3tag_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/id3tag/gstid3mux.c b/gst/id3tag/gstid3mux.c
index deb8213..89a8127 100644
--- a/gst/id3tag/gstid3mux.c
+++ b/gst/id3tag/gstid3mux.c
@@ -61,10 +61,10 @@
 
 enum
 {
-  ARG_0,
-  ARG_WRITE_V1,
-  ARG_WRITE_V2,
-  ARG_V2_MAJOR_VERSION
+  PROP_0,
+  PROP_WRITE_V1,
+  PROP_WRITE_V2,
+  PROP_V2_MAJOR_VERSION
 };
 
 #define DEFAULT_WRITE_V1 FALSE
@@ -102,17 +102,17 @@
   gobject_class->set_property = gst_id3_mux_set_property;
   gobject_class->get_property = gst_id3_mux_get_property;
 
-  g_object_class_install_property (gobject_class, ARG_WRITE_V1,
+  g_object_class_install_property (gobject_class, PROP_WRITE_V1,
       g_param_spec_boolean ("write-v1", "Write id3v1 tag",
           "Write an id3v1 tag at the end of the file", DEFAULT_WRITE_V1,
           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
 
-  g_object_class_install_property (gobject_class, ARG_WRITE_V2,
+  g_object_class_install_property (gobject_class, PROP_WRITE_V2,
       g_param_spec_boolean ("write-v2", "Write id3v2 tag",
           "Write an id3v2 tag at the start of the file", DEFAULT_WRITE_V2,
           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
 
-  g_object_class_install_property (gobject_class, ARG_V2_MAJOR_VERSION,
+  g_object_class_install_property (gobject_class, PROP_V2_MAJOR_VERSION,
       g_param_spec_int ("v2-version", "Version (3 or 4) of id3v2 tag",
           "Set version (3 for id3v2.3, 4 for id3v2.4) of id3v2 tags",
           3, 4, DEFAULT_V2_MAJOR_VERSION,
@@ -152,13 +152,13 @@
   GstId3Mux *mux = GST_ID3_MUX (object);
 
   switch (prop_id) {
-    case ARG_WRITE_V1:
+    case PROP_WRITE_V1:
       mux->write_v1 = g_value_get_boolean (value);
       break;
-    case ARG_WRITE_V2:
+    case PROP_WRITE_V2:
       mux->write_v2 = g_value_get_boolean (value);
       break;
-    case ARG_V2_MAJOR_VERSION:
+    case PROP_V2_MAJOR_VERSION:
       mux->v2_major_version = g_value_get_int (value);
       break;
     default:
@@ -174,13 +174,13 @@
   GstId3Mux *mux = GST_ID3_MUX (object);
 
   switch (prop_id) {
-    case ARG_WRITE_V1:
+    case PROP_WRITE_V1:
       g_value_set_boolean (value, mux->write_v1);
       break;
-    case ARG_WRITE_V2:
+    case PROP_WRITE_V2:
       g_value_set_boolean (value, mux->write_v2);
       break;
-    case ARG_V2_MAJOR_VERSION:
+    case PROP_V2_MAJOR_VERSION:
       g_value_set_int (value, mux->v2_major_version);
       break;
     default:
diff --git a/gst/inter/Makefile.am b/gst/inter/Makefile.am
index 48480b5..773facf 100644
--- a/gst/inter/Makefile.am
+++ b/gst/inter/Makefile.am
@@ -48,17 +48,3 @@
 	$(GST_PLUGINS_BASE_LIBS) \
 	$(GST_LIBS) \
 	$(LIBM)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstinter -:SHARED libgstinter \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstinter_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstinter_la_CFLAGS) \
-	 -:LDFLAGS $(libgstinter_la_LDFLAGS) \
-	           $(libgstinter_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/inter/Makefile.in b/gst/inter/Makefile.in
index ea5cb31..467eb75 100644
--- a/gst/inter/Makefile.in
+++ b/gst/inter/Makefile.in
@@ -1208,20 +1208,6 @@
 	uninstall-am uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstinter -:SHARED libgstinter \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstinter_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstinter_la_CFLAGS) \
-	 -:LDFLAGS $(libgstinter_la_LDFLAGS) \
-	           $(libgstinter_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/inter/gstintertest.c b/gst/inter/gstintertest.c
index ee396f6..cff4f0d 100644
--- a/gst/inter/gstintertest.c
+++ b/gst/inter/gstintertest.c
@@ -80,11 +80,6 @@
   GstInterTest *intertest2;
   GMainLoop *main_loop;
 
-#if !GLIB_CHECK_VERSION (2, 31, 0)
-  if (!g_thread_supported ())
-    g_thread_init (NULL);
-#endif
-
   context = g_option_context_new ("- Internal src/sink test");
   g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
   g_option_context_add_group (context, gst_init_get_option_group ());
diff --git a/gst/interlace/Makefile.am b/gst/interlace/Makefile.am
index e321213..01b64e3 100644
--- a/gst/interlace/Makefile.am
+++ b/gst/interlace/Makefile.am
@@ -14,17 +14,3 @@
 
 libgstinterlace_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstinterlace_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstinterlace -:SHARED libgstinterlace \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstinterlace_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstinterlace_la_CFLAGS) \
-	 -:LDFLAGS $(libgstinterlace_la_LDFLAGS) \
-	           $(libgstinterlace_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
\ No newline at end of file
diff --git a/gst/interlace/Makefile.in b/gst/interlace/Makefile.in
index 1a86cc7..9a57dbd 100644
--- a/gst/interlace/Makefile.in
+++ b/gst/interlace/Makefile.in
@@ -1073,20 +1073,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstinterlace -:SHARED libgstinterlace \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstinterlace_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstinterlace_la_CFLAGS) \
-	 -:LDFLAGS $(libgstinterlace_la_LDFLAGS) \
-	           $(libgstinterlace_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/ivfparse/Makefile.am b/gst/ivfparse/Makefile.am
index d5167c5..951ac54 100644
--- a/gst/ivfparse/Makefile.am
+++ b/gst/ivfparse/Makefile.am
@@ -11,17 +11,3 @@
 libgstivfparse_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstivfparse.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstivfparse -:SHARED libgstivfparse \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstivfparse_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstivfparse_la_CFLAGS) \
-	 -:LDFLAGS $(libgstivfparse_la_LDFLAGS) \
-	           $(libgstivfparse_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
\ No newline at end of file
diff --git a/gst/ivfparse/Makefile.in b/gst/ivfparse/Makefile.in
index 19cd46f..ccb1e30 100644
--- a/gst/ivfparse/Makefile.in
+++ b/gst/ivfparse/Makefile.in
@@ -1073,20 +1073,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstivfparse -:SHARED libgstivfparse \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstivfparse_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstivfparse_la_CFLAGS) \
-	 -:LDFLAGS $(libgstivfparse_la_LDFLAGS) \
-	           $(libgstivfparse_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/ivtc/Makefile.am b/gst/ivtc/Makefile.am
index 5b1ce94..26f123a 100644
--- a/gst/ivtc/Makefile.am
+++ b/gst/ivtc/Makefile.am
@@ -9,20 +9,3 @@
 	$(GST_BASE_LIBS) $(GST_LIBS)
 libgstivtc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstivtc_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-
-EXTRA_DIST =
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstivtc -:SHARED libgstivtc \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstivtc_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstivtc_la_CFLAGS) \
-	 -:LDFLAGS $(libgstivtc_la_LDFLAGS) \
-	           $(libgstivtc_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/ivtc/Makefile.in b/gst/ivtc/Makefile.in
index fdfaacb..49f5557 100644
--- a/gst/ivtc/Makefile.in
+++ b/gst/ivtc/Makefile.in
@@ -746,7 +746,6 @@
 
 libgstivtc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstivtc_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-EXTRA_DIST = 
 all: all-am
 
 .SUFFIXES:
@@ -1081,20 +1080,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstivtc -:SHARED libgstivtc \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstivtc_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstivtc_la_CFLAGS) \
-	 -:LDFLAGS $(libgstivtc_la_LDFLAGS) \
-	           $(libgstivtc_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/jp2kdecimator/Makefile.am b/gst/jp2kdecimator/Makefile.am
index 780a983..1107eba 100644
--- a/gst/jp2kdecimator/Makefile.am
+++ b/gst/jp2kdecimator/Makefile.am
@@ -12,17 +12,3 @@
 libgstjp2kdecimator_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstjp2kdecimator.h jp2kcodestream.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstjp2kdecimator -:SHARED libgstjp2kdecimator \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstjp2kdecimator_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstjp2kdecimator_la_CFLAGS) \
-	 -:LDFLAGS $(libgstjp2kdecimator_la_LDFLAGS) \
-	           $(libgstjp2kdecimator_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/jp2kdecimator/Makefile.in b/gst/jp2kdecimator/Makefile.in
index f9d2b74..8b5611b 100644
--- a/gst/jp2kdecimator/Makefile.in
+++ b/gst/jp2kdecimator/Makefile.in
@@ -1084,20 +1084,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstjp2kdecimator -:SHARED libgstjp2kdecimator \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstjp2kdecimator_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstjp2kdecimator_la_CFLAGS) \
-	 -:LDFLAGS $(libgstjp2kdecimator_la_LDFLAGS) \
-	           $(libgstjp2kdecimator_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/jpegformat/Makefile.am b/gst/jpegformat/Makefile.am
index dc480b7..66506cf 100644
--- a/gst/jpegformat/Makefile.am
+++ b/gst/jpegformat/Makefile.am
@@ -9,17 +9,3 @@
 libgstjpegformat_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstjpegformat.h gstjpegparse.h gstjifmux.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstjpegformat -:SHARED libgstjpegformat \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstjpegformat_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstjpegformat_la_CFLAGS) \
-	 -:LDFLAGS $(libgstjpegformat_la_LDFLAGS) \
-	           $(libgstjpegformat_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/jpegformat/Makefile.in b/gst/jpegformat/Makefile.in
index e7b4065..d5571dc 100644
--- a/gst/jpegformat/Makefile.in
+++ b/gst/jpegformat/Makefile.in
@@ -1089,20 +1089,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstjpegformat -:SHARED libgstjpegformat \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstjpegformat_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstjpegformat_la_CFLAGS) \
-	 -:LDFLAGS $(libgstjpegformat_la_LDFLAGS) \
-	           $(libgstjpegformat_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/librfb/Makefile.am b/gst/librfb/Makefile.am
index 3a808a4..d542ffc 100644
--- a/gst/librfb/Makefile.am
+++ b/gst/librfb/Makefile.am
@@ -25,17 +25,3 @@
 	rfbutil.h \
 	gstrfbsrc.h \
 	d3des.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstrfbsrc -:SHARED libgstrfbsrc \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstrfbsrc_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstrfbsrc_la_CFLAGS) \
-	 -:LDFLAGS $(libgstrfbsrc_la_LDFLAGS) \
-	           $(libgstrfbsrc_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-$(GST_API_VERSION)' \
-	> $@
diff --git a/gst/librfb/Makefile.in b/gst/librfb/Makefile.in
index 878a8c2..6808f6b 100644
--- a/gst/librfb/Makefile.in
+++ b/gst/librfb/Makefile.in
@@ -1133,20 +1133,6 @@
 	uninstall-am uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstrfbsrc -:SHARED libgstrfbsrc \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstrfbsrc_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstrfbsrc_la_CFLAGS) \
-	 -:LDFLAGS $(libgstrfbsrc_la_LDFLAGS) \
-	           $(libgstrfbsrc_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-$(GST_API_VERSION)' \
-	> $@
-
 # 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/gst/librfb/gstrfbsrc.c b/gst/librfb/gstrfbsrc.c
index cec4077..7f9e591 100644
--- a/gst/librfb/gstrfbsrc.c
+++ b/gst/librfb/gstrfbsrc.c
@@ -36,19 +36,19 @@
 
 enum
 {
-  ARG_0,
-  ARG_HOST,
-  ARG_PORT,
-  ARG_VERSION,
-  ARG_PASSWORD,
-  ARG_OFFSET_X,
-  ARG_OFFSET_Y,
-  ARG_WIDTH,
-  ARG_HEIGHT,
-  ARG_INCREMENTAL,
-  ARG_USE_COPYRECT,
-  ARG_SHARED,
-  ARG_VIEWONLY
+  PROP_0,
+  PROP_HOST,
+  PROP_PORT,
+  PROP_VERSION,
+  PROP_PASSWORD,
+  PROP_OFFSET_X,
+  PROP_OFFSET_Y,
+  PROP_WIDTH,
+  PROP_HEIGHT,
+  PROP_INCREMENTAL,
+  PROP_USE_COPYRECT,
+  PROP_SHARED,
+  PROP_VIEWONLY
 };
 
 GST_DEBUG_CATEGORY_STATIC (rfbsrc_debug);
@@ -102,47 +102,47 @@
   gobject_class->set_property = gst_rfb_src_set_property;
   gobject_class->get_property = gst_rfb_src_get_property;
 
-  g_object_class_install_property (gobject_class, ARG_HOST,
+  g_object_class_install_property (gobject_class, PROP_HOST,
       g_param_spec_string ("host", "Host to connect to", "Host to connect to",
           "127.0.0.1", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, ARG_PORT,
+  g_object_class_install_property (gobject_class, PROP_PORT,
       g_param_spec_int ("port", "Port", "Port",
           1, 65535, 5900, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, ARG_VERSION,
+  g_object_class_install_property (gobject_class, PROP_VERSION,
       g_param_spec_string ("version", "RFB protocol version",
           "RFB protocol version", "3.3",
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, ARG_PASSWORD,
+  g_object_class_install_property (gobject_class, PROP_PASSWORD,
       g_param_spec_string ("password", "Password for authentication",
           "Password for authentication", "",
           G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, ARG_OFFSET_X,
+  g_object_class_install_property (gobject_class, PROP_OFFSET_X,
       g_param_spec_int ("offset-x", "x offset for screen scrapping",
           "x offset for screen scrapping", 0, 65535, 0,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, ARG_OFFSET_Y,
+  g_object_class_install_property (gobject_class, PROP_OFFSET_Y,
       g_param_spec_int ("offset-y", "y offset for screen scrapping",
           "y offset for screen scrapping", 0, 65535, 0,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, ARG_WIDTH,
+  g_object_class_install_property (gobject_class, PROP_WIDTH,
       g_param_spec_int ("width", "width of screen", "width of screen", 0, 65535,
           0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, ARG_HEIGHT,
+  g_object_class_install_property (gobject_class, PROP_HEIGHT,
       g_param_spec_int ("height", "height of screen", "height of screen", 0,
           65535, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, ARG_INCREMENTAL,
+  g_object_class_install_property (gobject_class, PROP_INCREMENTAL,
       g_param_spec_boolean ("incremental", "Incremental updates",
           "Incremental updates", TRUE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, ARG_USE_COPYRECT,
+  g_object_class_install_property (gobject_class, PROP_USE_COPYRECT,
       g_param_spec_boolean ("use-copyrect", "Use copyrect encoding",
           "Use copyrect encoding", FALSE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, ARG_SHARED,
+  g_object_class_install_property (gobject_class, PROP_SHARED,
       g_param_spec_boolean ("shared", "Share desktop with other clients",
           "Share desktop with other clients", TRUE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, ARG_VIEWONLY,
+  g_object_class_install_property (gobject_class, PROP_VIEWONLY,
       g_param_spec_boolean ("view-only", "Only view the desktop",
           "only view the desktop", FALSE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
@@ -249,41 +249,41 @@
   GstRfbSrc *src = GST_RFB_SRC (object);
 
   switch (prop_id) {
-    case ARG_HOST:
+    case PROP_HOST:
       src->host = g_strdup (g_value_get_string (value));
       break;
-    case ARG_PORT:
+    case PROP_PORT:
       src->port = g_value_get_int (value);
       break;
-    case ARG_VERSION:
+    case PROP_VERSION:
       gst_rfb_property_set_version (src, g_strdup (g_value_get_string (value)));
       break;
-    case ARG_PASSWORD:
+    case PROP_PASSWORD:
       g_free (src->decoder->password);
       src->decoder->password = g_strdup (g_value_get_string (value));
       break;
-    case ARG_OFFSET_X:
+    case PROP_OFFSET_X:
       src->decoder->offset_x = g_value_get_int (value);
       break;
-    case ARG_OFFSET_Y:
+    case PROP_OFFSET_Y:
       src->decoder->offset_y = g_value_get_int (value);
       break;
-    case ARG_WIDTH:
+    case PROP_WIDTH:
       src->decoder->rect_width = g_value_get_int (value);
       break;
-    case ARG_HEIGHT:
+    case PROP_HEIGHT:
       src->decoder->rect_height = g_value_get_int (value);
       break;
-    case ARG_INCREMENTAL:
+    case PROP_INCREMENTAL:
       src->incremental_update = g_value_get_boolean (value);
       break;
-    case ARG_USE_COPYRECT:
+    case PROP_USE_COPYRECT:
       src->decoder->use_copyrect = g_value_get_boolean (value);
       break;
-    case ARG_SHARED:
+    case PROP_SHARED:
       src->decoder->shared_flag = g_value_get_boolean (value);
       break;
-    case ARG_VIEWONLY:
+    case PROP_VIEWONLY:
       src->view_only = g_value_get_boolean (value);
       break;
     default:
@@ -299,39 +299,39 @@
   gchar *version;
 
   switch (prop_id) {
-    case ARG_HOST:
+    case PROP_HOST:
       g_value_set_string (value, src->host);
       break;
-    case ARG_PORT:
+    case PROP_PORT:
       g_value_set_int (value, src->port);
       break;
-    case ARG_VERSION:
+    case PROP_VERSION:
       version = gst_rfb_property_get_version (src);
       g_value_set_string (value, version);
       g_free (version);
       break;
-    case ARG_OFFSET_X:
+    case PROP_OFFSET_X:
       g_value_set_int (value, src->decoder->offset_x);
       break;
-    case ARG_OFFSET_Y:
+    case PROP_OFFSET_Y:
       g_value_set_int (value, src->decoder->offset_y);
       break;
-    case ARG_WIDTH:
+    case PROP_WIDTH:
       g_value_set_int (value, src->decoder->rect_width);
       break;
-    case ARG_HEIGHT:
+    case PROP_HEIGHT:
       g_value_set_int (value, src->decoder->rect_height);
       break;
-    case ARG_INCREMENTAL:
+    case PROP_INCREMENTAL:
       g_value_set_boolean (value, src->incremental_update);
       break;
-    case ARG_USE_COPYRECT:
+    case PROP_USE_COPYRECT:
       g_value_set_boolean (value, src->decoder->use_copyrect);
       break;
-    case ARG_SHARED:
+    case PROP_SHARED:
       g_value_set_boolean (value, src->decoder->shared_flag);
       break;
-    case ARG_VIEWONLY:
+    case PROP_VIEWONLY:
       g_value_set_boolean (value, src->view_only);
       break;
     default:
diff --git a/gst/liveadder/Makefile.am b/gst/liveadder/Makefile.am
index d9cc7cf..e6f5d44 100644
--- a/gst/liveadder/Makefile.am
+++ b/gst/liveadder/Makefile.am
@@ -9,17 +9,3 @@
 libgstliveadder_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = liveadder.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstliveadder -:SHARED libgstliveadder \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstliveadder_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstliveadder_la_CFLAGS) \
-	 -:LDFLAGS $(libgstliveadder_la_LDFLAGS) \
-	           $(libgstliveadder_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/liveadder/Makefile.in b/gst/liveadder/Makefile.in
index f3a475c..6969eba 100644
--- a/gst/liveadder/Makefile.in
+++ b/gst/liveadder/Makefile.in
@@ -1070,20 +1070,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstliveadder -:SHARED libgstliveadder \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstliveadder_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstliveadder_la_CFLAGS) \
-	 -:LDFLAGS $(libgstliveadder_la_LDFLAGS) \
-	           $(libgstliveadder_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/liveadder/liveadder.c b/gst/liveadder/liveadder.c
index af7fbbb..f060cde 100644
--- a/gst/liveadder/liveadder.c
+++ b/gst/liveadder/liveadder.c
@@ -1354,11 +1354,7 @@
   adder = GST_LIVE_ADDER (element);
 
   /* increment pad counter */
-#if GLIB_CHECK_VERSION(2,29,5)
   padcount = g_atomic_int_add (&adder->padcount, 1);
-#else
-  padcount = g_atomic_int_exchange_and_add (&adder->padcount, 1);
-#endif
 
   name = g_strdup_printf ("sink_%u", padcount);
   newpad = gst_pad_new_from_template (templ, name);
diff --git a/gst/midi/Makefile.am b/gst/midi/Makefile.am
index 058a778..55f12df 100644
--- a/gst/midi/Makefile.am
+++ b/gst/midi/Makefile.am
@@ -14,17 +14,3 @@
 libgstmidi_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = midiparse.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstmidi -:SHARED libgstmidi \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstmidi_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmidi_la_CFLAGS) \
-	 -:LDFLAGS $(libgstmidi_la_LDFLAGS) \
-	           $(libgstmidi_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-1.0' \
-	> $@
diff --git a/gst/midi/Makefile.in b/gst/midi/Makefile.in
index 49df014..dc72359 100644
--- a/gst/midi/Makefile.in
+++ b/gst/midi/Makefile.in
@@ -1085,20 +1085,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstmidi -:SHARED libgstmidi \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstmidi_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmidi_la_CFLAGS) \
-	 -:LDFLAGS $(libgstmidi_la_LDFLAGS) \
-	           $(libgstmidi_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-1.0' \
-	> $@
-
 # 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/gst/mpegdemux/Makefile.am b/gst/mpegdemux/Makefile.am
index 5c23016..df59955 100644
--- a/gst/mpegdemux/Makefile.am
+++ b/gst/mpegdemux/Makefile.am
@@ -19,17 +19,3 @@
 	gstmpegdefs.h   \
 	gstmpegdemux.h  \
 	gstpesfilter.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstmpegpsdemux -:SHARED libgstmpegpsdemux \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstmpegpsdemux_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmpegpsdemux_la_CFLAGS) \
-	 -:LDFLAGS $(libgstmpegpsdemux_la_LDFLAGS) \
-	           $(libgstmpegpsdemux_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/mpegdemux/Makefile.in b/gst/mpegdemux/Makefile.in
index 49379f4..9c8a0bb 100644
--- a/gst/mpegdemux/Makefile.in
+++ b/gst/mpegdemux/Makefile.in
@@ -1100,20 +1100,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstmpegpsdemux -:SHARED libgstmpegpsdemux \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstmpegpsdemux_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmpegpsdemux_la_CFLAGS) \
-	 -:LDFLAGS $(libgstmpegpsdemux_la_LDFLAGS) \
-	           $(libgstmpegpsdemux_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/mpegdemux/gstmpegdemux.c b/gst/mpegdemux/gstmpegdemux.c
index 69ca8e1..ab9b364 100644
--- a/gst/mpegdemux/gstmpegdemux.c
+++ b/gst/mpegdemux/gstmpegdemux.c
@@ -89,8 +89,7 @@
 
 enum
 {
-  ARG_0,
-  ARG_SYNC,
+  PROP_0,
   /* FILL ME */
 };
 
@@ -306,6 +305,8 @@
       if (stream->pad && GST_PAD_PARENT (stream->pad)) {
         gst_flow_combiner_remove_pad (demux->flowcombiner, stream->pad);
         gst_element_remove_pad (GST_ELEMENT_CAST (demux), stream->pad);
+      } else {
+        gst_object_unref (stream->pad);
       }
 
       if (stream->pending_tags)
@@ -532,6 +533,7 @@
        * add a whole new set of pads, drop old and no-more-pads again */
       GST_DEBUG_OBJECT (demux,
           "but already signalled no-more-pads; not adding");
+      gst_object_ref_sink (stream->pad);
     }
 
     demux->streams[id] = stream;
@@ -900,6 +902,7 @@
 {
   gint i, count = demux->found_count;
 
+  gst_flow_combiner_reset (demux->flowcombiner);
   /* Clear the last ts for all streams */
   for (i = 0; i < count; i++) {
     GstPsStream *stream = demux->streams_found[i];
diff --git a/gst/mpegpsmux/Makefile.am b/gst/mpegpsmux/Makefile.am
index 457465e..293fbec 100644
--- a/gst/mpegpsmux/Makefile.am
+++ b/gst/mpegpsmux/Makefile.am
@@ -21,17 +21,3 @@
 	mpegpsmux_h264.h \
 	bits.h \
 	crc.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstmpegpsmux -:SHARED libgstmpegpsmux \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstmpegpsmux_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmpegpsmux_la_CFLAGS) \
-	 -:LDFLAGS $(libgstmpegpsmux_la_LDFLAGS) \
-	           $(libgstmpegpsmux_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/mpegpsmux/Makefile.in b/gst/mpegpsmux/Makefile.in
index eed4af9..091aaf2 100644
--- a/gst/mpegpsmux/Makefile.in
+++ b/gst/mpegpsmux/Makefile.in
@@ -1117,20 +1117,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstmpegpsmux -:SHARED libgstmpegpsmux \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstmpegpsmux_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmpegpsmux_la_CFLAGS) \
-	 -:LDFLAGS $(libgstmpegpsmux_la_LDFLAGS) \
-	           $(libgstmpegpsmux_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/mpegtsdemux/Makefile.am b/gst/mpegtsdemux/Makefile.am
index 3bf5123..b4e053c 100644
--- a/gst/mpegtsdemux/Makefile.am
+++ b/gst/mpegtsdemux/Makefile.am
@@ -28,17 +28,3 @@
 	mpegtsparse.h \
 	tsdemux.h	\
 	pesparse.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstmpegtsdemux -:SHARED libgstmpegtsdemux \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstmpegtsdemux_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmpegtsdemux_la_CFLAGS) \
-	 -:LDFLAGS $(libgstmpegtsdemux_la_LDFLAGS) \
-	           $(libgstmpegtsdemux_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/mpegtsdemux/Makefile.in b/gst/mpegtsdemux/Makefile.in
index fd3b57a..7728b53 100644
--- a/gst/mpegtsdemux/Makefile.in
+++ b/gst/mpegtsdemux/Makefile.in
@@ -1139,20 +1139,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstmpegtsdemux -:SHARED libgstmpegtsdemux \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstmpegtsdemux_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmpegtsdemux_la_CFLAGS) \
-	 -:LDFLAGS $(libgstmpegtsdemux_la_LDFLAGS) \
-	           $(libgstmpegtsdemux_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/mpegtsdemux/mpegtsbase.c b/gst/mpegtsdemux/mpegtsbase.c
index 117b975..63e567c 100644
--- a/gst/mpegtsdemux/mpegtsbase.c
+++ b/gst/mpegtsdemux/mpegtsbase.c
@@ -41,9 +41,6 @@
 #include "mpegtsbase.h"
 #include "gstmpegdesc.h"
 
-/* latency in mseconds */
-#define TS_LATENCY 700
-
 #define RUNNING_STATUS_RUNNING 4
 
 GST_DEBUG_CATEGORY_STATIC (mpegts_base_debug);
@@ -200,9 +197,6 @@
   base->seen_pat = FALSE;
   base->seek_offset = -1;
 
-  base->upstream_live = FALSE;
-  base->queried_latency = FALSE;
-
   g_hash_table_foreach_remove (base->programs, (GHRFunc) remove_each_program,
       base);
 
@@ -1089,22 +1083,6 @@
   return res;
 }
 
-static void
-query_upstream_latency (MpegTSBase * base)
-{
-  GstQuery *query;
-
-  query = gst_query_new_latency ();
-  if (gst_pad_peer_query (base->sinkpad, query)) {
-    gst_query_parse_latency (query, &base->upstream_live, NULL, NULL);
-    GST_DEBUG_OBJECT (base, "Upstream is %s",
-        base->upstream_live ? "LIVE" : "NOT LIVE");
-  } else
-    GST_WARNING_OBJECT (base, "Failed to query upstream latency");
-  gst_query_unref (query);
-  base->queried_latency = TRUE;
-}
-
 static GstFlowReturn
 mpegts_base_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
 {
@@ -1120,10 +1098,6 @@
 
   packetizer = base->packetizer;
 
-  if (G_UNLIKELY (base->queried_latency == FALSE)) {
-    query_upstream_latency (base);
-  }
-
   if (klass->input_done)
     gst_buffer_ref (buf);
 
@@ -1410,15 +1384,17 @@
         GST_WARNING ("seeking failed %s", gst_flow_get_name (ret));
       else {
         GstEvent *new_seek;
-        base->mode = BASE_MODE_SEEKING;
 
-        new_seek = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags,
-            GST_SEEK_TYPE_SET, base->seek_offset, GST_SEEK_TYPE_NONE, -1);
-        gst_event_set_seqnum (new_seek, GST_EVENT_SEQNUM (event));
-        if (!gst_pad_push_event (base->sinkpad, new_seek))
-          ret = GST_FLOW_ERROR;
-        else
-          base->last_seek_seqnum = GST_EVENT_SEQNUM (event);
+        if (GST_CLOCK_TIME_IS_VALID (base->seek_offset)) {
+          base->mode = BASE_MODE_SEEKING;
+          new_seek = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags,
+              GST_SEEK_TYPE_SET, base->seek_offset, GST_SEEK_TYPE_NONE, -1);
+          gst_event_set_seqnum (new_seek, GST_EVENT_SEQNUM (event));
+          if (!gst_pad_push_event (base->sinkpad, new_seek))
+            ret = GST_FLOW_ERROR;
+          else
+            base->last_seek_seqnum = GST_EVENT_SEQNUM (event);
+        }
         base->mode = BASE_MODE_PUSHING;
       }
     }
diff --git a/gst/mpegtsdemux/mpegtspacketizer.c b/gst/mpegtsdemux/mpegtspacketizer.c
index f4d3a58..1cdb9e9 100644
--- a/gst/mpegtsdemux/mpegtspacketizer.c
+++ b/gst/mpegtsdemux/mpegtspacketizer.c
@@ -148,7 +148,7 @@
       return sub;
   }
 
-  return FALSE;
+  return NULL;
 }
 
 static gboolean
@@ -347,24 +347,25 @@
   if ((packet->scram_afc_cc & 0x30) == 0x20) {
     /* no payload, adaptation field of 183 bytes */
     if (length > 183) {
-      GST_WARNING ("PID %d afc == 0x%02x and length %d > 183",
+      GST_WARNING ("PID 0x%04x afc == 0x%02x and length %d > 183",
           packet->pid, packet->scram_afc_cc & 0x30, length);
       return FALSE;
     }
     if (length != 183) {
-      GST_WARNING ("PID %d afc == 0x%02x and length %d != 183",
+      GST_WARNING ("PID 0x%04x afc == 0x%02x and length %d != 183",
           packet->pid, packet->scram_afc_cc & 0x30, length);
       GST_MEMDUMP ("Unknown payload", packet->data + length,
           packet->data_end - packet->data - length);
     }
   } else if (length > 182) {
-    GST_WARNING ("PID %d afc == 0x%02x and length %d > 182",
+    GST_WARNING ("PID 0x%04x afc == 0x%02x and length %d > 182",
         packet->pid, packet->scram_afc_cc & 0x30, length);
     return FALSE;
   }
 
   if (packet->data + length > packet->data_end) {
-    GST_DEBUG ("PID %d afc length %d overflows the buffer current %d max %d",
+    GST_DEBUG
+        ("PID 0x%04x afc length %d overflows the buffer current %d max %d",
         packet->pid, length, (gint) (packet->data - packet->data_start),
         (gint) (packet->data_end - packet->data_start));
     return FALSE;
@@ -638,7 +639,7 @@
 {
   MpegTSPacketizerStream *stream = packetizer->streams[pid];
   if (stream) {
-    GST_INFO ("Removing stream for PID %d", pid);
+    GST_INFO ("Removing stream for PID 0x%04x", pid);
     mpegts_packetizer_stream_free (stream);
     packetizer->streams[pid] = NULL;
   }
diff --git a/gst/mpegtsdemux/mpegtsparse.c b/gst/mpegtsdemux/mpegtsparse.c
index d306e48..743da4f 100644
--- a/gst/mpegtsdemux/mpegtsparse.c
+++ b/gst/mpegtsdemux/mpegtsparse.c
@@ -234,8 +234,10 @@
 
   parse->current_pcr = GST_CLOCK_TIME_NONE;
   parse->previous_pcr = GST_CLOCK_TIME_NONE;
+  parse->base_pcr = GST_CLOCK_TIME_NONE;
   parse->bytes_since_pcr = 0;
   parse->pcr_pid = parse->user_pcr_pid;
+  parse->ts_offset = 0;
 }
 
 static void
@@ -360,6 +362,9 @@
   if (G_UNLIKELY (GST_EVENT_TYPE (event) == GST_EVENT_EOS))
     drain_pending_buffers (parse, TRUE);
 
+  if (G_UNLIKELY (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT))
+    parse->ts_offset = 0;
+
   for (tmp = parse->srcpads; tmp; tmp = tmp->next) {
     GstPad *pad = (GstPad *) tmp->data;
     if (pad) {
@@ -680,8 +685,12 @@
     if (parse->pcr_pid == -1)
       parse->pcr_pid = packet->pid;
     /* Check the PCR-PID matches the program we want for multiple programs */
-    if (parse->pcr_pid == packet->pid)
+    if (parse->pcr_pid == packet->pid) {
       parse->current_pcr = PCRTIME_TO_GSTTIME (packet->pcr);
+      if (parse->base_pcr == GST_CLOCK_TIME_NONE) {
+        parse->base_pcr = parse->current_pcr;
+      }
+    }
   }
 }
 
@@ -807,8 +816,8 @@
         "InputTS %" GST_TIME_FORMAT " out %" GST_TIME_FORMAT,
         GST_TIME_ARGS (GST_BUFFER_PTS (buffer)), GST_TIME_ARGS (out_ts));
 
-    GST_BUFFER_PTS (buffer) = out_ts;
-    GST_BUFFER_DTS (buffer) = out_ts;
+    GST_BUFFER_PTS (buffer) = out_ts + parse->ts_offset;
+    GST_BUFFER_DTS (buffer) = out_ts + parse->ts_offset;
     if (ret == GST_FLOW_OK)
       ret = gst_pad_push (parse->srcpad, buffer);
     else
@@ -914,6 +923,10 @@
     tspad->program = NULL;
     parseprogram->tspad = NULL;
   }
+
+  parse->pcr_pid = -1;
+  parse->ts_offset += parse->current_pcr - parse->base_pcr;
+  parse->base_pcr = GST_CLOCK_TIME_NONE;
 }
 
 static gboolean
diff --git a/gst/mpegtsdemux/mpegtsparse.h b/gst/mpegtsdemux/mpegtsparse.h
index b1253bf..d3bc6a2 100644
--- a/gst/mpegtsdemux/mpegtsparse.h
+++ b/gst/mpegtsdemux/mpegtsparse.h
@@ -52,6 +52,8 @@
   guint group_id;
 
   GstClockTime smoothing_latency;
+  GstClockTime base_pcr;
+  GstClockTime ts_offset;
   GstClockTime current_pcr;
   gint user_pcr_pid;
   gint pcr_pid;
diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c
index 9313cc5..e8c13f6 100644
--- a/gst/mpegtsdemux/tsdemux.c
+++ b/gst/mpegtsdemux/tsdemux.c
@@ -66,6 +66,9 @@
 
 #define GST_FLOW_REWINDING GST_FLOW_CUSTOM_ERROR
 
+/* latency in nsecs */
+#define TS_LATENCY (700 * GST_MSECOND)
+
 GST_DEBUG_CATEGORY_STATIC (ts_demux_debug);
 #define GST_CAT_DEFAULT ts_demux_debug
 
@@ -258,7 +261,7 @@
 
 enum
 {
-  ARG_0,
+  PROP_0,
   PROP_PROGRAM_NUMBER,
   PROP_EMIT_STATS,
   /* FILL ME */
@@ -455,6 +458,25 @@
 }
 
 static gboolean
+gst_ts_demux_get_duration (GstTSDemux * demux, GstClockTime * dur)
+{
+  MpegTSBase *base = (MpegTSBase *) demux;
+  gboolean res = FALSE;
+  gint64 val;
+
+  /* Get total size in bytes */
+  if (gst_pad_peer_query_duration (base->sinkpad, GST_FORMAT_BYTES, &val)) {
+    /* Convert it to duration */
+    *dur =
+        mpegts_packetizer_offset_to_ts (base->packetizer, val,
+        demux->program->pcr_pid);
+    if (GST_CLOCK_TIME_IS_VALID (*dur))
+      res = TRUE;
+  }
+  return res;
+}
+
+static gboolean
 gst_ts_demux_srcpad_query (GstPad * pad, GstObject * parent, GstQuery * query)
 {
   gboolean res = TRUE;
@@ -472,20 +494,11 @@
       gst_query_parse_duration (query, &format, NULL);
       if (format == GST_FORMAT_TIME) {
         if (!gst_pad_peer_query (base->sinkpad, query)) {
-          gint64 val;
-
-          format = GST_FORMAT_BYTES;
-          if (!gst_pad_peer_query_duration (base->sinkpad, format, &val))
+          GstClockTime dur;
+          if (gst_ts_demux_get_duration (demux, &dur))
+            gst_query_set_duration (query, GST_FORMAT_TIME, dur);
+          else
             res = FALSE;
-          else {
-            GstClockTime dur =
-                mpegts_packetizer_offset_to_ts (base->packetizer, val,
-                demux->program->pcr_pid);
-            if (GST_CLOCK_TIME_IS_VALID (dur))
-              gst_query_set_duration (query, GST_FORMAT_TIME, dur);
-            else
-              res = FALSE;
-          }
         }
       } else {
         GST_DEBUG_OBJECT (demux, "only query duration on TIME is supported");
@@ -497,7 +510,7 @@
     {
       GST_DEBUG ("query latency");
       res = gst_pad_peer_query (base->sinkpad, query);
-      if (res && base->upstream_live) {
+      if (res) {
         GstClockTime min_lat, max_lat;
         gboolean live;
 
@@ -509,10 +522,10 @@
            PTS/DTS. We therefore allow a latency of 700ms for that.
          */
         gst_query_parse_latency (query, &live, &min_lat, &max_lat);
-        if (min_lat != -1)
-          min_lat += 700 * GST_MSECOND;
-        if (max_lat != -1)
-          max_lat += 700 * GST_MSECOND;
+        if (min_lat)
+          min_lat += TS_LATENCY;
+        if (GST_CLOCK_TIME_IS_VALID (max_lat))
+          max_lat += TS_LATENCY;
         gst_query_set_latency (query, live, min_lat, max_lat);
       }
       break;
@@ -521,6 +534,7 @@
     {
       GST_DEBUG ("query seeking");
       gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
+      GST_DEBUG ("asked for format %s", gst_format_get_name (format));
       if (format == GST_FORMAT_TIME) {
         gboolean seekable = FALSE;
 
@@ -529,9 +543,13 @@
 
         /* If upstream is not seekable in TIME format we use
          * our own values here */
-        if (!seekable)
-          gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0,
-              demux->segment.duration);
+        if (!seekable) {
+          GstClockTime dur;
+          if (gst_ts_demux_get_duration (demux, &dur)) {
+            gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, dur);
+            GST_DEBUG ("Gave duration: %" GST_TIME_FORMAT, GST_TIME_ARGS (dur));
+          }
+        }
       } else {
         GST_DEBUG_OBJECT (demux, "only TIME is supported for query seeking");
         res = FALSE;
@@ -800,12 +818,29 @@
   /* configure the segment with the seek variables */
   GST_DEBUG_OBJECT (demux, "configuring seek");
 
-  start_offset =
-      mpegts_packetizer_ts_to_offset (base->packetizer, MAX (0,
-          start - SEEK_TIMESTAMP_OFFSET), demux->program->pcr_pid);
+  if (start_type != GST_SEEK_TYPE_NONE) {
+    start_offset =
+        mpegts_packetizer_ts_to_offset (base->packetizer, MAX (0,
+            start - SEEK_TIMESTAMP_OFFSET), demux->program->pcr_pid);
 
-  if (G_UNLIKELY (start_offset == -1)) {
-    GST_WARNING ("Couldn't convert start position to an offset");
+    if (G_UNLIKELY (start_offset == -1)) {
+      GST_WARNING ("Couldn't convert start position to an offset");
+      goto done;
+    }
+  } else {
+    start_offset = GST_CLOCK_TIME_NONE;
+    for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
+      TSDemuxStream *stream = tmp->data;
+
+      stream->need_newsegment = TRUE;
+    }
+    gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
+    if (demux->segment_event) {
+      gst_event_unref (demux->segment_event);
+      demux->segment_event = NULL;
+    }
+    demux->rate = rate;
+    res = GST_FLOW_OK;
     goto done;
   }
 
@@ -1399,6 +1434,7 @@
     stream->active = FALSE;
 
     stream->need_newsegment = TRUE;
+    demux->reset_segment = TRUE;
     stream->needs_keyframe = FALSE;
     stream->discont = TRUE;
     stream->pts = GST_CLOCK_TIME_NONE;
@@ -1456,6 +1492,11 @@
 
   gst_ts_demux_stream_flush (stream, GST_TS_DEMUX_CAST (base), TRUE);
 
+  if (stream->taglist != NULL) {
+    gst_tag_list_unref (stream->taglist);
+    stream->taglist = NULL;
+  }
+
   tsdemux_h264_parsing_info_clear (&stream->h264infos);
 }
 
@@ -1957,12 +1998,14 @@
       demux->segment = base->segment;
     } else {
       /* Start from the first ts/pts */
+      GstClockTime base = demux->segment.position - demux->segment.start;
       gst_segment_init (&demux->segment, GST_FORMAT_TIME);
       demux->segment.start = firstts;
       demux->segment.stop = GST_CLOCK_TIME_NONE;
       demux->segment.position = firstts;
       demux->segment.time = firstts;
       demux->segment.rate = demux->rate;
+      demux->segment.base = base;
     }
   } else if (demux->segment.start < firstts) {
     /* Take into account the offset to the first buffer timestamp */
@@ -2200,6 +2243,11 @@
     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
   stream->discont = FALSE;
 
+  if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DTS (buffer)))
+    demux->segment.position = GST_BUFFER_DTS (buffer) - stream->first_dts;
+  else if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_PTS (buffer)))
+    demux->segment.position = GST_BUFFER_PTS (buffer) - stream->first_dts;
+
   res = gst_pad_push (stream->pad, buffer);
   /* Record that a buffer was pushed */
   stream->nb_out_buffers += 1;
diff --git a/gst/mpegtsmux/mpegtsmux.c b/gst/mpegtsmux/mpegtsmux.c
index be296d7..8da8b08 100644
--- a/gst/mpegtsmux/mpegtsmux.c
+++ b/gst/mpegtsmux/mpegtsmux.c
@@ -102,13 +102,13 @@
 
 enum
 {
-  ARG_0,
-  ARG_PROG_MAP,
-  ARG_M2TS_MODE,
-  ARG_PAT_INTERVAL,
-  ARG_PMT_INTERVAL,
-  ARG_ALIGNMENT,
-  ARG_SI_INTERVAL
+  PROP_0,
+  PROP_PROG_MAP,
+  PROP_M2TS_MODE,
+  PROP_PAT_INTERVAL,
+  PROP_PMT_INTERVAL,
+  PROP_ALIGNMENT,
+  PROP_SI_INTERVAL
 };
 
 #define MPEGTSMUX_DEFAULT_ALIGNMENT    -1
@@ -254,37 +254,37 @@
   gstelement_class->get_index = GST_DEBUG_FUNCPTR (mpegtsmux_get_index);
 #endif
 
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PROG_MAP,
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PROG_MAP,
       g_param_spec_boxed ("prog-map", "Program map",
           "A GstStructure specifies the mapping from elementary streams to programs",
           GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_M2TS_MODE,
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_M2TS_MODE,
       g_param_spec_boolean ("m2ts-mode", "M2TS(192 bytes) Mode",
           "Set to TRUE to output Blu-Ray disc format with 192 byte packets. "
           "FALSE for standard TS format with 188 byte packets.",
           MPEGTSMUX_DEFAULT_M2TS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PAT_INTERVAL,
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PAT_INTERVAL,
       g_param_spec_uint ("pat-interval", "PAT interval",
           "Set the interval (in ticks of the 90kHz clock) for writing out the PAT table",
           1, G_MAXUINT, TSMUX_DEFAULT_PAT_INTERVAL,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PMT_INTERVAL,
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PMT_INTERVAL,
       g_param_spec_uint ("pmt-interval", "PMT interval",
           "Set the interval (in ticks of the 90kHz clock) for writing out the PMT table",
           1, G_MAXUINT, TSMUX_DEFAULT_PMT_INTERVAL,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ALIGNMENT,
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ALIGNMENT,
       g_param_spec_int ("alignment", "packet alignment",
           "Number of packets per buffer (padded with dummy packets on EOS) "
           "(-1 = auto, 0 = all available packets, 7 for UDP streaming)",
           -1, G_MAXINT, MPEGTSMUX_DEFAULT_ALIGNMENT,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SI_INTERVAL,
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SI_INTERVAL,
       g_param_spec_uint ("si-interval", "SI interval",
           "Set the interval (in ticks of the 90kHz clock) for writing out the Service"
           "Information tables", 1, G_MAXUINT, TSMUX_DEFAULT_SI_INTERVAL,
@@ -456,11 +456,11 @@
   GSList *walk;
 
   switch (prop_id) {
-    case ARG_M2TS_MODE:
+    case PROP_M2TS_MODE:
       /*set incase if the output stream need to be of 192 bytes */
       mux->m2ts_mode = g_value_get_boolean (value);
       break;
-    case ARG_PROG_MAP:
+    case PROP_PROG_MAP:
     {
       const GstStructure *s = gst_value_get_structure (value);
       if (mux->prog_map) {
@@ -472,12 +472,12 @@
         mux->prog_map = NULL;
       break;
     }
-    case ARG_PAT_INTERVAL:
+    case PROP_PAT_INTERVAL:
       mux->pat_interval = g_value_get_uint (value);
       if (mux->tsmux)
         tsmux_set_pat_interval (mux->tsmux, mux->pat_interval);
       break;
-    case ARG_PMT_INTERVAL:
+    case PROP_PMT_INTERVAL:
       walk = mux->collect->data;
       mux->pmt_interval = g_value_get_uint (value);
 
@@ -488,10 +488,10 @@
         walk = g_slist_next (walk);
       }
       break;
-    case ARG_ALIGNMENT:
+    case PROP_ALIGNMENT:
       mux->alignment = g_value_get_int (value);
       break;
-    case ARG_SI_INTERVAL:
+    case PROP_SI_INTERVAL:
       mux->si_interval = g_value_get_uint (value);
       tsmux_set_si_interval (mux->tsmux, mux->si_interval);
       break;
@@ -508,22 +508,22 @@
   MpegTsMux *mux = GST_MPEG_TSMUX (object);
 
   switch (prop_id) {
-    case ARG_M2TS_MODE:
+    case PROP_M2TS_MODE:
       g_value_set_boolean (value, mux->m2ts_mode);
       break;
-    case ARG_PROG_MAP:
+    case PROP_PROG_MAP:
       gst_value_set_structure (value, mux->prog_map);
       break;
-    case ARG_PAT_INTERVAL:
+    case PROP_PAT_INTERVAL:
       g_value_set_uint (value, mux->pat_interval);
       break;
-    case ARG_PMT_INTERVAL:
+    case PROP_PMT_INTERVAL:
       g_value_set_uint (value, mux->pmt_interval);
       break;
-    case ARG_ALIGNMENT:
+    case PROP_ALIGNMENT:
       g_value_set_int (value, mux->alignment);
       break;
-    case ARG_SI_INTERVAL:
+    case PROP_SI_INTERVAL:
       g_value_set_uint (value, mux->si_interval);
       break;
     default:
diff --git a/gst/mve/Makefile.am b/gst/mve/Makefile.am
index 20b5100..3ba6d2a 100644
--- a/gst/mve/Makefile.am
+++ b/gst/mve/Makefile.am
@@ -19,17 +19,3 @@
 noinst_HEADERS = gstmvedemux.h gstmvemux.h mve.h
 
 EXTRA_DIST = TODO
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstmve -:SHARED libgstmve \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstmve_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmve_la_CFLAGS) \
-	 -:LDFLAGS $(libgstmve_la_LDFLAGS) \
-	           $(libgstmve_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/mve/Makefile.in b/gst/mve/Makefile.in
index 2c67b12..80e5771 100644
--- a/gst/mve/Makefile.in
+++ b/gst/mve/Makefile.in
@@ -1146,20 +1146,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstmve -:SHARED libgstmve \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstmve_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmve_la_CFLAGS) \
-	 -:LDFLAGS $(libgstmve_la_LDFLAGS) \
-	           $(libgstmve_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/mve/gstmvemux.c b/gst/mve/gstmvemux.c
index c468d9b..043211c 100644
--- a/gst/mve/gstmvemux.c
+++ b/gst/mve/gstmvemux.c
@@ -42,11 +42,11 @@
 
 enum
 {
-  ARG_0,
-  ARG_AUDIO_COMPRESSION,
-  ARG_VIDEO_QUICK_ENCODING,
-  ARG_VIDEO_SCREEN_WIDTH,
-  ARG_VIDEO_SCREEN_HEIGHT
+  PROP_0,
+  PROP_AUDIO_COMPRESSION,
+  PROP_VIDEO_QUICK_ENCODING,
+  PROP_VIDEO_SCREEN_WIDTH,
+  PROP_VIDEO_SCREEN_HEIGHT
 };
 
 #define MVE_MUX_DEFAULT_COMPRESSION    FALSE
@@ -226,16 +226,16 @@
   mvemux = GST_MVE_MUX (object);
 
   switch (prop_id) {
-    case ARG_AUDIO_COMPRESSION:
+    case PROP_AUDIO_COMPRESSION:
       g_value_set_boolean (value, mvemux->compression);
       break;
-    case ARG_VIDEO_QUICK_ENCODING:
+    case PROP_VIDEO_QUICK_ENCODING:
       g_value_set_boolean (value, mvemux->quick_encoding);
       break;
-    case ARG_VIDEO_SCREEN_WIDTH:
+    case PROP_VIDEO_SCREEN_WIDTH:
       g_value_set_uint (value, mvemux->screen_width);
       break;
-    case ARG_VIDEO_SCREEN_HEIGHT:
+    case PROP_VIDEO_SCREEN_HEIGHT:
       g_value_set_uint (value, mvemux->screen_height);
       break;
     default:
@@ -254,16 +254,16 @@
   mvemux = GST_MVE_MUX (object);
 
   switch (prop_id) {
-    case ARG_AUDIO_COMPRESSION:
+    case PROP_AUDIO_COMPRESSION:
       mvemux->compression = g_value_get_boolean (value);
       break;
-    case ARG_VIDEO_QUICK_ENCODING:
+    case PROP_VIDEO_QUICK_ENCODING:
       mvemux->quick_encoding = g_value_get_boolean (value);
       break;
-    case ARG_VIDEO_SCREEN_WIDTH:
+    case PROP_VIDEO_SCREEN_WIDTH:
       mvemux->screen_width = g_value_get_uint (value);
       break;
-    case ARG_VIDEO_SCREEN_HEIGHT:
+    case PROP_VIDEO_SCREEN_HEIGHT:
       mvemux->screen_height = g_value_get_uint (value);
       break;
     default:
@@ -1402,23 +1402,23 @@
   gobject_class->get_property = gst_mve_mux_get_property;
   gobject_class->set_property = gst_mve_mux_set_property;
 
-  g_object_class_install_property (gobject_class, ARG_AUDIO_COMPRESSION,
+  g_object_class_install_property (gobject_class, PROP_AUDIO_COMPRESSION,
       g_param_spec_boolean ("compression", "Audio compression",
           "Whether to compress audio data", MVE_MUX_DEFAULT_COMPRESSION,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  g_object_class_install_property (gobject_class, ARG_VIDEO_QUICK_ENCODING,
+  g_object_class_install_property (gobject_class, PROP_VIDEO_QUICK_ENCODING,
       g_param_spec_boolean ("quick", "Quick encoding",
           "Whether to disable expensive encoding operations", TRUE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  g_object_class_install_property (gobject_class, ARG_VIDEO_SCREEN_WIDTH,
+  g_object_class_install_property (gobject_class, PROP_VIDEO_SCREEN_WIDTH,
       g_param_spec_uint ("screen-width", "Screen width",
           "Suggested screen width", 320, 1600,
           MVE_MUX_DEFAULT_SCREEN_WIDTH,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-  g_object_class_install_property (gobject_class, ARG_VIDEO_SCREEN_HEIGHT,
+  g_object_class_install_property (gobject_class, PROP_VIDEO_SCREEN_HEIGHT,
       g_param_spec_uint ("screen-height", "Screen height",
           "Suggested screen height", 200, 1200,
           MVE_MUX_DEFAULT_SCREEN_HEIGHT,
diff --git a/gst/mxf/Makefile.am b/gst/mxf/Makefile.am
index ce19033..6ec4a78 100644
--- a/gst/mxf/Makefile.am
+++ b/gst/mxf/Makefile.am
@@ -43,17 +43,3 @@
 	mxfup.h \
 	mxfvc3.h \
 	mxfdms1.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstmxf -:SHARED libgstmxf \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstmxf_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmxf_la_CFLAGS) \
-	 -:LDFLAGS $(libgstmxf_la_LDFLAGS) \
-	           $(libgstmxf_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/mxf/Makefile.in b/gst/mxf/Makefile.in
index 90e0c04..8c61ff3 100644
--- a/gst/mxf/Makefile.in
+++ b/gst/mxf/Makefile.in
@@ -1241,20 +1241,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstmxf -:SHARED libgstmxf \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstmxf_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstmxf_la_CFLAGS) \
-	 -:LDFLAGS $(libgstmxf_la_LDFLAGS) \
-	           $(libgstmxf_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/mxf/mxfdemux.c b/gst/mxf/mxfdemux.c
index 7681d51..e45e49c 100644
--- a/gst/mxf/mxfdemux.c
+++ b/gst/mxf/mxfdemux.c
@@ -2048,11 +2048,13 @@
       (GCompareFunc) compare_index_table_segments);
 
   /* Prevent duplicates */
-  if (l == NULL)
+  if (l == NULL) {
     demux->pending_index_table_segments =
         g_list_prepend (demux->pending_index_table_segments, segment);
-  else
+  } else {
+    mxf_index_table_segment_reset (segment);
     g_free (segment);
+  }
 
   return GST_FLOW_OK;
 }
@@ -3554,6 +3556,7 @@
       }
       p->discont = TRUE;
     }
+    gst_flow_combiner_reset (demux->flowcombiner);
     if (new_offset == -1) {
       GST_WARNING_OBJECT (demux, "No new offset found");
       ret = FALSE;
diff --git a/gst/mxf/mxfdv-dif.c b/gst/mxf/mxfdv-dif.c
index dda0cae..6f72c90 100644
--- a/gst/mxf/mxfdv-dif.c
+++ b/gst/mxf/mxfdv-dif.c
@@ -23,7 +23,7 @@
 
 /* TODO:
  *  - playbin hangs on a lot of MXF/DV-DIF files (bug #563827)
- *  - decodebin2 creates loops inside the linking graph (bug #563828)
+ *  - decodebin creates loops inside the linking graph (bug #563828)
  *  - track descriptor might be multiple descriptor, one for sound, one for video
  *  - there might be 2 tracks for one essence, i.e. one audio/one video track
  */
diff --git a/gst/mxf/mxfmetadata.c b/gst/mxf/mxfmetadata.c
index 7c314e8..e306a55 100644
--- a/gst/mxf/mxfmetadata.c
+++ b/gst/mxf/mxfmetadata.c
@@ -2239,6 +2239,7 @@
       if (d->linked_track_id == package->tracks[i]->track_id ||
           (d->linked_track_id == 0 && package->n_essence_tracks == 1 &&
               (package->tracks[i]->type & 0xf0) == 0x30)) {
+        g_free (package->tracks[i]->descriptor);
         package->tracks[i]->descriptor =
             g_new0 (MXFMetadataFileDescriptor *, 1);
         package->tracks[i]->descriptor[0] = d;
@@ -2264,6 +2265,7 @@
           n_descriptor++;
       }
 
+      g_free (package->tracks[i]->descriptor);
       package->tracks[i]->descriptor =
           g_new0 (MXFMetadataFileDescriptor *, n_descriptor);
       package->tracks[i]->n_descriptor = n_descriptor;
diff --git a/gst/mxf/mxfmux.c b/gst/mxf/mxfmux.c
index a08d05e..273d3b6 100644
--- a/gst/mxf/mxfmux.c
+++ b/gst/mxf/mxfmux.c
@@ -25,7 +25,7 @@
  * <refsect2>
  * <title>Example launch line</title>
  * |[
- * gst-launch -v filesrc location=/path/to/audio ! decodebin2 ! queue ! mxfmux name=m ! filesink location=file.mxf   filesrc location=/path/to/video ! decodebin2 ! queue ! m.
+ * gst-launch -v filesrc location=/path/to/audio ! decodebin ! queue ! mxfmux name=m ! filesink location=file.mxf   filesrc location=/path/to/video ! decodebin ! queue ! m.
  * ]| This pipeline muxes an audio and video file into a single MXF file.
  * </refsect2>
  */
diff --git a/gst/nuvdemux/Makefile.am b/gst/nuvdemux/Makefile.am
index 981eb09..aecae51 100644
--- a/gst/nuvdemux/Makefile.am
+++ b/gst/nuvdemux/Makefile.am
@@ -8,17 +8,3 @@
 libgstnuvdemux_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstnuvdemux.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstnuvdemux -:SHARED libgstnuvdemux \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstnuvdemux_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstnuvdemux_la_CFLAGS) \
-	 -:LDFLAGS $(libgstnuvdemux_la_LDFLAGS) \
-	           $(libgstnuvdemux_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/nuvdemux/Makefile.in b/gst/nuvdemux/Makefile.in
index f5e5d2b..1857e90 100644
--- a/gst/nuvdemux/Makefile.in
+++ b/gst/nuvdemux/Makefile.in
@@ -1066,20 +1066,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstnuvdemux -:SHARED libgstnuvdemux \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstnuvdemux_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstnuvdemux_la_CFLAGS) \
-	 -:LDFLAGS $(libgstnuvdemux_la_LDFLAGS) \
-	           $(libgstnuvdemux_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/onvif/Makefile.am b/gst/onvif/Makefile.am
index 8ec94b1..8dfbcf0 100644
--- a/gst/onvif/Makefile.am
+++ b/gst/onvif/Makefile.am
@@ -10,20 +10,3 @@
 	$(GST_BASE_LIBS) $(GST_LIBS) -lgstrtp-$(GST_API_VERSION)
 libgstrtponvif_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstrtponvif_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-
-EXTRA_DIST =
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstrtponvif -:SHARED libgstrtponvif \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstrtponvif_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstrtponvif_la_CFLAGS) \
-	 -:LDFLAGS $(libgstrtponvif_la_LDFLAGS) \
-	           $(libgstrtponvif_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/onvif/Makefile.in b/gst/onvif/Makefile.in
index e5b33d1..40a3187 100644
--- a/gst/onvif/Makefile.in
+++ b/gst/onvif/Makefile.in
@@ -748,7 +748,6 @@
 
 libgstrtponvif_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstrtponvif_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-EXTRA_DIST = 
 all: all-am
 
 .SUFFIXES:
@@ -1091,20 +1090,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstrtponvif -:SHARED libgstrtponvif \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstrtponvif_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstrtponvif_la_CFLAGS) \
-	 -:LDFLAGS $(libgstrtponvif_la_LDFLAGS) \
-	           $(libgstrtponvif_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/onvif/gstrtponviftimestamp.c b/gst/onvif/gstrtponviftimestamp.c
index 7251d3f..818c8af 100644
--- a/gst/onvif/gstrtponviftimestamp.c
+++ b/gst/onvif/gstrtponviftimestamp.c
@@ -58,7 +58,7 @@
 
 enum
 {
-  ARG_0,
+  PROP_0,
   PROP_NTP_OFFSET,
   PROP_CSEQ,
   PROP_SET_E_BIT,
diff --git a/gst/patchdetect/Makefile.am b/gst/patchdetect/Makefile.am
index 44ba88c..5ddef3f 100644
--- a/gst/patchdetect/Makefile.am
+++ b/gst/patchdetect/Makefile.am
@@ -17,17 +17,3 @@
 libgstpatchdetect_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstpatchdetect.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstpatchdetect -:SHARED libgstpatchdetect \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstpatchdetect_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstpatchdetect_la_CFLAGS) \
-	 -:LDFLAGS $(libgstpatchdetect_la_LDFLAGS) \
-	           $(libgstpatchdetect_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/patchdetect/Makefile.in b/gst/patchdetect/Makefile.in
index 1e6caf2..02ee256 100644
--- a/gst/patchdetect/Makefile.in
+++ b/gst/patchdetect/Makefile.in
@@ -1081,20 +1081,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstpatchdetect -:SHARED libgstpatchdetect \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstpatchdetect_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstpatchdetect_la_CFLAGS) \
-	 -:LDFLAGS $(libgstpatchdetect_la_LDFLAGS) \
-	           $(libgstpatchdetect_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/pcapparse/Makefile.am b/gst/pcapparse/Makefile.am
index 0a2a4f8..0e4c078 100644
--- a/gst/pcapparse/Makefile.am
+++ b/gst/pcapparse/Makefile.am
@@ -10,17 +10,3 @@
 libgstpcapparse_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(WINSOCK2_LIBS)
 libgstpcapparse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstpcapparse_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstpcapparse -:SHARED libgstpcapparse \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstpcapparse_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstpcapparse_la_CFLAGS) \
-	 -:LDFLAGS $(libgstpcapparse_la_LDFLAGS) \
-	           $(libgstpcapparse_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/pcapparse/Makefile.in b/gst/pcapparse/Makefile.in
index 8e64945..d439529 100644
--- a/gst/pcapparse/Makefile.in
+++ b/gst/pcapparse/Makefile.in
@@ -1089,20 +1089,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstpcapparse -:SHARED libgstpcapparse \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstpcapparse_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstpcapparse_la_CFLAGS) \
-	 -:LDFLAGS $(libgstpcapparse_la_LDFLAGS) \
-	           $(libgstpcapparse_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/pcapparse/gstpcapparse.c b/gst/pcapparse/gstpcapparse.c
index ade724d..1a5388e 100644
--- a/gst/pcapparse/gstpcapparse.c
+++ b/gst/pcapparse/gstpcapparse.c
@@ -64,8 +64,7 @@
   PROP_SRC_PORT,
   PROP_DST_PORT,
   PROP_CAPS,
-  PROP_TS_OFFSET,
-  PROP_LAST
+  PROP_TS_OFFSET
 };
 
 GST_DEBUG_CATEGORY_STATIC (gst_pcap_parse_debug);
@@ -309,7 +308,6 @@
   self->initialized = FALSE;
   self->swap_endian = FALSE;
   self->cur_packet_size = -1;
-  self->buffer_offset = 0;
   self->cur_ts = GST_CLOCK_TIME_NONE;
   self->base_ts = GST_CLOCK_TIME_NONE;
   self->newsegment_sent = FALSE;
@@ -453,6 +451,7 @@
 {
   GstPcapParse *self = GST_PCAP_PARSE (parent);
   GstFlowReturn ret = GST_FLOW_OK;
+  GstBufferList *list = NULL;
 
   gst_adapter_push (self->adapter, buffer);
 
@@ -479,46 +478,34 @@
           if (gst_pcap_parse_scan_frame (self, data, self->cur_packet_size,
                   &payload_data, &payload_size)) {
             GstBuffer *out_buf;
-            GstMapInfo map;
+            guintptr offset = payload_data - data;
 
-            out_buf = gst_buffer_new_and_alloc (payload_size);
-            if (out_buf) {
+            self->cur_packet_size -= offset;
+            self->cur_packet_size -= payload_size;
 
-              if (GST_CLOCK_TIME_IS_VALID (self->cur_ts)) {
-                if (!GST_CLOCK_TIME_IS_VALID (self->base_ts))
-                  self->base_ts = self->cur_ts;
-                if (self->offset >= 0) {
-                  self->cur_ts -= self->base_ts;
-                  self->cur_ts += self->offset;
-                }
+            gst_adapter_unmap (self->adapter);
+            gst_adapter_flush (self->adapter, offset);
+            out_buf = gst_adapter_take_buffer_fast (self->adapter,
+                payload_size);
+
+            if (GST_CLOCK_TIME_IS_VALID (self->cur_ts)) {
+              if (!GST_CLOCK_TIME_IS_VALID (self->base_ts))
+                self->base_ts = self->cur_ts;
+              if (self->offset >= 0) {
+                self->cur_ts -= self->base_ts;
+                self->cur_ts += self->offset;
               }
-
-              gst_buffer_map (out_buf, &map, GST_MAP_WRITE);
-              memcpy (map.data, payload_data, payload_size);
-              gst_buffer_unmap (out_buf, &map);
-              GST_BUFFER_TIMESTAMP (out_buf) = self->cur_ts;
-
-              if (!self->newsegment_sent &&
-                  GST_CLOCK_TIME_IS_VALID (self->cur_ts)) {
-                GstSegment segment;
-
-                if (self->caps)
-                  gst_pad_set_caps (self->src_pad, self->caps);
-                gst_segment_init (&segment, GST_FORMAT_TIME);
-                segment.start = self->cur_ts;
-                gst_pad_push_event (self->src_pad,
-                    gst_event_new_segment (&segment));
-                self->newsegment_sent = TRUE;
-              }
-
-              ret = gst_pad_push (self->src_pad, out_buf);
-
-              self->buffer_offset += payload_size;
             }
-          }
+            GST_BUFFER_TIMESTAMP (out_buf) = self->cur_ts;
 
-          gst_adapter_unmap (self->adapter);
-          gst_adapter_flush (self->adapter, self->cur_packet_size);
+
+            if (list == NULL)
+              list = gst_buffer_list_new ();
+            gst_buffer_list_add (list, out_buf);
+          } else {
+            gst_adapter_unmap (self->adapter);
+            gst_adapter_flush (self->adapter, self->cur_packet_size);
+          }
         }
 
         self->cur_packet_size = -1;
@@ -594,7 +581,27 @@
     }
   }
 
+  if (list) {
+    if (!self->newsegment_sent && GST_CLOCK_TIME_IS_VALID (self->cur_ts)) {
+      GstSegment segment;
+
+      if (self->caps)
+        gst_pad_set_caps (self->src_pad, self->caps);
+      gst_segment_init (&segment, GST_FORMAT_TIME);
+      segment.start = self->cur_ts;
+      gst_pad_push_event (self->src_pad, gst_event_new_segment (&segment));
+      self->newsegment_sent = TRUE;
+    }
+
+    ret = gst_pad_push_list (self->src_pad, list);
+    list = NULL;
+  }
+
 out:
+
+  if (list)
+    gst_buffer_list_unref (list);
+
   if (ret != GST_FLOW_OK)
     gst_pcap_parse_reset (self);
 
diff --git a/gst/pcapparse/gstpcapparse.h b/gst/pcapparse/gstpcapparse.h
index 2c9216f..02ed95f 100644
--- a/gst/pcapparse/gstpcapparse.h
+++ b/gst/pcapparse/gstpcapparse.h
@@ -84,8 +84,6 @@
   GstPcapParseLinktype linktype;
 
   gboolean newsegment_sent;
-
-  gint64 buffer_offset;
 };
 
 struct _GstPcapParseClass
diff --git a/gst/pnm/Makefile.am b/gst/pnm/Makefile.am
index e6c397b..2f242f9 100644
--- a/gst/pnm/Makefile.am
+++ b/gst/pnm/Makefile.am
@@ -7,17 +7,3 @@
 libgstpnm_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstpnmdec.h gstpnmutils.h gstpnmenc.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstpnm -:SHARED libgstpnm \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstpnm_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstpnm_la_CFLAGS) \
-	 -:LDFLAGS $(libgstpnm_la_LDFLAGS) \
-	           $(libgstpnm_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/pnm/Makefile.in b/gst/pnm/Makefile.in
index 5cedcf2..b2f7977 100644
--- a/gst/pnm/Makefile.in
+++ b/gst/pnm/Makefile.in
@@ -1093,20 +1093,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstpnm -:SHARED libgstpnm \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstpnm_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstpnm_la_CFLAGS) \
-	 -:LDFLAGS $(libgstpnm_la_LDFLAGS) \
-	           $(libgstpnm_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/rawparse/Makefile.am b/gst/rawparse/Makefile.am
index 15d2804..03eeb48 100644
--- a/gst/rawparse/Makefile.am
+++ b/gst/rawparse/Makefile.am
@@ -22,17 +22,3 @@
 	gstaudioparse.h \
 	gstrawparse.h \
 	gstvideoparse.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstrawparse -:SHARED libgstrawparse \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstrawparse_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstrawparse_la_CFLAGS) \
-	 -:LDFLAGS $(libgstrawparse_la_LDFLAGS) \
-	           $(libgstrawparse_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/rawparse/Makefile.in b/gst/rawparse/Makefile.in
index fd4b406..282125e 100644
--- a/gst/rawparse/Makefile.in
+++ b/gst/rawparse/Makefile.in
@@ -1111,20 +1111,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstrawparse -:SHARED libgstrawparse \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstrawparse_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstrawparse_la_CFLAGS) \
-	 -:LDFLAGS $(libgstrawparse_la_LDFLAGS) \
-	           $(libgstrawparse_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/removesilence/gstremovesilence.c b/gst/removesilence/gstremovesilence.c
index f1105fe..d63c60a 100644
--- a/gst/removesilence/gstremovesilence.c
+++ b/gst/removesilence/gstremovesilence.c
@@ -26,7 +26,7 @@
  * <refsect2>
  * <title>Example launch line</title>
  * |[
- * gst-launch -v -m filesrc location="audiofile" ! decodebin2 ! removesilence remove=true ! wavenc ! filesink location=without_audio.wav 
+ * gst-launch -v -m filesrc location="audiofile" ! decodebin ! removesilence remove=true ! wavenc ! filesink location=without_audio.wav
  * ]|
  * </refsect2>
  */
@@ -93,7 +93,6 @@
 static GstFlowReturn gst_remove_silence_transform_ip (GstBaseTransform * base,
     GstBuffer * buf);
 static void gst_remove_silence_finalize (GObject * obj);
-static void gst_remove_silence_reset (GstRemoveSilence * filter);
 
 /* GObject vmethod implementations */
 
@@ -153,18 +152,6 @@
     GST_DEBUG ("Error initializing VAD !!");
     return;
   }
-
-  gst_remove_silence_reset (filter);
-}
-
-static void
-gst_remove_silence_reset (GstRemoveSilence * filter)
-{
-  GST_DEBUG ("Reseting VAD");
-  if (filter->vad) {
-    vad_reset (filter->vad);
-  }
-  GST_DEBUG ("VAD Reseted");
 }
 
 static void
@@ -231,7 +218,6 @@
   gst_buffer_unmap (inbuf, &map);
 
   if (frame_type == VAD_SILENCE) {
-
     GST_DEBUG ("Silence detected");
 
     if (filter->remove) {
diff --git a/gst/rtp/Makefile.am b/gst/rtp/Makefile.am
index cc4e0df..8566ed0 100644
--- a/gst/rtp/Makefile.am
+++ b/gst/rtp/Makefile.am
@@ -23,17 +23,3 @@
 noinst_HEADERS =			\
 	gstrtph265depay.h \
 	gstrtph265pay.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstrtpbad -:SHARED libgstrtpbad \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstrtpbad_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstrtpbad_la_CFLAGS) \
-	 -:LDFLAGS $(libgstrtpbad_la_LDFLAGS) \
-	  $(libgstrtpbad_la_LIBADD) \
-	  -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-	      LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/rtp/Makefile.in b/gst/rtp/Makefile.in
index d04a764..ec2b9a1 100644
--- a/gst/rtp/Makefile.in
+++ b/gst/rtp/Makefile.in
@@ -1105,20 +1105,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstrtpbad -:SHARED libgstrtpbad \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstrtpbad_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstrtpbad_la_CFLAGS) \
-	 -:LDFLAGS $(libgstrtpbad_la_LDFLAGS) \
-	  $(libgstrtpbad_la_LIBADD) \
-	  -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-	      LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/rtp/gstrtph265pay.c b/gst/rtp/gstrtph265pay.c
index b2da44d..171a242 100644
--- a/gst/rtp/gstrtph265pay.c
+++ b/gst/rtp/gstrtph265pay.c
@@ -108,8 +108,7 @@
 {
   PROP_0,
   PROP_SPROP_PARAMETER_SETS,
-  PROP_CONFIG_INTERVAL,
-  PROP_LAST
+  PROP_CONFIG_INTERVAL
 };
 
 #define IS_ACCESS_UNIT(x) (((x) > 0x00) && ((x) < 0x06))
diff --git a/gst/sdi/Makefile.am b/gst/sdi/Makefile.am
index 47897cf..04744fa 100644
--- a/gst/sdi/Makefile.am
+++ b/gst/sdi/Makefile.am
@@ -11,17 +11,3 @@
 libgstsdi_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstsdidemux.h gstsdimux.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstsdi -:SHARED libgstsdi \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstsdi_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstsdi_la_CFLAGS) \
-	 -:LDFLAGS $(libgstsdi_la_LDFLAGS) \
-	           $(libgstsdi_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
\ No newline at end of file
diff --git a/gst/sdi/Makefile.in b/gst/sdi/Makefile.in
index fb2c6af..7fb612f 100644
--- a/gst/sdi/Makefile.in
+++ b/gst/sdi/Makefile.in
@@ -1089,20 +1089,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstsdi -:SHARED libgstsdi \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstsdi_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstsdi_la_CFLAGS) \
-	 -:LDFLAGS $(libgstsdi_la_LDFLAGS) \
-	           $(libgstsdi_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/sdp/Makefile.am b/gst/sdp/Makefile.am
index 8c5e94c..395b857 100644
--- a/gst/sdp/Makefile.am
+++ b/gst/sdp/Makefile.am
@@ -10,17 +10,3 @@
 libgstsdpelem_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstsdpdemux.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstsdp -:SHARED libgstsdp \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstsdp_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstsdp_la_CFLAGS) \
-	 -:LDFLAGS $(libgstsdp_la_LDFLAGS) \
-	           $(libgstsdp_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/sdp/Makefile.in b/gst/sdp/Makefile.in
index 465bc96..04122c8 100644
--- a/gst/sdp/Makefile.in
+++ b/gst/sdp/Makefile.in
@@ -1080,20 +1080,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstsdp -:SHARED libgstsdp \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstsdp_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstsdp_la_CFLAGS) \
-	 -:LDFLAGS $(libgstsdp_la_LDFLAGS) \
-	           $(libgstsdp_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/sdp/gstsdpdemux.c b/gst/sdp/gstsdpdemux.c
index d2a1fa3..df3e69e 100644
--- a/gst/sdp/gstsdpdemux.c
+++ b/gst/sdp/gstsdpdemux.c
@@ -84,8 +84,7 @@
   PROP_DEBUG,
   PROP_TIMEOUT,
   PROP_LATENCY,
-  PROP_REDIRECT,
-  PROP_LAST
+  PROP_REDIRECT
 };
 
 static void gst_sdp_demux_finalize (GObject * object);
diff --git a/gst/segmentclip/Makefile.am b/gst/segmentclip/Makefile.am
index 22d55a2..03eb2e2 100644
--- a/gst/segmentclip/Makefile.am
+++ b/gst/segmentclip/Makefile.am
@@ -8,17 +8,3 @@
 libgstsegmentclip_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstsegmentclip.h gstaudiosegmentclip.h gstvideosegmentclip.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstsegmentclip -:SHARED libgstsegmentclip \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstsegmentclip_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstsegmentclip_la_CFLAGS) \
-	 -:LDFLAGS $(libgstsegmentclip_la_LDFLAGS) \
-	           $(libgstsegmentclip_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
\ No newline at end of file
diff --git a/gst/segmentclip/Makefile.in b/gst/segmentclip/Makefile.in
index 24c95c5..dffa001 100644
--- a/gst/segmentclip/Makefile.in
+++ b/gst/segmentclip/Makefile.in
@@ -1095,20 +1095,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstsegmentclip -:SHARED libgstsegmentclip \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstsegmentclip_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstsegmentclip_la_CFLAGS) \
-	 -:LDFLAGS $(libgstsegmentclip_la_LDFLAGS) \
-	           $(libgstsegmentclip_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/siren/Makefile.am b/gst/siren/Makefile.am
index dc27f77..d419b71 100644
--- a/gst/siren/Makefile.am
+++ b/gst/siren/Makefile.am
@@ -14,17 +14,3 @@
 	$(GST_BASE_LIBS) $(GST_LIBS) $(LIBM)
 libgstsiren_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstsiren_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstsiren -:SHARED libgstsiren \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstsiren_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstsiren_la_CFLAGS) \
-	 -:LDFLAGS $(libgstsiren_la_LDFLAGS) \
-	           $(libgstsiren_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
\ No newline at end of file
diff --git a/gst/siren/Makefile.in b/gst/siren/Makefile.in
index cb2773b..df58a5e 100644
--- a/gst/siren/Makefile.in
+++ b/gst/siren/Makefile.in
@@ -1143,20 +1143,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstsiren -:SHARED libgstsiren \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstsiren_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstsiren_la_CFLAGS) \
-	 -:LDFLAGS $(libgstsiren_la_LDFLAGS) \
-	           $(libgstsiren_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/smooth/Makefile.am b/gst/smooth/Makefile.am
index 74f7231..7d8ca06 100644
--- a/gst/smooth/Makefile.am
+++ b/gst/smooth/Makefile.am
@@ -14,17 +14,3 @@
 libgstsmooth_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gstsmooth.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstsmooth -:SHARED libgstsmooth \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstsmooth_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstsmooth_la_CFLAGS) \
-	 -:LDFLAGS $(libgstsmooth_la_LDFLAGS) \
-	           $(libgstsmooth_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/smooth/Makefile.in b/gst/smooth/Makefile.in
index a6e58d5..d8480d2 100644
--- a/gst/smooth/Makefile.in
+++ b/gst/smooth/Makefile.in
@@ -1075,20 +1075,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstsmooth -:SHARED libgstsmooth \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstsmooth_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstsmooth_la_CFLAGS) \
-	 -:LDFLAGS $(libgstsmooth_la_LDFLAGS) \
-	           $(libgstsmooth_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/speed/Makefile.am b/gst/speed/Makefile.am
index 812a27f..1878e98 100644
--- a/gst/speed/Makefile.am
+++ b/gst/speed/Makefile.am
@@ -16,17 +16,3 @@
 #demo_mp3_SOURCES = demo-mp3.c
 #demo_mp3_CFLAGS  = $(GTK_CFLAGS) $(GST_CFLAGS) 
 #demo_mp3_LDFLAGS = $(GST_LIBS) $(GTK_LIBS)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstspeed -:SHARED libgstspeed \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstspeed_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstspeed_la_CFLAGS) \
-	 -:LDFLAGS $(libgstspeed_la_LDFLAGS) \
-	           $(libgstspeed_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/speed/Makefile.in b/gst/speed/Makefile.in
index b2fc0dc..c996df1 100644
--- a/gst/speed/Makefile.in
+++ b/gst/speed/Makefile.in
@@ -1075,20 +1075,6 @@
 #demo_mp3_CFLAGS  = $(GTK_CFLAGS) $(GST_CFLAGS) 
 #demo_mp3_LDFLAGS = $(GST_LIBS) $(GTK_LIBS)
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstspeed -:SHARED libgstspeed \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstspeed_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstspeed_la_CFLAGS) \
-	 -:LDFLAGS $(libgstspeed_la_LDFLAGS) \
-	           $(libgstspeed_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/speed/gstspeed.c b/gst/speed/gstspeed.c
index 40d1612..9fcdad3 100644
--- a/gst/speed/gstspeed.c
+++ b/gst/speed/gstspeed.c
@@ -52,8 +52,8 @@
 
 enum
 {
-  ARG_0,
-  ARG_SPEED
+  PROP_0,
+  PROP_SPEED
 };
 
 /* assumption here: sizeof (gfloat) = 4 */
@@ -388,7 +388,7 @@
   gobject_class->get_property = speed_get_property;
   gstelement_class->change_state = speed_change_state;
 
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SPEED,
+  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SPEED,
       g_param_spec_float ("speed", "speed", "speed",
           0.1, 40.0, 1.0,
           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
@@ -641,7 +641,7 @@
   GstSpeed *filter = GST_SPEED (object);
 
   switch (prop_id) {
-    case ARG_SPEED:
+    case PROP_SPEED:
       filter->speed = g_value_get_float (value);
       break;
     default:
@@ -658,7 +658,7 @@
   GstSpeed *filter = GST_SPEED (object);
 
   switch (prop_id) {
-    case ARG_SPEED:
+    case PROP_SPEED:
       g_value_set_float (value, filter->speed);
       break;
     default:
diff --git a/gst/stereo/Makefile.am b/gst/stereo/Makefile.am
index e27f6d4..f141b0f 100644
--- a/gst/stereo/Makefile.am
+++ b/gst/stereo/Makefile.am
@@ -8,19 +8,3 @@
 libgststereo_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gststereo.h
-
-EXTRA_DIST =
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgststereo -:SHARED libgststereo \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgststereo_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgststereo_la_CFLAGS) \
-	 -:LDFLAGS $(libgststereo_la_LDFLAGS) \
-	           $(libgststereo_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/stereo/Makefile.in b/gst/stereo/Makefile.in
index 67f1b04..4ed88c0 100644
--- a/gst/stereo/Makefile.in
+++ b/gst/stereo/Makefile.in
@@ -741,7 +741,6 @@
 libgststereo_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgststereo_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 noinst_HEADERS = gststereo.h
-EXTRA_DIST = 
 all: all-am
 
 .SUFFIXES:
@@ -1068,20 +1067,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgststereo -:SHARED libgststereo \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgststereo_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgststereo_la_CFLAGS) \
-	 -:LDFLAGS $(libgststereo_la_LDFLAGS) \
-	           $(libgststereo_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/stereo/gststereo.c b/gst/stereo/gststereo.c
index 4247e4d..ebadf9a 100644
--- a/gst/stereo/gststereo.c
+++ b/gst/stereo/gststereo.c
@@ -59,9 +59,9 @@
 
 enum
 {
-  ARG_0,
-  ARG_ACTIVE,
-  ARG_STEREO
+  PROP_0,
+  PROP_ACTIVE,
+  PROP_STEREO
 };
 
 static void gst_stereo_set_property (GObject * object, guint prop_id,
@@ -95,12 +95,12 @@
   gobject_class->set_property = gst_stereo_set_property;
   gobject_class->get_property = gst_stereo_get_property;
 
-  g_object_class_install_property (gobject_class, ARG_ACTIVE,
+  g_object_class_install_property (gobject_class, PROP_ACTIVE,
       g_param_spec_boolean ("active", "active", "active",
           TRUE,
           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
 
-  g_object_class_install_property (gobject_class, ARG_STEREO,
+  g_object_class_install_property (gobject_class, PROP_STEREO,
       g_param_spec_float ("stereo", "stereo", "stereo",
           0.0, 1.0, 0.1,
           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
@@ -169,10 +169,10 @@
   GstStereo *stereo = GST_STEREO (object);
 
   switch (prop_id) {
-    case ARG_ACTIVE:
+    case PROP_ACTIVE:
       stereo->active = g_value_get_boolean (value);
       break;
-    case ARG_STEREO:
+    case PROP_STEREO:
       stereo->stereo = g_value_get_float (value) * 10.0;
       break;
     default:
@@ -188,10 +188,10 @@
   GstStereo *stereo = GST_STEREO (object);
 
   switch (prop_id) {
-    case ARG_ACTIVE:
+    case PROP_ACTIVE:
       g_value_set_boolean (value, stereo->active);
       break;
-    case ARG_STEREO:
+    case PROP_STEREO:
       g_value_set_float (value, stereo->stereo / 10.0);
       break;
     default:
diff --git a/gst/subenc/Makefile.am b/gst/subenc/Makefile.am
index 013b2ba..6ac45c5 100644
--- a/gst/subenc/Makefile.am
+++ b/gst/subenc/Makefile.am
@@ -12,17 +12,3 @@
 noinst_HEADERS = \
 	gstsrtenc.h \
 	gstwebvttenc.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstsubenc -:SHARED libgstsubenc \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstsubenc_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstsubenc_la_CFLAGS) \
-	 -:LDFLAGS $(libgstsubenc_la_LDFLAGS) \
-	           $(libgstsubenc_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/subenc/Makefile.in b/gst/subenc/Makefile.in
index 483598c..366e98a 100644
--- a/gst/subenc/Makefile.in
+++ b/gst/subenc/Makefile.in
@@ -1090,20 +1090,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstsubenc -:SHARED libgstsubenc \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstsubenc_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstsubenc_la_CFLAGS) \
-	 -:LDFLAGS $(libgstsubenc_la_LDFLAGS) \
-	           $(libgstsubenc_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/subenc/gstsrtenc.c b/gst/subenc/gstsrtenc.c
index d9dcdd6..079fc44 100644
--- a/gst/subenc/gstsrtenc.c
+++ b/gst/subenc/gstsrtenc.c
@@ -30,9 +30,9 @@
 
 enum
 {
-  ARG_0,
-  ARG_TIMESTAMP,
-  ARG_DURATION
+  PROP_0,
+  PROP_TIMESTAMP,
+  PROP_DURATION
 };
 
 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
@@ -190,10 +190,10 @@
   srtenc = GST_SRT_ENC (object);
 
   switch (prop_id) {
-    case ARG_TIMESTAMP:
+    case PROP_TIMESTAMP:
       g_value_set_int64 (value, srtenc->timestamp);
       break;
-    case ARG_DURATION:
+    case PROP_DURATION:
       g_value_set_int64 (value, srtenc->duration);
       break;
     default:
@@ -212,10 +212,10 @@
   srtenc = GST_SRT_ENC (object);
 
   switch (prop_id) {
-    case ARG_TIMESTAMP:
+    case PROP_TIMESTAMP:
       srtenc->timestamp = g_value_get_int64 (value);
       break;
-    case ARG_DURATION:
+    case PROP_DURATION:
       srtenc->duration = g_value_get_int64 (value);
       break;
     default:
@@ -235,12 +235,12 @@
 
   element_class->change_state = GST_DEBUG_FUNCPTR (gst_srt_enc_change_state);
 
-  g_object_class_install_property (gobject_class, ARG_TIMESTAMP,
+  g_object_class_install_property (gobject_class, PROP_TIMESTAMP,
       g_param_spec_int64 ("timestamp", "Offset for the starttime",
           "Offset for the starttime for the subtitles", G_MININT64, G_MAXINT64,
           0,
           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, ARG_DURATION,
+  g_object_class_install_property (gobject_class, PROP_DURATION,
       g_param_spec_int64 ("duration", "Offset for the duration",
           "Offset for the duration of the subtitles", G_MININT64, G_MAXINT64,
           0,
diff --git a/gst/subenc/gstwebvttenc.c b/gst/subenc/gstwebvttenc.c
index a829580..67b6305 100644
--- a/gst/subenc/gstwebvttenc.c
+++ b/gst/subenc/gstwebvttenc.c
@@ -31,9 +31,9 @@
 
 enum
 {
-  ARG_0,
-  ARG_TIMESTAMP,
-  ARG_DURATION
+  PROP_0,
+  PROP_TIMESTAMP,
+  PROP_DURATION
 };
 
 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
@@ -210,10 +210,10 @@
   webvttenc = GST_WEBVTT_ENC (object);
 
   switch (prop_id) {
-    case ARG_TIMESTAMP:
+    case PROP_TIMESTAMP:
       g_value_set_int64 (value, webvttenc->timestamp);
       break;
-    case ARG_DURATION:
+    case PROP_DURATION:
       g_value_set_int64 (value, webvttenc->duration);
       break;
     default:
@@ -232,10 +232,10 @@
   webvttenc = GST_WEBVTT_ENC (object);
 
   switch (prop_id) {
-    case ARG_TIMESTAMP:
+    case PROP_TIMESTAMP:
       webvttenc->timestamp = g_value_get_int64 (value);
       break;
-    case ARG_DURATION:
+    case PROP_DURATION:
       webvttenc->duration = g_value_get_int64 (value);
       break;
     default:
@@ -255,12 +255,12 @@
 
   element_class->change_state = GST_DEBUG_FUNCPTR (gst_webvtt_enc_change_state);
 
-  g_object_class_install_property (gobject_class, ARG_TIMESTAMP,
+  g_object_class_install_property (gobject_class, PROP_TIMESTAMP,
       g_param_spec_int64 ("timestamp", "Offset for the starttime",
           "Offset for the starttime for the subtitles", G_MININT64, G_MAXINT64,
           0,
           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, ARG_DURATION,
+  g_object_class_install_property (gobject_class, PROP_DURATION,
       g_param_spec_int64 ("duration", "Offset for the duration",
           "Offset for the duration of the subtitles", G_MININT64, G_MAXINT64,
           0,
diff --git a/gst/tta/Makefile.am b/gst/tta/Makefile.am
index c20414a..3c8aa0f 100644
--- a/gst/tta/Makefile.am
+++ b/gst/tta/Makefile.am
@@ -11,17 +11,3 @@
 libgsttta_la_LIBADD = $(GST_LIBS) $(LIBM)
 libgsttta_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgsttta_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgsttta -:SHARED libgsttta \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgsttta_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgsttta_la_CFLAGS) \
-	 -:LDFLAGS $(libgsttta_la_LDFLAGS) \
-	           $(libgsttta_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
\ No newline at end of file
diff --git a/gst/tta/Makefile.in b/gst/tta/Makefile.in
index 4de83c4..38d218a 100644
--- a/gst/tta/Makefile.in
+++ b/gst/tta/Makefile.in
@@ -1089,20 +1089,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgsttta -:SHARED libgsttta \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgsttta_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgsttta_la_CFLAGS) \
-	 -:LDFLAGS $(libgsttta_la_LDFLAGS) \
-	           $(libgsttta_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/tta/gstttadec.c b/gst/tta/gstttadec.c
index d30a519..f4e29a2 100644
--- a/gst/tta/gstttadec.c
+++ b/gst/tta/gstttadec.c
@@ -70,7 +70,7 @@
 
 enum
 {
-  ARG_0
+  PROP_0
 };
 
 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
diff --git a/gst/videofilters/Makefile.am b/gst/videofilters/Makefile.am
index 276f853..80393c4 100644
--- a/gst/videofilters/Makefile.am
+++ b/gst/videofilters/Makefile.am
@@ -27,17 +27,3 @@
 noinst_HEADERS = \
 	gstzebrastripe.h \
 	gstscenechange.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstvideofilters -:SHARED libgstvideofilters \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstvideofilters_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstvideofilters_la_CFLAGS) \
-	 -:LDFLAGS $(libgstvideofilters_la_LDFLAGS) \
-	           $(libgstvideofilters_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/videofilters/Makefile.in b/gst/videofilters/Makefile.in
index be48ccb..04844b9 100644
--- a/gst/videofilters/Makefile.in
+++ b/gst/videofilters/Makefile.in
@@ -1121,20 +1121,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstvideofilters -:SHARED libgstvideofilters \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstvideofilters_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstvideofilters_la_CFLAGS) \
-	 -:LDFLAGS $(libgstvideofilters_la_LDFLAGS) \
-	           $(libgstvideofilters_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/videomeasure/Makefile.am b/gst/videomeasure/Makefile.am
index d3c2f78..139dee9 100644
--- a/gst/videomeasure/Makefile.am
+++ b/gst/videomeasure/Makefile.am
@@ -16,17 +16,3 @@
     -lgstvideo-@GST_API_VERSION@ $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM)
 libgstvideomeasure_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstvideomeasure_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstvideomeasure -:SHARED libgstvideomeasure \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstvideomeasure_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstvideomeasure_la_CFLAGS) \
-	 -:LDFLAGS $(libgstvideomeasure_la_LDFLAGS) \
-	           $(libgstvideomeasure_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
\ No newline at end of file
diff --git a/gst/videomeasure/Makefile.in b/gst/videomeasure/Makefile.in
index 29d9caa..1bab53c 100644
--- a/gst/videomeasure/Makefile.in
+++ b/gst/videomeasure/Makefile.in
@@ -1098,20 +1098,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstvideomeasure -:SHARED libgstvideomeasure \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstvideomeasure_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstvideomeasure_la_CFLAGS) \
-	 -:LDFLAGS $(libgstvideomeasure_la_LDFLAGS) \
-	           $(libgstvideomeasure_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/videomeasure/gstvideomeasure_ssim.c b/gst/videomeasure/gstvideomeasure_ssim.c
index 8ccac88..e85d68f 100644
--- a/gst/videomeasure/gstvideomeasure_ssim.c
+++ b/gst/videomeasure/gstvideomeasure_ssim.c
@@ -39,8 +39,8 @@
  * <title>Example launch line</title>
  * |[
  * gst-launch ssim name=ssim ssim.src0 ! videoconvert ! glimagesink filesrc
- * location=orig.avi ! decodebin2 ! ssim.original filesrc location=compr.avi !
- * decodebin2 ! ssim.modified0
+ * location=orig.avi ! decodebin ! ssim.original filesrc location=compr.avi !
+ * decodebin ! ssim.modified0
  * ]| This pipeline produces a video stream that consists of SSIM frames.
  * </refsect2>
  */
diff --git a/gst/videoparsers/Makefile.am b/gst/videoparsers/Makefile.am
index ccb7d5b..f1b0a11 100644
--- a/gst/videoparsers/Makefile.am
+++ b/gst/videoparsers/Makefile.am
@@ -32,19 +32,3 @@
 	gstpngparse.h \
 	gstvc1parse.h \
 	gsth265parse.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstvideoparsersbad -:SHARED libgstvideoparsersbad \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstvideoparsersbad_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstvideoparsersbad_la_CFLAGS) \
-	 -:LDFLAGS $(libgstvideoparsersbad_la_LDFLAGS) \
-	           $(libgstvideoparsersbad_la_LIBADD) \
-	           -ldl \
-	 -:LIBFILTER_STATIC gstbaseparse-@GST_API_VERSION@ \
-	                    gstcodecparsers-@GST_API_VERSION@ \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/videoparsers/Makefile.in b/gst/videoparsers/Makefile.in
index 0c29932..a59437c 100644
--- a/gst/videoparsers/Makefile.in
+++ b/gst/videoparsers/Makefile.in
@@ -1188,22 +1188,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstvideoparsersbad -:SHARED libgstvideoparsersbad \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstvideoparsersbad_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstvideoparsersbad_la_CFLAGS) \
-	 -:LDFLAGS $(libgstvideoparsersbad_la_LDFLAGS) \
-	           $(libgstvideoparsersbad_la_LIBADD) \
-	           -ldl \
-	 -:LIBFILTER_STATIC gstbaseparse-@GST_API_VERSION@ \
-	                    gstcodecparsers-@GST_API_VERSION@ \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c
index f7a56e2..969342e 100644
--- a/gst/videoparsers/gsth264parse.c
+++ b/gst/videoparsers/gsth264parse.c
@@ -41,8 +41,7 @@
 enum
 {
   PROP_0,
-  PROP_CONFIG_INTERVAL,
-  PROP_LAST
+  PROP_CONFIG_INTERVAL
 };
 
 enum
@@ -361,7 +360,7 @@
   caps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (h264parse));
   GST_DEBUG_OBJECT (h264parse, "allowed caps: %" GST_PTR_FORMAT, caps);
 
-  /* concentrate on leading structure, since decodebin2 parser
+  /* concentrate on leading structure, since decodebin parser
    * capsfilter always includes parser template caps */
   if (caps) {
     caps = gst_caps_truncate (caps);
@@ -887,7 +886,6 @@
     if (h264parse->split_packetized) {
       GST_ELEMENT_ERROR (h264parse, STREAM, FAILED, (NULL),
           ("invalid AVC input data"));
-      gst_buffer_unref (buffer);
 
       return GST_FLOW_ERROR;
     } else {
@@ -1397,6 +1395,121 @@
   gst_caps_unref (filter_caps);
 }
 
+static const gchar *
+digit_to_string (guint digit)
+{
+  static const char itoa[][2] = {
+    "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
+  };
+
+  if (G_LIKELY (digit < 10))
+    return itoa[digit];
+  else
+    return NULL;
+}
+
+static const gchar *
+get_profile_string (GstH264SPS * sps)
+{
+  const gchar *profile = NULL;
+
+  switch (sps->profile_idc) {
+    case 66:
+      if (sps->constraint_set1_flag)
+        profile = "constrained-baseline";
+      else
+        profile = "baseline";
+      break;
+    case 77:
+      profile = "main";
+      break;
+    case 88:
+      profile = "extended";
+      break;
+    case 100:
+      profile = "high";
+      break;
+    case 110:
+      if (sps->constraint_set3_flag)
+        profile = "high-10-intra";
+      else
+        profile = "high-10";
+      break;
+    case 122:
+      if (sps->constraint_set3_flag)
+        profile = "high-4:2:2-intra";
+      else
+        profile = "high-4:2:2";
+      break;
+    case 244:
+      if (sps->constraint_set3_flag)
+        profile = "high-4:4:4-intra";
+      else
+        profile = "high-4:4:4";
+      break;
+    case 44:
+      profile = "cavlc-4:4:4-intra";
+      break;
+    case 118:
+      profile = "multiview-high";
+      break;
+    case 128:
+      profile = "stereo-high";
+      break;
+    case 83:
+      if (sps->constraint_set5_flag)
+        profile = "scalable-constrained-baseline";
+      else
+        profile = "scalable-baseline";
+      break;
+    case 86:
+      profile = "scalable-high";
+      break;
+    default:
+      return NULL;
+  }
+
+  return profile;
+}
+
+static const gchar *
+get_level_string (GstH264SPS * sps)
+{
+  if ((sps->level_idc == 11 && sps->constraint_set3_flag)
+      || sps->level_idc == 9)
+    return "1b";
+  else if (sps->level_idc % 10 == 0)
+    return digit_to_string (sps->level_idc / 10);
+  else {
+    switch (sps->level_idc) {
+      case 11:
+        return "1.1";
+      case 12:
+        return "1.2";
+      case 13:
+        return "1.3";
+      case 21:
+        return "2.1";
+      case 22:
+        return "2.2";
+      case 31:
+        return "3.1";
+      case 32:
+        return "3.2";
+      case 41:
+        return "4.1";
+      case 42:
+        return "4.2";
+      case 51:
+        return "5.1";
+      case 52:
+        return "5.2";
+      default:
+        return NULL;
+    }
+  }
+}
+
 static void
 gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps)
 {
@@ -1556,17 +1669,18 @@
 
     /* set profile and level in caps */
     if (sps) {
-      GstMapInfo map;
-      GstBuffer *sps_buf = h264parse->sps_nals[sps->id];
+      const gchar *profile, *level;
 
-      if (sps_buf) {
-        gst_buffer_map (sps_buf, &map, GST_MAP_READ);
-        gst_codec_utils_h264_caps_set_level_and_profile (caps,
-            map.data + 1, map.size - 1);
-        gst_buffer_unmap (sps_buf, &map);
-        /* relax the profile constraint to find a suitable decoder */
-        ensure_caps_profile (h264parse, caps, sps);
-      }
+      profile = get_profile_string (sps);
+      if (profile != NULL)
+        gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
+
+      level = get_level_string (sps);
+      if (level != NULL)
+        gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
+
+      /* relax the profile constraint to find a suitable decoder */
+      ensure_caps_profile (h264parse, caps, sps);
     }
 
     src_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (h264parse));
@@ -2238,11 +2352,6 @@
     h264parse->packetized = FALSE;
     /* we have 4 sync bytes */
     h264parse->nal_length_size = 4;
-
-    if (format == GST_H264_PARSE_FORMAT_NONE) {
-      format = GST_H264_PARSE_FORMAT_BYTE;
-      align = GST_H264_PARSE_ALIGN_AU;
-    }
   } else {
     /* probably AVC3 without codec_data field, anything to do here? */
   }
diff --git a/gst/videoparsers/gsth265parse.c b/gst/videoparsers/gsth265parse.c
index 2d7b997..896b7e8 100644
--- a/gst/videoparsers/gsth265parse.c
+++ b/gst/videoparsers/gsth265parse.c
@@ -37,8 +37,7 @@
 enum
 {
   PROP_0,
-  PROP_CONFIG_INTERVAL,
-  PROP_LAST
+  PROP_CONFIG_INTERVAL
 };
 
 enum
@@ -230,7 +229,7 @@
   GST_DEBUG_OBJECT (parse, "stop");
   gst_h265_parse_reset (h265parse);
 
-  for (i = 0; i < GST_H265_MAX_SPS_COUNT; i++)
+  for (i = 0; i < GST_H265_MAX_VPS_COUNT; i++)
     gst_buffer_replace (&h265parse->vps_nals[i], NULL);
   for (i = 0; i < GST_H265_MAX_SPS_COUNT; i++)
     gst_buffer_replace (&h265parse->sps_nals[i], NULL);
@@ -321,7 +320,7 @@
   caps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (h265parse));
   GST_DEBUG_OBJECT (h265parse, "allowed caps: %" GST_PTR_FORMAT, caps);
 
-  /* concentrate on leading structure, since decodebin2 parser
+  /* concentrate on leading structure, since decodebin parser
    * capsfilter always includes parser template caps */
   if (caps) {
     caps = gst_caps_truncate (caps);
@@ -1199,6 +1198,81 @@
   }
 }
 
+static const gchar *
+digit_to_string (guint digit)
+{
+  static const char itoa[][2] = {
+    "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
+  };
+
+  if (G_LIKELY (digit < 10))
+    return itoa[digit];
+  else
+    return NULL;
+}
+
+static const gchar *
+get_profile_string (guint8 profile_idc)
+{
+  const gchar *profile = NULL;
+
+  if (profile_idc == 1)
+    profile = "main";
+  else if (profile_idc == 2)
+    profile = "main-10";
+  else if (profile_idc == 3)
+    profile = "main-still-picture";
+
+  return profile;
+}
+
+static const gchar *
+get_tier_string (guint8 tier_flag)
+{
+  const gchar *tier = NULL;
+
+  if (tier_flag)
+    tier = "high";
+  else
+    tier = "main";
+
+  return tier;
+}
+
+static const gchar *
+get_level_string (guint8 level_idc)
+{
+  if (level_idc % 30 == 0)
+    return digit_to_string (level_idc / 30);
+  else {
+    switch (level_idc) {
+      case 63:
+        return "2.1";
+        break;
+      case 93:
+        return "3.1";
+        break;
+      case 123:
+        return "4.1";
+        break;
+      case 153:
+        return "5.1";
+        break;
+      case 156:
+        return "5.2";
+        break;
+      case 183:
+        return "6.1";
+        break;
+      case 186:
+        return "6.2";
+        break;
+      default:
+        return NULL;
+    }
+  }
+}
+
 static void
 gst_h265_parse_update_src_caps (GstH265Parse * h265parse, GstCaps * caps)
 {
@@ -1255,9 +1329,24 @@
   if (G_UNLIKELY (!sps)) {
     caps = gst_caps_copy (sink_caps);
   } else {
-    h265parse->width = sps->width;
-    h265parse->height = sps->height;
-    modified = TRUE;
+    gint crop_width, crop_height;
+
+    if (sps->conformance_window_flag) {
+      crop_width = sps->crop_rect_width;
+      crop_height = sps->crop_rect_height;
+    } else {
+      crop_width = sps->width;
+      crop_height = sps->height;
+    }
+
+    if (G_UNLIKELY (h265parse->width != crop_width ||
+            h265parse->height != crop_height)) {
+      GST_INFO_OBJECT (h265parse, "resolution changed %dx%d",
+          crop_width, crop_height);
+      h265parse->width = crop_width;
+      h265parse->height = crop_height;
+      modified = TRUE;
+    }
 
     /* 0/1 is set as the default in the codec parser */
     if (sps->vui_params.timing_info_present_flag &&
@@ -1343,15 +1432,19 @@
 
     /* set profile and level in caps */
     if (sps) {
-      GstMapInfo map;
-      GstBuffer *sps_buf = h265parse->sps_nals[sps->id];
+      const gchar *profile, *tier, *level;
 
-      if (sps_buf) {
-        gst_buffer_map (sps_buf, &map, GST_MAP_READ);
-        gst_codec_utils_h265_caps_set_level_tier_and_profile (caps,
-            map.data + 1, map.size - 1);
-        gst_buffer_unmap (sps_buf, &map);
-      }
+      profile = get_profile_string (sps->profile_tier_level.profile_idc);
+      if (profile != NULL)
+        gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
+
+      tier = get_tier_string (sps->profile_tier_level.tier_flag);
+      if (tier != NULL)
+        gst_caps_set_simple (caps, "tier", G_TYPE_STRING, tier, NULL);
+
+      level = get_level_string (sps->profile_tier_level.level_idc);
+      if (level != NULL)
+        gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
     }
 
     src_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (h265parse));
diff --git a/gst/videoparsers/gstmpeg4videoparse.c b/gst/videoparsers/gstmpeg4videoparse.c
index a169363..3188439 100644
--- a/gst/videoparsers/gstmpeg4videoparse.c
+++ b/gst/videoparsers/gstmpeg4videoparse.c
@@ -66,8 +66,7 @@
 {
   PROP_0,
   PROP_DROP,
-  PROP_CONFIG_INTERVAL,
-  PROP_LAST
+  PROP_CONFIG_INTERVAL
 };
 
 #define gst_mpeg4vparse_parent_class parent_class
diff --git a/gst/videoparsers/gstmpegvideoparse.c b/gst/videoparsers/gstmpegvideoparse.c
index dd57e93..bf166d0 100644
--- a/gst/videoparsers/gstmpegvideoparse.c
+++ b/gst/videoparsers/gstmpegvideoparse.c
@@ -59,8 +59,7 @@
 {
   PROP_0,
   PROP_DROP,
-  PROP_GOP_SPLIT,
-  PROP_LAST
+  PROP_GOP_SPLIT
 };
 
 #define parent_class gst_mpegv_parse_parent_class
diff --git a/gst/videoparsers/h263parse.c b/gst/videoparsers/h263parse.c
index d794f7a..98a30e7 100644
--- a/gst/videoparsers/h263parse.c
+++ b/gst/videoparsers/h263parse.c
@@ -271,29 +271,46 @@
     }
 
     if (ufep == 1) {
-      guint32 cpfmt = 0;
+      if (params->format == 6) {
+        /* A fixed length codeword of 23 bits that is present only if the use of
+         * a custom picture format is signalled in PLUSPTYPE and UFEP is 001 */
+        guint32 cpfmt = 0;
 
-      /* 5.1.5 CPFMT : Custom Picture Format (23 bits) */
-      if (!gst_bit_reader_get_bits_uint32 (&br, &cpfmt, 23))
-        goto more;
-      if (!(cpfmt & 0x200)) {
-        GST_WARNING ("Corrupted CPFMT (0x%x)", cpfmt);
-        goto beach;
-      }
-      temp8 = cpfmt >> 19;
-      params->width = (((cpfmt >> 10) & 0x1f) + 1) * 4;
-      params->height = ((cpfmt & 0x1f) + 1) * 4;
-
-      if (temp8 == 0xf) {
-        guint32 epar = 0;
-        /* 5.1.6 EPAR : Extended Pixel Aspect Ratio (16bits) */
-        if (!gst_bit_reader_get_bits_uint32 (&br, &epar, 16))
+        /* 5.1.5 CPFMT : Custom Picture Format (23 bits) */
+        if (!gst_bit_reader_get_bits_uint32 (&br, &cpfmt, 23))
           goto more;
-        params->parnum = epar >> 8;
-        params->pardenom = epar & 0xf;
+        if (!(cpfmt & 0x200)) {
+          GST_WARNING ("Corrupted CPFMT (0x%x)", cpfmt);
+          goto beach;
+        }
+        temp8 = cpfmt >> 19;
+        /* Bits 5-13: Picture Width Indication: Range [0, ... , 511];
+         * Number of pixels per line = (PWI + 1) * 4 */
+        params->width = (((cpfmt >> 10) & 0x1ff) + 1) * 4;
+        /* Bits 15-23  Picture Height Indication: Range [1, ... , 288];
+         * Number of lines = PHI * 4 */
+        params->height = (cpfmt & 0x1ff) * 4;
+
+        if (temp8 == 0xf) {
+          guint32 epar = 0;
+          /* 5.1.6 EPAR : Extended Pixel Aspect Ratio (16bits) */
+          if (!gst_bit_reader_get_bits_uint32 (&br, &epar, 16))
+            goto more;
+          params->parnum = epar >> 8;
+          params->pardenom = epar & 0xf;
+        } else {
+          params->parnum = partable[temp8][0];
+          params->pardenom = partable[temp8][1];
+        }
       } else {
-        params->parnum = partable[temp8][0];
-        params->pardenom = partable[temp8][1];
+        /* Fill in width/height based on format */
+        params->width = sizetable[params->format][0];
+        params->height = sizetable[params->format][1];
+        GST_DEBUG (" Picture width x height: %d x %d",
+            params->width, params->height);
+        /* Fill in default Pixel aspect ratios */
+        params->parnum = 12;
+        params->pardenom = 11;
       }
 
       if (params->custompcfpresent) {
diff --git a/gst/videosignal/Makefile.am b/gst/videosignal/Makefile.am
index 8a17d9f..cd5bb9e 100644
--- a/gst/videosignal/Makefile.am
+++ b/gst/videosignal/Makefile.am
@@ -12,17 +12,3 @@
 libgstvideosignal_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstvideo-@GST_API_VERSION@ $(GST_BASE_LIBS) $(GST_LIBS)
 libgstvideosignal_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstvideosignal_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstvideosignal -:SHARED libgstvideosignal \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstvideosignal_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstvideosignal_la_CFLAGS) \
-	 -:LDFLAGS $(libgstvideosignal_la_LDFLAGS) \
-	           $(libgstvideosignal_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-$(GST_API_VERSION)' \
-	> $@
diff --git a/gst/videosignal/Makefile.in b/gst/videosignal/Makefile.in
index df8f4aa..98c3f25 100644
--- a/gst/videosignal/Makefile.in
+++ b/gst/videosignal/Makefile.in
@@ -1099,20 +1099,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstvideosignal -:SHARED libgstvideosignal \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstvideosignal_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstvideosignal_la_CFLAGS) \
-	 -:LDFLAGS $(libgstvideosignal_la_LDFLAGS) \
-	           $(libgstvideosignal_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-$(GST_API_VERSION)' \
-	> $@
-
 # 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/gst/vmnc/Makefile.am b/gst/vmnc/Makefile.am
index 5419dee..29ac9b3 100644
--- a/gst/vmnc/Makefile.am
+++ b/gst/vmnc/Makefile.am
@@ -8,17 +8,3 @@
 	$(GST_BASE_LIBS) $(GST_LIBS)
 libgstvmnc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstvmnc_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstvmnc -:SHARED libgstvmnc \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstvmnc_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstvmnc_la_CFLAGS) \
-	 -:LDFLAGS $(libgstvmnc_la_LDFLAGS) \
-	           $(libgstvmnc_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/vmnc/Makefile.in b/gst/vmnc/Makefile.in
index f7a55d6..7e0364b 100644
--- a/gst/vmnc/Makefile.in
+++ b/gst/vmnc/Makefile.in
@@ -1069,20 +1069,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstvmnc -:SHARED libgstvmnc \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstvmnc_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstvmnc_la_CFLAGS) \
-	 -:LDFLAGS $(libgstvmnc_la_LDFLAGS) \
-	           $(libgstvmnc_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/vmnc/vmncdec.c b/gst/vmnc/vmncdec.c
index 058a844..54a42ed 100644
--- a/gst/vmnc/vmncdec.c
+++ b/gst/vmnc/vmncdec.c
@@ -51,7 +51,7 @@
 
 enum
 {
-  ARG_0,
+  PROP_0,
 };
 
 enum
diff --git a/gst/y4m/Makefile.am b/gst/y4m/Makefile.am
index 3913fc5..b91c84a 100644
--- a/gst/y4m/Makefile.am
+++ b/gst/y4m/Makefile.am
@@ -10,17 +10,3 @@
 libgsty4mdec_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 noinst_HEADERS = gsty4mdec.h
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgsty4m -:SHARED libgsty4m \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgsty4m_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgsty4m_la_CFLAGS) \
-	 -:LDFLAGS $(libgsty4m_la_LDFLAGS) \
-	           $(libgsty4m_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/y4m/Makefile.in b/gst/y4m/Makefile.in
index 53318f9..19c04da 100644
--- a/gst/y4m/Makefile.in
+++ b/gst/y4m/Makefile.in
@@ -1070,20 +1070,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgsty4m -:SHARED libgsty4m \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgsty4m_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgsty4m_la_CFLAGS) \
-	 -:LDFLAGS $(libgsty4m_la_LDFLAGS) \
-	           $(libgsty4m_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/gst/yadif/Makefile.am b/gst/yadif/Makefile.am
index 31417b9..0887bf7 100644
--- a/gst/yadif/Makefile.am
+++ b/gst/yadif/Makefile.am
@@ -10,17 +10,3 @@
 
 
 EXTRA_DIST = yadif_template.c
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstyadif -:SHARED libgstyadif \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstyadif_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstyadif_la_CFLAGS) \
-	 -:LDFLAGS $(libgstyadif_la_LDFLAGS) \
-	           $(libgstyadif_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
diff --git a/gst/yadif/Makefile.in b/gst/yadif/Makefile.in
index c58fa96..2a6171d 100644
--- a/gst/yadif/Makefile.in
+++ b/gst/yadif/Makefile.in
@@ -1086,20 +1086,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstyadif -:SHARED libgstyadif \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstyadif_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstyadif_la_CFLAGS) \
-	 -:LDFLAGS $(libgstyadif_la_LDFLAGS) \
-	           $(libgstyadif_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
-	> $@
-
 # 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/po/POTFILES.in b/po/POTFILES.in
index 752ccd2..ad42318 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -11,7 +11,9 @@
 gst/asfmux/gstasfmux.c
 gst/camerabin2/camerabingeneral.c
 gst/camerabin2/gstcamerabin2.c
+gst/camerabin2/gstdigitalzoom.c
 gst/camerabin2/gstviewfinderbin.c
+gst/camerabin2/gstwrappercamerabinsrc.c
 gst/dvdspu/gstdvdspu.c
 gst-libs/gst/adaptivedemux/gstadaptivedemux.c
 gst/mpegtsdemux/mpegtsbase.c
diff --git a/po/af.gmo b/po/af.gmo
index 46d780e..9e7a0f6 100644
--- a/po/af.gmo
+++ b/po/af.gmo
Binary files differ
diff --git a/po/af.po b/po/af.po
index 0930405..b2f373c 100644
--- a/po/af.po
+++ b/po/af.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins 0.7.6\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+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"
@@ -165,6 +165,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/az.gmo b/po/az.gmo
index a4260ed..58f4729 100644
--- a/po/az.gmo
+++ b/po/az.gmo
Binary files differ
diff --git a/po/az.po b/po/az.po
index d6e9679..7d8921b 100644
--- a/po/az.po
+++ b/po/az.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-0.8.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+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"
@@ -166,6 +166,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/bg.gmo b/po/bg.gmo
index ad15d10..e57e7db 100644
--- a/po/bg.gmo
+++ b/po/bg.gmo
Binary files differ
diff --git a/po/bg.po b/po/bg.po
index a42695e..81aa7b3 100644
--- a/po/bg.po
+++ b/po/bg.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 0.10.21.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2011-04-26 22:30+0300\n"
 "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
 "Language-Team: Bulgarian <dict@fsa-bg.org>\n"
@@ -167,6 +167,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/ca.gmo b/po/ca.gmo
index f5f4e33..02e728b 100644
--- a/po/ca.gmo
+++ b/po/ca.gmo
Binary files differ
diff --git a/po/ca.po b/po/ca.po
index 9441c2f..383241b 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 0.10.21.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+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"
@@ -168,6 +168,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/cs.gmo b/po/cs.gmo
index b033408..9c6eb03 100644
--- a/po/cs.gmo
+++ b/po/cs.gmo
Binary files differ
diff --git a/po/cs.po b/po/cs.po
index 0e809d7..d2c1cf8 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -11,7 +11,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 1.1.4\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2013-09-18 10:05+0200\n"
 "Last-Translator: Marek Černocký <marek@manet.cz>\n"
 "Language-Team: Czech <translation-team-cs@lists.sourceforge.net>\n"
@@ -173,6 +173,9 @@
 "Umístění souboru je nastavené prázdné, nastavte jej prosím na platný název "
 "souboru"
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr "Formát podřízeného obrázku nebyl nastaven před datovým tokem"
 
diff --git a/po/da.gmo b/po/da.gmo
index ac413cf..dd72ec5 100644
--- a/po/da.gmo
+++ b/po/da.gmo
Binary files differ
diff --git a/po/da.po b/po/da.po
index 5ab9031..4745c59 100644
--- a/po/da.po
+++ b/po/da.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad-1.3.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2014-05-24 11:28+0200\n"
 "Last-Translator: Joe Hansen <joedalton2@yahoo.dk>\n"
 "Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
@@ -165,6 +165,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr "Filplacering er sat til NULL, sæt den venligst til et gyldigt filnavn"
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr "Format for underbillede blev ikke konfigureret før datastrøm"
 
diff --git a/po/de.gmo b/po/de.gmo
index a9eca7d..3ef4916 100644
--- a/po/de.gmo
+++ b/po/de.gmo
Binary files differ
diff --git a/po/de.po b/po/de.po
index 6e5a53c..62f89f4 100644
--- a/po/de.po
+++ b/po/de.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 1.3.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2014-05-22 18:27+0100\n"
 "Last-Translator: Christian Kirbach <christian.kirbach@gmail.com>\n"
 "Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
@@ -171,6 +171,9 @@
 "Dateiort ist als NULL festgelegt. Bitte legen Sie einen gültigen Dateinamen "
 "fest"
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr "Format des Unterbilds wurde nicht vor dem Datenfluss konfiguriert"
 
diff --git a/po/el.gmo b/po/el.gmo
index 840665a..f90ef8d 100644
--- a/po/el.gmo
+++ b/po/el.gmo
Binary files differ
diff --git a/po/el.po b/po/el.po
index 343aeec..133774f 100644
--- a/po/el.po
+++ b/po/el.po
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 0.10.21.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2012-05-05 19:17+0100\n"
 "Last-Translator: Savvas Radevic <vicedar@gmail.com>\n"
 "Language-Team: Greek <team@lists.gnome.gr>\n"
@@ -169,6 +169,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/en_GB.gmo b/po/en_GB.gmo
index 99b79c2..14b49fe 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 bb8d6a6..c593a42 100644
--- a/po/en_GB.po
+++ b/po/en_GB.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins 0.8.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+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"
@@ -164,6 +164,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/eo.gmo b/po/eo.gmo
index 1110cc2..ab08613 100644
--- a/po/eo.gmo
+++ b/po/eo.gmo
Binary files differ
diff --git a/po/eo.po b/po/eo.po
index 2e11bbe..1add6e8 100644
--- a/po/eo.po
+++ b/po/eo.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 0.10.21.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2011-06-04 22:18+0200\n"
 "Last-Translator: Kristjan SCHMIDT <kristjan.schmidt@googlemail.com>\n"
 "Language-Team: Esperanto <translation-team-eo@lists.sourceforge.net>\n"
@@ -166,6 +166,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/es.gmo b/po/es.gmo
index 7eb92e4..33d923e 100644
--- a/po/es.gmo
+++ b/po/es.gmo
Binary files differ
diff --git a/po/es.po b/po/es.po
index 4667e85..b1efa34 100644
--- a/po/es.po
+++ b/po/es.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 0.10.21.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2011-10-02 15:47+0200\n"
 "Last-Translator: Jorge González González <aloriel@gmail.com>\n"
 "Language-Team: Spanish <es@li.org>\n"
@@ -166,6 +166,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/eu.gmo b/po/eu.gmo
index c49c679..6ad1b5f 100644
--- a/po/eu.gmo
+++ b/po/eu.gmo
Binary files differ
diff --git a/po/eu.po b/po/eu.po
index 74d31b8..45e6fa4 100644
--- a/po/eu.po
+++ b/po/eu.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad-0.10.17.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2010-03-25 12:30+0100\n"
 "Last-Translator: Mikel Olasagasti Uranga <hey_neken@mundurat.net>\n"
 "Language-Team: Basque <translation-team-eu@lists.sourceforge.net>\n"
@@ -167,6 +167,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/fi.gmo b/po/fi.gmo
index 5d506dc..06417b5 100644
--- a/po/fi.gmo
+++ b/po/fi.gmo
Binary files differ
diff --git a/po/fi.po b/po/fi.po
index 0758e6c..d5a8def 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -11,7 +11,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 0.10.13.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2009-08-12 22:13+0300\n"
 "Last-Translator: Tommi Vainikainen <Tommi.Vainikainen@iki.fi>\n"
 "Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n"
@@ -170,6 +170,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/fr.gmo b/po/fr.gmo
index f093dc4..a02b1d6 100644
--- a/po/fr.gmo
+++ b/po/fr.gmo
Binary files differ
diff --git a/po/fr.po b/po/fr.po
index 22bd82f..5e54619 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 0.10.21.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2011-04-28 09:13+0200\n"
 "Last-Translator: Claude Paroz <claude@2xlibre.net>\n"
 "Language-Team: French <traduc@traduc.org>\n"
@@ -166,6 +166,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/gl.gmo b/po/gl.gmo
index cd24db0..bbe4105 100644
--- a/po/gl.gmo
+++ b/po/gl.gmo
Binary files differ
diff --git a/po/gl.po b/po/gl.po
index 4552466..514c645 100644
--- a/po/gl.po
+++ b/po/gl.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 0.10.21.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2011-09-05 12:50+0200\n"
 "Last-Translator: Fran Dieguez <frandieguez@ubuntu.com>\n"
 "Language-Team: Galician <proxecto@trasno.net>\n"
@@ -168,6 +168,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/gst-plugins-bad-1.0.pot b/po/gst-plugins-bad-1.0.pot
index 7eb4e83..169fa78 100644
--- a/po/gst-plugins-bad-1.0.pot
+++ b/po/gst-plugins-bad-1.0.pot
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 1.5.0.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+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"
@@ -16,7 +16,7 @@
 "Content-Type: text/plain; charset=CHARSET\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ext/gl/gstgltestsrc.c:707
+#: ext/gl/gstgltestsrc.c:673
 msgid "format wasn't negotiated before get function"
 msgstr ""
 
@@ -137,7 +137,7 @@
 msgid "Describes the selected visualization element."
 msgstr ""
 
-#: ext/opencv/gsttemplatematch.c:441
+#: ext/opencv/gsttemplatematch.c:442
 msgid "OpenCV failed to load template image"
 msgstr ""
 
@@ -164,8 +164,8 @@
 msgid "Could not read DVD."
 msgstr ""
 
-#: ext/smoothstreaming/gstmssdemux.c:378
-#: gst-libs/gst/adaptivedemux/gstadaptivedemux.c:514
+#: ext/smoothstreaming/gstmssdemux.c:380
+#: gst-libs/gst/adaptivedemux/gstadaptivedemux.c:520
 msgid "This file contains no playable streams."
 msgstr ""
 
@@ -198,7 +198,7 @@
 msgstr ""
 
 #: gst/camerabin2/camerabingeneral.c:166 gst/camerabin2/gstcamerabin2.c:1876
-#: gst/camerabin2/gstviewfinderbin.c:271
+#: gst/camerabin2/gstdigitalzoom.c:282 gst/camerabin2/gstviewfinderbin.c:271
 #, c-format
 msgid "Missing element '%s' - check your GStreamer installation."
 msgstr ""
@@ -207,6 +207,10 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+#: gst/camerabin2/gstwrappercamerabinsrc.c:584
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 #: gst/dvdspu/gstdvdspu.c:1036
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
@@ -215,13 +219,14 @@
 msgid "Failed to get fragment URL."
 msgstr ""
 
-#: gst-libs/gst/adaptivedemux/gstadaptivedemux.c:2107
-#: gst/mpegtsdemux/mpegtsbase.c:1361 gst/mpegtsdemux/mpegtsbase.c:1365
+#: gst-libs/gst/adaptivedemux/gstadaptivedemux.c:2096
+#: gst-libs/gst/adaptivedemux/gstadaptivedemux.c:2260
+#: gst/mpegtsdemux/mpegtsbase.c:1335 gst/mpegtsdemux/mpegtsbase.c:1339
 #: gst/nuvdemux/gstnuvdemux.c:736
 msgid "Internal data stream error."
 msgstr ""
 
-#: gst-libs/gst/adaptivedemux/gstadaptivedemux.c:2208
+#: gst-libs/gst/adaptivedemux/gstadaptivedemux.c:2197
 msgid "Couldn't download fragments"
 msgstr ""
 
diff --git a/po/hr.gmo b/po/hr.gmo
index 56d6302..3791362 100644
--- a/po/hr.gmo
+++ b/po/hr.gmo
Binary files differ
diff --git a/po/hr.po b/po/hr.po
index cceca5a..615a4d7 100644
--- a/po/hr.po
+++ b/po/hr.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 0.10.21.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2012-04-16 02:06+0200\n"
 "Last-Translator: Tomislav Krznar <tomislav.krznar@gmail.com>\n"
 "Language-Team: Croatian <lokalizacija@linux.hr>\n"
@@ -166,6 +166,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/hu.gmo b/po/hu.gmo
index d7a5527..c57c203 100644
--- a/po/hu.gmo
+++ b/po/hu.gmo
Binary files differ
diff --git a/po/hu.po b/po/hu.po
index eb79537..78630a0 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 1.3.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2014-05-23 20:42+0200\n"
 "Last-Translator: Balázs Úr <urbalazs@gmail.com>\n"
 "Language-Team: Hungarian <translation-team-hu@lists.sourceforge.net>\n"
@@ -169,6 +169,9 @@
 "A fájl helye NULL értékre lett állítva, kérjük állítsa be egy érvényes "
 "fájlnévre"
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr "A részkép formátuma nem lett beállítva az adatfolyam előtt"
 
diff --git a/po/id.gmo b/po/id.gmo
index ef12db4..7cb8d1b 100644
--- a/po/id.gmo
+++ b/po/id.gmo
Binary files differ
diff --git a/po/id.po b/po/id.po
index 94747ec..08fe85c 100644
--- a/po/id.po
+++ b/po/id.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 1.3.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2014-05-31 22:16+0700\n"
 "Last-Translator: Andhika Padmawan <andhika.padmawan@gmail.com>\n"
 "Language-Team: Indonesian <translation-team-id@lists.sourceforge.net>\n"
@@ -165,6 +165,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr "Lokasi berkas diisi NULL, harap isi dengan nama berkas yang valid"
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr "Format subgambar tak ditata sebelum aliran data"
 
diff --git a/po/it.gmo b/po/it.gmo
index b719847..b155342 100644
--- a/po/it.gmo
+++ b/po/it.gmo
Binary files differ
diff --git a/po/it.po b/po/it.po
index a1ff11d..d4a2663 100644
--- a/po/it.po
+++ b/po/it.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 0.10.13.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2009-08-14 00:12+0200\n"
 "Last-Translator: Luca Ferretti <elle.uca@infinito.it>\n"
 "Language-Team: Italian <tp@lists.linux.it>\n"
@@ -164,6 +164,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/ja.gmo b/po/ja.gmo
index 1cb927e..28ade9b 100644
--- a/po/ja.gmo
+++ b/po/ja.gmo
Binary files differ
diff --git a/po/ja.po b/po/ja.po
index 0be8b44..1c6ff18 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 0.10.21.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2011-04-26 19:38+0900\n"
 "Last-Translator: Makoto Kato <makoto.kt@gmail.com>\n"
 "Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n"
@@ -166,6 +166,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/ky.gmo b/po/ky.gmo
index bd885ff..5f48b47 100644
--- a/po/ky.gmo
+++ b/po/ky.gmo
Binary files differ
diff --git a/po/ky.po b/po/ky.po
index eed1f32..49036e8 100644
--- a/po/ky.po
+++ b/po/ky.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 0.10.5\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2007-11-13 17:16+0600\n"
 "Last-Translator: Ilyas Bakirov <just_ilyas@yahoo.com>\n"
 "Language-Team: Kirghiz <i18n-team-ky-kyrgyz@lists.sourceforge.net>\n"
@@ -163,6 +163,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/lt.gmo b/po/lt.gmo
index 0d9865f..7bb7ebd 100644
--- a/po/lt.gmo
+++ b/po/lt.gmo
Binary files differ
diff --git a/po/lt.po b/po/lt.po
index 29431e5..a9461c3 100644
--- a/po/lt.po
+++ b/po/lt.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad-0.10.6.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2008-05-14 02:13+0300\n"
 "Last-Translator: Gintautas Miliauskas <gintas@akl.lt>\n"
 "Language-Team: Lithuanian <komp_lt@konferencijos.lt>\n"
@@ -168,6 +168,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/lv.gmo b/po/lv.gmo
index b1945bc..c7af6a3 100644
--- a/po/lv.gmo
+++ b/po/lv.gmo
Binary files differ
diff --git a/po/lv.po b/po/lv.po
index af5c461..faaadbb 100644
--- a/po/lv.po
+++ b/po/lv.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 1.2.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2014-04-20 15:52+0300\n"
 "Last-Translator: Rihards Prieditis <rprieditis@gmail.com>\n"
 "Language-Team: Latvian <translation-team-lv@lists.sourceforge.net>\n"
@@ -171,6 +171,9 @@
 msgstr ""
 "Datnes vieta ir iestatīta uz NULL, lūdzu, iestatiet derīgu datnes nosaukumu"
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr "Apakšattēla formāts netika konfigurēts pirms datu plūsmas"
 
diff --git a/po/mt.gmo b/po/mt.gmo
index 638449a..b560c0a 100644
--- a/po/mt.gmo
+++ b/po/mt.gmo
Binary files differ
diff --git a/po/mt.po b/po/mt.po
index 4f5dbcd..fa8eb22 100644
--- a/po/mt.po
+++ b/po/mt.po
@@ -5,7 +5,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad-0.10.8.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2008-10-26 20:27+0100\n"
 "Last-Translator: Michel Bugeja <michelbugeja@rabatmalta.com>\n"
 "Language-Team: Maltese <translation-team-mt@lists.sourceforge.net>\n"
@@ -166,6 +166,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/nb.gmo b/po/nb.gmo
index 111ee95..0c18d60 100644
--- a/po/nb.gmo
+++ b/po/nb.gmo
Binary files differ
diff --git a/po/nb.po b/po/nb.po
index 4c0332e..3843bd7 100644
--- a/po/nb.po
+++ b/po/nb.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 1.2.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2014-01-22 17:56+0100\n"
 "Last-Translator: Johnny A. Solbu <johnny@solbu.net>\n"
 "Language-Team: Norwegian Bokmaal <i18n-nb@lister.ping.uio.no>\n"
@@ -166,6 +166,9 @@
 msgstr ""
 "Filplassering er satt til NULL, vennligst sett den til et gyldig filnavn"
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr "Underbildeformat er ikke konfigurert før dataflyt"
 
diff --git a/po/nl.gmo b/po/nl.gmo
index 85759b4..0087718 100644
--- a/po/nl.gmo
+++ b/po/nl.gmo
Binary files differ
diff --git a/po/nl.po b/po/nl.po
index af108f9..e59c6c7 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 1.3.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2014-05-22 00:31+0200\n"
 "Last-Translator: Freek de Kruijf <f.de.kruijf@gmail.com>\n"
 "Language-Team: Dutch <vertaling@vrijschrift.org>\n"
@@ -168,6 +168,9 @@
 msgstr ""
 "Locatie van bestand is op NUL gezet, stel het in op een geldige bestandsnaam"
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 "Het format van de subafbeelding was niet ingesteld voor de gegevensstroom"
diff --git a/po/or.gmo b/po/or.gmo
index f7ae2fe..de15104 100644
--- a/po/or.gmo
+++ b/po/or.gmo
Binary files differ
diff --git a/po/or.po b/po/or.po
index 4df1c9b..2530918 100644
--- a/po/or.po
+++ b/po/or.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-0.8.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+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"
@@ -166,6 +166,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/pl.gmo b/po/pl.gmo
index f3e4a22..0be1fd6 100644
--- a/po/pl.gmo
+++ b/po/pl.gmo
Binary files differ
diff --git a/po/pl.po b/po/pl.po
index 70f064c..7b520e1 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 1.3.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2014-05-22 18:34+0200\n"
 "Last-Translator: Jakub Bogusz <qboosh@pld-linux.org>\n"
 "Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"
@@ -163,6 +163,9 @@
 msgstr ""
 "Położenie pliku ustawiono na NULL, proszę ustawić na poprawną nazwę pliku"
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr "Format podobrazu nie został skonfigurowany przed przepływem danych"
 
diff --git a/po/pt_BR.gmo b/po/pt_BR.gmo
index 74030a0..a76e467 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 829c47f..4e7f4d5 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad-1.2.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2013-12-17 01:09-0200\n"
 "Last-Translator: Fabrício Godoy <skarllot@gmail.com>\n"
 "Language-Team: Brazilian Portuguese <ldpbr-translation@lists.sourceforge."
@@ -169,6 +169,9 @@
 msgstr ""
 "A localização do arquivo está NULA, favor definir um nome de arquivo válido"
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr "O formato de subimagem não foi configurado antes do fluxo de dados"
 
diff --git a/po/ro.gmo b/po/ro.gmo
index 1b1a1d9..2b41a06 100644
--- a/po/ro.gmo
+++ b/po/ro.gmo
Binary files differ
diff --git a/po/ro.po b/po/ro.po
index fe85b30..a731a07 100644
--- a/po/ro.po
+++ b/po/ro.po
@@ -5,7 +5,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 0.10.18.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2010-08-16 03:11+0300\n"
 "Last-Translator: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>\n"
 "Language-Team: Romanian <translation-team-ro@lists.sourceforge.net>\n"
@@ -165,6 +165,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/ru.gmo b/po/ru.gmo
index ee190c1..a78ce6b 100644
--- a/po/ru.gmo
+++ b/po/ru.gmo
Binary files differ
diff --git a/po/ru.po b/po/ru.po
index e16f882..abb49e5 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 1.3.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2014-05-22 19:59+0400\n"
 "Last-Translator: Yuri Kozlov <yuray@komyakino.ru>\n"
 "Language-Team: Russian <gnu@mx.ru>\n"
@@ -168,6 +168,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr "Расположение файла равно NULL, укажите правильное имя файла"
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr "Не настроен формат субграфики (subpicture) до потока данных"
 
diff --git a/po/sk.gmo b/po/sk.gmo
index cf28033..ba790f3 100644
--- a/po/sk.gmo
+++ b/po/sk.gmo
Binary files differ
diff --git a/po/sk.po b/po/sk.po
index 6bd978e..2ea8c8a 100644
--- a/po/sk.po
+++ b/po/sk.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 1.2.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2014-01-30 10:44+0100\n"
 "Last-Translator: Peter Tuharsky <tuharsky@misbb.sk>\n"
 "Language-Team: Slovak <sk-i18n@lists.linux.sk>\n"
@@ -171,6 +171,9 @@
 "Umiestnenie súboru je nastavené na NULOVÉ, prosím nastavte platný názov "
 "súboru"
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr "Formát podobrázku nebol nastavený pred prúdom údajov."
 
diff --git a/po/sl.gmo b/po/sl.gmo
index 36cf5dc..6c173dc 100644
--- a/po/sl.gmo
+++ b/po/sl.gmo
Binary files differ
diff --git a/po/sl.po b/po/sl.po
index b008e6f..9ea8b45 100644
--- a/po/sl.po
+++ b/po/sl.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 0.10.21.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2011-04-26 15:21+0100\n"
 "Last-Translator: Klemen Košir <klemen.kosir@gmx.com>\n"
 "Language-Team: Slovenian <translation-team-sl@lists.sourceforge.net>\n"
@@ -171,6 +171,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/sq.gmo b/po/sq.gmo
index baf3157..86c94d3 100644
--- a/po/sq.gmo
+++ b/po/sq.gmo
Binary files differ
diff --git a/po/sq.po b/po/sq.po
index be7b476..cc61954 100644
--- a/po/sq.po
+++ b/po/sq.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 0.10.7.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2008-08-15 16:07+0200\n"
 "Last-Translator: Laurent Dhima <laurenti@alblinux.net>\n"
 "Language-Team: Albanian <translation-team-sq@lists.sourceforge.net>\n"
@@ -165,6 +165,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/sr.gmo b/po/sr.gmo
index f82d259..b7d1b6d 100644
--- a/po/sr.gmo
+++ b/po/sr.gmo
Binary files differ
diff --git a/po/sr.po b/po/sr.po
index 94a07f0..b85c487 100644
--- a/po/sr.po
+++ b/po/sr.po
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad-1.3.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2014-06-18 19:15+0200\n"
 "Last-Translator: Мирослав Николић <miroslavnikolic@rocketmail.com>\n"
 "Language-Team: Serbian <(nothing)>\n"
@@ -165,6 +165,9 @@
 msgstr ""
 "Место датотеке је подешено на НИШТА, подесите га на исправан назив датотеке"
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr "Запис подслике није подешен пре протока података"
 
diff --git a/po/sv.gmo b/po/sv.gmo
index ef193a7..153a868 100644
--- a/po/sv.gmo
+++ b/po/sv.gmo
Binary files differ
diff --git a/po/sv.po b/po/sv.po
index 3189391..6b50487 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 1.3.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2014-07-11 02:52+0200\n"
 "Last-Translator: Sebastian Rasmussen <sebras@gmail.com>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
@@ -164,6 +164,9 @@
 msgstr ""
 "Filposition är satt till NULL, vänligen sätt den till ett giltigt filnamn"
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr "Delbildsformat var inte konfigurerat före dataflöde"
 
diff --git a/po/tr.gmo b/po/tr.gmo
index b781e73..88a2985 100644
--- a/po/tr.gmo
+++ b/po/tr.gmo
Binary files differ
diff --git a/po/tr.po b/po/tr.po
index b800e06..7adfd79 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -6,7 +6,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad-0.10.21.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2011-04-26 19:21+0200\n"
 "Last-Translator: Server Acim <serveracim@gmail.com>\n"
 "Language-Team: Turkish <gnu-tr-u12a@lists.sourceforge.net>\n"
@@ -165,6 +165,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/po/uk.gmo b/po/uk.gmo
index 976cead..aee5c34 100644
--- a/po/uk.gmo
+++ b/po/uk.gmo
Binary files differ
diff --git a/po/uk.po b/po/uk.po
index 1dea347..7efb682 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 1.3.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2014-05-22 07:31+0300\n"
 "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
 "Language-Team: Ukrainian <translation-team-uk@lists.sourceforge.net>\n"
@@ -171,6 +171,9 @@
 "Значенням розташування файла є NULL. Будь ласка, встановіть чинне значення "
 "назви файла."
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr "Формат підзображення не було налаштовано до створення потоку даних"
 
diff --git a/po/vi.gmo b/po/vi.gmo
index efc67de..f38dc26 100644
--- a/po/vi.gmo
+++ b/po/vi.gmo
Binary files differ
diff --git a/po/vi.po b/po/vi.po
index b101484..2313f7c 100644
--- a/po/vi.po
+++ b/po/vi.po
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad-1.3.90\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2014-06-30 08:59+0700\n"
 "Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n"
 "Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n"
@@ -171,6 +171,9 @@
 msgstr ""
 "Vị trí tập tin được đặt thành “NULL”. xin hãy đặt một tên tập tin hợp lệ"
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr "Định dạng ảnh phụ chưa được cấu hình trước khi dữ liệu truyền đến"
 
diff --git a/po/zh_CN.gmo b/po/zh_CN.gmo
index a25acae..a7e5183 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 ef1bc2c..4a0271e 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: gst-plugins-bad 0.10.16.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2015-03-17 09:28+0100\n"
+"POT-Creation-Date: 2015-05-13 13:05+0300\n"
 "PO-Revision-Date: 2009-11-20 18:12中国标准时间\n"
 "Last-Translator: Ji ZhengYu <zhengyuji@gmail.com>\n"
 "Language-Team: Chinese (simplified) <i18n-zh@googlegroups.com>\n"
@@ -166,6 +166,9 @@
 msgid "File location is set to NULL, please set it to a valid filename"
 msgstr ""
 
+msgid "Digitalzoom element cound't be created"
+msgstr ""
+
 msgid "Subpicture format was not configured before data flow"
 msgstr ""
 
diff --git a/sys/androidmedia/Makefile.am b/sys/androidmedia/Makefile.am
index 937ce32..5fcfb8f 100644
--- a/sys/androidmedia/Makefile.am
+++ b/sys/androidmedia/Makefile.am
@@ -30,18 +30,3 @@
 	$(ORC_LIBS)
 libgstandroidmedia_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstandroidmedia_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstandroidmedia -:SHARED libgstandroidmedia \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstandroidmedia_la_SOURCES) \
-	           $(nodist_libgstandroidmedia_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstandroidmedia_la_CFLAGS) \
-	 -:LDFLAGS $(libgstandroidmedia_la_LDFLAGS) \
-	           $(libgstandroidmedia_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-@GST_API_VERSION@' \
-	> $@
diff --git a/sys/androidmedia/Makefile.in b/sys/androidmedia/Makefile.in
index 9d1d4a0..dc4c492 100644
--- a/sys/androidmedia/Makefile.in
+++ b/sys/androidmedia/Makefile.in
@@ -1130,21 +1130,6 @@
 	uninstall-pluginLTLIBRARIES
 
 
-Android.mk: Makefile.am $(BUILT_SOURCES)
-	androgenizer \
-	-:PROJECT libgstandroidmedia -:SHARED libgstandroidmedia \
-	 -:TAGS eng debug \
-         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-	 -:SOURCES $(libgstandroidmedia_la_SOURCES) \
-	           $(nodist_libgstandroidmedia_la_SOURCES) \
-	 -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstandroidmedia_la_CFLAGS) \
-	 -:LDFLAGS $(libgstandroidmedia_la_LDFLAGS) \
-	           $(libgstandroidmedia_la_LIBADD) \
-	           -ldl \
-	 -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-		       LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-@GST_API_VERSION@' \
-	> $@
-
 # 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/sys/androidmedia/gstamc-constants.h b/sys/androidmedia/gstamc-constants.h
index 6117032..ae52464 100644
--- a/sys/androidmedia/gstamc-constants.h
+++ b/sys/androidmedia/gstamc-constants.h
@@ -94,18 +94,26 @@
   COLOR_Format24BitABGR6666 = 43,
   COLOR_FormatAndroidOpaque = 0x7F000789,
   COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100,
+  COLOR_INTEL_FormatYUV420PackedSemiPlanar = 0x7fa00e00,
+  COLOR_INTEL_FormatYUV420PackedSemiPlanar_Tiled = 0x7fa00f00,
   COLOR_QCOM_FormatYUV420SemiPlanar = 0x7fa30c00,
   COLOR_QCOM_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7fa30c03,
   /* NV12 but with stride and plane heights aligned to 32 */
   COLOR_QCOM_FormatYVU420SemiPlanar32m = 0x7fa30c04,
+  /* NV12 but with stride and plane heights aligned to 32, Stores two images,
+   * one after the other in top-bottom layout */
+  COLOR_QCOM_FormatYVU420SemiPlanar32mMultiView = 0x7fa30c05,
   /* From hardware/ti/omap4xxx/domx/omx_core/inc/OMX_TI_IVCommon.h */
   COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced = 0x7f000001,
+  COLOR_FormatYUV420Flexible = 0x7f420888,
   /* This format is Exynos specific from the OMX vendor-specific
    * numeric range, but is defined in the Android OMX headers, so
    * we shouldn't find incompatible usage and crash horribly... right?
    * FIXME: Not actually implemented in the video decoder, it will just error out
    * The format seems to be equiv to V4L2_PIX_FMT_NV12MT_16X16 */
-  COLOR_OMX_SEC_FormatNV12Tiled = 0x7fc00002
+  COLOR_OMX_SEC_FormatNV12Tiled = 0x7fc00002,
+  /* YV12: http://developer.android.com/reference/android/graphics/ImageFormat.html#YV12 */
+  COLOR_FormatYV12 = 0x32315659,
 };
 
 enum
diff --git a/sys/androidmedia/gstamc.c b/sys/androidmedia/gstamc.c
index 1f45f31..8080de4 100644
--- a/sys/androidmedia/gstamc.c
+++ b/sys/androidmedia/gstamc.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2012, Collabora Ltd.
  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * Copyright (C) 2015, Sebastian Dröge <sebastian@centricular.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -117,36 +118,29 @@
 
   env = gst_amc_jni_get_env ();
 
-  name_str = (*env)->NewStringUTF (env, name);
-  if (name_str == NULL) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_INIT, err,
-        "Failed to create Java String");
+  name_str = gst_amc_jni_string_from_gchar (env, err, FALSE, name);
+  if (!name_str) {
     goto error;
   }
 
   codec = g_slice_new0 (GstAmcCodec);
 
-  object =
-      (*env)->CallStaticObjectMethod (env, media_codec.klass,
-      media_codec.create_by_codec_name, name_str);
-  if ((*env)->ExceptionCheck (env) || !object) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_INIT, err,
-        "Failed to create codec '%s'", name);
+  if (!gst_amc_jni_call_static_object_method (env, err, media_codec.klass,
+          media_codec.create_by_codec_name, &object, name_str))
     goto error;
-  }
 
-  codec->object = (*env)->NewGlobalRef (env, object);
+  codec->object = gst_amc_jni_object_make_global (env, object);
+  object = NULL;
+
   if (!codec->object) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_INIT, err,
-        "Failed to create global codec reference");
+    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+        GST_LIBRARY_ERROR_SETTINGS, "Failed to create global codec reference");
     goto error;
   }
 
 done:
-  if (object)
-    (*env)->DeleteLocalRef (env, object);
   if (name_str)
-    (*env)->DeleteLocalRef (env, name_str);
+    gst_amc_jni_object_local_unref (env, name_str);
   name_str = NULL;
 
   return codec;
@@ -166,7 +160,7 @@
   g_return_if_fail (codec != NULL);
 
   env = gst_amc_jni_get_env ();
-  (*env)->DeleteGlobalRef (env, codec->object);
+  gst_amc_jni_object_unref (env, codec->object);
   g_slice_free (GstAmcCodec, codec);
 }
 
@@ -175,25 +169,13 @@
     GError ** err)
 {
   JNIEnv *env;
-  gboolean ret = TRUE;
 
   g_return_val_if_fail (codec != NULL, FALSE);
   g_return_val_if_fail (format != NULL, FALSE);
 
   env = gst_amc_jni_get_env ();
-
-  (*env)->CallVoidMethod (env, codec->object, media_codec.configure,
-      format->object, NULL, NULL, flags);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_SETTINGS,
-        err, "Failed to configure codec");
-    ret = FALSE;
-    goto done;
-  }
-
-done:
-
-  return ret;
+  return gst_amc_jni_call_void_method (env, err, codec->object,
+      media_codec.configure, format->object, NULL, NULL, flags);
 }
 
 GstAmcFormat *
@@ -207,27 +189,20 @@
 
   env = gst_amc_jni_get_env ();
 
-  object =
-      (*env)->CallObjectMethod (env, codec->object,
-      media_codec.get_output_format);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_SETTINGS,
-        err, "Failed to get output format");
+  if (!gst_amc_jni_call_object_method (env, err, codec->object,
+          media_codec.get_output_format, &object))
     goto done;
-  }
 
   ret = g_slice_new0 (GstAmcFormat);
 
-  ret->object = (*env)->NewGlobalRef (env, object);
+  ret->object = gst_amc_jni_object_make_global (env, object);
   if (!ret->object) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_SETTINGS,
-        err, "Failed to create global format reference");
+    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+        GST_LIBRARY_ERROR_SETTINGS, "Failed to create global format reference");
     g_slice_free (GstAmcFormat, ret);
     ret = NULL;
   }
 
-  (*env)->DeleteLocalRef (env, object);
-
 done:
 
   return ret;
@@ -237,109 +212,48 @@
 gst_amc_codec_start (GstAmcCodec * codec, GError ** err)
 {
   JNIEnv *env;
-  gboolean ret = TRUE;
 
   g_return_val_if_fail (codec != NULL, FALSE);
 
   env = gst_amc_jni_get_env ();
-
-  (*env)->CallVoidMethod (env, codec->object, media_codec.start);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to start codec");
-    ret = FALSE;
-    goto done;
-  }
-
-done:
-
-  return ret;
+  return gst_amc_jni_call_void_method (env, err, codec->object,
+      media_codec.start);
 }
 
 gboolean
 gst_amc_codec_stop (GstAmcCodec * codec, GError ** err)
 {
   JNIEnv *env;
-  gboolean ret = TRUE;
 
   g_return_val_if_fail (codec != NULL, FALSE);
 
   env = gst_amc_jni_get_env ();
-
-  (*env)->CallVoidMethod (env, codec->object, media_codec.stop);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to stop codec");
-    ret = FALSE;
-    goto done;
-  }
-
-done:
-
-  return ret;
+  return gst_amc_jni_call_void_method (env, err, codec->object,
+      media_codec.stop);
 }
 
 gboolean
 gst_amc_codec_flush (GstAmcCodec * codec, GError ** err)
 {
   JNIEnv *env;
-  gboolean ret = TRUE;
 
   g_return_val_if_fail (codec != NULL, FALSE);
 
   env = gst_amc_jni_get_env ();
-
-  (*env)->CallVoidMethod (env, codec->object, media_codec.flush);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to flush codec");
-    ret = FALSE;
-    goto done;
-  }
-
-done:
-
-  return ret;
+  return gst_amc_jni_call_void_method (env, err, codec->object,
+      media_codec.flush);
 }
 
 gboolean
 gst_amc_codec_release (GstAmcCodec * codec, GError ** err)
 {
   JNIEnv *env;
-  gboolean ret = TRUE;
 
   g_return_val_if_fail (codec != NULL, FALSE);
 
   env = gst_amc_jni_get_env ();
-
-  (*env)->CallVoidMethod (env, codec->object, media_codec.release);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to release codec");
-    ret = FALSE;
-    goto done;
-  }
-
-done:
-
-  return ret;
-}
-
-void
-gst_amc_codec_free_buffers (GstAmcBuffer * buffers, gsize n_buffers)
-{
-  JNIEnv *env;
-  jsize i;
-
-  g_return_if_fail (buffers != NULL);
-
-  env = gst_amc_jni_get_env ();
-
-  for (i = 0; i < n_buffers; i++) {
-    if (buffers[i].object)
-      (*env)->DeleteGlobalRef (env, buffers[i].object);
-  }
-  g_free (buffers);
+  return gst_amc_jni_call_void_method (env, err, codec->object,
+      media_codec.release);
 }
 
 GstAmcBuffer *
@@ -348,9 +262,7 @@
 {
   JNIEnv *env;
   jobject output_buffers = NULL;
-  jsize n_output_buffers;
   GstAmcBuffer *ret = NULL;
-  jsize i;
 
   g_return_val_if_fail (codec != NULL, NULL);
   g_return_val_if_fail (n_buffers != NULL, NULL);
@@ -358,64 +270,17 @@
   *n_buffers = 0;
   env = gst_amc_jni_get_env ();
 
-  output_buffers =
-      (*env)->CallObjectMethod (env, codec->object,
-      media_codec.get_output_buffers);
-  if ((*env)->ExceptionCheck (env) || !output_buffers) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to get output buffers");
+  if (!gst_amc_jni_call_object_method (env, err, codec->object,
+          media_codec.get_output_buffers, &output_buffers))
     goto done;
-  }
 
-  n_output_buffers = (*env)->GetArrayLength (env, output_buffers);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to get output buffers array length");
-    goto done;
-  }
-
-  *n_buffers = n_output_buffers;
-  ret = g_new0 (GstAmcBuffer, n_output_buffers);
-
-  for (i = 0; i < n_output_buffers; i++) {
-    jobject buffer = NULL;
-
-    buffer = (*env)->GetObjectArrayElement (env, output_buffers, i);
-    if ((*env)->ExceptionCheck (env) || !buffer) {
-      gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-          err, "Failed to get output buffer %d", i);
-      goto error;
-    }
-
-    ret[i].object = (*env)->NewGlobalRef (env, buffer);
-    (*env)->DeleteLocalRef (env, buffer);
-    if (!ret[i].object) {
-      gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-          err, "Failed to create global output buffer reference %d", i);
-      goto error;
-    }
-
-    ret[i].data = (*env)->GetDirectBufferAddress (env, ret[i].object);
-    if (!ret[i].data) {
-      gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-          err, "Failed to get output buffer address %d", i);
-      goto error;
-    }
-    ret[i].size = (*env)->GetDirectBufferCapacity (env, ret[i].object);
-  }
+  gst_amc_jni_get_buffer_array (env, err, output_buffers, &ret, n_buffers);
 
 done:
   if (output_buffers)
-    (*env)->DeleteLocalRef (env, output_buffers);
-  output_buffers = NULL;
+    gst_amc_jni_object_local_unref (env, output_buffers);
 
   return ret;
-error:
-  if (ret)
-    gst_amc_codec_free_buffers (ret, n_output_buffers);
-  ret = NULL;
-  *n_buffers = 0;
-  goto done;
 }
 
 GstAmcBuffer *
@@ -424,9 +289,7 @@
 {
   JNIEnv *env;
   jobject input_buffers = NULL;
-  jsize n_input_buffers;
   GstAmcBuffer *ret = NULL;
-  jsize i;
 
   g_return_val_if_fail (codec != NULL, NULL);
   g_return_val_if_fail (n_buffers != NULL, NULL);
@@ -434,64 +297,26 @@
   *n_buffers = 0;
   env = gst_amc_jni_get_env ();
 
-  input_buffers =
-      (*env)->CallObjectMethod (env, codec->object,
-      media_codec.get_input_buffers);
-  if ((*env)->ExceptionCheck (env) || !input_buffers) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to get input buffers");
+  if (!gst_amc_jni_call_object_method (env, err, codec->object,
+          media_codec.get_input_buffers, &input_buffers))
     goto done;
-  }
 
-  n_input_buffers = (*env)->GetArrayLength (env, input_buffers);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to get input buffers array length");
-    goto done;
-  }
-
-  *n_buffers = n_input_buffers;
-  ret = g_new0 (GstAmcBuffer, n_input_buffers);
-
-  for (i = 0; i < n_input_buffers; i++) {
-    jobject buffer = NULL;
-
-    buffer = (*env)->GetObjectArrayElement (env, input_buffers, i);
-    if ((*env)->ExceptionCheck (env) || !buffer) {
-      gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-          err, "Failed to get input buffer %d", i);
-      goto error;
-    }
-
-    ret[i].object = (*env)->NewGlobalRef (env, buffer);
-    (*env)->DeleteLocalRef (env, buffer);
-    if (!ret[i].object) {
-      gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-          err, "Failed to create global input buffer reference %d", i);
-      goto error;
-    }
-
-    ret[i].data = (*env)->GetDirectBufferAddress (env, ret[i].object);
-    if (!ret[i].data) {
-      gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-          err, "Failed to get input buffer address %d", i);
-      goto error;
-    }
-    ret[i].size = (*env)->GetDirectBufferCapacity (env, ret[i].object);
-  }
+  gst_amc_jni_get_buffer_array (env, err, input_buffers, &ret, n_buffers);
 
 done:
   if (input_buffers)
-    (*env)->DeleteLocalRef (env, input_buffers);
-  input_buffers = NULL;
+    gst_amc_jni_object_local_unref (env, input_buffers);
 
   return ret;
-error:
-  if (ret)
-    gst_amc_codec_free_buffers (ret, n_input_buffers);
-  ret = NULL;
-  *n_buffers = 0;
-  goto done;
+}
+
+void
+gst_amc_codec_free_buffers (GstAmcBuffer * buffers, gsize n_buffers)
+{
+  JNIEnv *env;
+
+  env = gst_amc_jni_get_env ();
+  gst_amc_jni_free_buffer_array (env, buffers, n_buffers);
 }
 
 gint
@@ -504,18 +329,9 @@
   g_return_val_if_fail (codec != NULL, G_MININT);
 
   env = gst_amc_jni_get_env ();
-
-  ret =
-      (*env)->CallIntMethod (env, codec->object,
-      media_codec.dequeue_input_buffer, timeoutUs);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to dequeue input buffer");
-    ret = G_MININT;
-    goto done;
-  }
-
-done:
+  if (!gst_amc_jni_call_int_method (env, err, codec->object,
+          media_codec.dequeue_input_buffer, &ret, timeoutUs))
+    return G_MININT;
 
   return ret;
 }
@@ -526,39 +342,22 @@
 {
   g_return_val_if_fail (buffer_info != NULL, FALSE);
 
-  info->flags =
-      (*env)->GetIntField (env, buffer_info, media_codec_buffer_info.flags);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to get buffer info flags");
+  if (!gst_amc_jni_get_int_field (env, err, buffer_info,
+          media_codec_buffer_info.flags, &info->flags))
     return FALSE;
-  }
 
-  info->offset =
-      (*env)->GetIntField (env, buffer_info, media_codec_buffer_info.offset);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to get buffer info offset");
+  if (!gst_amc_jni_get_int_field (env, err, buffer_info,
+          media_codec_buffer_info.offset, &info->offset))
     return FALSE;
-  }
 
-  info->presentation_time_us =
-      (*env)->GetLongField (env, buffer_info,
-      media_codec_buffer_info.presentation_time_us);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to get buffer info pts");
+  if (!gst_amc_jni_get_long_field (env, err, buffer_info,
+          media_codec_buffer_info.presentation_time_us,
+          &info->presentation_time_us))
     return FALSE;
-  }
 
-  info->size =
-      (*env)->GetIntField (env, buffer_info, media_codec_buffer_info.size);
-  if ((*env)->ExceptionCheck (env)) {
-    (*env)->ExceptionClear (env);
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to get buffer info size");
+  if (!gst_amc_jni_get_int_field (env, err, buffer_info,
+          media_codec_buffer_info.size, &info->size))
     return FALSE;
-  }
 
   return TRUE;
 }
@@ -576,20 +375,13 @@
   env = gst_amc_jni_get_env ();
 
   info_o =
-      (*env)->NewObject (env, media_codec_buffer_info.klass,
+      gst_amc_jni_new_object (env, err, FALSE, media_codec_buffer_info.klass,
       media_codec_buffer_info.constructor);
-  if (!info_o) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to create buffer info instance");
+  if (!info_o)
     goto done;
-  }
 
-  ret =
-      (*env)->CallIntMethod (env, codec->object,
-      media_codec.dequeue_output_buffer, info_o, timeoutUs);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to dequeue output buffer");
+  if (!gst_amc_jni_call_int_method (env, err, codec->object,
+          media_codec.dequeue_output_buffer, &ret, info_o, timeoutUs)) {
     ret = G_MININT;
     goto done;
   }
@@ -601,7 +393,7 @@
 
 done:
   if (info_o)
-    (*env)->DeleteLocalRef (env, info_o);
+    gst_amc_jni_object_local_unref (env, info_o);
   info_o = NULL;
 
   return ret;
@@ -612,25 +404,14 @@
     const GstAmcBufferInfo * info, GError ** err)
 {
   JNIEnv *env;
-  gboolean ret = TRUE;
 
   g_return_val_if_fail (codec != NULL, FALSE);
   g_return_val_if_fail (info != NULL, FALSE);
 
   env = gst_amc_jni_get_env ();
-
-  (*env)->CallVoidMethod (env, codec->object, media_codec.queue_input_buffer,
-      index, info->offset, info->size, info->presentation_time_us, info->flags);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to queue input buffer");
-    ret = FALSE;
-    goto done;
-  }
-
-done:
-
-  return ret;
+  return gst_amc_jni_call_void_method (env, err, codec->object,
+      media_codec.queue_input_buffer, index, info->offset, info->size,
+      info->presentation_time_us, info->flags);
 }
 
 gboolean
@@ -638,24 +419,12 @@
     GError ** err)
 {
   JNIEnv *env;
-  gboolean ret = TRUE;
 
   g_return_val_if_fail (codec != NULL, FALSE);
 
   env = gst_amc_jni_get_env ();
-
-  (*env)->CallVoidMethod (env, codec->object, media_codec.release_output_buffer,
-      index, JNI_FALSE);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to release output buffer");
-    ret = FALSE;
-    goto done;
-  }
-
-done:
-
-  return ret;
+  return gst_amc_jni_call_void_method (env, err, codec->object,
+      media_codec.release_output_buffer, index, JNI_FALSE);
 }
 
 GstAmcFormat *
@@ -665,42 +434,25 @@
   JNIEnv *env;
   GstAmcFormat *format = NULL;
   jstring mime_str;
-  jobject object = NULL;
 
   g_return_val_if_fail (mime != NULL, NULL);
 
   env = gst_amc_jni_get_env ();
 
-  mime_str = (*env)->NewStringUTF (env, mime);
-  if (mime_str == NULL) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_INIT, err,
-        "Failed to create Java string");
+  mime_str = gst_amc_jni_string_from_gchar (env, err, FALSE, mime);
+  if (!mime_str)
     goto error;
-  }
 
   format = g_slice_new0 (GstAmcFormat);
-
-  object =
-      (*env)->CallStaticObjectMethod (env, media_format.klass,
+  format->object =
+      gst_amc_jni_new_object_from_static (env, err, TRUE, media_format.klass,
       media_format.create_audio_format, mime_str, sample_rate, channels);
-  if ((*env)->ExceptionCheck (env) || !object) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_INIT, err,
-        "Failed to create format instance '%s'", mime);
+  if (!format->object)
     goto error;
-  }
-
-  format->object = (*env)->NewGlobalRef (env, object);
-  if (!format->object) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_INIT, err,
-        "Failed to create global format reference");
-    goto error;
-  }
 
 done:
-  if (object)
-    (*env)->DeleteLocalRef (env, object);
   if (mime_str)
-    (*env)->DeleteLocalRef (env, mime_str);
+    gst_amc_jni_object_local_unref (env, mime_str);
   mime_str = NULL;
 
   return format;
@@ -719,42 +471,25 @@
   JNIEnv *env;
   GstAmcFormat *format = NULL;
   jstring mime_str;
-  jobject object = NULL;
 
   g_return_val_if_fail (mime != NULL, NULL);
 
   env = gst_amc_jni_get_env ();
 
-  mime_str = (*env)->NewStringUTF (env, mime);
-  if (mime_str == NULL) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_INIT, err,
-        "Failed to create Java string");
+  mime_str = gst_amc_jni_string_from_gchar (env, err, FALSE, mime);
+  if (!mime_str)
     goto error;
-  }
 
   format = g_slice_new0 (GstAmcFormat);
-
-  object =
-      (*env)->CallStaticObjectMethod (env, media_format.klass,
+  format->object =
+      gst_amc_jni_new_object_from_static (env, err, TRUE, media_format.klass,
       media_format.create_video_format, mime_str, width, height);
-  if ((*env)->ExceptionCheck (env) || !object) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_INIT, err,
-        "Failed to create format instance '%s'", mime);
+  if (!format->object)
     goto error;
-  }
-
-  format->object = (*env)->NewGlobalRef (env, object);
-  if (!format->object) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_INIT, err,
-        "Failed to create global format reference");
-    goto error;
-  }
 
 done:
-  if (object)
-    (*env)->DeleteLocalRef (env, object);
   if (mime_str)
-    (*env)->DeleteLocalRef (env, mime_str);
+    gst_amc_jni_object_local_unref (env, mime_str);
   mime_str = NULL;
 
   return format;
@@ -774,7 +509,7 @@
   g_return_if_fail (format != NULL);
 
   env = gst_amc_jni_get_env ();
-  (*env)->DeleteGlobalRef (env, format->object);
+  gst_amc_jni_object_unref (env, format->object);
   g_slice_free (GstAmcFormat, format);
 }
 
@@ -783,35 +518,18 @@
 {
   JNIEnv *env;
   jstring v_str = NULL;
-  const gchar *v = NULL;
   gchar *ret = NULL;
 
   g_return_val_if_fail (format != NULL, FALSE);
 
   env = gst_amc_jni_get_env ();
 
-  v_str =
-      (*env)->CallObjectMethod (env, format->object, media_format.to_string);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to convert format to string");
+  if (!gst_amc_jni_call_object_method (env, err, format->object,
+          media_format.to_string, &v_str))
     goto done;
-  }
-
-  v = (*env)->GetStringUTFChars (env, v_str, NULL);
-  if (!v) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to get UTF8 string");
-    goto done;
-  }
-
-  ret = g_strdup (v);
+  ret = gst_amc_jni_string_to_gchar (env, v_str, TRUE);
 
 done:
-  if (v)
-    (*env)->ReleaseStringUTFChars (env, v_str, v);
-  if (v_str)
-    (*env)->DeleteLocalRef (env, v_str);
 
   return ret;
 }
@@ -829,25 +547,17 @@
 
   env = gst_amc_jni_get_env ();
 
-  key_str = (*env)->NewStringUTF (env, key);
-  if (!key_str) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to create Java string");
+  key_str = gst_amc_jni_string_from_gchar (env, err, FALSE, key);
+  if (!key_str)
     goto done;
-  }
 
-  ret =
-      (*env)->CallBooleanMethod (env, format->object, media_format.contains_key,
-      key_str);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to check if format contains key '%s'", key);
+  if (!gst_amc_jni_call_boolean_method (env, err, format->object,
+          media_format.contains_key, &ret, key_str))
     goto done;
-  }
 
 done:
   if (key_str)
-    (*env)->DeleteLocalRef (env, key_str);
+    gst_amc_jni_object_local_unref (env, key_str);
 
   return ret;
 }
@@ -867,60 +577,50 @@
   *value = 0;
   env = gst_amc_jni_get_env ();
 
-  key_str = (*env)->NewStringUTF (env, key);
-  if (!key_str) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to create Java string");
+  key_str = gst_amc_jni_string_from_gchar (env, err, FALSE, key);
+  if (!key_str)
     goto done;
-  }
 
-  *value =
-      (*env)->CallFloatMethod (env, format->object, media_format.get_float,
-      key_str);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed get float key '%s'", key);
+  if (!gst_amc_jni_call_float_method (env, err, format->object,
+          media_format.get_float, value, key_str))
     goto done;
-  }
   ret = TRUE;
 
 done:
   if (key_str)
-    (*env)->DeleteLocalRef (env, key_str);
+    gst_amc_jni_object_local_unref (env, key_str);
 
   return ret;
 }
 
-void
+gboolean
 gst_amc_format_set_float (GstAmcFormat * format, const gchar * key,
     gfloat value, GError ** err)
 {
   JNIEnv *env;
   jstring key_str = NULL;
+  gboolean ret = FALSE;
 
-  g_return_if_fail (format != NULL);
-  g_return_if_fail (key != NULL);
+  g_return_val_if_fail (format != NULL, FALSE);
+  g_return_val_if_fail (key != NULL, FALSE);
 
   env = gst_amc_jni_get_env ();
 
-  key_str = (*env)->NewStringUTF (env, key);
-  if (!key_str) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to create Java string");
+  key_str = gst_amc_jni_string_from_gchar (env, err, FALSE, key);
+  if (!key_str)
     goto done;
-  }
 
-  (*env)->CallVoidMethod (env, format->object, media_format.set_float, key_str,
-      value);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed set float key '%s'", key);
+  if (!gst_amc_jni_call_void_method (env, err, format->object,
+          media_format.set_float, key_str, value))
     goto done;
-  }
+
+  ret = TRUE;
 
 done:
   if (key_str)
-    (*env)->DeleteLocalRef (env, key_str);
+    gst_amc_jni_object_local_unref (env, key_str);
+
+  return ret;
 }
 
 gboolean
@@ -938,61 +638,51 @@
   *value = 0;
   env = gst_amc_jni_get_env ();
 
-  key_str = (*env)->NewStringUTF (env, key);
-  if (!key_str) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to create Java string");
+  key_str = gst_amc_jni_string_from_gchar (env, err, FALSE, key);
+  if (!key_str)
     goto done;
-  }
 
-  *value =
-      (*env)->CallIntMethod (env, format->object, media_format.get_integer,
-      key_str);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed get integer key '%s'", key);
+  if (!gst_amc_jni_call_int_method (env, err, format->object,
+          media_format.get_integer, value, key_str))
     goto done;
-  }
   ret = TRUE;
 
 done:
   if (key_str)
-    (*env)->DeleteLocalRef (env, key_str);
+    gst_amc_jni_object_local_unref (env, key_str);
 
   return ret;
 
 }
 
-void
+gboolean
 gst_amc_format_set_int (GstAmcFormat * format, const gchar * key, gint value,
     GError ** err)
 {
   JNIEnv *env;
   jstring key_str = NULL;
+  gboolean ret = FALSE;
 
-  g_return_if_fail (format != NULL);
-  g_return_if_fail (key != NULL);
+  g_return_val_if_fail (format != NULL, FALSE);
+  g_return_val_if_fail (key != NULL, FALSE);
 
   env = gst_amc_jni_get_env ();
 
-  key_str = (*env)->NewStringUTF (env, key);
-  if (!key_str) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to create Java string");
+  key_str = gst_amc_jni_string_from_gchar (env, err, FALSE, key);
+  if (!key_str)
     goto done;
-  }
 
-  (*env)->CallVoidMethod (env, format->object, media_format.set_integer,
-      key_str, value);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed set integer key '%s'", key);
+  if (!gst_amc_jni_call_void_method (env, err, format->object,
+          media_format.set_integer, key_str, value))
     goto done;
-  }
+
+  ret = TRUE;
 
 done:
   if (key_str)
-    (*env)->DeleteLocalRef (env, key_str);
+    gst_amc_jni_object_local_unref (env, key_str);
+
+  return ret;
 }
 
 gboolean
@@ -1003,7 +693,6 @@
   gboolean ret = FALSE;
   jstring key_str = NULL;
   jstring v_str = NULL;
-  const gchar *v = NULL;
 
   g_return_val_if_fail (format != NULL, FALSE);
   g_return_val_if_fail (key != NULL, FALSE);
@@ -1012,85 +701,61 @@
   *value = 0;
   env = gst_amc_jni_get_env ();
 
-  key_str = (*env)->NewStringUTF (env, key);
-  if (!key_str) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to create Java string");
+  key_str = gst_amc_jni_string_from_gchar (env, err, FALSE, key);
+  if (!key_str)
     goto done;
-  }
 
-  v_str =
-      (*env)->CallObjectMethod (env, format->object, media_format.get_string,
-      key_str);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed get string key '%s'", key);
+  if (!gst_amc_jni_call_object_method (env, err, format->object,
+          media_format.get_string, &v_str, key_str))
     goto done;
-  }
 
-  v = (*env)->GetStringUTFChars (env, v_str, NULL);
-  if (!v) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed get string UTF8 characters");
-    goto done;
-  }
-
-  *value = g_strdup (v);
+  *value = gst_amc_jni_string_to_gchar (env, v_str, TRUE);
 
   ret = TRUE;
 
 done:
   if (key_str)
-    (*env)->DeleteLocalRef (env, key_str);
-  if (v)
-    (*env)->ReleaseStringUTFChars (env, v_str, v);
-  if (v_str)
-    (*env)->DeleteLocalRef (env, v_str);
+    gst_amc_jni_object_local_unref (env, key_str);
 
   return ret;
 }
 
-void
+gboolean
 gst_amc_format_set_string (GstAmcFormat * format, const gchar * key,
     const gchar * value, GError ** err)
 {
   JNIEnv *env;
   jstring key_str = NULL;
   jstring v_str = NULL;
+  gboolean ret = FALSE;
 
-  g_return_if_fail (format != NULL);
-  g_return_if_fail (key != NULL);
-  g_return_if_fail (value != NULL);
+  g_return_val_if_fail (format != NULL, FALSE);
+  g_return_val_if_fail (key != NULL, FALSE);
+  g_return_val_if_fail (value != NULL, FALSE);
 
   env = gst_amc_jni_get_env ();
 
-  key_str = (*env)->NewStringUTF (env, key);
-  if (!key_str) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to create Java string");
+  key_str = gst_amc_jni_string_from_gchar (env, err, FALSE, key);
+  if (!key_str)
     goto done;
-  }
 
-  v_str = (*env)->NewStringUTF (env, value);
-  if (!v_str) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to create Java string");
+  v_str = gst_amc_jni_string_from_gchar (env, err, FALSE, value);
+  if (!v_str)
     goto done;
-  }
 
-  (*env)->CallVoidMethod (env, format->object, media_format.set_string, key_str,
-      v_str);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed set string key '%s'", key);
+  if (!gst_amc_jni_call_void_method (env, err, format->object,
+          media_format.set_string, key_str, v_str))
     goto done;
-  }
+
+  ret = TRUE;
 
 done:
   if (key_str)
-    (*env)->DeleteLocalRef (env, key_str);
+    gst_amc_jni_object_local_unref (env, key_str);
   if (v_str)
-    (*env)->DeleteLocalRef (env, v_str);
+    gst_amc_jni_object_local_unref (env, v_str);
+
+  return ret;
 }
 
 gboolean
@@ -1111,25 +776,18 @@
   *size = 0;
   env = gst_amc_jni_get_env ();
 
-  key_str = (*env)->NewStringUTF (env, key);
-  if (!key_str) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to create Java string");
+  key_str = gst_amc_jni_string_from_gchar (env, err, FALSE, key);
+  if (!key_str)
     goto done;
-  }
 
-  v = (*env)->CallObjectMethod (env, format->object,
-      media_format.get_byte_buffer, key_str);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed get buffer key '%s'", key);
+  if (!gst_amc_jni_call_object_method (env, err, format->object,
+          media_format.get_byte_buffer, &v, key_str))
     goto done;
-  }
 
   *data = (*env)->GetDirectBufferAddress (env, v);
   if (!data) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed get buffer address");
+    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+        GST_LIBRARY_ERROR_FAILED, "Failed get buffer address");
     goto done;
   }
   *size = (*env)->GetDirectBufferCapacity (env, v);
@@ -1139,55 +797,53 @@
 
 done:
   if (key_str)
-    (*env)->DeleteLocalRef (env, key_str);
+    gst_amc_jni_object_local_unref (env, key_str);
   if (v)
-    (*env)->DeleteLocalRef (env, v);
+    gst_amc_jni_object_local_unref (env, v);
 
   return ret;
 }
 
-void
+gboolean
 gst_amc_format_set_buffer (GstAmcFormat * format, const gchar * key,
     guint8 * data, gsize size, GError ** err)
 {
   JNIEnv *env;
   jstring key_str = NULL;
   jobject v = NULL;
+  gboolean ret = FALSE;
 
-  g_return_if_fail (format != NULL);
-  g_return_if_fail (key != NULL);
-  g_return_if_fail (data != NULL);
+  g_return_val_if_fail (format != NULL, FALSE);
+  g_return_val_if_fail (key != NULL, FALSE);
+  g_return_val_if_fail (data != NULL, FALSE);
 
   env = gst_amc_jni_get_env ();
 
-  key_str = (*env)->NewStringUTF (env, key);
-  if (!key_str) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to create Java string");
+  key_str = gst_amc_jni_string_from_gchar (env, err, FALSE, key);
+  if (!key_str)
     goto done;
-  }
 
   /* FIXME: The memory must remain valid until the codec is stopped */
   v = (*env)->NewDirectByteBuffer (env, data, size);
   if (!v) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed create Java byte buffer");
+    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+        GST_LIBRARY_ERROR_FAILED, "Failed create Java byte buffer");
     goto done;
   }
 
-  (*env)->CallVoidMethod (env, format->object, media_format.set_byte_buffer,
-      key_str, v);
-  if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed set buffer key '%s'", key);
+  if (!gst_amc_jni_call_void_method (env, err, format->object,
+          media_format.set_byte_buffer, key_str, v))
     goto done;
-  }
+
+  ret = TRUE;
 
 done:
   if (key_str)
-    (*env)->DeleteLocalRef (env, key_str);
+    gst_amc_jni_object_local_unref (env, key_str);
   if (v)
-    (*env)->DeleteLocalRef (env, v);
+    gst_amc_jni_object_local_unref (env, v);
+
+  return ret;
 }
 
 static gboolean
@@ -2119,14 +1775,18 @@
 } color_format_mapping_table[] = {
   {
   COLOR_FormatYUV420Planar, GST_VIDEO_FORMAT_I420}, {
+  COLOR_FormatYUV420Flexible, GST_VIDEO_FORMAT_I420}, {
   COLOR_FormatYUV420SemiPlanar, GST_VIDEO_FORMAT_NV12}, {
   COLOR_TI_FormatYUV420PackedSemiPlanar, GST_VIDEO_FORMAT_NV12}, {
   COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced, GST_VIDEO_FORMAT_NV12}, {
+  COLOR_INTEL_FormatYUV420PackedSemiPlanar, GST_VIDEO_FORMAT_NV12}, {
+  COLOR_INTEL_FormatYUV420PackedSemiPlanar_Tiled, GST_VIDEO_FORMAT_NV12}, {
   COLOR_QCOM_FormatYUV420SemiPlanar, GST_VIDEO_FORMAT_NV12}, {
   COLOR_QCOM_FormatYUV420PackedSemiPlanar64x32Tile2m8ka, GST_VIDEO_FORMAT_NV12}, {
   COLOR_QCOM_FormatYVU420SemiPlanar32m, GST_VIDEO_FORMAT_NV12}, {
   COLOR_OMX_SEC_FormatNV12Tiled, GST_VIDEO_FORMAT_NV12}, {
-  COLOR_FormatYCbYCr, GST_VIDEO_FORMAT_YUY2}
+  COLOR_FormatYCbYCr, GST_VIDEO_FORMAT_YUY2}, {
+  COLOR_FormatYV12, GST_VIDEO_FORMAT_YV12}
 };
 
 static gboolean
@@ -2301,7 +1961,7 @@
   if (slice_height == 0) {
     /* NVidia Tegra 3 on Nexus 7 does not set this */
     if (g_str_has_prefix (codec_info->name, "OMX.Nvidia."))
-      slice_height = GST_ROUND_UP_32 (height);
+      slice_height = GST_ROUND_UP_16 (height);
   }
 
   if (width == 0 || height == 0) {
@@ -2310,7 +1970,9 @@
   }
 
   switch (color_format) {
-    case COLOR_FormatYUV420Planar:{
+    case COLOR_FormatYUV420Planar:
+    case COLOR_FormatYUV420Flexible:{
+    case COLOR_FormatYV12:
       if (stride == 0 || slice_height == 0) {
         GST_ERROR ("Stride or slice height is 0");
         return FALSE;
@@ -2321,6 +1983,20 @@
               1) / 2);
       break;
     }
+    case COLOR_INTEL_FormatYUV420PackedSemiPlanar:
+    case COLOR_INTEL_FormatYUV420PackedSemiPlanar_Tiled:
+      if (stride == 0) {
+        GST_ERROR ("Stride is 0");
+        return FALSE;
+      }
+      if (slice_height <= 0)
+        slice_height = height;
+
+      frame_size =
+          stride * (slice_height - crop_top / 2) +
+          (GST_ROUND_UP_2 (stride) * ((slice_height + 1) / 2));
+      break;
+
     case COLOR_TI_FormatYUV420PackedSemiPlanar:
     case COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced:{
       if (stride == 0 || slice_height == 0) {
diff --git a/sys/androidmedia/gstamc.h b/sys/androidmedia/gstamc.h
index 7fcae1e..e216039 100644
--- a/sys/androidmedia/gstamc.h
+++ b/sys/androidmedia/gstamc.h
@@ -26,6 +26,8 @@
 #include <gst/audio/audio.h>
 #include <jni.h>
 
+#include "gstjniutils.h"
+
 G_BEGIN_DECLS
 
 typedef struct _GstAmcCodecInfo GstAmcCodecInfo;
@@ -33,7 +35,6 @@
 typedef struct _GstAmcCodec GstAmcCodec;
 typedef struct _GstAmcBufferInfo GstAmcBufferInfo;
 typedef struct _GstAmcFormat GstAmcFormat;
-typedef struct _GstAmcBuffer GstAmcBuffer;
 typedef struct _GstAmcColorFormatInfo GstAmcColorFormatInfo;
 
 struct _GstAmcCodecType {
@@ -56,12 +57,6 @@
   gint n_supported_types;
 };
 
-struct _GstAmcBuffer {
-  jobject object; /* global reference */
-  guint8 *data;
-  gsize size;
-};
-
 struct _GstAmcFormat {
   /* < private > */
   jobject object; /* global reference */
@@ -112,13 +107,13 @@
 gboolean gst_amc_format_contains_key (GstAmcFormat *format, const gchar *key, GError **err);
 
 gboolean gst_amc_format_get_float (GstAmcFormat *format, const gchar *key, gfloat *value, GError **err);
-void gst_amc_format_set_float (GstAmcFormat *format, const gchar *key, gfloat value, GError **err);
+gboolean gst_amc_format_set_float (GstAmcFormat *format, const gchar *key, gfloat value, GError **err);
 gboolean gst_amc_format_get_int (GstAmcFormat *format, const gchar *key, gint *value, GError **err);
-void gst_amc_format_set_int (GstAmcFormat *format, const gchar *key, gint value, GError **err);
+gboolean gst_amc_format_set_int (GstAmcFormat *format, const gchar *key, gint value, GError **err);
 gboolean gst_amc_format_get_string (GstAmcFormat *format, const gchar *key, gchar **value, GError **err);
-void gst_amc_format_set_string (GstAmcFormat *format, const gchar *key, const gchar *value, GError **err);
+gboolean gst_amc_format_set_string (GstAmcFormat *format, const gchar *key, const gchar *value, GError **err);
 gboolean gst_amc_format_get_buffer (GstAmcFormat *format, const gchar *key, guint8 **data, gsize *size, GError **err);
-void gst_amc_format_set_buffer (GstAmcFormat *format, const gchar *key, guint8 *data, gsize size, GError **err);
+gboolean gst_amc_format_set_buffer (GstAmcFormat *format, const gchar *key, guint8 *data, gsize size, GError **err);
 
 GstVideoFormat gst_amc_color_format_to_video_format (const GstAmcCodecInfo * codec_info, const gchar * mime, gint color_format);
 gint gst_amc_video_format_to_color_format (const GstAmcCodecInfo * codec_info, const gchar * mime, GstVideoFormat video_format);
diff --git a/sys/androidmedia/gstamcaudiodec.c b/sys/androidmedia/gstamcaudiodec.c
index 034591e..d381eec 100644
--- a/sys/androidmedia/gstamcaudiodec.c
+++ b/sys/androidmedia/gstamcaudiodec.c
@@ -43,6 +43,16 @@
 GST_DEBUG_CATEGORY_STATIC (gst_amc_audio_dec_debug_category);
 #define GST_CAT_DEFAULT gst_amc_audio_dec_debug_category
 
+#define GST_AUDIO_DECODER_ERROR_FROM_ERROR(el, err) G_STMT_START { \
+  gchar *__dbg = g_strdup (err->message);                               \
+  GstAudioDecoder *__dec = GST_AUDIO_DECODER (el);                      \
+  GST_WARNING_OBJECT (el, "error: %s", __dbg);                          \
+  _gst_audio_decoder_error (__dec, 1,                                   \
+    err->domain, err->code,                                             \
+    NULL, __dbg, __FILE__, GST_FUNCTION, __LINE__);                     \
+  g_clear_error (&err); \
+} G_STMT_END
+
 /* prototypes */
 static void gst_amc_audio_dec_finalize (GObject * object);
 
@@ -630,7 +640,7 @@
   }
 failed_release:
   {
-    GST_ELEMENT_ERROR_FROM_ERROR (self, err);
+    GST_AUDIO_DECODER_ERROR_FROM_ERROR (self, err);
     gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
     gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
     self->downstream_flow_ret = GST_FLOW_ERROR;
@@ -1193,7 +1203,7 @@
   }
 queue_error:
   {
-    GST_ELEMENT_ERROR_FROM_ERROR (self, err);
+    GST_AUDIO_DECODER_ERROR_FROM_ERROR (self, err);
     if (minfo.data)
       gst_buffer_unmap (inbuf, &minfo);
     if (inbuf)
diff --git a/sys/androidmedia/gstamcvideodec.c b/sys/androidmedia/gstamcvideodec.c
index 00f9b18..a2ac65e 100644
--- a/sys/androidmedia/gstamcvideodec.c
+++ b/sys/androidmedia/gstamcvideodec.c
@@ -46,6 +46,16 @@
 GST_DEBUG_CATEGORY_STATIC (gst_amc_video_dec_debug_category);
 #define GST_CAT_DEFAULT gst_amc_video_dec_debug_category
 
+#define GST_VIDEO_DECODER_ERROR_FROM_ERROR(el, err) G_STMT_START { \
+  gchar *__dbg = g_strdup (err->message);                               \
+  GstVideoDecoder *__dec = GST_VIDEO_DECODER (el);                      \
+  GST_WARNING_OBJECT (el, "error: %s", __dbg);                          \
+  _gst_video_decoder_error (__dec, 1,                                   \
+    err->domain, err->code,                                             \
+    NULL, __dbg, __FILE__, GST_FUNCTION, __LINE__);                     \
+  g_clear_error (&err); \
+} G_STMT_END
+
 typedef struct _BufferIdentification BufferIdentification;
 struct _BufferIdentification
 {
@@ -825,7 +835,7 @@
   }
 failed_release:
   {
-    GST_ELEMENT_ERROR_FROM_ERROR (self, err);
+    GST_VIDEO_DECODER_ERROR_FROM_ERROR (self, err);
     gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
     gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
     self->downstream_flow_ret = GST_FLOW_ERROR;
@@ -1304,7 +1314,7 @@
   }
 queue_error:
   {
-    GST_ELEMENT_ERROR_FROM_ERROR (self, err);
+    GST_VIDEO_DECODER_ERROR_FROM_ERROR (self, err);
     if (minfo.data)
       gst_buffer_unmap (frame->input_buffer, &minfo);
     gst_video_codec_frame_unref (frame);
diff --git a/sys/androidmedia/gstjniutils.c b/sys/androidmedia/gstjniutils.c
index 0deadfa..02bc3a8 100644
--- a/sys/androidmedia/gstjniutils.c
+++ b/sys/androidmedia/gstjniutils.c
@@ -38,28 +38,25 @@
     jsize * nVMs);
 static jint (*create_java_vm) (JavaVM ** p_vm, JNIEnv ** p_env, void *vm_args);
 static JavaVM *java_vm;
-static gboolean initialized = FALSE;
 static gboolean started_java_vm = FALSE;
 static pthread_key_t current_jni_env;
 
 jclass
-gst_amc_jni_get_class (JNIEnv * env, const gchar * name)
+gst_amc_jni_get_class (JNIEnv * env, GError ** err, const gchar * name)
 {
   jclass tmp, ret = NULL;
 
   GST_DEBUG ("Retrieving Java class %s", name);
 
   tmp = (*env)->FindClass (env, name);
-  if (!tmp) {
-    ret = FALSE;
-    (*env)->ExceptionClear (env);
-    GST_ERROR ("Failed to get %s class", name);
+  if ((*env)->ExceptionCheck (env) || !tmp) {
+    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+        GST_LIBRARY_ERROR_FAILED, "Failed to find class %s", name);
     goto done;
   }
 
   ret = (*env)->NewGlobalRef (env, tmp);
   if (!ret) {
-    (*env)->ExceptionClear (env);
     GST_ERROR ("Failed to get %s class global reference", name);
   }
 
@@ -72,49 +69,67 @@
 }
 
 jmethodID
-gst_amc_jni_get_method (JNIEnv * env, jclass klass, const gchar * name,
-    const gchar * signature)
+gst_amc_jni_get_method_id (JNIEnv * env, GError ** err, jclass klass,
+    const gchar * name, const gchar * signature)
 {
   jmethodID ret;
 
   ret = (*env)->GetMethodID (env, klass, name, signature);
-  if (!ret) {
-    (*env)->ExceptionClear (env);
-    GST_ERROR ("Failed to get method ID %s", name);
+  if ((*env)->ExceptionCheck (env) || !ret) {
+    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+        GST_LIBRARY_ERROR_FAILED, "Failed to get method ID %s (%s)", name,
+        signature);
   }
   return ret;
 }
 
 jmethodID
-gst_amc_jni_get_static_method (JNIEnv * env, jclass klass, const gchar * name,
-    const gchar * signature)
+gst_amc_jni_get_static_method_id (JNIEnv * env, GError ** err, jclass klass,
+    const gchar * name, const gchar * signature)
 {
   jmethodID ret;
 
   ret = (*env)->GetStaticMethodID (env, klass, name, signature);
-  if (!ret) {
-    (*env)->ExceptionClear (env);
-    GST_ERROR ("Failed to get static method id %s", name);
+  if ((*env)->ExceptionCheck (env) || !ret) {
+    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+        GST_LIBRARY_ERROR_FAILED, "Failed to get static method ID %s (%s)",
+        name, signature);
   }
   return ret;
 }
 
 jfieldID
-gst_amc_jni_get_field_id (JNIEnv * env, jclass klass, const gchar * name,
-    const gchar * type)
+gst_amc_jni_get_field_id (JNIEnv * env, GError ** err, jclass klass,
+    const gchar * name, const gchar * type)
 {
   jfieldID ret;
 
   ret = (*env)->GetFieldID (env, klass, name, type);
-  if (!ret) {
-    (*env)->ExceptionClear (env);
-    GST_ERROR ("Failed to get field ID %s", name);
+  if ((*env)->ExceptionCheck (env) || !ret) {
+    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+        GST_LIBRARY_ERROR_FAILED, "Failed to get field ID %s (%s)", name, type);
+  }
+  return ret;
+}
+
+jfieldID
+gst_amc_jni_get_static_field_id (JNIEnv * env, GError ** err, jclass klass,
+    const gchar * name, const gchar * type)
+{
+  jfieldID ret;
+
+  ret = (*env)->GetStaticFieldID (env, klass, name, type);
+  if ((*env)->ExceptionCheck (env) || !ret) {
+    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+        GST_LIBRARY_ERROR_FAILED, "Failed to get static field ID %s (%s)", name,
+        type);
   }
   return ret;
 }
 
 jobject
-gst_amc_jni_new_object (JNIEnv * env, jclass klass, jmethodID constructor, ...)
+gst_amc_jni_new_object (JNIEnv * env, GError ** err, gboolean global,
+    jclass klass, jmethodID constructor, ...)
 {
   jobject tmp;
   va_list args;
@@ -123,18 +138,21 @@
   tmp = (*env)->NewObjectV (env, klass, constructor, args);
   va_end (args);
 
-  if (!tmp) {
-    (*env)->ExceptionClear (env);
-    GST_ERROR ("Failed to create object");
+  if ((*env)->ExceptionCheck (env) || !tmp) {
+    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+        GST_LIBRARY_ERROR_FAILED, "Failed to create object");
     return NULL;
   }
 
-  return gst_amc_jni_object_make_global (env, tmp);
+  if (global)
+    return gst_amc_jni_object_make_global (env, tmp);
+  else
+    return tmp;
 }
 
 jobject
-gst_amc_jni_new_object_from_static (JNIEnv * env, jclass klass,
-    jmethodID method, ...)
+gst_amc_jni_new_object_from_static (JNIEnv * env, GError ** err,
+    gboolean global, jclass klass, jmethodID method, ...)
 {
   jobject tmp;
   va_list args;
@@ -144,12 +162,15 @@
   va_end (args);
 
   if ((*env)->ExceptionCheck (env) || !tmp) {
-    (*env)->ExceptionClear (env);
-    GST_ERROR ("Failed to create object from static method");
+    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+        GST_LIBRARY_ERROR_FAILED, "Failed to create object");
     return NULL;
   }
 
-  return gst_amc_jni_object_make_global (env, tmp);
+  if (global)
+    return gst_amc_jni_object_make_global (env, tmp);
+  else
+    return tmp;
 }
 
 jobject
@@ -160,10 +181,9 @@
   ret = (*env)->NewGlobalRef (env, object);
   if (!ret) {
     GST_ERROR ("Failed to create global reference");
-    (*env)->ExceptionClear (env);
-  } else {
-    gst_amc_jni_object_local_unref (env, object);
   }
+  gst_amc_jni_object_local_unref (env, object);
+
   return ret;
 }
 
@@ -175,7 +195,6 @@
   ret = (*env)->NewGlobalRef (env, object);
   if (!ret) {
     GST_ERROR ("Failed to create global reference");
-    (*env)->ExceptionClear (env);
   }
   return ret;
 }
@@ -193,9 +212,22 @@
 }
 
 jstring
-gst_amc_jni_string_from_gchar (JNIEnv * env, const gchar * string)
+gst_amc_jni_string_from_gchar (JNIEnv * env, GError ** err,
+    gboolean global, const gchar * string)
 {
-  return (*env)->NewStringUTF (env, string);
+  jstring tmp;
+
+  tmp = (*env)->NewStringUTF (env, string);
+  if ((*env)->ExceptionCheck (env)) {
+    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+        GST_LIBRARY_ERROR_FAILED, "Failed to call Java method");
+    tmp = NULL;
+  }
+
+  if (global)
+    return gst_amc_jni_object_make_global (env, tmp);
+  else
+    return tmp;
 }
 
 gchar *
@@ -207,13 +239,13 @@
   s = (*env)->GetStringUTFChars (env, string, NULL);
   if (!s) {
     GST_ERROR ("Failed to convert string to UTF8");
-    (*env)->ExceptionClear (env);
-    return ret;
+    goto done;
   }
 
   ret = g_strdup (s);
   (*env)->ReleaseStringUTFChars (env, string, s);
 
+done:
   if (release) {
     (*env)->DeleteLocalRef (env, string);
   }
@@ -425,14 +457,15 @@
 {
   JNIEnv *env;
   JavaVMAttachArgs args;
+  gint ret;
 
   GST_DEBUG ("Attaching thread %p", g_thread_self ());
   args.version = JNI_VERSION_1_6;
   args.name = NULL;
   args.group = NULL;
 
-  if ((*java_vm)->AttachCurrentThread (java_vm, &env, &args) < 0) {
-    GST_ERROR ("Failed to attach current thread");
+  if ((ret = (*java_vm)->AttachCurrentThread (java_vm, &env, &args)) != JNI_OK) {
+    GST_ERROR ("Failed to attach current thread: %d", ret);
     return NULL;
   }
 
@@ -442,8 +475,12 @@
 static void
 gst_amc_jni_detach_current_thread (void *env)
 {
+  gint ret;
+
   GST_DEBUG ("Detaching thread %p", g_thread_self ());
-  (*java_vm)->DetachCurrentThread (java_vm);
+  if ((ret = (*java_vm)->DetachCurrentThread (java_vm)) != JNI_OK) {
+    GST_ERROR ("Failed to detach current thread: %d", ret);
+  }
 }
 
 static gboolean
@@ -514,6 +551,7 @@
 gst_amc_jni_initialize_java_vm (void)
 {
   jsize n_vms;
+  gint ret;
 
   /* Returns TRUE if we can safely
    * a) get the current VMs and
@@ -533,7 +571,7 @@
   }
 
   n_vms = 0;
-  if (get_created_java_vms (&java_vm, 1, &n_vms) < 0)
+  if ((ret = get_created_java_vms (&java_vm, 1, &n_vms)) != JNI_OK)
     goto get_created_failed;
 
   if (n_vms > 0) {
@@ -554,7 +592,7 @@
     vm_args.options = options;
     vm_args.nOptions = 4;
     vm_args.ignoreUnrecognized = JNI_TRUE;
-    if (create_java_vm (&java_vm, &env, &vm_args) < 0)
+    if ((ret = create_java_vm (&java_vm, &env, &vm_args)) != JNI_OK)
       goto create_failed;
     GST_DEBUG ("Successfully created Java VM %p", java_vm);
 
@@ -565,14 +603,14 @@
 
 get_created_failed:
   {
-    GST_ERROR ("Failed to get already created VMs");
+    GST_ERROR ("Failed to get already created VMs: %d", ret);
     g_module_close (java_module);
     java_module = NULL;
     return FALSE;
   }
 create_failed:
   {
-    GST_ERROR ("Failed to create a Java VM");
+    GST_ERROR ("Failed to create a Java VM: %d", ret);
     g_module_close (java_module);
     java_module = NULL;
     return FALSE;
@@ -580,8 +618,8 @@
 }
 
 static void
-gst_amc_jni_set_error_string (JNIEnv * env, GQuark domain, gint code,
-    GError ** err, const gchar * message)
+gst_amc_jni_set_error_string (JNIEnv * env, GError ** err, GQuark domain,
+    gint code, const gchar * message)
 {
   jthrowable exception;
 
@@ -616,8 +654,8 @@
 }
 
 G_GNUC_PRINTF (5, 6)
-     void gst_amc_jni_set_error (JNIEnv * env, GQuark domain, gint code,
-    GError ** err, const gchar * format, ...)
+     void gst_amc_jni_set_error (JNIEnv * env, GError ** err, GQuark domain,
+    gint code, const gchar * format, ...)
 {
   gchar *message;
   va_list var_args;
@@ -626,20 +664,25 @@
   message = g_strdup_vprintf (format, var_args);
   va_end (var_args);
 
-  gst_amc_jni_set_error_string (env, domain, code, err, message);
+  gst_amc_jni_set_error_string (env, err, domain, code, message);
 
   g_free (message);
 }
 
+static gpointer
+gst_amc_jni_initialize_internal (gpointer data)
+{
+  pthread_key_create (&current_jni_env, gst_amc_jni_detach_current_thread);
+  return gst_amc_jni_initialize_java_vm ()? GINT_TO_POINTER (1) : NULL;
+}
 
 gboolean
 gst_amc_jni_initialize (void)
 {
-  if (!initialized) {
-    pthread_key_create (&current_jni_env, gst_amc_jni_detach_current_thread);
-    initialized = gst_amc_jni_initialize_java_vm ();
-  }
-  return initialized;
+  GOnce once = G_ONCE_INIT;
+
+  g_once (&once, gst_amc_jni_initialize_internal, NULL);
+  return once.retval != NULL;
 }
 
 JNIEnv *
@@ -661,32 +704,31 @@
   return started_java_vm;
 }
 
-#define CALL_STATIC_TYPE_METHOD(_type, _name,  _jname, _retval)                                                     \
-_type gst_amc_jni_call_static_##_name##_method (JNIEnv *env, GError ** err, jclass klass, jmethodID methodID, ...)   \
+#define CALL_STATIC_TYPE_METHOD(_type, _name,  _jname)                                                     \
+gboolean gst_amc_jni_call_static_##_name##_method (JNIEnv *env, GError ** err, jclass klass, jmethodID methodID, _type * value, ...)   \
   {                                                                                                          \
-    _type ret;                                                                                               \
+    gboolean ret = TRUE;                                                                                     \
     va_list args;                                                                                            \
-    va_start(args, methodID);                                                                                \
-    ret = (*env)->CallStatic##_jname##MethodV(env, klass, methodID, args);                                           \
+    va_start(args, value);                                                                                \
+    *value = (*env)->CallStatic##_jname##MethodV(env, klass, methodID, args);                                \
     if ((*env)->ExceptionCheck (env)) {                                                                      \
-      gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,                               \
-          err, "Failed to call static Java method");                                                                \
-      (*env)->ExceptionClear (env);                                                                          \
-      ret = _retval;                                                                                         \
+      gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,                               \
+          "Failed to call static Java method");                                                         \
+      ret = FALSE;                                                                                           \
     }                                                                                                        \
     va_end(args);                                                                                            \
-    return (_type) ret;                                                                                      \
+    return ret;                                                                                              \
   }
 
-CALL_STATIC_TYPE_METHOD (gboolean, boolean, Boolean, FALSE);
-CALL_STATIC_TYPE_METHOD (gint8, byte, Byte, G_MININT8);
-CALL_STATIC_TYPE_METHOD (gshort, short, Short, G_MINSHORT);
-CALL_STATIC_TYPE_METHOD (gint, int, Int, G_MININT);
-CALL_STATIC_TYPE_METHOD (gchar, char, Char, 0);
-CALL_STATIC_TYPE_METHOD (glong, long, Long, G_MINLONG);
-CALL_STATIC_TYPE_METHOD (gfloat, float, Float, G_MINFLOAT);
-CALL_STATIC_TYPE_METHOD (gdouble, double, Double, G_MINDOUBLE);
-CALL_STATIC_TYPE_METHOD (jobject, object, Object, NULL);
+CALL_STATIC_TYPE_METHOD (gboolean, boolean, Boolean);
+CALL_STATIC_TYPE_METHOD (gint8, byte, Byte);
+CALL_STATIC_TYPE_METHOD (gshort, short, Short);
+CALL_STATIC_TYPE_METHOD (gint, int, Int);
+CALL_STATIC_TYPE_METHOD (gchar, char, Char);
+CALL_STATIC_TYPE_METHOD (gint64, long, Long);
+CALL_STATIC_TYPE_METHOD (gfloat, float, Float);
+CALL_STATIC_TYPE_METHOD (gdouble, double, Double);
+CALL_STATIC_TYPE_METHOD (jobject, object, Object);
 
 gboolean
 gst_amc_jni_call_static_void_method (JNIEnv * env, GError ** err, jclass klass,
@@ -698,41 +740,39 @@
 
   (*env)->CallStaticVoidMethodV (env, klass, methodID, args);
   if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to call static Java method");
-    (*env)->ExceptionClear (env);
+    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+        GST_LIBRARY_ERROR_FAILED, "Failed to call static Java method");
     ret = FALSE;
   }
   va_end (args);
   return ret;
 }
 
-#define CALL_TYPE_METHOD(_type, _name,  _jname, _retval)                                                     \
-_type gst_amc_jni_call_##_name##_method (JNIEnv *env, GError ** err, jobject obj, jmethodID methodID, ...)   \
+#define CALL_TYPE_METHOD(_type, _name,  _jname)                                                              \
+gboolean gst_amc_jni_call_##_name##_method (JNIEnv *env, GError ** err, jobject obj, jmethodID methodID, _type *value, ...)   \
   {                                                                                                          \
-    _type ret;                                                                                               \
+    gboolean ret = TRUE;                                                                                     \
     va_list args;                                                                                            \
-    va_start(args, methodID);                                                                                \
-    ret = (*env)->Call##_jname##MethodV(env, obj, methodID, args);                                           \
+    va_start(args, value);                                                                                \
+    *value = (*env)->Call##_jname##MethodV(env, obj, methodID, args);                                        \
     if ((*env)->ExceptionCheck (env)) {                                                                      \
-      gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,                               \
-          err, "Failed to call Java method");                                                                \
-      (*env)->ExceptionClear (env);                                                                          \
-      ret = _retval;                                                                                         \
+      gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,                               \
+          "Failed to call Java method");                                                                \
+      ret = FALSE;                                                                                           \
     }                                                                                                        \
     va_end(args);                                                                                            \
-    return (_type) ret;                                                                                      \
+    return ret;                                                                                              \
   }
 
-CALL_TYPE_METHOD (gboolean, boolean, Boolean, FALSE);
-CALL_TYPE_METHOD (gint8, byte, Byte, G_MININT8);
-CALL_TYPE_METHOD (gshort, short, Short, G_MINSHORT);
-CALL_TYPE_METHOD (gint, int, Int, G_MININT);
-CALL_TYPE_METHOD (gchar, char, Char, 0);
-CALL_TYPE_METHOD (glong, long, Long, G_MINLONG);
-CALL_TYPE_METHOD (gfloat, float, Float, G_MINFLOAT);
-CALL_TYPE_METHOD (gdouble, double, Double, G_MINDOUBLE);
-CALL_TYPE_METHOD (jobject, object, Object, NULL);
+CALL_TYPE_METHOD (gboolean, boolean, Boolean);
+CALL_TYPE_METHOD (gint8, byte, Byte);
+CALL_TYPE_METHOD (gshort, short, Short);
+CALL_TYPE_METHOD (gint, int, Int);
+CALL_TYPE_METHOD (gchar, char, Char);
+CALL_TYPE_METHOD (gint64, long, Long);
+CALL_TYPE_METHOD (gfloat, float, Float);
+CALL_TYPE_METHOD (gdouble, double, Double);
+CALL_TYPE_METHOD (jobject, object, Object);
 
 gboolean
 gst_amc_jni_call_void_method (JNIEnv * env, GError ** err, jobject obj,
@@ -744,29 +784,121 @@
 
   (*env)->CallVoidMethodV (env, obj, methodID, args);
   if ((*env)->ExceptionCheck (env)) {
-    gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,
-        err, "Failed to call Java method");
-    (*env)->ExceptionClear (env);
+    gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+        GST_LIBRARY_ERROR_FAILED, "Failed to call Java method");
     ret = FALSE;
   }
   va_end (args);
   return ret;
 }
 
-#define GET_TYPE_FIELD(_type, _name, _jname, _retval)                                               \
-_type gst_amc_jni_get_##_name##_field (JNIEnv *env, GError ** err, jobject obj, jfieldID fieldID)   \
+#define GET_TYPE_FIELD(_type, _name, _jname)                                               \
+gboolean gst_amc_jni_get_##_name##_field (JNIEnv *env, GError ** err, jobject obj, jfieldID fieldID, _type *value)   \
   {                                                                                                 \
-    _type res;                                                                                      \
+    gboolean ret = TRUE;                                                                            \
                                                                                                     \
-    res = (*env)->Get##_jname##Field(env, obj, fieldID);                                            \
+    *value = (*env)->Get##_jname##Field(env, obj, fieldID);                                         \
     if ((*env)->ExceptionCheck (env)) {                                                             \
-      gst_amc_jni_set_error (env, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,                      \
-          err, "Failed to call Java field");                                                        \
-      (*env)->ExceptionClear (env);                                                                 \
-      res = _retval;                                                                                \
+      gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,                      \
+          "Failed to get Java field");                                                         \
+      ret = FALSE;                                                                                  \
     }                                                                                               \
-    return res;                                                                                     \
+    return ret;                                                                                     \
   }
 
-GET_TYPE_FIELD (gint, int, Int, G_MININT);
-GET_TYPE_FIELD (glong, long, Long, G_MINLONG);
+GET_TYPE_FIELD (gboolean, boolean, Boolean);
+GET_TYPE_FIELD (gint8, byte, Byte);
+GET_TYPE_FIELD (gshort, short, Short);
+GET_TYPE_FIELD (gint, int, Int);
+GET_TYPE_FIELD (gchar, char, Char);
+GET_TYPE_FIELD (gint64, long, Long);
+GET_TYPE_FIELD (gfloat, float, Float);
+GET_TYPE_FIELD (gdouble, double, Double);
+GET_TYPE_FIELD (jobject, object, Object);
+
+#define GET_STATIC_TYPE_FIELD(_type, _name, _jname)                                               \
+gboolean gst_amc_jni_get_static_##_name##_field (JNIEnv *env, GError ** err, jclass klass, jfieldID fieldID, _type *value)   \
+  {                                                                                                 \
+    gboolean ret = TRUE;                                                                            \
+                                                                                                    \
+    *value = (*env)->GetStatic##_jname##Field(env, klass, fieldID);                                 \
+    if ((*env)->ExceptionCheck (env)) {                                                             \
+      gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED,                      \
+          "Failed to get static Java field");                                                  \
+      ret = FALSE;                                                                                  \
+    }                                                                                               \
+    return ret;                                                                                     \
+  }
+
+GET_STATIC_TYPE_FIELD (gboolean, boolean, Boolean);
+GET_STATIC_TYPE_FIELD (gint8, byte, Byte);
+GET_STATIC_TYPE_FIELD (gshort, short, Short);
+GET_STATIC_TYPE_FIELD (gint, int, Int);
+GET_STATIC_TYPE_FIELD (gchar, char, Char);
+GET_STATIC_TYPE_FIELD (gint64, long, Long);
+GET_STATIC_TYPE_FIELD (gfloat, float, Float);
+GET_STATIC_TYPE_FIELD (gdouble, double, Double);
+GET_STATIC_TYPE_FIELD (jobject, object, Object);
+
+gboolean
+gst_amc_jni_get_buffer_array (JNIEnv * env, GError ** err, jobject array,
+    GstAmcBuffer ** buffers, gsize * n_buffers)
+{
+  jsize i;
+
+  *n_buffers = (*env)->GetArrayLength (env, array);
+  *buffers = g_new0 (GstAmcBuffer, *n_buffers);
+
+  for (i = 0; i < *n_buffers; i++) {
+    jobject buffer = NULL;
+
+    buffer = (*env)->GetObjectArrayElement (env, array, i);
+    if ((*env)->ExceptionCheck (env) || !buffer) {
+      gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+          GST_LIBRARY_ERROR_FAILED, "Failed to get buffer %d", i);
+      goto error;
+    }
+
+    (*buffers)[i].object = gst_amc_jni_object_make_global (env, buffer);
+    if (!(*buffers)[i].object) {
+      gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+          GST_LIBRARY_ERROR_FAILED,
+          "Failed to create global buffer reference %d", i);
+      goto error;
+    }
+
+    (*buffers)[i].data =
+        (*env)->GetDirectBufferAddress (env, (*buffers)[i].object);
+    if (!(*buffers)[i].data) {
+      gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
+          GST_LIBRARY_ERROR_FAILED, "Failed to get buffer address %d", i);
+      goto error;
+    }
+    (*buffers)[i].size =
+        (*env)->GetDirectBufferCapacity (env, (*buffers)[i].object);
+  }
+
+  return TRUE;
+
+error:
+  if (*buffers)
+    gst_amc_jni_free_buffer_array (env, *buffers, *n_buffers);
+  *buffers = NULL;
+  *n_buffers = 0;
+  return FALSE;
+}
+
+void
+gst_amc_jni_free_buffer_array (JNIEnv * env, GstAmcBuffer * buffers,
+    gsize n_buffers)
+{
+  jsize i;
+
+  g_return_if_fail (buffers != NULL);
+
+  for (i = 0; i < n_buffers; i++) {
+    if (buffers[i].object)
+      gst_amc_jni_object_unref (env, buffers[i].object);
+  }
+  g_free (buffers);
+}
diff --git a/sys/androidmedia/gstjniutils.h b/sys/androidmedia/gstjniutils.h
index 0c75c45..0b25daa 100644
--- a/sys/androidmedia/gstjniutils.h
+++ b/sys/androidmedia/gstjniutils.h
@@ -30,30 +30,46 @@
 #include <gst/gst.h>
 
 jclass    gst_amc_jni_get_class              (JNIEnv * env,
+                                             GError ** err,
                                              const gchar * name);
 
-jmethodID gst_amc_jni_get_method             (JNIEnv * env,
+jmethodID gst_amc_jni_get_method_id          (JNIEnv * env,
+                                             GError ** err,
                                              jclass klass,
                                              const gchar * name,
                                              const gchar * signature);
 
-jmethodID gst_amc_jni_get_static_method      (JNIEnv * env,
+jmethodID gst_amc_jni_get_static_method_id   (JNIEnv * env,
+                                             GError ** err,
                                              jclass klass,
                                              const gchar * name,
                                              const gchar * signature);
 
 jfieldID gst_amc_jni_get_field_id            (JNIEnv * env,
+                                             GError ** err,
+                                             jclass klass,
+                                             const gchar * name,
+                                             const gchar * type);
+
+jfieldID gst_amc_jni_get_static_field_id     (JNIEnv * env,
+                                             GError ** err,
                                              jclass klass,
                                              const gchar * name,
                                              const gchar * type);
 
 jobject gst_amc_jni_new_object               (JNIEnv * env,
+                                             GError ** err,
+                                             gboolean global,
                                              jclass klass,
-                                             jmethodID constructor, ...);
+                                             jmethodID constructor,
+                                             ...);
 
 jobject gst_amc_jni_new_object_from_static   (JNIEnv * env,
+                                             GError ** err,
+                                             gboolean global,
                                              jclass klass,
-                                             jmethodID constructor, ...);
+                                             jmethodID constructor,
+                                             ...);
 
 jobject gst_amc_jni_object_make_global       (JNIEnv * env,
                                              jobject object);
@@ -72,13 +88,15 @@
                                              gboolean release);
 
 jstring gst_amc_jni_string_from_gchar        (JNIEnv * env,
+                                             GError ** error,
+                                             gboolean global,
                                              const gchar * string);
 
 G_GNUC_PRINTF (5, 6)
 void gst_amc_jni_set_error                   (JNIEnv * env,
+                                              GError ** error,
                                               GQuark domain,
                                               gint code,
-                                              GError ** error,
                                               const gchar * format, ...);
 
 gboolean gst_amc_jni_initialize              (void);
@@ -88,14 +106,14 @@
 JNIEnv *gst_amc_jni_get_env                  (void);
 
 #define DEF_CALL_STATIC_TYPE_METHOD(_type, _name,  _jname, _retval) \
-_type gst_amc_jni_call_static_##_name##_method (JNIEnv *env, GError ** err, jclass klass, jmethodID methodID, ...)
+gboolean gst_amc_jni_call_static_##_name##_method (JNIEnv *env, GError ** err, jclass klass, jmethodID methodID, _type * value, ...)
 
 DEF_CALL_STATIC_TYPE_METHOD (gboolean, boolean, Boolean, FALSE);
 DEF_CALL_STATIC_TYPE_METHOD (gint8, byte, Byte, G_MININT8);
 DEF_CALL_STATIC_TYPE_METHOD (gshort, short, Short, G_MINSHORT);
 DEF_CALL_STATIC_TYPE_METHOD (gint, int, Int, G_MININT);
 DEF_CALL_STATIC_TYPE_METHOD (gchar, char, Char, 0);
-DEF_CALL_STATIC_TYPE_METHOD (glong, long, Long, G_MINLONG);
+DEF_CALL_STATIC_TYPE_METHOD (gint64, long, Long, G_MINLONG);
 DEF_CALL_STATIC_TYPE_METHOD (gfloat, float, Float, G_MINFLOAT);
 DEF_CALL_STATIC_TYPE_METHOD (gdouble, double, Double, G_MINDOUBLE);
 DEF_CALL_STATIC_TYPE_METHOD (jobject, object, Object, NULL);
@@ -106,14 +124,14 @@
                                                     jmethodID method, ...);
 
 #define DEF_CALL_TYPE_METHOD(_type, _name,  _jname, _retval) \
-_type gst_amc_jni_call_##_name##_method (JNIEnv *env, GError ** err, jobject obj, jmethodID methodID, ...)
+gboolean gst_amc_jni_call_##_name##_method (JNIEnv *env, GError ** err, jobject obj, jmethodID methodID, _type * value, ...)
 
 DEF_CALL_TYPE_METHOD (gboolean, boolean, Boolean, FALSE);
 DEF_CALL_TYPE_METHOD (gint8, byte, Byte, G_MININT8);
 DEF_CALL_TYPE_METHOD (gshort, short, Short, G_MINSHORT);
 DEF_CALL_TYPE_METHOD (gint, int, Int, G_MININT);
 DEF_CALL_TYPE_METHOD (gchar, char, Char, 0);
-DEF_CALL_TYPE_METHOD (glong, long, Long, G_MINLONG);
+DEF_CALL_TYPE_METHOD (gint64, long, Long, G_MINLONG);
 DEF_CALL_TYPE_METHOD (gfloat, float, Float, G_MINFLOAT);
 DEF_CALL_TYPE_METHOD (gdouble, double, Double, G_MINDOUBLE);
 DEF_CALL_TYPE_METHOD (jobject, object, Object, NULL);
@@ -123,10 +141,41 @@
                                              jobject obj,
                                              jmethodID method, ...);
 
-#define DEF_GET_TYPE_FIELD(_type, _name, _jname, _retval) \
-_type gst_amc_jni_get_##_name##_field (JNIEnv *env, GError ** err, jobject obj, jfieldID fieldID)
+#define DEF_GET_TYPE_FIELD(_type, _name, _jname) \
+gboolean gst_amc_jni_get_##_name##_field (JNIEnv *env, GError ** err, jobject obj, jfieldID fieldID, _type * value)
 
-DEF_GET_TYPE_FIELD (gint, int, Int, G_MININT);
-DEF_GET_TYPE_FIELD (glong, long, Long, G_MINLONG);
+DEF_GET_TYPE_FIELD (gboolean, boolean, Boolean);
+DEF_GET_TYPE_FIELD (gint8, byte, Byte);
+DEF_GET_TYPE_FIELD (gshort, short, Short);
+DEF_GET_TYPE_FIELD (gint, int, Int);
+DEF_GET_TYPE_FIELD (gchar, char, Char);
+DEF_GET_TYPE_FIELD (gint64, long, Long);
+DEF_GET_TYPE_FIELD (gfloat, float, Float);
+DEF_GET_TYPE_FIELD (gdouble, double, Double);
+DEF_GET_TYPE_FIELD (jobject, object, Object);
+
+#define DEF_GET_STATIC_TYPE_FIELD(_type, _name, _jname) \
+gboolean gst_amc_jni_get_static_##_name##_field (JNIEnv *env, GError ** err, jclass klass, jfieldID fieldID, _type * value)
+
+DEF_GET_STATIC_TYPE_FIELD (gboolean, boolean, Boolean);
+DEF_GET_STATIC_TYPE_FIELD (gint8, byte, Byte);
+DEF_GET_STATIC_TYPE_FIELD (gshort, short, Short);
+DEF_GET_STATIC_TYPE_FIELD (gint, int, Int);
+DEF_GET_STATIC_TYPE_FIELD (gchar, char, Char);
+DEF_GET_STATIC_TYPE_FIELD (gint64, long, Long);
+DEF_GET_STATIC_TYPE_FIELD (gfloat, float, Float);
+DEF_GET_STATIC_TYPE_FIELD (gdouble, double, Double);
+DEF_GET_STATIC_TYPE_FIELD (jobject, object, Object);
+
+typedef struct _GstAmcBuffer GstAmcBuffer;
+
+struct _GstAmcBuffer {
+  jobject object; /* global reference */
+  guint8 *data;
+  gsize size;
+};
+
+gboolean gst_amc_jni_get_buffer_array (JNIEnv * env, GError ** err, jobject array, GstAmcBuffer ** buffers, gsize * n_buffers);
+void gst_amc_jni_free_buffer_array (JNIEnv * env, GstAmcBuffer * buffers, gsize n_buffers);
 
 #endif
diff --git a/sys/applemedia/avfvideosrc.m b/sys/applemedia/avfvideosrc.m
index f04a977..00f5c65 100644
--- a/sys/applemedia/avfvideosrc.m
+++ b/sys/applemedia/avfvideosrc.m
@@ -83,6 +83,7 @@
   AVCaptureInput *input;
   AVCaptureVideoDataOutput *output;
   AVCaptureDevice *device;
+  AVCaptureConnection *connection;
   CMClockRef inputClock;
 
   dispatch_queue_t mainQueue;
@@ -92,12 +93,11 @@
   BOOL stopRequest;
 
   GstCaps *caps;
+  GstVideoFormat internalFormat;
   GstVideoFormat format;
   gint width, height;
   GstClockTime latency;
   guint64 offset;
-  GstClockTime startAVFTimestamp;
-  GstClockTime startTimestamp;
 
   GstClockTime lastSampling;
   guint count;
@@ -298,6 +298,10 @@
     [session addInput:input];
     [session addOutput:output];
 
+    /* retained by session */
+    connection = [[output connections] firstObject];
+    inputClock = ((AVCaptureInputPort *)connection.inputPorts[0]).clock;
+
     *successPtr = YES;
   });
 
@@ -313,6 +317,9 @@
   dispatch_sync (mainQueue, ^{
     g_assert (![session isRunning]);
 
+    connection = nil;
+    inputClock = nil;
+
     [session removeInput:input];
     [session removeOutput:output];
 
@@ -458,7 +465,7 @@
           gdouble max_frame_rate;
 
           [[rate valueForKey:@"maxFrameRate"] getValue:&max_frame_rate];
-          if (abs (framerate - max_frame_rate) < 0.00001) {
+          if (fabs (framerate - max_frame_rate) < 0.00001) {
             NSValue *min_frame_duration, *max_frame_duration;
 
             found_framerate = TRUE;
@@ -619,6 +626,7 @@
   width = info.width;
   height = info.height;
   format = info.finfo->format;
+  internalFormat = GST_VIDEO_FORMAT_UNKNOWN;
   latency = gst_util_uint64_scale (GST_SECOND, info.fps_d, info.fps_n);
 
   dispatch_sync (mainQueue, ^{
@@ -658,22 +666,28 @@
       }
     }
 
+    internalFormat = format;
     switch (format) {
       case GST_VIDEO_FORMAT_NV12:
         newformat = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
         break;
       case GST_VIDEO_FORMAT_UYVY:
-         newformat = kCVPixelFormatType_422YpCbCr8;
+        newformat = kCVPixelFormatType_422YpCbCr8;
         break;
       case GST_VIDEO_FORMAT_YUY2:
-         newformat = kCVPixelFormatType_422YpCbCr8_yuvs;
+        newformat = kCVPixelFormatType_422YpCbCr8_yuvs;
         break;
       case GST_VIDEO_FORMAT_RGBA:
-        /* In order to do RGBA, we negotiate BGRA (since RGBA is not supported
-         * if not in textures) and then we get RGBA textures via
-         * CVOpenGL*TextureCacheCreateTextureFromImage. Computers. */
+#if !HAVE_IOS
+        newformat = kCVPixelFormatType_422YpCbCr8;
+        internalFormat = GST_VIDEO_FORMAT_UYVY;
+#else
+        newformat = kCVPixelFormatType_32BGRA;
+        internalFormat = GST_VIDEO_FORMAT_BGRA;
+#endif
+        break;
       case GST_VIDEO_FORMAT_BGRA:
-         newformat = kCVPixelFormatType_32BGRA;
+        newformat = kCVPixelFormatType_32BGRA;
         break;
       default:
         *successPtr = NO;
@@ -682,10 +696,10 @@
         return;
     }
 
-    GST_DEBUG_OBJECT(element,
-       "Width: %d Height: %d Format: %" GST_FOURCC_FORMAT,
-       width, height,
-       GST_FOURCC_ARGS (gst_video_format_to_fourcc (format)));
+    GST_INFO_OBJECT(element,
+        "width: %d height: %d format: %s internalFormat: %s", width, height,
+        gst_video_format_to_string (format),
+        gst_video_format_to_string (internalFormat));
 
     output.videoSettings = [NSDictionary
         dictionaryWithObject:[NSNumber numberWithInt:newformat]
@@ -712,9 +726,6 @@
 
   offset = 0;
   latency = GST_CLOCK_TIME_NONE;
-  startAVFTimestamp = GST_CLOCK_TIME_NONE;
-  startTimestamp = GST_CLOCK_TIME_NONE;
-  inputClock = nil;
 
   lastSampling = GST_CLOCK_TIME_NONE;
   count = 0;
@@ -732,7 +743,6 @@
   bufQueueLock = nil;
   [bufQueue release];
   bufQueue = nil;
-  inputClock = nil;
 
   if (textureCache)
       gst_core_video_texture_cache_free (textureCache);
@@ -769,28 +779,34 @@
   useVideoMeta = gst_query_find_allocation_meta (query,
       GST_VIDEO_META_API_TYPE, NULL);
 
-  guint idx;
-  if (gst_query_find_allocation_meta (query,
-        GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx)) {
-    GstGLContext *context;
-    const GstStructure *upload_meta_params;
+  /* determine whether we can pass GL textures to downstream element */
+  GstCapsFeatures *features = gst_caps_get_features (caps, 0);
+  if (gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) {
+    GstGLContext *glContext = NULL;
 
-    gst_query_parse_nth_allocation_meta (query, idx, &upload_meta_params);
-    if (gst_structure_get (upload_meta_params, "gst.gl.GstGLContext",
-          GST_GL_TYPE_CONTEXT, &context, NULL) && context) {
-      GstCaps *query_caps;
-      GstCapsFeatures *features;
-
-      gst_query_parse_allocation (query, &query_caps, NULL);
-      features = gst_caps_get_features (query_caps, 0);
-      if (gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) {
-        textureCache = gst_core_video_texture_cache_new (context);
-        gst_core_video_texture_cache_set_format (textureCache,
-            "NV12", query_caps);
+    /* get GL context from downstream element */
+    GstQuery *query = gst_query_new_context ("gst.gl.local_context");
+    if (gst_pad_peer_query (GST_BASE_SRC_PAD (element), query)) {
+      GstContext *context;
+      gst_query_parse_context (query, &context);
+      if (context) {
+        const GstStructure *s = gst_context_get_structure (context);
+        gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &glContext,
+            NULL);
       }
-      gst_object_unref (context);
     }
-  }
+    gst_query_unref (query);
+
+    if (glContext) {
+      GST_INFO_OBJECT (element, "pushing textures. Internal format %s, context %p",
+          gst_video_format_to_string (internalFormat), glContext);
+      textureCache = gst_core_video_texture_cache_new (glContext);
+      gst_core_video_texture_cache_set_format (textureCache, internalFormat, caps);
+      gst_object_unref (glContext);
+    } else {
+      GST_WARNING_OBJECT (element, "got memory:GLMemory caps but not GL context from downstream element");
+    }
+  } 
 
   return YES;
 }
@@ -808,7 +824,7 @@
 {
   [bufQueueLock lock];
   stopRequest = NO;
-  [bufQueueLock unlock];
+  [bufQueueLock unlockWithCondition:([bufQueue count] == 0) ? NO_BUFFERS : HAS_BUFFER_OR_STOP_REQUEST];
 
   return YES;
 }
@@ -832,7 +848,7 @@
 
 - (void)captureOutput:(AVCaptureOutput *)captureOutput
 didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
-       fromConnection:(AVCaptureConnection *)connection
+       fromConnection:(AVCaptureConnection *)aConnection
 {
   GstClockTime timestamp, duration;
 
@@ -843,10 +859,13 @@
     return;
   }
 
-  if (inputClock == nil)
-    inputClock = ((AVCaptureInputPort *)connection.inputPorts[0]).clock;
   [self getSampleBuffer:sampleBuffer timestamp:&timestamp duration:&duration];
 
+  if (timestamp == GST_CLOCK_TIME_NONE) {
+    [bufQueueLock unlockWithCondition:([bufQueue count] == 0) ? NO_BUFFERS : HAS_BUFFER_OR_STOP_REQUEST];
+    return;
+  }
+
   if ([bufQueue count] == BUFFER_QUEUE_SIZE)
     [bufQueue removeLastObject];
 
@@ -903,6 +922,11 @@
   }
 
   *buf = gst_core_media_buffer_new (sbuf, useVideoMeta, textureCache == NULL);
+  if (*buf == NULL) {
+    CFRelease (sbuf);
+    return GST_FLOW_ERROR;
+  }
+
   if (format == GST_VIDEO_FORMAT_RGBA) {
     /* So now buf contains BGRA data (!) . Since downstream is actually going to
      * use the GL upload meta to get RGBA textures (??), we need to override the
@@ -914,11 +938,14 @@
   }
   CFRelease (sbuf);
 
-  if (textureCache != NULL)
+  if (textureCache != NULL) {
     *buf = gst_core_video_texture_cache_get_gl_buffer (textureCache, *buf);
+    if (*buf == NULL)
+      return GST_FLOW_ERROR;
+  }
 
   GST_BUFFER_OFFSET (*buf) = offset++;
-  GST_BUFFER_OFFSET_END (*buf) = GST_BUFFER_OFFSET (buf) + 1;
+  GST_BUFFER_OFFSET_END (*buf) = GST_BUFFER_OFFSET (*buf) + 1;
   GST_BUFFER_TIMESTAMP (*buf) = timestamp;
   GST_BUFFER_DURATION (*buf) = duration;
 
@@ -933,7 +960,7 @@
                duration:(GstClockTime *)outDuration
 {
   CMSampleTimingInfo time_info;
-  GstClockTime timestamp, duration, inputClockNow, running_time;
+  GstClockTime timestamp, avf_timestamp, duration, input_clock_now, input_clock_diff, running_time;
   CMItemCount num_timings;
   GstClock *clock;
   CMTime now;
@@ -941,7 +968,7 @@
   timestamp = GST_CLOCK_TIME_NONE;
   duration = GST_CLOCK_TIME_NONE;
   if (CMSampleBufferGetOutputSampleTimingInfoArray(sbuf, 1, &time_info, &num_timings) == noErr) {
-    timestamp = gst_util_uint64_scale (GST_SECOND,
+    avf_timestamp = gst_util_uint64_scale (GST_SECOND,
             time_info.presentationTimeStamp.value, time_info.presentationTimeStamp.timescale);
 
     if (CMTIME_IS_VALID (time_info.duration) && time_info.duration.timescale != 0)
@@ -949,13 +976,34 @@
           time_info.duration.value, time_info.duration.timescale);
 
     now = CMClockGetTime(inputClock);
-    inputClockNow = gst_util_uint64_scale (GST_SECOND,
+    input_clock_now = gst_util_uint64_scale (GST_SECOND,
         now.value, now.timescale);
+    input_clock_diff = input_clock_now - avf_timestamp;
 
     GST_OBJECT_LOCK (element);
     clock = GST_ELEMENT_CLOCK (element);
-    running_time = gst_clock_get_time (clock) - element->base_time;
-    timestamp = running_time + (inputClockNow - timestamp);
+    if (clock) {
+      running_time = gst_clock_get_time (clock) - element->base_time;
+      /* We use presentationTimeStamp to determine how much time it took
+       * between capturing and receiving the frame in our delegate
+       * (e.g. how long it spent in AVF queues), then we subtract that time
+       * from our running time to get the actual timestamp.
+       */
+      if (running_time >= input_clock_diff)
+        timestamp = running_time - input_clock_diff;
+      else
+        timestamp = running_time;
+
+      GST_DEBUG_OBJECT (element, "AVF clock: %"GST_TIME_FORMAT ", AVF PTS: %"GST_TIME_FORMAT
+          ", AVF clock diff: %"GST_TIME_FORMAT
+          ", running time: %"GST_TIME_FORMAT ", out PTS: %"GST_TIME_FORMAT,
+          GST_TIME_ARGS (input_clock_now), GST_TIME_ARGS (avf_timestamp),
+          GST_TIME_ARGS (input_clock_diff),
+          GST_TIME_ARGS (running_time), GST_TIME_ARGS (timestamp));
+    } else {
+      /* no clock, can't set timestamps */
+      timestamp = GST_CLOCK_TIME_NONE;
+    }
     GST_OBJECT_UNLOCK (element);
   }
 
diff --git a/sys/applemedia/corevideotexturecache.m b/sys/applemedia/corevideotexturecache.m
index 0bd4afa..a35dcf6 100644
--- a/sys/applemedia/corevideotexturecache.m
+++ b/sys/applemedia/corevideotexturecache.m
@@ -75,7 +75,7 @@
 #if !HAVE_IOS
   CVOpenGLTextureCacheRelease (cache->cache);
 #else
-  /* FIXME: how do we release ->cache ? */
+  CFRelease (cache->cache); /* iOS has no "CVOpenGLESTextureCacheRelease" */
 #endif
   gst_object_unref (cache->convert);
   gst_object_unref (cache->ctx);
@@ -84,7 +84,7 @@
 
 void
 gst_core_video_texture_cache_set_format (GstCoreVideoTextureCache * cache,
-    const gchar * input_format, GstCaps * out_caps)
+    GstVideoFormat in_format, GstCaps * out_caps)
 {
   GstCaps *in_caps;
   GstCapsFeatures *features;
@@ -97,7 +97,8 @@
   gst_video_info_from_caps (&cache->output_info, out_caps); 
   
   in_caps = gst_caps_copy (out_caps);
-  gst_caps_set_simple (in_caps, "format", G_TYPE_STRING, input_format, NULL);
+  gst_caps_set_simple (in_caps, "format",
+          G_TYPE_STRING, gst_video_format_to_string (in_format), NULL);
   features = gst_caps_get_features (in_caps, 0);
   gst_caps_features_add (features, GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
   gst_video_info_from_caps (&cache->input_info, in_caps);
@@ -127,6 +128,7 @@
 gl_mem_from_buffer (GstCoreVideoTextureCache * cache,
         GstBuffer * buffer, GstMemory **mem1, GstMemory **mem2)
 {
+  gboolean ret = TRUE;
 #if !HAVE_IOS
   CVOpenGLTextureRef texture = NULL;
 #else
@@ -139,49 +141,78 @@
 
 #if !HAVE_IOS
   CVOpenGLTextureCacheFlush (cache->cache, 0);
-
-  if (CVOpenGLTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
-      cache->cache, pixel_buf, NULL, &texture) != kCVReturnSuccess)
-    goto error;
-
-  *mem1 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
-      CVOpenGLTextureGetName (texture), CVOpenGLTextureGetTarget (texture),
-      &cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
 #else
   CVOpenGLESTextureCacheFlush (cache->cache, 0);
-
-  if (CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
-      cache->cache, pixel_buf, NULL, GL_TEXTURE_2D, GL_LUMINANCE,
-      GST_VIDEO_INFO_WIDTH (&cache->input_info),
-      GST_VIDEO_INFO_HEIGHT (&cache->input_info),
-      GL_LUMINANCE, GL_UNSIGNED_BYTE, 0, &texture) != kCVReturnSuccess)
-    goto error;
-
-  *mem1 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
-      CVOpenGLESTextureGetName (texture), CVOpenGLESTextureGetTarget (texture),
-      &cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
-
-  if (CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
-      cache->cache, pixel_buf, NULL, GL_TEXTURE_2D, GL_LUMINANCE_ALPHA,
-      GST_VIDEO_INFO_WIDTH (&cache->input_info) / 2,
-      GST_VIDEO_INFO_HEIGHT (&cache->input_info) / 2,
-      GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 1, &texture) != kCVReturnSuccess)
-    goto error;
-
-  *mem2 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
-      CVOpenGLESTextureGetName (texture), CVOpenGLESTextureGetTarget (texture),
-      &cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
 #endif
 
-  return TRUE;
+  switch (GST_VIDEO_INFO_FORMAT (&cache->input_info)) {
+#if !HAVE_IOS
+      case GST_VIDEO_FORMAT_UYVY:
+        /* both avfvideosrc and vtdec on OSX when doing GLMemory negotiate UYVY
+         * under the hood, which means a single output texture. */
+        if (CVOpenGLTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
+              cache->cache, pixel_buf, NULL, &texture) != kCVReturnSuccess)
+          goto error;
+
+        *mem1 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
+            CVOpenGLTextureGetName (texture), CVOpenGLTextureGetTarget (texture),
+            &cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
+        break;
+#else
+      case GST_VIDEO_FORMAT_BGRA:
+        /* avfvideosrc does BGRA on iOS when doing GLMemory */
+        if (CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
+              cache->cache, pixel_buf, NULL, GL_TEXTURE_2D, GL_RGBA,
+              GST_VIDEO_INFO_WIDTH (&cache->input_info),
+              GST_VIDEO_INFO_HEIGHT (&cache->input_info),
+              GL_RGBA, GL_UNSIGNED_BYTE, 0, &texture) != kCVReturnSuccess)
+          goto error;
+
+        *mem1 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
+            CVOpenGLESTextureGetName (texture), CVOpenGLESTextureGetTarget (texture),
+            &cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
+        break;
+      case GST_VIDEO_FORMAT_NV12:
+        /* vtdec does NV12 on iOS when doing GLMemory */
+        if (CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
+              cache->cache, pixel_buf, NULL, GL_TEXTURE_2D, GL_LUMINANCE,
+              GST_VIDEO_INFO_WIDTH (&cache->input_info),
+              GST_VIDEO_INFO_HEIGHT (&cache->input_info),
+              GL_LUMINANCE, GL_UNSIGNED_BYTE, 0, &texture) != kCVReturnSuccess)
+          goto error;
+
+        *mem1 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
+            CVOpenGLESTextureGetName (texture), CVOpenGLESTextureGetTarget (texture),
+            &cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
+
+        if (CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault,
+              cache->cache, pixel_buf, NULL, GL_TEXTURE_2D, GL_LUMINANCE_ALPHA,
+              GST_VIDEO_INFO_WIDTH (&cache->input_info) / 2,
+              GST_VIDEO_INFO_HEIGHT (&cache->input_info) / 2,
+              GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 1, &texture) != kCVReturnSuccess)
+          goto error;
+
+        *mem2 = (GstMemory *) gst_gl_memory_wrapped_texture (cache->ctx,
+            CVOpenGLESTextureGetName (texture), CVOpenGLESTextureGetTarget (texture),
+            &cache->input_info, 0, NULL, texture, (GDestroyNotify) CFRelease);
+        break;
+#endif
+      default:
+        g_warn_if_reached ();
+        ret = FALSE;
+    }
+
+  return ret;
 
 error:
+  ret = FALSE;
+
   if (*mem1)
       gst_memory_unref (*mem1);
   if (*mem2)
       gst_memory_unref (*mem2);
 
-  return FALSE;
+  return ret;
 }
 
 static void
diff --git a/sys/applemedia/plugin.m b/sys/applemedia/plugin.m
index 7bd2445..c17c38b 100644
--- a/sys/applemedia/plugin.m
+++ b/sys/applemedia/plugin.m
@@ -86,7 +86,7 @@
 
 #ifdef HAVE_VIDEOTOOLBOX
   /* Check if the framework actually exists at runtime */
-  if (VTCompressionSessionCreate != NULL) {
+  if (&VTCompressionSessionCreate != NULL) {
     gst_vtdec_register_elements (plugin);
     gst_vtenc_register_elements (plugin);
   }
diff --git a/sys/applemedia/vtdec.c b/sys/applemedia/vtdec.c
index 1f550e1..8c22e24 100644
--- a/sys/applemedia/vtdec.c
+++ b/sys/applemedia/vtdec.c
@@ -198,37 +198,48 @@
 gst_vtdec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
 {
   gboolean ret;
+  GstCaps *caps;
+  GstCapsFeatures *features;
   GstVtdec *vtdec = GST_VTDEC (decoder);
 
   ret =
       GST_VIDEO_DECODER_CLASS (gst_vtdec_parent_class)->decide_allocation
       (decoder, query);
-  if (ret) {
-    GstCaps *caps;
-    GstCapsFeatures *features;
-    guint idx;
+  if (!ret)
+    goto out;
 
-    gst_query_parse_allocation (query, &caps, NULL);
-    if (caps) {
-      features = gst_caps_get_features (caps, 0);
+  gst_query_parse_allocation (query, &caps, NULL);
+  if (caps) {
+    GstGLContext *gl_context = NULL;
+    features = gst_caps_get_features (caps, 0);
 
-      if (gst_caps_features_contains (features,
-              GST_CAPS_FEATURE_MEMORY_GL_MEMORY)
-          && gst_query_find_allocation_meta (query,
-              GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx)) {
-        GstGLContext *context;
-        const GstStructure *upload_meta_params;
+    if (gst_caps_features_contains (features,
+            GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) {
+      GstContext *context = NULL;
+      GstQuery *query = gst_query_new_context ("gst.gl.local_context");
+      if (gst_pad_peer_query (GST_VIDEO_DECODER_SRC_PAD (decoder), query)) {
 
-        gst_query_parse_nth_allocation_meta (query, idx, &upload_meta_params);
-        if (gst_structure_get (upload_meta_params, "gst.gl.GstGLContext",
-                GST_GL_TYPE_CONTEXT, &context, NULL) && context) {
-          vtdec->texture_cache = gst_core_video_texture_cache_new (context);
-          gst_object_unref (context);
+        gst_query_parse_context (query, &context);
+        if (context) {
+          const GstStructure *s = gst_context_get_structure (context);
+          gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &gl_context,
+              NULL);
         }
       }
+      gst_query_unref (query);
+
+      if (context) {
+        GST_INFO_OBJECT (decoder, "pushing textures. GL context %p", context);
+        vtdec->texture_cache = gst_core_video_texture_cache_new (gl_context);
+        gst_object_unref (gl_context);
+      } else {
+        GST_WARNING_OBJECT (decoder,
+            "got memory:GLMemory caps but not GL context from downstream element");
+      }
     }
   }
 
+out:
   return ret;
 }
 
@@ -302,7 +313,6 @@
   vtdec->format_description = format_description;
 
   output_format = gst_vtdec_negotiate_output_format (vtdec);
-
   if (!gst_vtdec_create_session (vtdec, output_format))
     return FALSE;
 
@@ -694,15 +704,25 @@
   GstFlowReturn ret = GST_FLOW_OK;
   GstVideoDecoder *decoder = GST_VIDEO_DECODER (vtdec);
 
+  /* FIXME: Instead of this, implement GstVideoDecoder::negotiate() and
+   * just call gst_video_decoder_negotiate()
+   */
   /* negotiate now so that we know whether we need to use the GL upload meta or
    * not */
   if (gst_pad_check_reconfigure (decoder->srcpad)) {
     gst_video_decoder_negotiate (decoder);
     if (vtdec->texture_cache) {
+      GstVideoFormat internal_format;
       GstVideoCodecState *output_state =
           gst_video_decoder_get_output_state (decoder);
+
+#ifdef HAVE_IOS
+      internal_format = GST_VIDEO_FORMAT_NV12;
+#else
+      internal_format = GST_VIDEO_FORMAT_UYVY;
+#endif
       gst_core_video_texture_cache_set_format (vtdec->texture_cache,
-          GST_VTDEC_VIDEO_FORMAT_STR, output_state->caps);
+          internal_format, output_state->caps);
       gst_video_codec_state_unref (output_state);
     }
   }
diff --git a/sys/decklink/gstdecklink.cpp b/sys/decklink/gstdecklink.cpp
index 7335ab3..f3ddeb9 100644
--- a/sys/decklink/gstdecklink.cpp
+++ b/sys/decklink/gstdecklink.cpp
@@ -64,18 +64,18 @@
     {GST_DECKLINK_MODE_720p5994, "720p5994", "HD720 59.94p"},
     {GST_DECKLINK_MODE_720p60, "720p60", "HD720 60p"},
 
-    {GST_DECKLINK_MODE_2048p2398, "2048p2398", "2k 23.98p"},
-    {GST_DECKLINK_MODE_2048p24, "2048p24", "2k 24p"},
-    {GST_DECKLINK_MODE_2048p25, "2048p25", "2k 25p"},
+    {GST_DECKLINK_MODE_1556p2398, "1556p2398", "2k 23.98p"},
+    {GST_DECKLINK_MODE_1556p24, "1556p24", "2k 24p"},
+    {GST_DECKLINK_MODE_1556p25, "1556p25", "2k 25p"},
 
-    {GST_DECKLINK_MODE_3184p2398, "3184p2398", "4k 23.98p"},
-    {GST_DECKLINK_MODE_3184p24, "3184p24", "4k 24p"},
-    {GST_DECKLINK_MODE_3184p25, "3184p25", "4k 25p"},
-    {GST_DECKLINK_MODE_3184p2997, "3184p2997", "4k 29.97p"},
-    {GST_DECKLINK_MODE_3184p30, "3184p30", "4k 30p"},
-    {GST_DECKLINK_MODE_3184p50, "3184p50", "4k 50p"},
-    {GST_DECKLINK_MODE_3184p5994, "3184p5994", "4k 59.94p"},
-    {GST_DECKLINK_MODE_3184p60, "3184p60", "4k 60p"},
+    {GST_DECKLINK_MODE_2160p2398, "2160p2398", "4k 23.98p"},
+    {GST_DECKLINK_MODE_2160p24, "2160p24", "4k 24p"},
+    {GST_DECKLINK_MODE_2160p25, "2160p25", "4k 25p"},
+    {GST_DECKLINK_MODE_2160p2997, "2160p2997", "4k 29.97p"},
+    {GST_DECKLINK_MODE_2160p30, "2160p30", "4k 30p"},
+    {GST_DECKLINK_MODE_2160p50, "2160p50", "4k 50p"},
+    {GST_DECKLINK_MODE_2160p5994, "2160p5994", "4k 59.94p"},
+    {GST_DECKLINK_MODE_2160p60, "2160p60", "4k 60p"},
 
     {0, NULL, NULL}
   };
@@ -178,7 +178,7 @@
   {bmdMode4K2160p25, 3840, 2160, 25, 1, false, UHD},
   {bmdMode4K2160p2997, 3840, 2160, 30000, 1001, false, UHD},
   {bmdMode4K2160p30, 3840, 2160, 30, 1, false, UHD},
-  {bmdMode4K2160p50, 3840, 2160, 55, 1, false, UHD},
+  {bmdMode4K2160p50, 3840, 2160, 50, 1, false, UHD},
   {bmdMode4K2160p5994, 3840, 2160, 60000, 1001, false, UHD},
   {bmdMode4K2160p60, 3840, 2160, 60, 1, false, UHD}
 };
@@ -186,7 +186,7 @@
 const GstDecklinkMode *
 gst_decklink_get_mode (GstDecklinkModeEnum e)
 {
-  if (e < GST_DECKLINK_MODE_AUTO || e > GST_DECKLINK_MODE_3184p60)
+  if (e < GST_DECKLINK_MODE_AUTO || e > GST_DECKLINK_MODE_2160p60)
     return NULL;
   return &modes[e];
 }
@@ -254,37 +254,37 @@
       displayMode = GST_DECKLINK_MODE_720p60;
       break;
     case bmdMode2k2398:
-      displayMode = GST_DECKLINK_MODE_2048p2398;
+      displayMode = GST_DECKLINK_MODE_1556p2398;
       break;
     case bmdMode2k24:
-      displayMode = GST_DECKLINK_MODE_2048p24;
+      displayMode = GST_DECKLINK_MODE_1556p24;
       break;
     case bmdMode2k25:
-      displayMode = GST_DECKLINK_MODE_2048p25;
+      displayMode = GST_DECKLINK_MODE_1556p25;
       break;
     case bmdMode4K2160p2398:
-      displayMode = GST_DECKLINK_MODE_3184p2398;
+      displayMode = GST_DECKLINK_MODE_2160p2398;
       break;
     case bmdMode4K2160p24:
-      displayMode = GST_DECKLINK_MODE_3184p24;
+      displayMode = GST_DECKLINK_MODE_2160p24;
       break;
     case bmdMode4K2160p25:
-      displayMode = GST_DECKLINK_MODE_3184p25;
+      displayMode = GST_DECKLINK_MODE_2160p25;
       break;
     case bmdMode4K2160p2997:
-      displayMode = GST_DECKLINK_MODE_3184p2997;
+      displayMode = GST_DECKLINK_MODE_2160p2997;
       break;
     case bmdMode4K2160p30:
-      displayMode = GST_DECKLINK_MODE_3184p30;
+      displayMode = GST_DECKLINK_MODE_2160p30;
       break;
     case bmdMode4K2160p50:
-      displayMode = GST_DECKLINK_MODE_3184p50;
+      displayMode = GST_DECKLINK_MODE_2160p50;
       break;
     case bmdMode4K2160p5994:
-      displayMode = GST_DECKLINK_MODE_3184p5994;
+      displayMode = GST_DECKLINK_MODE_2160p5994;
       break;
     case bmdMode4K2160p60:
-      displayMode = GST_DECKLINK_MODE_3184p60;
+      displayMode = GST_DECKLINK_MODE_2160p60;
       break;
     default:
       g_assert_not_reached ();
@@ -350,7 +350,7 @@
   GstStructure *s;
 
   caps = gst_caps_new_empty ();
-  for (i = 0; i < (int) G_N_ELEMENTS (modes); i++) {
+  for (i = 1; i < (int) G_N_ELEMENTS (modes); i++) {
     s = gst_decklink_mode_get_structure ((GstDecklinkModeEnum) i);
     gst_caps_append_structure (caps, s);
   }
diff --git a/sys/decklink/gstdecklink.h b/sys/decklink/gstdecklink.h
index 51071e7..b601e7c 100644
--- a/sys/decklink/gstdecklink.h
+++ b/sys/decklink/gstdecklink.h
@@ -70,18 +70,18 @@
   GST_DECKLINK_MODE_720p5994,
   GST_DECKLINK_MODE_720p60,
 
-  GST_DECKLINK_MODE_2048p2398,
-  GST_DECKLINK_MODE_2048p24,
-  GST_DECKLINK_MODE_2048p25,
+  GST_DECKLINK_MODE_1556p2398,
+  GST_DECKLINK_MODE_1556p24,
+  GST_DECKLINK_MODE_1556p25,
 
-  GST_DECKLINK_MODE_3184p2398,
-  GST_DECKLINK_MODE_3184p24,
-  GST_DECKLINK_MODE_3184p25,
-  GST_DECKLINK_MODE_3184p2997,
-  GST_DECKLINK_MODE_3184p30,
-  GST_DECKLINK_MODE_3184p50,
-  GST_DECKLINK_MODE_3184p5994,
-  GST_DECKLINK_MODE_3184p60
+  GST_DECKLINK_MODE_2160p2398,
+  GST_DECKLINK_MODE_2160p24,
+  GST_DECKLINK_MODE_2160p25,
+  GST_DECKLINK_MODE_2160p2997,
+  GST_DECKLINK_MODE_2160p30,
+  GST_DECKLINK_MODE_2160p50,
+  GST_DECKLINK_MODE_2160p5994,
+  GST_DECKLINK_MODE_2160p60
 } GstDecklinkModeEnum;
 #define GST_TYPE_DECKLINK_MODE (gst_decklink_mode_get_type ())
 GType gst_decklink_mode_get_type (void);
diff --git a/sys/decklink/gstdecklinkvideosrc.cpp b/sys/decklink/gstdecklinkvideosrc.cpp
index 0432e8c..4e8bcee 100644
--- a/sys/decklink/gstdecklinkvideosrc.cpp
+++ b/sys/decklink/gstdecklinkvideosrc.cpp
@@ -265,9 +265,13 @@
     GST_DEBUG_OBJECT (self, "Pad already has caps %" GST_PTR_FORMAT, caps);
 
     if (!gst_caps_is_equal (caps, current_caps)) {
-      GST_ERROR_OBJECT (self, "New caps are not equal to old caps");
+      GST_DEBUG_OBJECT (self, "New caps, reconfiguring");
       gst_caps_unref (current_caps);
-      return FALSE;
+      if (self->mode == GST_DECKLINK_MODE_AUTO) {
+        return TRUE;
+      } else {
+        return FALSE;
+      }
     } else {
       gst_caps_unref (current_caps);
       return TRUE;
@@ -514,9 +518,6 @@
         f->mode);
     self->caps_mode = f->mode;
     g_mutex_unlock (&self->lock);
-    g_mutex_lock (&self->input->lock);
-    self->input->mode = gst_decklink_get_mode (f->mode);
-    g_mutex_unlock (&self->input->lock);
     caps = gst_decklink_mode_get_caps (f->mode);
     gst_video_info_from_caps (&self->info, caps);
     gst_base_src_set_caps (GST_BASE_SRC_CAST (bsrc), caps);
diff --git a/sys/directsound/Makefile.am b/sys/directsound/Makefile.am
index 18b0980..cfc769f 100644
--- a/sys/directsound/Makefile.am
+++ b/sys/directsound/Makefile.am
@@ -5,7 +5,7 @@
 	$(GST_PLUGINS_BASE_CFLAGS) $(DIRECTX_CFLAGS)
 libgstdirectsoundsrc_la_LIBADD = \
 	$(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_API_VERSION) \
-	$(DIRECTX_LDFLAGS) -ldsound
+	$(DIRECTX_LDFLAGS) $(DIRECTSOUND_LIBS)
 libgstdirectsoundsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstdirectsoundsrc_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
diff --git a/sys/directsound/Makefile.in b/sys/directsound/Makefile.in
index e2bb5d4..93aa3ca 100644
--- a/sys/directsound/Makefile.in
+++ b/sys/directsound/Makefile.in
@@ -155,7 +155,8 @@
 LTLIBRARIES = $(plugin_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 libgstdirectsoundsrc_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
 am_libgstdirectsoundsrc_la_OBJECTS =  \
 	libgstdirectsoundsrc_la-gstdirectsoundsrc.lo \
 	libgstdirectsoundsrc_la-gstdirectsoundplugin.lo
@@ -744,7 +745,7 @@
 
 libgstdirectsoundsrc_la_LIBADD = \
 	$(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_API_VERSION) \
-	$(DIRECTX_LDFLAGS) -ldsound
+	$(DIRECTX_LDFLAGS) $(DIRECTSOUND_LIBS)
 
 libgstdirectsoundsrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstdirectsoundsrc_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
diff --git a/sys/directsound/gstdirectsoundsrc.c b/sys/directsound/gstdirectsoundsrc.c
index 420a70d..0bd77e8 100644
--- a/sys/directsound/gstdirectsoundsrc.c
+++ b/sys/directsound/gstdirectsoundsrc.c
@@ -73,18 +73,22 @@
 
 #include <windows.h>
 #include <dsound.h>
+#include <mmsystem.h>
 
 GST_DEBUG_CATEGORY_STATIC (directsoundsrc_debug);
 #define GST_CAT_DEFAULT directsoundsrc_debug
 
 /* defaults here */
 #define DEFAULT_DEVICE 0
+#define DEFAULT_MUTE FALSE
 
 /* properties */
 enum
 {
   PROP_0,
-  PROP_DEVICE_NAME
+  PROP_DEVICE_NAME,
+  PROP_VOLUME,
+  PROP_MUTE
 };
 
 static HRESULT (WINAPI * pDSoundCaptureCreate) (LPGUID,
@@ -114,6 +118,18 @@
 
 static guint gst_directsound_src_delay (GstAudioSrc * asrc);
 
+static gboolean gst_directsound_src_mixer_find (GstDirectSoundSrc * dsoundsrc,
+    MIXERCAPS * mixer_caps);
+static void gst_directsound_src_mixer_init (GstDirectSoundSrc * dsoundsrc);
+
+static gdouble gst_directsound_src_get_volume (GstDirectSoundSrc * dsoundsrc);
+static void gst_directsound_src_set_volume (GstDirectSoundSrc * dsoundsrc,
+    gdouble volume);
+
+static gboolean gst_directsound_src_get_mute (GstDirectSoundSrc * dsoundsrc);
+static void gst_directsound_src_set_mute (GstDirectSoundSrc * dsoundsrc,
+    gboolean mute);
+
 static GstStaticPadTemplate directsound_src_src_factory =
 GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
@@ -124,7 +140,9 @@
         "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]"));
 
 #define gst_directsound_src_parent_class parent_class
-G_DEFINE_TYPE (GstDirectSoundSrc, gst_directsound_src, GST_TYPE_AUDIO_SRC);
+G_DEFINE_TYPE_WITH_CODE (GstDirectSoundSrc, gst_directsound_src,
+    GST_TYPE_AUDIO_SRC, G_IMPLEMENT_INTERFACE (GST_TYPE_STREAM_VOLUME, NULL)
+    );
 
 static void
 gst_directsound_src_dispose (GObject * object)
@@ -193,6 +211,18 @@
       (gobject_class, PROP_DEVICE_NAME,
       g_param_spec_string ("device-name", "Device name",
           "Human-readable name of the sound device", NULL, G_PARAM_READWRITE));
+
+  g_object_class_install_property
+      (gobject_class, PROP_VOLUME,
+      g_param_spec_double ("volume", "Volume",
+          "Volume of this stream", 0.0, 1.0, 1.0,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property
+      (gobject_class, PROP_MUTE,
+      g_param_spec_boolean ("mute", "Mute",
+          "Mute state of this stream", DEFAULT_MUTE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 }
 
 static GstCaps *
@@ -223,6 +253,12 @@
       }
 
       break;
+    case PROP_VOLUME:
+      gst_directsound_src_set_volume (src, g_value_get_double (value));
+      break;
+    case PROP_MUTE:
+      gst_directsound_src_set_mute (src, g_value_get_boolean (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -241,6 +277,12 @@
     case PROP_DEVICE_NAME:
       g_value_set_string (value, src->device_name);
       break;
+    case PROP_VOLUME:
+      g_value_set_double (value, gst_directsound_src_get_volume (src));
+      break;
+    case PROP_MUTE:
+      g_value_set_boolean (value, gst_directsound_src_get_mute (src));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -260,6 +302,11 @@
   g_mutex_init (&src->dsound_lock);
   src->device_guid = NULL;
   src->device_name = NULL;
+  src->mixer = NULL;
+  src->control_id_mute = -1;
+  src->control_id_volume = -1;
+  src->volume = 100;
+  src->mute = FALSE;
 }
 
 
@@ -326,6 +373,7 @@
     goto capture_object;
   }
 
+  gst_directsound_src_mixer_init (dsoundsrc);
   return TRUE;
 
 capture_function:
@@ -374,6 +422,9 @@
   /* Close library */
   FreeLibrary (dsoundsrc->DSoundDLL);
 
+  if (dsoundsrc->mixer)
+    mixerClose (dsoundsrc->mixer);
+
   return TRUE;
 }
 
@@ -661,3 +712,215 @@
 
   GST_DSOUND_UNLOCK (dsoundsrc);
 }
+
+/* If the PROP_DEVICE_NAME is set, find the mixer related to device;
+ * otherwise we get the default input mixer. */
+static gboolean
+gst_directsound_src_mixer_find (GstDirectSoundSrc * dsoundsrc,
+    MIXERCAPS * mixer_caps)
+{
+  MMRESULT mmres;
+  guint i, num_mixers;
+
+  num_mixers = mixerGetNumDevs ();
+  for (i = 0; i < num_mixers; i++) {
+    mmres = mixerOpen (&dsoundsrc->mixer, i, 0L, 0L,
+        MIXER_OBJECTF_MIXER | MIXER_OBJECTF_WAVEIN);
+
+    if (mmres != MMSYSERR_NOERROR)
+      continue;
+
+    mmres = mixerGetDevCaps ((UINT) dsoundsrc->mixer,
+        mixer_caps, sizeof (MIXERCAPS));
+
+    if (mmres != MMSYSERR_NOERROR) {
+      mixerClose (dsoundsrc->mixer);
+      continue;
+    }
+
+    /* Get default mixer */
+    if (dsoundsrc->device_name == NULL) {
+      GST_DEBUG ("Got default input mixer: %s", mixer_caps->szPname);
+      return TRUE;
+    }
+
+    if (g_strstr_len (dsoundsrc->device_name, -1, mixer_caps->szPname) != NULL) {
+      GST_DEBUG ("Got requested input mixer: %s", mixer_caps->szPname);
+      return TRUE;
+    }
+
+    /* Wrong mixer */
+    mixerClose (dsoundsrc->mixer);
+  }
+
+  GST_DEBUG ("Can't find input mixer");
+  return FALSE;
+}
+
+static void
+gst_directsound_src_mixer_init (GstDirectSoundSrc * dsoundsrc)
+{
+  gint i, k;
+  gboolean found_mic;
+  MMRESULT mmres;
+  MIXERCAPS mixer_caps;
+  MIXERLINE mixer_line;
+  MIXERLINECONTROLS ml_ctrl;
+  PMIXERCONTROL pamixer_ctrls;
+
+  if (!gst_directsound_src_mixer_find (dsoundsrc, &mixer_caps))
+    goto mixer_init_fail;
+
+  /* Find the MIXERLINE related to MICROPHONE */
+  found_mic = FALSE;
+  for (i = 0; i < mixer_caps.cDestinations && !found_mic; i++) {
+    gint j, num_connections;
+
+    mixer_line.cbStruct = sizeof (mixer_line);
+    mixer_line.dwDestination = i;
+    mmres = mixerGetLineInfo ((HMIXEROBJ) dsoundsrc->mixer,
+        &mixer_line, MIXER_GETLINEINFOF_DESTINATION);
+
+    if (mmres != MMSYSERR_NOERROR)
+      goto mixer_init_fail;
+
+    num_connections = mixer_line.cConnections;
+    for (j = 0; j < num_connections && !found_mic; j++) {
+      mixer_line.cbStruct = sizeof (mixer_line);
+      mixer_line.dwDestination = i;
+      mixer_line.dwSource = j;
+      mmres = mixerGetLineInfo ((HMIXEROBJ) dsoundsrc->mixer,
+          &mixer_line, MIXER_GETLINEINFOF_SOURCE);
+
+      if (mmres != MMSYSERR_NOERROR)
+        goto mixer_init_fail;
+
+      if (mixer_line.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE
+          || mixer_line.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_LINE)
+        found_mic = TRUE;
+    }
+  }
+
+  if (found_mic == FALSE) {
+    GST_DEBUG ("Can't find mixer line related to input");
+    goto mixer_init_fail;
+  }
+
+  /* Get control associated with microphone audio line */
+  pamixer_ctrls = g_malloc (sizeof (MIXERCONTROL) * mixer_line.cControls);
+  ml_ctrl.cbStruct = sizeof (ml_ctrl);
+  ml_ctrl.dwLineID = mixer_line.dwLineID;
+  ml_ctrl.cControls = mixer_line.cControls;
+  ml_ctrl.cbmxctrl = sizeof (MIXERCONTROL);
+  ml_ctrl.pamxctrl = pamixer_ctrls;
+  mmres = mixerGetLineControls ((HMIXEROBJ) dsoundsrc->mixer,
+      &ml_ctrl, MIXER_GETLINECONTROLSF_ALL);
+
+  /* Find control associated with volume and mute */
+  for (k = 0; k < mixer_line.cControls; k++) {
+    if (strstr (pamixer_ctrls[k].szName, "Volume") != NULL) {
+      dsoundsrc->control_id_volume = pamixer_ctrls[k].dwControlID;
+      dsoundsrc->dw_vol_max = pamixer_ctrls[k].Bounds.dwMaximum;
+      dsoundsrc->dw_vol_min = pamixer_ctrls[k].Bounds.dwMinimum;
+    } else if (strstr (pamixer_ctrls[k].szName, "Mute") != NULL) {
+      dsoundsrc->control_id_mute = pamixer_ctrls[k].dwControlID;
+    } else {
+      GST_DEBUG ("Control not handled: %s", pamixer_ctrls[k].szName);
+    }
+  }
+  g_free (pamixer_ctrls);
+
+  if (dsoundsrc->control_id_volume < 0 && dsoundsrc->control_id_mute < 0)
+    goto mixer_init_fail;
+
+  /* Save cChannels information to properly changes in volume */
+  dsoundsrc->mixerline_cchannels = mixer_line.cChannels;
+  return;
+
+mixer_init_fail:
+  GST_WARNING ("Failed to get Volume and Mute controls");
+  if (dsoundsrc->mixer != NULL) {
+    mixerClose (dsoundsrc->mixer);
+    dsoundsrc->mixer = NULL;
+  }
+}
+
+static gdouble
+gst_directsound_src_get_volume (GstDirectSoundSrc * dsoundsrc)
+{
+  return (gdouble) dsoundsrc->volume / 100;
+}
+
+static gboolean
+gst_directsound_src_get_mute (GstDirectSoundSrc * dsoundsrc)
+{
+  return dsoundsrc->mute;
+}
+
+static void
+gst_directsound_src_set_volume (GstDirectSoundSrc * dsoundsrc, gdouble volume)
+{
+  MMRESULT mmres;
+  MIXERCONTROLDETAILS details;
+  MIXERCONTROLDETAILS_UNSIGNED details_unsigned;
+  glong dwvolume;
+
+  if (dsoundsrc->mixer == NULL || dsoundsrc->control_id_volume < 0) {
+    GST_WARNING ("mixer not initialized");
+    return;
+  }
+
+  dwvolume = volume * dsoundsrc->dw_vol_max;
+  dwvolume = CLAMP (dwvolume, dsoundsrc->dw_vol_min, dsoundsrc->dw_vol_max);
+
+  GST_DEBUG ("max volume %ld | min volume %ld",
+      dsoundsrc->dw_vol_max, dsoundsrc->dw_vol_min);
+  GST_DEBUG ("set volume to %f (%ld)", volume, dwvolume);
+
+  details.cbStruct = sizeof (details);
+  details.dwControlID = dsoundsrc->control_id_volume;
+  details.cChannels = dsoundsrc->mixerline_cchannels;
+  details.cMultipleItems = 0;
+
+  details_unsigned.dwValue = dwvolume;
+  details.cbDetails = sizeof (MIXERCONTROLDETAILS_UNSIGNED);
+  details.paDetails = &details_unsigned;
+
+  mmres = mixerSetControlDetails ((HMIXEROBJ) dsoundsrc->mixer,
+      &details, MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE);
+
+  if (mmres != MMSYSERR_NOERROR)
+    GST_WARNING ("Failed to set volume");
+  else
+    dsoundsrc->volume = volume * 100;
+}
+
+static void
+gst_directsound_src_set_mute (GstDirectSoundSrc * dsoundsrc, gboolean mute)
+{
+  MMRESULT mmres;
+  MIXERCONTROLDETAILS details;
+  MIXERCONTROLDETAILS_BOOLEAN details_boolean;
+
+  if (dsoundsrc->mixer == NULL || dsoundsrc->control_id_mute < 0) {
+    GST_WARNING ("mixer not initialized");
+    return;
+  }
+
+  details.cbStruct = sizeof (details);
+  details.dwControlID = dsoundsrc->control_id_mute;
+  details.cChannels = dsoundsrc->mixerline_cchannels;
+  details.cMultipleItems = 0;
+
+  details_boolean.fValue = mute;
+  details.cbDetails = sizeof (MIXERCONTROLDETAILS_BOOLEAN);
+  details.paDetails = &details_boolean;
+
+  mmres = mixerSetControlDetails ((HMIXEROBJ) dsoundsrc->mixer,
+      &details, MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE);
+
+  if (mmres != MMSYSERR_NOERROR)
+    GST_WARNING ("Failed to set mute");
+  else
+    dsoundsrc->mute = mute;
+}
diff --git a/sys/directsound/gstdirectsoundsrc.h b/sys/directsound/gstdirectsoundsrc.h
index 4c65372..a2ac6ff 100644
--- a/sys/directsound/gstdirectsoundsrc.h
+++ b/sys/directsound/gstdirectsoundsrc.h
@@ -52,6 +52,7 @@
 #include <gst/audio/gstaudiosrc.h>

 #include <windows.h>

 #include <dsound.h>

+#include <mmsystem.h>
 

 /* add here some headers if needed */

 

@@ -91,6 +92,15 @@
   guint buffer_time;

   guint latency_time;

 

+  HMIXER mixer;
+  DWORD mixerline_cchannels;
+  gint control_id_volume;
+  gint control_id_mute;
+  glong dw_vol_max;
+  glong dw_vol_min;
+
+  glong volume;
+  gboolean mute;
 

   GUID *device_guid;

   char *device_name;

diff --git a/sys/opensles/openslessink.c b/sys/opensles/openslessink.c
index 266174a..236f8b3 100644
--- a/sys/opensles/openslessink.c
+++ b/sys/opensles/openslessink.c
@@ -65,7 +65,8 @@
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS ("audio/x-raw, "
         "format = (string) { " GST_AUDIO_NE (S16) ", " GST_AUDIO_NE (U8) "}, "
-        "rate = (int) { " RATES "}, " "channels = (int) [1, 2]")
+        "rate = (int) { " RATES "}, " "channels = (int) [1, 2], "
+        "layout = (string) interleaved")
     );
 
 #define _do_init \
diff --git a/sys/opensles/openslessrc.c b/sys/opensles/openslessrc.c
index 3fd9cb2..18db5eb 100644
--- a/sys/opensles/openslessrc.c
+++ b/sys/opensles/openslessrc.c
@@ -48,7 +48,8 @@
     GST_STATIC_CAPS ("audio/x-raw, "
         "format = (string) " GST_AUDIO_NE (S16) ", "
         "rate = (int) 16000, "
-        "channels = (int) 1")
+        "channels = (int) 1, "
+        "layout = (string) interleaved")
     );
 /* *INDENT-ON* */
 
diff --git a/sys/shm/gstshmsrc.c b/sys/shm/gstshmsrc.c
index 8af1f34..1e69af7 100644
--- a/sys/shm/gstshmsrc.c
+++ b/sys/shm/gstshmsrc.c
@@ -54,7 +54,8 @@
 {
   PROP_0,
   PROP_SOCKET_PATH,
-  PROP_IS_LIVE
+  PROP_IS_LIVE,
+  PROP_SHM_AREA_NAME
 };
 
 struct GstShmBuffer
@@ -123,14 +124,20 @@
   g_object_class_install_property (gobject_class, PROP_SOCKET_PATH,
       g_param_spec_string ("socket-path",
           "Path to the control socket",
-          "The path to the control socket used to control the shared memory"
-          " transport", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+          "The path to the control socket used to control the shared memory",
+          NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   g_object_class_install_property (gobject_class, PROP_IS_LIVE,
       g_param_spec_boolean ("is-live", "Is this a live source",
           "True if the element cannot produce data in PAUSED", FALSE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_SHM_AREA_NAME,
+      g_param_spec_string ("shm-area-name",
+          "Name of the shared memory area",
+          "The name of the shared memory area used to get buffers",
+          NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
   gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&srctemplate));
 
@@ -205,6 +212,12 @@
     case PROP_IS_LIVE:
       g_value_set_boolean (value, gst_base_src_is_live (GST_BASE_SRC (object)));
       break;
+    case PROP_SHM_AREA_NAME:
+      GST_OBJECT_LOCK (object);
+      if (self->pipe)
+        g_value_set_string (value, sp_get_shm_area_name (self->pipe->pipe));
+      GST_OBJECT_UNLOCK (object);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
diff --git a/sys/shm/shmpipe.c b/sys/shm/shmpipe.c
index 6bd9efc..de89026 100644
--- a/sys/shm/shmpipe.c
+++ b/sys/shm/shmpipe.c
@@ -90,6 +90,7 @@
   int id;
 
   int use_count;
+  int is_writer;
 
   int shm_fd;
 
@@ -286,6 +287,8 @@
 
   area->shm_area_len = size;
 
+  area->is_writer = (path == NULL);
+
 
   if (path)
     flags = O_RDONLY;
@@ -320,6 +323,7 @@
 
     prot = PROT_READ | PROT_WRITE;
   } else {
+    area->shm_area_name = strdup (path);
     prot = PROT_READ;
   }
 
@@ -353,7 +357,8 @@
     close (area->shm_fd);
 
   if (area->shm_area_name) {
-    shm_unlink (area->shm_area_name);
+    if (area->is_writer)
+      shm_unlink (area->shm_area_name);
     free (area->shm_area_name);
   }
 
@@ -664,13 +669,15 @@
       assert (cb.payload.new_shm_area.path_size > 0);
       assert (cb.payload.new_shm_area.size > 0);
 
-      area_name = malloc (cb.payload.new_shm_area.path_size);
+      area_name = malloc (cb.payload.new_shm_area.path_size + 1);
       retval = recv (self->main_socket, area_name,
           cb.payload.new_shm_area.path_size, 0);
       if (retval != cb.payload.new_shm_area.path_size) {
         free (area_name);
         return -3;
       }
+      /* Ensure area_name is NULL terminated */
+      area_name[retval] = 0;
 
       newarea = sp_open_shm (area_name, cb.area_id, 0,
           cb.payload.new_shm_area.size);
@@ -935,6 +942,15 @@
   return self->main_socket;
 }
 
+const gchar *
+sp_get_shm_area_name (ShmPipe * self)
+{
+  if (self->shm_area)
+    return self->shm_area->shm_area_name;
+
+  return NULL;
+}
+
 int
 sp_writer_get_client_fd (ShmClient * client)
 {
diff --git a/sys/shm/shmpipe.h b/sys/shm/shmpipe.h
index 6d75629..1f746ac 100644
--- a/sys/shm/shmpipe.h
+++ b/sys/shm/shmpipe.h
@@ -91,6 +91,7 @@
 int sp_writer_resize (ShmPipe * self, size_t size);
 
 int sp_get_fd (ShmPipe * self);
+const char *sp_get_shm_area_name (ShmPipe *self);
 int sp_writer_get_client_fd (ShmClient * client);
 
 ShmBlock *sp_writer_alloc_block (ShmPipe * self, size_t size);
diff --git a/sys/winks/Makefile.am b/sys/winks/Makefile.am
index 4233b64..10626b1 100644
--- a/sys/winks/Makefile.am
+++ b/sys/winks/Makefile.am
@@ -3,6 +3,7 @@
 libgstwinks_la_SOURCES = gstksclock.c \
 	gstksvideodevice.c \
 	gstksvideosrc.c \
+	ksdeviceprovider.c ksdeviceprovider.h \
 	kshelpers.c kshelpers.h \
 	ksvideohelpers.c 
 libgstwinks_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) \
diff --git a/sys/winks/Makefile.in b/sys/winks/Makefile.in
index 4524e32..1eeb3fb 100644
--- a/sys/winks/Makefile.in
+++ b/sys/winks/Makefile.in
@@ -159,7 +159,8 @@
 	$(am__DEPENDENCIES_1)
 am_libgstwinks_la_OBJECTS = libgstwinks_la-gstksclock.lo \
 	libgstwinks_la-gstksvideodevice.lo \
-	libgstwinks_la-gstksvideosrc.lo libgstwinks_la-kshelpers.lo \
+	libgstwinks_la-gstksvideosrc.lo \
+	libgstwinks_la-ksdeviceprovider.lo libgstwinks_la-kshelpers.lo \
 	libgstwinks_la-ksvideohelpers.lo
 libgstwinks_la_OBJECTS = $(am_libgstwinks_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
@@ -742,6 +743,7 @@
 libgstwinks_la_SOURCES = gstksclock.c \
 	gstksvideodevice.c \
 	gstksvideosrc.c \
+	ksdeviceprovider.c ksdeviceprovider.h \
 	kshelpers.c kshelpers.h \
 	ksvideohelpers.c 
 
@@ -837,6 +839,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstwinks_la-gstksclock.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstwinks_la-gstksvideodevice.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstwinks_la-gstksvideosrc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstwinks_la-ksdeviceprovider.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstwinks_la-kshelpers.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstwinks_la-ksvideohelpers.Plo@am__quote@
 
@@ -885,6 +888,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 $(libgstwinks_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstwinks_la_CFLAGS) $(CFLAGS) -c -o libgstwinks_la-gstksvideosrc.lo `test -f 'gstksvideosrc.c' || echo '$(srcdir)/'`gstksvideosrc.c
 
+libgstwinks_la-ksdeviceprovider.lo: ksdeviceprovider.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstwinks_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstwinks_la_CFLAGS) $(CFLAGS) -MT libgstwinks_la-ksdeviceprovider.lo -MD -MP -MF $(DEPDIR)/libgstwinks_la-ksdeviceprovider.Tpo -c -o libgstwinks_la-ksdeviceprovider.lo `test -f 'ksdeviceprovider.c' || echo '$(srcdir)/'`ksdeviceprovider.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstwinks_la-ksdeviceprovider.Tpo $(DEPDIR)/libgstwinks_la-ksdeviceprovider.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='ksdeviceprovider.c' object='libgstwinks_la-ksdeviceprovider.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 $(libgstwinks_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstwinks_la_CFLAGS) $(CFLAGS) -c -o libgstwinks_la-ksdeviceprovider.lo `test -f 'ksdeviceprovider.c' || echo '$(srcdir)/'`ksdeviceprovider.c
+
 libgstwinks_la-kshelpers.lo: kshelpers.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstwinks_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstwinks_la_CFLAGS) $(CFLAGS) -MT libgstwinks_la-kshelpers.lo -MD -MP -MF $(DEPDIR)/libgstwinks_la-kshelpers.Tpo -c -o libgstwinks_la-kshelpers.lo `test -f 'kshelpers.c' || echo '$(srcdir)/'`kshelpers.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libgstwinks_la-kshelpers.Tpo $(DEPDIR)/libgstwinks_la-kshelpers.Plo
diff --git a/sys/winks/gstksclock.c b/sys/winks/gstksclock.c
index e67e02f..8d46905 100644
--- a/sys/winks/gstksclock.c
+++ b/sys/winks/gstksclock.c
@@ -133,7 +133,7 @@
 
   priv->state = KSSTATE_STOP;
 
-  devices = ks_enumerate_devices (&KSCATEGORY_CLOCK);
+  devices = ks_enumerate_devices (&KSCATEGORY_CLOCK, &KSCATEGORY_CAPTURE);
   if (devices == NULL)
     goto error;
 
diff --git a/sys/winks/gstksvideodevice.c b/sys/winks/gstksvideodevice.c
index 95dec48..d00b6a7 100644
--- a/sys/winks/gstksvideodevice.c
+++ b/sys/winks/gstksvideodevice.c
@@ -83,6 +83,7 @@
   guint fps_n;
   guint fps_d;
   guint8 *rgb_swap_buf;
+  gboolean is_muxed;
 
   HANDLE pin_handle;
 
@@ -752,14 +753,17 @@
   if (!gst_structure_get_int (s, "width", &width) ||
       !gst_structure_get_int (s, "height", &height) ||
       !gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d)) {
-    GST_ERROR ("Failed to get width/height/fps");
-    goto error;
+    gst_structure_get_boolean (s, "systemstream", &priv->is_muxed);
+    if (!priv->is_muxed) {
+      GST_ERROR ("Failed to get width/height/fps");
+      goto error;
+    }
+  } else {
+    if (!ks_video_fixate_media_type (media_type->range,
+            media_type->format, width, height, fps_n, fps_d))
+      goto error;
   }
 
-  if (!ks_video_fixate_media_type (media_type->range,
-          media_type->format, width, height, fps_n, fps_d))
-    goto error;
-
   if (priv->cur_media_type != NULL) {
     if (media_type->format_size == priv->cur_media_type->format_size &&
         memcmp (media_type->format, priv->cur_media_type->format,
@@ -967,7 +971,10 @@
   if (!gst_buffer_map (req->buf, &info, GST_MAP_WRITE))
     goto map_failed;
 
-  params->header.Size = sizeof (KSSTREAM_HEADER) + sizeof (KS_FRAME_INFO);
+  params->header.Size = sizeof (KSSTREAM_HEADER);
+  if (!priv->is_muxed) {
+    params->header.Size += sizeof (KS_FRAME_INFO);
+  }
   params->header.PresentationTime.Numerator = 1;
   params->header.PresentationTime.Denominator = 1;
   params->header.FrameExtent = gst_ks_video_device_get_frame_size (self);
@@ -1217,3 +1224,11 @@
 
   ResetEvent (priv->cancel_event);
 }
+
+gboolean
+gst_ks_video_device_stream_is_muxed (GstKsVideoDevice * self)
+{
+  GstKsVideoDevicePrivate *priv = GST_KS_VIDEO_DEVICE_GET_PRIVATE (self);
+
+  return priv->is_muxed;
+}
diff --git a/sys/winks/gstksvideodevice.h b/sys/winks/gstksvideodevice.h
index 105b79d..649faaa 100644
--- a/sys/winks/gstksvideodevice.h
+++ b/sys/winks/gstksvideodevice.h
@@ -81,6 +81,8 @@
 void gst_ks_video_device_cancel (GstKsVideoDevice * self);
 void gst_ks_video_device_cancel_stop (GstKsVideoDevice * self);
 
+gboolean gst_ks_video_device_stream_is_muxed (GstKsVideoDevice * self);
+
 G_END_DECLS
 
 #endif /* __GST_KS_VIDEO_DEVICE_H__ */
diff --git a/sys/winks/gstksvideosrc.c b/sys/winks/gstksvideosrc.c
index cd61a99..79cbb7a 100644
--- a/sys/winks/gstksvideosrc.c
+++ b/sys/winks/gstksvideosrc.c
@@ -45,6 +45,7 @@
 #include "gstksvideodevice.h"
 #include "kshelpers.h"
 #include "ksvideohelpers.h"
+#include "ksdeviceprovider.h"
 
 #define DEFAULT_DEVICE_PATH     NULL
 #define DEFAULT_DEVICE_NAME     NULL
@@ -222,9 +223,6 @@
       g_param_spec_boolean ("enable-quirks", "Enable quirks",
           "Enable driver-specific quirks", DEFAULT_ENABLE_QUIRKS,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  GST_DEBUG_CATEGORY_INIT (gst_ks_debug, "ksvideosrc",
-      0, "Kernel streaming video source");
 }
 
 static void
@@ -394,7 +392,7 @@
   GList *devices, *cur;
   GArray *array = g_array_new (TRUE, TRUE, sizeof (GValue));
 
-  devices = ks_enumerate_devices (&KSCATEGORY_VIDEO);
+  devices = ks_enumerate_devices (&KSCATEGORY_VIDEO, &KSCATEGORY_CAPTURE);
   if (devices == NULL)
     return array;
 
@@ -425,7 +423,7 @@
 
   g_assert (priv->device == NULL);
 
-  devices = ks_enumerate_devices (&KSCATEGORY_VIDEO);
+  devices = ks_enumerate_devices (&KSCATEGORY_VIDEO, &KSCATEGORY_CAPTURE);
   if (devices == NULL)
     goto error_no_devices;
 
@@ -438,10 +436,14 @@
         entry->index, entry->name, entry->path);
   }
 
-  for (cur = devices; cur != NULL && device == NULL; cur = cur->next) {
+  for (cur = devices; cur != NULL; cur = cur->next) {
     KsDeviceEntry *entry = cur->data;
     gboolean match;
 
+    if (device != NULL) {
+      ks_device_entry_free (entry);
+      continue;
+    }
     if (priv->device_path != NULL) {
       match = g_ascii_strcasecmp (entry->path, priv->device_path) == 0;
     } else if (priv->device_name != NULL) {
@@ -813,6 +815,13 @@
   GstClock *clock;
   GstClockTime timestamp;
 
+  /* Don't timestamp muxed strams */
+  if (!gst_ks_video_device_stream_is_muxed (priv->device)) {
+    duration = timestamp = GST_CLOCK_TIME_NONE;
+    priv->offset++;
+    goto timestamp;
+  }
+
   duration = gst_ks_video_device_get_duration (priv->device);
 
   GST_OBJECT_LOCK (self);
@@ -898,9 +907,11 @@
     priv->prev_ts = timestamp;
   }
 
+timestamp:
   GST_BUFFER_OFFSET (buf) = priv->offset;
   GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET (buf) + 1;
-  GST_BUFFER_TIMESTAMP (buf) = timestamp;
+  GST_BUFFER_PTS (buf) = timestamp;
+  GST_BUFFER_DTS (buf) = GST_CLOCK_TIME_NONE;
   GST_BUFFER_DURATION (buf) = duration;
 
   return TRUE;
@@ -1068,8 +1079,18 @@
 static gboolean
 plugin_init (GstPlugin * plugin)
 {
-  return gst_element_register (plugin, "ksvideosrc",
-      GST_RANK_NONE, GST_TYPE_KS_VIDEO_SRC);
+  GST_DEBUG_CATEGORY_INIT (gst_ks_debug, "ksvideosrc",
+      0, "Kernel streaming video source");
+
+  if (!gst_element_register (plugin, "ksvideosrc",
+          GST_RANK_NONE, GST_TYPE_KS_VIDEO_SRC))
+    return FALSE;
+
+  if (!gst_device_provider_register (plugin, "ksdeviceprovider",
+          GST_RANK_PRIMARY, GST_TYPE_KS_DEVICE_PROVIDER))
+    return FALSE;
+
+  return TRUE;
 }
 
 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
diff --git a/sys/winks/ksdeviceprovider.c b/sys/winks/ksdeviceprovider.c
new file mode 100644
index 0000000..54429eb
--- /dev/null
+++ b/sys/winks/ksdeviceprovider.c
@@ -0,0 +1,795 @@
+/* GStreamer
+ * Copyright (C) 2015 Руслан Ижбулатов <lrn1986@gmail.com>
+ *
+ * ksdeviceprovider.c: Kernel Streaming device probing and monitoring
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstksvideosrc.h"
+#include "ksdeviceprovider.h"
+
+#include <string.h>
+
+#include <dbt.h>                /* for DBT_* consts and [_]DEV_* structs */
+#include <devguid.h>            /* for GUID_DEVCLASS_WCEUSBS */
+#include <setupapi.h>           /* for DIGCF_ALLCLASSES */
+
+#include <gst/gst.h>
+
+#include "kshelpers.h"
+#include "ksvideohelpers.h"
+
+
+GST_DEBUG_CATEGORY_EXTERN (gst_ks_debug);
+#define GST_CAT_DEFAULT gst_ks_debug
+
+
+static GstDevice *gst_ks_device_new (guint id,
+    const gchar * device_name, GstCaps * caps, const gchar * device_path,
+    GstKsDeviceType type);
+
+G_DEFINE_TYPE (GstKsDeviceProvider, gst_ks_device_provider,
+    GST_TYPE_DEVICE_PROVIDER);
+
+static GList *gst_ks_device_provider_probe (GstDeviceProvider * provider);
+static gboolean gst_ks_device_provider_start (GstDeviceProvider * provider);
+static void gst_ks_device_provider_stop (GstDeviceProvider * provider);
+
+static void
+gst_ks_device_provider_class_init (GstKsDeviceProviderClass * klass)
+{
+  GstDeviceProviderClass *dm_class = GST_DEVICE_PROVIDER_CLASS (klass);
+
+  dm_class->probe = gst_ks_device_provider_probe;
+  dm_class->start = gst_ks_device_provider_start;
+  dm_class->stop = gst_ks_device_provider_stop;
+
+  gst_device_provider_class_set_static_metadata (dm_class,
+      "KernelStreaming Device Provider", "Sink/Source/Audio/Video",
+      "List and provide KernelStreaming source and sink devices",
+      "Руслан Ижбулатов <lrn1986@gmail.com>");
+}
+
+static void
+gst_ks_device_provider_init (GstKsDeviceProvider * self)
+{
+}
+
+static GstDevice *
+new_video_source (const KsDeviceEntry * info)
+{
+  GstCaps *caps;
+  HANDLE filter_handle;
+  GList *media_types;
+  GList *cur;
+
+  g_assert (info->path != NULL);
+
+  caps = gst_caps_new_empty ();
+
+  filter_handle = CreateFile (info->path,
+      GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
+      FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
+  if (!ks_is_valid_handle (filter_handle))
+    goto error;
+
+  media_types = ks_video_probe_filter_for_caps (filter_handle);
+
+  for (cur = media_types; cur != NULL; cur = cur->next) {
+    KsVideoMediaType *media_type = cur->data;
+
+    gst_caps_append (caps, gst_caps_copy (media_type->translated_caps));
+
+    ks_video_media_type_free (media_type);
+  }
+
+  CloseHandle (filter_handle);
+  g_list_free (media_types);
+
+  return gst_ks_device_new (info->index, info->name,
+      caps, info->path, GST_KS_DEVICE_TYPE_VIDEO_SOURCE);
+error:
+  gst_caps_unref (caps);
+  return NULL;
+}
+
+static GList *
+gst_ks_device_provider_probe (GstDeviceProvider * provider)
+{
+  /*GstKsDeviceProvider *self = GST_KS_DEVICE_PROVIDER (provider); */
+  GList *devices, *cur;
+  GList *result;
+
+  result = NULL;
+
+  devices = ks_enumerate_devices (&KSCATEGORY_VIDEO, &KSCATEGORY_CAPTURE);
+  if (devices == NULL)
+    return result;
+
+  devices = ks_video_device_list_sort_cameras_first (devices);
+
+  for (cur = devices; cur != NULL; cur = cur->next) {
+    GstDevice *source;
+    KsDeviceEntry *entry = cur->data;
+
+    source = new_video_source (entry);
+    if (source)
+      result = g_list_prepend (result, gst_object_ref_sink (source));
+
+    ks_device_entry_free (entry);
+  }
+
+  result = g_list_reverse (result);
+
+  g_list_free (devices);
+
+  return result;
+}
+
+static const gchar *
+get_dev_type (DEV_BROADCAST_HDR * dev_msg_header)
+{
+  switch (dev_msg_header->dbch_devicetype) {
+    case DBT_DEVTYP_DEVICEINTERFACE:
+      return "Device interface class";
+    case DBT_DEVTYP_HANDLE:
+      return "Filesystem handle";
+    case DBT_DEVTYP_OEM:
+      return "OEM or IHV device type";
+    case DBT_DEVTYP_PORT:
+      return "Port device";
+    case DBT_DEVTYP_VOLUME:
+      return "Logical volume";
+    default:
+      return "Unknown device type";
+  }
+}
+
+#define KS_MSG_WINDOW_CLASS "gst_winks_device_msg_window"
+#define WM_QUITTHREAD (WM_USER + 0)
+
+static void unreg_msg_window_class (ATOM class_id, const char *class_name,
+    HINSTANCE inst);
+
+static HDEVNOTIFY
+register_device_interface (GstKsDeviceProvider * self,
+    GUID interface_class_guid, HWND window_handle)
+{
+  DEV_BROADCAST_DEVICEINTERFACE notification_filter;
+  HDEVNOTIFY notification_handle;
+  DWORD error;
+
+  memset (&notification_filter, 0, sizeof (notification_filter));
+  notification_filter.dbcc_size = sizeof (notification_filter);
+  notification_filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
+  notification_filter.dbcc_classguid = interface_class_guid;
+
+  notification_handle = RegisterDeviceNotificationW (window_handle,
+      &notification_filter,
+      DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
+  error = GetLastError ();
+
+  if (notification_handle == NULL)
+    GST_ERROR_OBJECT (self,
+        "Could not register for a device notification: %lu", error);
+
+  return notification_handle;
+}
+
+static INT_PTR WINAPI
+msg_window_message_proc (HWND window_handle, UINT message,
+    WPARAM wparam, LPARAM lparam)
+{
+  LRESULT result;
+  LONG_PTR user_data;
+  GstKsDeviceProvider *self;
+  PDEV_BROADCAST_DEVICEINTERFACE bcdi;
+  DEV_BROADCAST_HDR *dev_msg_header;
+  struct _DEV_BROADCAST_USERDEFINED *user_dev_msg_header;
+  CREATESTRUCT *create_data;
+  DWORD error;
+  HINSTANCE inst;
+  GstKsDevice *dev;
+  GstDevice *source;
+  GList *item;
+  GstDeviceProvider *provider;
+  GList *devices;
+  gchar *guid_str;
+
+  result = TRUE;
+
+  switch (message) {
+    case WM_CREATE:
+      create_data = (CREATESTRUCT *) lparam;
+
+      if (create_data->lpCreateParams == NULL) {
+        /* DO SOMETHING!! */
+      }
+
+      self = GST_KS_DEVICE_PROVIDER (create_data->lpCreateParams);
+
+      SetLastError (0);
+      SetWindowLongPtr (window_handle, GWLP_USERDATA, (LONG_PTR) self);
+      error = GetLastError ();
+      if (error != NO_ERROR) {
+        GST_ERROR_OBJECT (self,
+            "Could not attach user data to the message window: %lu", error);
+        DestroyWindow (window_handle);
+        inst = (HINSTANCE) GetModuleHandle (NULL);
+        GST_OBJECT_LOCK (self);
+        unreg_msg_window_class (self->message_window_class, KS_MSG_WINDOW_CLASS,
+            inst);
+        self->message_window_class = 0;
+        GST_OBJECT_UNLOCK (self);
+      }
+      result = FALSE;
+      break;
+    case WM_DEVICECHANGE:
+      GST_DEBUG ("WM_DEVICECHANGE for %x %x", (unsigned int) wparam,
+          (unsigned int) lparam);
+
+      user_data = GetWindowLongPtr (window_handle, GWLP_USERDATA);
+      if (user_data == 0)
+        break;
+
+      self = GST_KS_DEVICE_PROVIDER (user_data);
+      provider = GST_DEVICE_PROVIDER (self);
+
+      dev_msg_header = (DEV_BROADCAST_HDR *) lparam;
+
+      switch (wparam) {
+        case DBT_CONFIGCHANGECANCELED:
+          GST_DEBUG_OBJECT (self, "DBT_CONFIGCHANGECANCELED for %s",
+              get_dev_type (dev_msg_header));
+          break;
+        case DBT_CONFIGCHANGED:
+          GST_DEBUG_OBJECT (self, "DBT_CONFIGCHANGED for %s",
+              get_dev_type (dev_msg_header));
+          break;
+        case DBT_CUSTOMEVENT:
+          GST_DEBUG_OBJECT (self, "DBT_CUSTOMEVENT for %s",
+              get_dev_type (dev_msg_header));
+          break;
+        case DBT_DEVICEARRIVAL:
+          GST_DEBUG_OBJECT (self, "DBT_DEVICEARRIVAL for %s",
+              get_dev_type (dev_msg_header));
+
+          if (dev_msg_header->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE)
+            break;
+
+          bcdi = (PDEV_BROADCAST_DEVICEINTERFACE) lparam;
+          guid_str = ks_guid_to_string (&bcdi->dbcc_classguid);
+          GST_INFO_OBJECT (self, "New device, class interface GUID %s, path %s",
+              guid_str, bcdi->dbcc_name);
+          g_free (guid_str);
+          break;
+        case DBT_DEVICEQUERYREMOVE:
+          GST_DEBUG_OBJECT (self, "DBT_DEVICEQUERYREMOVE for %s",
+              get_dev_type (dev_msg_header));
+          break;
+        case DBT_DEVICEQUERYREMOVEFAILED:
+          GST_DEBUG_OBJECT (self, "DBT_DEVICEQUERYREMOVEFAILED for %s",
+              get_dev_type (dev_msg_header));
+          break;
+        case DBT_DEVICEREMOVECOMPLETE:
+          GST_DEBUG_OBJECT (self, "DBT_DEVICEREMOVECOMPLETE for %s",
+              get_dev_type (dev_msg_header));
+
+          if (dev_msg_header->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE)
+            break;
+
+          bcdi = (PDEV_BROADCAST_DEVICEINTERFACE) lparam;
+
+          guid_str = ks_guid_to_string (&bcdi->dbcc_classguid);
+          GST_INFO_OBJECT (self,
+              "Removed device, class interface GUID %s, path %s", guid_str,
+              bcdi->dbcc_name);
+          g_free (guid_str);
+          break;
+        case DBT_DEVICEREMOVEPENDING:
+          GST_DEBUG_OBJECT (self, "DBT_DEVICEREMOVEPENDING for %s",
+              get_dev_type (dev_msg_header));
+          break;
+        case DBT_DEVICETYPESPECIFIC:
+          GST_DEBUG_OBJECT (self, "DBT_DEVICETYPESPECIFIC for %s",
+              get_dev_type (dev_msg_header));
+          break;
+        case DBT_DEVNODES_CHANGED:
+          GST_DEBUG_OBJECT (self, "DBT_DEVNODES_CHANGED for %s",
+              get_dev_type (dev_msg_header));
+          break;
+        case DBT_QUERYCHANGECONFIG:
+          GST_DEBUG_OBJECT (self, "DBT_QUERYCHANGECONFIG for %s",
+              get_dev_type (dev_msg_header));
+          break;
+        case DBT_USERDEFINED:
+          user_dev_msg_header = (struct _DEV_BROADCAST_USERDEFINED *) lparam;
+          dev_msg_header =
+              (DEV_BROADCAST_HDR *) & user_dev_msg_header->dbud_dbh;
+          GST_DEBUG_OBJECT (self, "DBT_USERDEFINED for %s: %s",
+              get_dev_type (dev_msg_header), user_dev_msg_header->dbud_szName);
+          break;
+        default:
+          break;
+      }
+
+      switch (wparam) {
+        case DBT_DEVICEARRIVAL:
+          if (dev_msg_header->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE)
+            break;
+
+          bcdi = (PDEV_BROADCAST_DEVICEINTERFACE) lparam;
+
+          if (!IsEqualGUID (&bcdi->dbcc_classguid, &KSCATEGORY_CAPTURE) &&
+              !IsEqualGUID (&bcdi->dbcc_classguid, &KSCATEGORY_RENDER))
+            break;
+
+          devices =
+              ks_enumerate_devices (&bcdi->dbcc_classguid,
+              &bcdi->dbcc_classguid);
+          if (devices == NULL)
+            break;
+
+          source = NULL;
+          for (item = devices; item != NULL; item = item->next) {
+            KsDeviceEntry *entry = item->data;
+            GST_DEBUG_OBJECT (self, "Listed device %s = %s", entry->name,
+                entry->path);
+
+            if ((source == NULL) &&
+                (strcasecmp (entry->path, bcdi->dbcc_name) == 0))
+              source = new_video_source (entry);
+
+            ks_device_entry_free (entry);
+          }
+
+          if (source)
+            gst_device_provider_device_add (GST_DEVICE_PROVIDER (self), source);
+
+          g_list_free (devices);
+          break;
+        case DBT_DEVICEREMOVECOMPLETE:
+          if (dev_msg_header->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE)
+            break;
+
+          bcdi = (PDEV_BROADCAST_DEVICEINTERFACE) lparam;
+          dev = NULL;
+
+          GST_OBJECT_LOCK (self);
+          for (item = provider->devices; item; item = item->next) {
+            dev = item->data;
+
+            if (strcasecmp (dev->path, bcdi->dbcc_name) == 0) {
+              guid_str = gst_device_get_display_name (GST_DEVICE (dev));
+              GST_INFO_OBJECT (self, "Device matches to %s", guid_str);
+              g_free (guid_str);
+              gst_object_ref (dev);
+              break;
+            }
+            dev = NULL;
+          }
+          GST_OBJECT_UNLOCK (self);
+
+          if (dev) {
+            gst_device_provider_device_remove (GST_DEVICE_PROVIDER (self),
+                GST_DEVICE (dev));
+            gst_object_unref (dev);
+          }
+          break;
+        default:
+          break;
+      }
+      result = FALSE;
+      break;
+    case WM_DESTROY:
+      PostQuitMessage (0);
+      result = FALSE;
+      break;
+    case WM_QUITTHREAD:
+      DestroyWindow (window_handle);
+      result = FALSE;
+      break;
+    default:
+      result = DefWindowProc (window_handle, message, wparam, lparam);
+      break;
+  }
+
+  return result;
+}
+
+static ATOM
+reg_msg_window_class (const char *class_name, HINSTANCE inst)
+{
+  WNDCLASSEXA classex;
+
+  memset (&classex, 0, sizeof (classex));
+  classex.cbSize = sizeof (classex);
+  classex.hInstance = inst;
+  classex.lpfnWndProc = (WNDPROC) msg_window_message_proc;
+  classex.lpszClassName = class_name;
+
+  return RegisterClassExA (&classex);
+}
+
+static void
+unreg_msg_window_class (ATOM class_id, const char *class_name, HINSTANCE inst)
+{
+  if (class_id != 0)
+    UnregisterClassA ((LPCSTR) MAKELPARAM (class_id, 0), inst);
+  else
+    UnregisterClassA (class_name, inst);
+}
+
+static gpointer
+ks_provider_msg_window_thread (gpointer dat)
+{
+  GstKsDeviceProvider *self;
+  MSG msg;
+  ATOM wnd_class;
+  BOOL message_status;
+  HINSTANCE inst;
+  HANDLE msg_window = NULL;
+  DWORD error;
+  HDEVNOTIFY devnotify = NULL;
+
+  g_return_val_if_fail (dat != NULL, NULL);
+
+  self = GST_KS_DEVICE_PROVIDER (dat);
+
+  GST_DEBUG_OBJECT (self, "Entering message window thread: %p",
+      g_thread_self ());
+
+  GST_OBJECT_LOCK (self);
+  wnd_class = self->message_window_class;
+  GST_OBJECT_UNLOCK (self);
+
+  inst = (HINSTANCE) GetModuleHandle (NULL);
+
+  msg_window = CreateWindowExA (0,
+      wnd_class != 0 ? (LPCSTR) MAKELPARAM (wnd_class, 0) : KS_MSG_WINDOW_CLASS,
+      "", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, inst, self);
+  error = GetLastError ();
+
+  if (msg_window == NULL) {
+    GST_ERROR_OBJECT (self, "Could not create a message window: %lu", error);
+    GST_OBJECT_LOCK (self);
+    unreg_msg_window_class (wnd_class, KS_MSG_WINDOW_CLASS, inst);
+    self->message_window_class = 0;
+    SetEvent (self->wakeup_event);
+    GST_OBJECT_UNLOCK (self);
+    return NULL;
+  }
+
+  GST_OBJECT_LOCK (self);
+  self->message_window = msg_window;
+
+  devnotify =
+      register_device_interface (self, GUID_DEVCLASS_WCEUSBS, msg_window);
+  if (devnotify == NULL) {
+    DestroyWindow (msg_window);
+    unreg_msg_window_class (wnd_class, KS_MSG_WINDOW_CLASS, inst);
+    self->message_window_class = 0;
+    self->message_window = NULL;
+    SetEvent (self->wakeup_event);
+    GST_OBJECT_UNLOCK (self);
+    return NULL;
+  }
+
+  self->device_notify_handle = devnotify;
+  SetEvent (self->wakeup_event);
+  GST_OBJECT_UNLOCK (self);
+
+  while ((message_status = GetMessage (&msg, NULL, 0, 0)) != 0) {
+    if (message_status < 0 || msg.message == WM_QUIT)
+      break;
+    TranslateMessage (&msg);
+    DispatchMessage (&msg);
+  }
+
+  GST_DEBUG_OBJECT (self, "Exiting internal window thread: %p",
+      g_thread_self ());
+
+  return NULL;
+}
+
+static gboolean
+gst_ks_device_provider_start (GstDeviceProvider * provider)
+{
+  ATOM wnd_class = 0;
+  HINSTANCE inst;
+  HANDLE wakeup_event;
+  HWND message_window;
+  DWORD error;
+  GList *devs;
+  GList *dev;
+  GstKsDeviceProvider *self = GST_KS_DEVICE_PROVIDER (provider);
+
+  GST_OBJECT_LOCK (self);
+  g_assert (self->message_window == NULL);
+  GST_OBJECT_UNLOCK (self);
+
+  /* We get notifications on *change*, so before we get to that,
+   * we need to obtain a complete list of devices, which we will
+   * watch for changes.
+   */
+  devs = gst_ks_device_provider_probe (provider);
+  for (dev = devs; dev; dev = dev->next) {
+    if (dev->data)
+      gst_device_provider_device_add (provider, (GstDevice *) dev->data);
+  }
+  g_list_free (devs);
+
+  inst = (HINSTANCE) GetModuleHandle (NULL);
+
+  wakeup_event = CreateEvent (NULL, TRUE, FALSE, NULL);
+  error = GetLastError ();
+  if (wakeup_event == NULL) {
+    GST_OBJECT_LOCK (self);
+    GST_ERROR_OBJECT (self, "Could not create a wakeup event: %lu", error);
+    GST_OBJECT_UNLOCK (self);
+    return FALSE;
+  }
+
+  wnd_class = reg_msg_window_class (KS_MSG_WINDOW_CLASS, inst);
+  error = GetLastError ();
+
+  if ((wnd_class == 0) && (error != ERROR_CLASS_ALREADY_EXISTS)) {
+    GST_ERROR_OBJECT (self,
+        "Could not register message window class: %lu", error);
+    CloseHandle (wakeup_event);
+    return FALSE;
+  }
+
+  GST_OBJECT_LOCK (self);
+  self->message_window_class = wnd_class;
+  self->wakeup_event = wakeup_event;
+
+  self->message_thread =
+      g_thread_new ("ks-device-provider-message-window-thread",
+      (GThreadFunc) ks_provider_msg_window_thread, self);
+  if (self->message_thread == NULL) {
+    GST_ERROR_OBJECT (self, "Could not create message window thread");
+    unreg_msg_window_class (wnd_class, KS_MSG_WINDOW_CLASS, inst);
+    self->message_window_class = 0;
+    CloseHandle (self->wakeup_event);
+    GST_OBJECT_UNLOCK (self);
+    return FALSE;
+  }
+  GST_OBJECT_UNLOCK (self);
+
+  if (WaitForSingleObject (wakeup_event, INFINITE) != WAIT_OBJECT_0) {
+    GST_ERROR_OBJECT (self,
+        "Failed to wait for the message thread to initialize");
+  }
+
+  GST_OBJECT_LOCK (self);
+  CloseHandle (self->wakeup_event);
+  self->wakeup_event = NULL;
+  message_window = self->message_window;
+  GST_OBJECT_UNLOCK (self);
+
+  if (message_window == NULL)
+    return FALSE;
+
+  return TRUE;
+}
+
+static void
+gst_ks_device_provider_stop (GstDeviceProvider * provider)
+{
+  HINSTANCE inst;
+  GThread *message_thread;
+  GstKsDeviceProvider *self = GST_KS_DEVICE_PROVIDER (provider);
+
+  GST_OBJECT_LOCK (self);
+
+  g_assert (self->message_window != NULL);
+
+  UnregisterDeviceNotification (self->device_notify_handle);
+  self->device_notify_handle = NULL;
+  PostMessage (self->message_window, WM_QUITTHREAD, 0, 0);
+  message_thread = self->message_thread;
+  GST_OBJECT_UNLOCK (self);
+
+  g_thread_join (message_thread);
+
+  GST_OBJECT_LOCK (self);
+  self->message_window = NULL;
+  self->message_thread = NULL;
+
+  inst = (HINSTANCE) GetModuleHandle (NULL);
+
+  unreg_msg_window_class (self->message_window_class, KS_MSG_WINDOW_CLASS,
+      inst);
+
+  self->message_window_class = 0;
+  GST_OBJECT_UNLOCK (self);
+}
+
+enum
+{
+  PROP_PATH = 1
+};
+
+G_DEFINE_TYPE (GstKsDevice, gst_ks_device, GST_TYPE_DEVICE);
+
+static void gst_ks_device_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+static void gst_ks_device_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_ks_device_finalize (GObject * object);
+static GstElement *gst_ks_device_create_element (GstDevice * device,
+    const gchar * name);
+static gboolean gst_ks_device_reconfigure_element (GstDevice * device,
+    GstElement * element);
+
+static void
+gst_ks_device_class_init (GstKsDeviceClass * klass)
+{
+  GstDeviceClass *dev_class = GST_DEVICE_CLASS (klass);
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  dev_class->create_element = gst_ks_device_create_element;
+  dev_class->reconfigure_element = gst_ks_device_reconfigure_element;
+
+  object_class->get_property = gst_ks_device_get_property;
+  object_class->set_property = gst_ks_device_set_property;
+  object_class->finalize = gst_ks_device_finalize;
+
+  g_object_class_install_property (object_class, PROP_PATH,
+      g_param_spec_string ("path", "System device path",
+          "The system path to the device", "",
+          G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+gst_ks_device_init (GstKsDevice * device)
+{
+}
+
+static void
+gst_ks_device_finalize (GObject * object)
+{
+  GstKsDevice *device = GST_KS_DEVICE (object);
+
+  g_free (device->path);
+
+  G_OBJECT_CLASS (gst_ks_device_parent_class)->finalize (object);
+}
+
+static GstElement *
+gst_ks_device_create_element (GstDevice * device, const gchar * name)
+{
+  GstKsDevice *ks_dev = GST_KS_DEVICE (device);
+  GstElement *elem;
+
+  elem = gst_element_factory_make (ks_dev->element, name);
+  g_object_set (elem, "device-path", ks_dev->path, NULL);
+
+  return elem;
+}
+
+static gboolean
+gst_ks_device_reconfigure_element (GstDevice * device, GstElement * element)
+{
+  GstKsDevice *ks_dev = GST_KS_DEVICE (device);
+
+  if (!strcmp (ks_dev->element, "ksvideosrc")) {
+    if (!GST_IS_KS_VIDEO_SRC (element))
+      return FALSE;
+/*
+  } else if (!strcmp (ks_dev->element, "ksaudiosrc")) {
+    if (!GST_IS_KS_AUDIO_SRC (element))
+      return FALSE;
+  } else if (!strcmp (ks_dev->element, "ksaudiosink")) {
+    if (!GST_IS_KS_AUDIO_SINK (element))
+      return FALSE;
+*/
+  } else {
+    g_assert_not_reached ();
+  }
+
+  g_object_set (element, "path", ks_dev->path, NULL);
+
+  return TRUE;
+}
+
+static GstDevice *
+gst_ks_device_new (guint device_index, const gchar * device_name,
+    GstCaps * caps, const gchar * device_path, GstKsDeviceType type)
+{
+  GstKsDevice *gstdev;
+  const gchar *element = NULL;
+  const gchar *klass = NULL;
+
+  g_return_val_if_fail (device_name, NULL);
+  g_return_val_if_fail (device_path, NULL);
+  g_return_val_if_fail (caps, NULL);
+
+
+  switch (type) {
+    case GST_KS_DEVICE_TYPE_VIDEO_SOURCE:
+      element = "ksvideosrc";
+      klass = "Video/Source";
+      break;
+    case GST_KS_DEVICE_TYPE_AUDIO_SOURCE:
+      element = "ksaudiosrc";
+      klass = "Audio/Source";
+      break;
+    case GST_KS_DEVICE_TYPE_AUDIO_SINK:
+      element = "ksaudiosink";
+      klass = "Audio/Sink";
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+  }
+
+
+  gstdev = g_object_new (GST_TYPE_KS_DEVICE,
+      "display-name", device_name, "caps", caps, "device-class", klass,
+      "path", device_path, NULL);
+
+  gstdev->type = type;
+  gstdev->device_index = device_index;
+  gstdev->path = g_strdup (device_path);
+  gstdev->element = element;
+
+  return GST_DEVICE (gstdev);
+}
+
+
+static void
+gst_ks_device_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GstKsDevice *device;
+
+  device = GST_KS_DEVICE_CAST (object);
+
+  switch (prop_id) {
+    case PROP_PATH:
+      g_value_set_string (value, device->path);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+
+static void
+gst_ks_device_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstKsDevice *device;
+
+  device = GST_KS_DEVICE_CAST (object);
+
+  switch (prop_id) {
+    case PROP_PATH:
+      device->path = g_value_dup_string (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
diff --git a/sys/winks/ksdeviceprovider.h b/sys/winks/ksdeviceprovider.h
new file mode 100644
index 0000000..24d14a0
--- /dev/null
+++ b/sys/winks/ksdeviceprovider.h
@@ -0,0 +1,101 @@
+/* GStreamer
+ * Copyright (C) 2015 Руслан Ижбулатов <lrn1986@gmail.com>
+ *
+ * ksdeviceprovider.h: Kernel Streaming device probing and monitoring
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GST_KS_DEVICE_PROVIDER_H__
+#define __GST_KS_DEVICE_PROVIDER_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <windows.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GstKsDeviceProvider GstKsDeviceProvider;
+typedef struct _GstKsDeviceProviderPrivate GstKsDeviceProviderPrivate;
+typedef struct _GstKsDeviceProviderClass GstKsDeviceProviderClass;
+
+#define GST_TYPE_KS_DEVICE_PROVIDER                 (gst_ks_device_provider_get_type())
+#define GST_IS_KS_DEVICE_PROVIDER(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_KS_DEVICE_PROVIDER))
+#define GST_IS_KS_DEVICE_PROVIDER_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_KS_DEVICE_PROVIDER))
+#define GST_KS_DEVICE_PROVIDER_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_KS_DEVICE_PROVIDER, GstKsDeviceProviderClass))
+#define GST_KS_DEVICE_PROVIDER(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_KS_DEVICE_PROVIDER, GstKsDeviceProvider))
+#define GST_KS_DEVICE_PROVIDER_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEVICE_PROVIDER, GstKsDeviceProviderClass))
+#define GST_KS_DEVICE_PROVIDER_CAST(obj)            ((GstKsDeviceProvider *)(obj))
+
+struct _GstKsDeviceProvider {
+  GstDeviceProvider parent;
+
+  HANDLE            message_window;
+  ATOM              message_window_class;
+  HDEVNOTIFY        device_notify_handle;
+  HANDLE            wakeup_event;
+  GThread          *message_thread;
+};
+
+typedef enum {
+  GST_KS_DEVICE_TYPE_INVALID = 0,
+  GST_KS_DEVICE_TYPE_VIDEO_SOURCE,
+  GST_KS_DEVICE_TYPE_VIDEO_SINK,
+  GST_KS_DEVICE_TYPE_AUDIO_SOURCE,
+  GST_KS_DEVICE_TYPE_AUDIO_SINK
+} GstKsDeviceType;
+
+struct _GstKsDeviceProviderClass {
+  GstDeviceProviderClass    parent_class;
+};
+
+GType gst_ks_device_provider_get_type (void);
+
+
+typedef struct _GstKsDevice GstKsDevice;
+typedef struct _GstKsDevicePrivate GstKsDevicePrivate;
+typedef struct _GstKsDeviceClass GstKsDeviceClass;
+
+#define GST_TYPE_KS_DEVICE                 (gst_ks_device_get_type())
+#define GST_IS_KS_DEVICE(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_KS_DEVICE))
+#define GST_IS_KS_DEVICE_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_KS_DEVICE))
+#define GST_KS_DEVICE_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_KS_DEVICE, GstKsDeviceClass))
+#define GST_KS_DEVICE(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_KS_DEVICE, GstKsDevice))
+#define GST_KS_DEVICE_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEVICE, GstKsDeviceClass))
+#define GST_KS_DEVICE_CAST(obj)            ((GstKsDevice *)(obj))
+
+struct _GstKsDevice {
+  GstDevice         parent;
+
+  GstKsDeviceType   type;
+  guint             device_index;
+  gchar            *path;
+  const gchar      *element;
+};
+
+struct _GstKsDeviceClass {
+  GstDeviceClass    parent_class;
+};
+
+GType gst_ks_device_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_KS_DEVICE_PROVIDER_H__ */
diff --git a/sys/winks/kshelpers.c b/sys/winks/kshelpers.c
index b6621de..bbb9b06 100644
--- a/sys/winks/kshelpers.c
+++ b/sys/winks/kshelpers.c
@@ -40,13 +40,13 @@
 }
 
 GList *
-ks_enumerate_devices (const GUID * category)
+ks_enumerate_devices (const GUID * devtype, const GUID * direction_category)
 {
   GList *result = NULL;
   HDEVINFO devinfo;
   gint i;
 
-  devinfo = SetupDiGetClassDevsW (category, NULL, NULL,
+  devinfo = SetupDiGetClassDevsW (devtype, NULL, NULL,
       DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
   if (!ks_is_valid_handle (devinfo))
     return NULL;                /* no devices */
@@ -54,6 +54,7 @@
   for (i = 0;; i++) {
     BOOL success;
     SP_DEVICE_INTERFACE_DATA if_data = { 0, };
+    SP_DEVICE_INTERFACE_DATA if_alias_data = { 0, };
     SP_DEVICE_INTERFACE_DETAIL_DATA_W *if_detail_data;
     DWORD if_detail_data_size;
     SP_DEVINFO_DATA devinfo_data = { 0, };
@@ -61,11 +62,17 @@
 
     if_data.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
 
-    success = SetupDiEnumDeviceInterfaces (devinfo, NULL, category, i,
-        &if_data);
+    success = SetupDiEnumDeviceInterfaces (devinfo, NULL, devtype, i, &if_data);
     if (!success)               /* all devices enumerated? */
       break;
 
+    if_alias_data.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
+    success =
+        SetupDiGetDeviceInterfaceAlias (devinfo, &if_data, direction_category,
+        &if_alias_data);
+    if (!success)
+      continue;
+
     if_detail_data_size = (MAX_PATH - 1) * sizeof (gunichar2);
     if_detail_data = g_malloc0 (if_detail_data_size);
     if_detail_data->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA_W);
diff --git a/sys/winks/kshelpers.h b/sys/winks/kshelpers.h
index 6e5871c..5181bfc 100644
--- a/sys/winks/kshelpers.h
+++ b/sys/winks/kshelpers.h
@@ -37,7 +37,7 @@
 
 gboolean ks_is_valid_handle (HANDLE h);
 
-GList * ks_enumerate_devices (const GUID * category);
+GList * ks_enumerate_devices (const GUID * devtype, const GUID * direction_category);
 void ks_device_entry_free (KsDeviceEntry * entry);
 void ks_device_list_free (GList * devices);
 
diff --git a/sys/winks/ksvideohelpers.c b/sys/winks/ksvideohelpers.c
index c4f9620..9d70461 100644
--- a/sys/winks/ksvideohelpers.c
+++ b/sys/winks/ksvideohelpers.c
@@ -182,7 +182,7 @@
   if (!structure) {
     GST_DEBUG ("Unknown DirectShow Video GUID "
         "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-        subtype_guid.Data1, subtype_guid.Data2, subtype_guid.Data3,
+        (guint) subtype_guid.Data1, subtype_guid.Data2, subtype_guid.Data3,
         subtype_guid.Data4[0], subtype_guid.Data4[1], subtype_guid.Data4[2],
         subtype_guid.Data4[3], subtype_guid.Data4[4], subtype_guid.Data4[5],
         subtype_guid.Data4[6], subtype_guid.Data4[7]);
@@ -446,7 +446,8 @@
         guint i;
 
         for (i = 0; i < items->Count; i++) {
-          if (IsEqualGUID (&range->MajorFormat, &KSDATAFORMAT_TYPE_VIDEO)) {
+          if (IsEqualGUID (&range->MajorFormat, &MEDIATYPE_Video)
+              || IsEqualGUID (&range->MajorFormat, &MEDIATYPE_Interleaved)) {
             KsVideoMediaType *entry;
             gpointer src_vscc, src_format;
             GstStructure *media_structure;
@@ -485,16 +486,22 @@
               entry->sample_size =
                   vr->VideoInfoHeader.hdr.bmiHeader.biSizeImage;
             } else if (IsEqualGUID (&range->Specifier, &FORMAT_MPEG2Video)) {
-              /* Untested and probably wrong... */
               KS_DATARANGE_MPEG2_VIDEO *vr =
                   (KS_DATARANGE_MPEG2_VIDEO *) entry->range;
-
               src_vscc = &vr->ConfigCaps;
               src_format = &vr->VideoInfoHeader;
 
               entry->format_size = sizeof (vr->VideoInfoHeader);
               entry->sample_size =
                   vr->VideoInfoHeader.hdr.bmiHeader.biSizeImage;
+            } else if (IsEqualGUID (&range->Specifier, &FORMAT_DvInfo)) {
+              KS_DATARANGE_DVVIDEO *vr = (KS_DATARANGE_DVVIDEO *) entry->range;
+
+              src_vscc = NULL;
+              src_format = &vr->DVVideoInfo;
+
+              entry->format_size = sizeof (vr->DVVideoInfo);
+              entry->sample_size = vr->DataRange.SampleSize;
             } else {
               gchar *guid_str;
 
@@ -510,19 +517,26 @@
             if (entry != NULL) {
               g_assert (entry->sample_size != 0);
 
-              memcpy ((gpointer) & entry->vscc, src_vscc, sizeof (entry->vscc));
+              if (src_vscc != NULL) {
+                memcpy ((gpointer) & entry->vscc, src_vscc,
+                    sizeof (entry->vscc));
+              }
 
               entry->format = g_malloc (entry->format_size);
               memcpy (entry->format, src_format, entry->format_size);
 
               media_structure =
                   ks_video_format_to_structure (range->SubFormat,
-                  range->MajorFormat);
+                  range->Specifier);
 
               if (media_structure == NULL) {
                 g_warning ("ks_video_format_to_structure returned NULL");
                 ks_video_media_type_free (entry);
                 entry = NULL;
+              } else if (src_vscc == NULL) {
+                entry->translated_caps = gst_caps_new_empty ();
+                gst_caps_append_structure (entry->translated_caps,
+                    media_structure);
               } else if (ks_video_append_video_stream_cfg_fields
                   (media_structure, &entry->vscc)) {
                 entry->translated_caps = gst_caps_new_empty ();
diff --git a/sys/winks/ksvideohelpers.h b/sys/winks/ksvideohelpers.h
index f4fb1b6..3aa0c38 100644
--- a/sys/winks/ksvideohelpers.h
+++ b/sys/winks/ksvideohelpers.h
@@ -51,6 +51,22 @@
   GstCaps * translated_caps;
 };
 
+typedef struct DVINFO {
+  DWORD dwDVAAuxSrc;
+  DWORD dwDVAAuxCtl;
+  DWORD dwDVAAuxSrc1;
+  DWORD dwDVAAuxCtl1;
+  DWORD dwDVVAuxSrc;
+  DWORD dwDVVAuxCtl;
+  DWORD dwDVReserved[2];
+} DVINFO;
+
+typedef struct KS_DATARANGE_DVVIDEO {
+  KSDATARANGE DataRange;
+  DVINFO DVVideoInfo;
+} KS_DATARANGE_DVVIDEO,*PKS_DATARANGE_DVVIDEO;
+
+
 GList * ks_video_device_list_sort_cameras_first (GList * devices);
 
 KsVideoMediaType * ks_video_media_type_dup (KsVideoMediaType * media_type);
diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am
index 4cf2dac..04e5d5d 100644
--- a/tests/check/Makefile.am
+++ b/tests/check/Makefile.am
@@ -9,14 +9,14 @@
 	GST_REGISTRY_1_0=$(CHECK_REGISTRY)
 
 # GST_PLUGINS_XYZ_DIR is only set in an uninstalled setup
-TESTS_ENVIRONMENT = \
+AM_TESTS_ENVIRONMENT = \
 	$(REGISTRY_ENVIRONMENT)                                 \
 	GST_PLUGIN_SYSTEM_PATH_1_0=				\
 	GST_PLUGIN_PATH_1_0=$(top_builddir)/gst:$(top_builddir)/sys:$(top_builddir)/ext:$(GST_PLUGINS_LIBAV_DIR):$(GST_PLUGINS_UGLY_DIR):$(GST_PLUGINS_GOOD_DIR):$(GST_PLUGINS_BASE_DIR):$(GST_PLUGINS_DIR) \
 	GST_PLUGIN_LOADING_WHITELIST="gstreamer@$(GST_PLUGINS_DIR):gst-plugins-base@$(GSTPB_PLUGINS_DIR):gst-plugins-good:gst-plugins-ugly:gst-libav:gst-plugins-bad@$(top_builddir)" \
 	GST_STATE_IGNORE_ELEMENTS="apexsink avdtpsrc camerabin dc1394src \
 	    dccpclientsrc dccpclientsink dccpserversrc dccpserversink decklinksrc \
-	    decklinksink dvbsrc dvbbasebin dfbvideosink festival fluidsynth gsettingsvideosrc \
+	    decklinksink dtlssrtpdec dtlssrtpenc dvbsrc dvbbasebin dfbvideosink festival fluidsynth gsettingsvideosrc \
 	    gsettingsvideosink gsettingsaudiosrc gsettingsaudiosink linsyssdisrc linsyssdisink nassink \
 	    rsndvdbin sdlaudiosink sdlvideosink vcdsrc rfbsrc vdpauyuvvideo vdpauvideoyuv \
 	    vdpaumpegdec vdpaumpeg4dec vdpauh264dec vdpauvideopostprocess vdpausink neonhttpsrc"
@@ -283,8 +283,9 @@
 TESTS = $(check_PROGRAMS)
 
 AM_CFLAGS = $(GST_CFLAGS) $(GST_CHECK_CFLAGS) $(GST_OPTION_CFLAGS) \
-		-DGST_TEST_FILES_PATH="\"$(TEST_FILES_DIRECTORY)\"" \
-		-UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS
+	-DGST_CHECK_TEST_ENVIRONMENT_BEACON="\"GST_PLUGIN_LOADING_WHITELIST\"" \
+	-DGST_TEST_FILES_PATH="\"$(TEST_FILES_DIRECTORY)\"" \
+	-UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS
 LDADD = $(GST_CHECK_LIBS)
 
 elements_audiomixer_LDADD = $(GST_BASE_LIBS) -lgstbase-@GST_API_VERSION@ $(LDADD)
@@ -516,8 +517,12 @@
 	-DGST_USE_UNSTABLE_API \
 	$(GST_BASE_CFLAGS) $(GST_CFLAGS) $(AM_CFLAGS)
 
-elements_compositor_LDADD = $(LDADD)  $(GST_BASE_LIBS)
-elements_compositor_CFLAGS = $(GST_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS)
+elements_compositor_LDADD = \
+	$(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_API_VERSION) \
+	$(GST_BASE_LIBS) $(LDADD)
+elements_compositor_CFLAGS = \
+	$(GST_PLUGINS_BASE_CFLAGS) \
+	$(GST_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS)
 
 elements_hlsdemux_m3u8_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS) -I$(top_srcdir)/ext/hls
 elements_hlsdemux_m3u8_LDADD = $(GST_BASE_LIBS) $(LDADD)
diff --git a/tests/check/Makefile.in b/tests/check/Makefile.in
index 730acfb..b3b9728 100644
--- a/tests/check/Makefile.in
+++ b/tests/check/Makefile.in
@@ -271,8 +271,8 @@
 elements_compositor_SOURCES = elements/compositor.c
 elements_compositor_OBJECTS =  \
 	elements/elements_compositor-compositor.$(OBJEXT)
-elements_compositor_DEPENDENCIES = $(am__DEPENDENCIES_2) \
-	$(am__DEPENDENCIES_1)
+elements_compositor_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
 elements_compositor_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
 	$(elements_compositor_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
@@ -1494,14 +1494,14 @@
 
 
 # GST_PLUGINS_XYZ_DIR is only set in an uninstalled setup
-TESTS_ENVIRONMENT = \
+AM_TESTS_ENVIRONMENT = \
 	$(REGISTRY_ENVIRONMENT)                                 \
 	GST_PLUGIN_SYSTEM_PATH_1_0=				\
 	GST_PLUGIN_PATH_1_0=$(top_builddir)/gst:$(top_builddir)/sys:$(top_builddir)/ext:$(GST_PLUGINS_LIBAV_DIR):$(GST_PLUGINS_UGLY_DIR):$(GST_PLUGINS_GOOD_DIR):$(GST_PLUGINS_BASE_DIR):$(GST_PLUGINS_DIR) \
 	GST_PLUGIN_LOADING_WHITELIST="gstreamer@$(GST_PLUGINS_DIR):gst-plugins-base@$(GSTPB_PLUGINS_DIR):gst-plugins-good:gst-plugins-ugly:gst-libav:gst-plugins-bad@$(top_builddir)" \
 	GST_STATE_IGNORE_ELEMENTS="apexsink avdtpsrc camerabin dc1394src \
 	    dccpclientsrc dccpclientsink dccpserversrc dccpserversink decklinksrc \
-	    decklinksink dvbsrc dvbbasebin dfbvideosink festival fluidsynth gsettingsvideosrc \
+	    decklinksink dtlssrtpdec dtlssrtpenc dvbsrc dvbbasebin dfbvideosink festival fluidsynth gsettingsvideosrc \
 	    gsettingsvideosink gsettingsaudiosrc gsettingsaudiosink linsyssdisrc linsyssdisink nassink \
 	    rsndvdbin sdlaudiosink sdlvideosink vcdsrc rfbsrc vdpauyuvvideo vdpauvideoyuv \
 	    vdpaumpegdec vdpaumpeg4dec vdpauh264dec vdpauvideopostprocess vdpausink neonhttpsrc"
@@ -1592,8 +1592,9 @@
 noinst_HEADERS = elements/mxfdemux.h
 TESTS = $(check_PROGRAMS)
 AM_CFLAGS = $(GST_CFLAGS) $(GST_CHECK_CFLAGS) $(GST_OPTION_CFLAGS) \
-		-DGST_TEST_FILES_PATH="\"$(TEST_FILES_DIRECTORY)\"" \
-		-UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS
+	-DGST_CHECK_TEST_ENVIRONMENT_BEACON="\"GST_PLUGIN_LOADING_WHITELIST\"" \
+	-DGST_TEST_FILES_PATH="\"$(TEST_FILES_DIRECTORY)\"" \
+	-UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS
 
 LDADD = $(GST_CHECK_LIBS)
 elements_audiomixer_LDADD = $(GST_BASE_LIBS) -lgstbase-@GST_API_VERSION@ $(LDADD)
@@ -1808,8 +1809,14 @@
 	-DGST_USE_UNSTABLE_API \
 	$(GST_BASE_CFLAGS) $(GST_CFLAGS) $(AM_CFLAGS)
 
-elements_compositor_LDADD = $(LDADD)  $(GST_BASE_LIBS)
-elements_compositor_CFLAGS = $(GST_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS)
+elements_compositor_LDADD = \
+	$(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_API_VERSION) \
+	$(GST_BASE_LIBS) $(LDADD)
+
+elements_compositor_CFLAGS = \
+	$(GST_PLUGINS_BASE_CFLAGS) \
+	$(GST_BASE_CFLAGS) $(CFLAGS) $(AM_CFLAGS)
+
 elements_hlsdemux_m3u8_CFLAGS = $(GST_BASE_CFLAGS) $(AM_CFLAGS) -I$(top_srcdir)/ext/hls
 elements_hlsdemux_m3u8_LDADD = $(GST_BASE_LIBS) $(LDADD)
 elements_hlsdemux_m3u8_SOURCES = elements/hlsdemux_m3u8.c
@@ -3793,38 +3800,38 @@
 # run any given test by running make test.check
 # if the test fails, run it again at at least debug level 2
 %.check: %
-	@$(TESTS_ENVIRONMENT)					\
+	@$(AM_TESTS_ENVIRONMENT)					\
 	CK_DEFAULT_TIMEOUT=20					\
 	$* ||							\
-	$(TESTS_ENVIRONMENT)					\
+	$(AM_TESTS_ENVIRONMENT)					\
 	GST_DEBUG=$$GST_DEBUG,*:2				\
 	CK_DEFAULT_TIMEOUT=20					\
 	$*
 
 # just like 'check', but don't run it again if it fails (useful for debugging)
 %.check-norepeat: %
-	@$(TESTS_ENVIRONMENT)					\
+	@$(AM_TESTS_ENVIRONMENT)					\
 	CK_DEFAULT_TIMEOUT=20					\
 	$*
 
 # run any given test in a loop
 %.torture: %
 	@for i in `seq 1 $(LOOPS)`; do				\
-	$(TESTS_ENVIRONMENT)					\
+	$(AM_TESTS_ENVIRONMENT)					\
 	CK_DEFAULT_TIMEOUT=20					\
 	$*; done
 
 # run any given test in an infinite loop
 %.forever: %
 	@while true; do						\
-	$(TESTS_ENVIRONMENT)					\
+	$(AM_TESTS_ENVIRONMENT)					\
 	CK_DEFAULT_TIMEOUT=20					\
 	$* || break; done
 
 # valgrind any given test by running make test.valgrind
 %.valgrind: %
 	@valgrind_log=$(subst /,-,$*-valgrind.log);		\
-	$(TESTS_ENVIRONMENT)					\
+	$(AM_TESTS_ENVIRONMENT)					\
 	CK_DEFAULT_TIMEOUT=360					\
 	G_SLICE=always-malloc					\
 	$(LIBTOOL) --mode=execute				\
@@ -3842,7 +3849,7 @@
 
 # valgrind any given test and generate suppressions for it
 %.valgrind.gen-suppressions: %
-	@$(TESTS_ENVIRONMENT)					\
+	@$(AM_TESTS_ENVIRONMENT)					\
 	CK_DEFAULT_TIMEOUT=360					\
 	G_SLICE=always-malloc					\
 	$(LIBTOOL) --mode=execute				\
@@ -3872,7 +3879,7 @@
 
 # gdb any given test by running make test.gdb
 %.gdb: %
-	@$(TESTS_ENVIRONMENT)					\
+	@$(AM_TESTS_ENVIRONMENT)					\
 	CK_FORK=no						\
 	$(LIBTOOL) --mode=execute				\
 	gdb $*
@@ -3976,7 +3983,7 @@
 	fi
 inspect:
 	@echo "Inspecting features ..."
-	@for e in `$(TESTS_ENVIRONMENT) $(GST_INSPECT) | head -n -2 	\
+	@for e in `$(AM_TESTS_ENVIRONMENT) $(GST_INSPECT) | head -n -2 	\
 	  | cut -d: -f2`;						\
 	  do echo Inspecting $$e;					\
 	     $(GST_INSPECT) $$e > /dev/null 2>&1; done
diff --git a/tests/check/elements/audiomixer.c b/tests/check/elements/audiomixer.c
index d758e75..ddfdbe1 100644
--- a/tests/check/elements/audiomixer.c
+++ b/tests/check/elements/audiomixer.c
@@ -89,7 +89,8 @@
   filter_caps = gst_caps_new_simple ("audio/x-raw",
       "format", G_TYPE_STRING, GST_AUDIO_NE (F32),
       "layout", G_TYPE_STRING, "interleaved",
-      "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 1, NULL);
+      "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 1,
+      "channel-mask", GST_TYPE_BITMASK, (guint64) 0x04, NULL);
 
   /* build pipeline */
   pipeline = gst_pipeline_new ("pipeline");
diff --git a/tests/check/elements/camerabin.c b/tests/check/elements/camerabin.c
index 0061606..3458cac 100644
--- a/tests/check/elements/camerabin.c
+++ b/tests/check/elements/camerabin.c
@@ -32,6 +32,8 @@
 #include <gst/video/video.h>
 #include <gst/check/gstcheck.h>
 #include <gst/basecamerabinsrc/gstbasecamerasrc.h>
+#include <gst/base/gstpushsrc.h>
+#include <gst/interfaces/photography.h>
 #include <gst/pbutils/encoding-profile.h>
 
 #define IMAGE_FILENAME "image"
@@ -42,6 +44,11 @@
 #define VIDEO_PAD_SUPPORTED_CAPS "video/x-raw, format=RGB, width=600, height=480"
 #define IMAGE_PAD_SUPPORTED_CAPS "video/x-raw, format=RGB, width=800, height=600"
 
+static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS ("video/x-raw, format=RGB"));
+
 static GstStaticPadTemplate vfsrc_template =
 GST_STATIC_PAD_TEMPLATE (GST_BASE_CAMERA_SRC_VIEWFINDER_PAD_NAME,
     GST_PAD_SRC,
@@ -67,10 +74,6 @@
   (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TEST_CAMERA_SRC,GstTestCameraSrc))
 #define GST_TEST_CAMERA_SRC_CLASS(klass) \
   (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TEST_CAMERA_SRC,GstTestCameraSrcClass))
-#define GST_IS_TEST_REVERSE_NEGOTIATION_SINK(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TEST_CAMERA_SRC))
-#define GST_IS_TEST_REVERSE_NEGOTIATION_SINK_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TEST_CAMERA_SRC))
 #define GST_TEST_CAMERA_SRC_CAST(obj) ((GstTestCameraSrc *)obj)
 
 typedef struct _GstTestCameraSrc GstTestCameraSrc;
@@ -93,7 +96,6 @@
 
 GType gst_test_camera_src_get_type (void);
 
-#define gst_test_camera_src_parent_class parent_class
 G_DEFINE_TYPE (GstTestCameraSrc, gst_test_camera_src, GST_TYPE_BASE_CAMERA_SRC);
 
 static gboolean
@@ -201,8 +203,244 @@
 
 /* end of custom test camera src element */
 
+/* custom video source element that implements GstPhotography iface */
+
+#define GST_TYPE_TEST_VIDEO_SRC \
+  (gst_test_video_src_get_type())
+#define GST_TEST_VIDEO_SRC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TEST_VIDEO_SRC,GstTestVideoSrc))
+#define GST_TEST_VIDEO_SRC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TEST_VIDEO_SRC,GstTestVideoSrcClass))
+#define GST_TEST_VIDEO_SRC_CAST(obj) ((GstTestVideoSrc *)obj)
+
+typedef struct _GstTestVideoSrc GstTestVideoSrc;
+typedef struct _GstTestVideoSrcClass GstTestVideoSrcClass;
+struct _GstTestVideoSrc
+{
+  GstPushSrc element;
+
+  gint width, height;
+  GstCaps *caps;
+
+  /* if TRUE, this element will only output resolutions with       *
+   * same width and height (square frames). This allows us testing *
+   * extra cropping feature with GstPhotography interface captures */
+  gboolean enable_resolution_restriction;
+};
+
+struct _GstTestVideoSrcClass
+{
+  GstPushSrcClass parent_class;
+};
+
+GType gst_test_video_src_get_type (void);
+
+enum
+{
+  PROP_0,
+  PROP_WB_MODE,
+  PROP_COLOR_TONE,
+  PROP_SCENE_MODE,
+  PROP_FLASH_MODE,
+  PROP_FLICKER_MODE,
+  PROP_FOCUS_MODE,
+  PROP_CAPABILITIES,
+  PROP_EV_COMP,
+  PROP_ISO_SPEED,
+  PROP_APERTURE,
+  PROP_EXPOSURE_TIME,
+  PROP_IMAGE_PREVIEW_SUPPORTED_CAPS,
+  PROP_IMAGE_CAPTURE_SUPPORTED_CAPS,
+  PROP_ZOOM,
+  PROP_COLOR_TEMPERATURE,
+  PROP_WHITE_POINT,
+  PROP_ANALOG_GAIN,
+  PROP_LENS_FOCUS,
+  PROP_MIN_EXPOSURE_TIME,
+  PROP_MAX_EXPORURE_TIME,
+  PROP_NOISE_REDUCTION
+};
+
+static gboolean
+gst_test_video_src_prepare_for_capture (GstPhotography * photo,
+    GstPhotographyCapturePrepared func, GstCaps * capture_caps,
+    gpointer user_data)
+{
+  GstCaps *caps;
+  GstTestVideoSrc *testvideosrc = GST_TEST_VIDEO_SRC (photo);
+
+  if (testvideosrc->enable_resolution_restriction) {
+    GstStructure *str = gst_caps_get_structure (capture_caps, 0);
+    gint width, height;
+
+    gst_structure_get_int (str, "width", &width);
+    gst_structure_get_int (str, "height", &height);
+
+    width = height = MAX (width, height);
+    str = gst_structure_copy (str);
+    gst_structure_set (str, "width", G_TYPE_INT, width, "height", G_TYPE_INT,
+        height, NULL);
+    caps = gst_caps_new_full (str, NULL);
+    caps = gst_caps_fixate (caps);
+    fail_unless (testvideosrc->caps == NULL);
+    testvideosrc->caps = gst_caps_ref (caps);
+  } else {
+    caps = gst_caps_ref (capture_caps);
+  }
+
+  func (user_data, caps);
+  gst_caps_unref (caps);
+  return TRUE;
+}
+
+static void
+gst_test_video_src_photography_init (gpointer g_iface, gpointer iface_data)
+{
+  GstPhotographyInterface *iface = g_iface;
+
+  iface->prepare_for_capture = gst_test_video_src_prepare_for_capture;
+}
+
+G_DEFINE_TYPE_WITH_CODE (GstTestVideoSrc, gst_test_video_src, GST_TYPE_PUSH_SRC,
+    G_IMPLEMENT_INTERFACE (GST_TYPE_PHOTOGRAPHY,
+        gst_test_video_src_photography_init));
+
+static void
+gst_test_video_src_get_property (GObject * object,
+    guint prop_id, GValue * value, GParamSpec * pspec)
+{
+  /* don't care */
+}
+
+static void
+gst_test_video_src_set_property (GObject * object,
+    guint prop_id, const GValue * value, GParamSpec * pspec)
+{
+  /* don't care */
+}
+
+static gboolean
+gst_test_video_src_set_caps (GstBaseSrc * src, GstCaps * caps)
+{
+  GstTestVideoSrc *self = GST_TEST_VIDEO_SRC (src);
+  GstStructure *structure = gst_caps_get_structure (caps, 0);
+
+
+  fail_unless (gst_structure_get_int (structure, "width", &self->width));
+  fail_unless (gst_structure_get_int (structure, "height", &self->height));
+
+  return TRUE;
+}
+
+static GstFlowReturn
+gst_test_video_src_alloc (GstPushSrc * src, GstBuffer ** buf)
+{
+  GstTestVideoSrc *self = GST_TEST_VIDEO_SRC (src);
+  guint8 *data;
+  gsize data_size;
+
+  if (self->caps) {
+    gst_base_src_set_caps (GST_BASE_SRC (self), self->caps);
+    gst_caps_unref (self->caps);
+    self->caps = NULL;
+  }
+
+  data_size = self->width * self->height * 3;   /* RGB size */
+  data = g_malloc (data_size);
+  *buf = gst_buffer_new_wrapped (data, data_size);
+
+  return GST_FLOW_OK;
+}
+
+static GstFlowReturn
+gst_test_video_src_fill (GstPushSrc * src, GstBuffer * buf)
+{
+  /* NOP */
+  return GST_FLOW_OK;
+}
+
+static void
+gst_test_video_src_class_init (GstTestVideoSrcClass * klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
+  GstBaseSrcClass *gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
+  GstPushSrcClass *gstpushsrc_class = GST_PUSH_SRC_CLASS (klass);
+
+  gst_element_class_set_static_metadata (gstelement_class,
+      "Test Camera Video Src",
+      "Video/Src",
+      "Test camera video src", "Thiago Santos <thiagoss@osg.samsung.com>");
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&src_template));
+
+  gobject_class->get_property = gst_test_video_src_get_property;
+  gobject_class->set_property = gst_test_video_src_set_property;
+
+  gstbasesrc_class->set_caps = gst_test_video_src_set_caps;
+  gstpushsrc_class->alloc = gst_test_video_src_alloc;
+  gstpushsrc_class->fill = gst_test_video_src_fill;
+
+  /* photography interface properties */
+  g_object_class_override_property (gobject_class, PROP_WB_MODE,
+      GST_PHOTOGRAPHY_PROP_WB_MODE);
+  g_object_class_override_property (gobject_class, PROP_COLOR_TONE,
+      GST_PHOTOGRAPHY_PROP_COLOR_TONE);
+  g_object_class_override_property (gobject_class, PROP_SCENE_MODE,
+      GST_PHOTOGRAPHY_PROP_SCENE_MODE);
+  g_object_class_override_property (gobject_class, PROP_FLASH_MODE,
+      GST_PHOTOGRAPHY_PROP_FLASH_MODE);
+  g_object_class_override_property (gobject_class, PROP_FLICKER_MODE,
+      GST_PHOTOGRAPHY_PROP_FLICKER_MODE);
+  g_object_class_override_property (gobject_class, PROP_FOCUS_MODE,
+      GST_PHOTOGRAPHY_PROP_FOCUS_MODE);
+  g_object_class_override_property (gobject_class, PROP_CAPABILITIES,
+      GST_PHOTOGRAPHY_PROP_CAPABILITIES);
+  g_object_class_override_property (gobject_class, PROP_EV_COMP,
+      GST_PHOTOGRAPHY_PROP_EV_COMP);
+  g_object_class_override_property (gobject_class, PROP_ISO_SPEED,
+      GST_PHOTOGRAPHY_PROP_ISO_SPEED);
+  g_object_class_override_property (gobject_class, PROP_APERTURE,
+      GST_PHOTOGRAPHY_PROP_APERTURE);
+  g_object_class_override_property (gobject_class, PROP_EXPOSURE_TIME,
+      GST_PHOTOGRAPHY_PROP_EXPOSURE_TIME);
+  g_object_class_override_property (gobject_class,
+      PROP_IMAGE_PREVIEW_SUPPORTED_CAPS,
+      GST_PHOTOGRAPHY_PROP_IMAGE_PREVIEW_SUPPORTED_CAPS);
+  g_object_class_override_property (gobject_class,
+      PROP_IMAGE_CAPTURE_SUPPORTED_CAPS,
+      GST_PHOTOGRAPHY_PROP_IMAGE_CAPTURE_SUPPORTED_CAPS);
+  g_object_class_override_property (gobject_class, PROP_ZOOM,
+      GST_PHOTOGRAPHY_PROP_ZOOM);
+  g_object_class_override_property (gobject_class, PROP_COLOR_TEMPERATURE,
+      GST_PHOTOGRAPHY_PROP_COLOR_TEMPERATURE);
+  g_object_class_override_property (gobject_class, PROP_WHITE_POINT,
+      GST_PHOTOGRAPHY_PROP_WHITE_POINT);
+  g_object_class_override_property (gobject_class, PROP_ANALOG_GAIN,
+      GST_PHOTOGRAPHY_PROP_ANALOG_GAIN);
+  g_object_class_override_property (gobject_class, PROP_LENS_FOCUS,
+      GST_PHOTOGRAPHY_PROP_LENS_FOCUS);
+  g_object_class_override_property (gobject_class, PROP_MIN_EXPOSURE_TIME,
+      GST_PHOTOGRAPHY_PROP_MIN_EXPOSURE_TIME);
+  g_object_class_override_property (gobject_class, PROP_MAX_EXPORURE_TIME,
+      GST_PHOTOGRAPHY_PROP_MAX_EXPOSURE_TIME);
+  g_object_class_override_property (gobject_class, PROP_NOISE_REDUCTION,
+      GST_PHOTOGRAPHY_PROP_NOISE_REDUCTION);
+}
+
+static void
+gst_test_video_src_init (GstTestVideoSrc * self)
+{
+  gst_base_src_set_format (GST_BASE_SRC (self), GST_FORMAT_TIME);
+}
+
+/* end of custom test camera src element */
+/* end of custom video source element that implements GstPhotography iface */
+
 
 static GstElement *camera;
+static GstElement *testsrc;
 static guint bus_source;
 static GMainLoop *main_loop;
 static gint capture_count = 0;
@@ -399,9 +637,30 @@
 }
 
 static void
-setup_wrappercamerabinsrc_videotestsrc (void)
+setup_camerabin_common (void)
 {
   GstBus *bus;
+  test_id = g_random_int ();
+  bus_source = 0;
+
+  main_loop = g_main_loop_new (NULL, TRUE);
+
+  camera = gst_check_setup_element ("camerabin");
+  fail_unless (camera != NULL, "failed to create camerabin element");
+
+  bus = gst_pipeline_get_bus (GST_PIPELINE (camera));
+  bus_source = gst_bus_add_watch (bus, (GstBusFunc) capture_bus_cb, main_loop);
+  gst_object_unref (bus);
+
+  tags_found = NULL;
+  capture_count = 0;
+  image_filename = make_test_file_name (IMAGE_FILENAME, -1);
+  video_filename = make_test_file_name (VIDEO_FILENAME, -1);
+}
+
+static void
+setup_wrappercamerabinsrc_videotestsrc (void)
+{
   GstElement *vfbin;
   GstElement *fakevideosink;
   GstElement *src;
@@ -410,13 +669,8 @@
 
   GST_INFO ("init");
 
-  test_id = g_random_int ();
-  bus_source = 0;
+  setup_camerabin_common ();
 
-  main_loop = g_main_loop_new (NULL, TRUE);
-
-  camera = gst_check_setup_element ("camerabin");
-  fail_unless (camera != NULL, "failed to create camerabin element");
   fakevideosink = gst_element_factory_make ("fakesink", NULL);
   fail_unless (fakevideosink != NULL, "failed to create fakesink element");
   src = gst_element_factory_make ("wrappercamerabinsrc", NULL);
@@ -443,14 +697,46 @@
   gst_object_unref (vfbin);
   gst_object_unref (fakevideosink);
 
-  bus = gst_pipeline_get_bus (GST_PIPELINE (camera));
-  bus_source = gst_bus_add_watch (bus, (GstBusFunc) capture_bus_cb, main_loop);
-  gst_object_unref (bus);
+  GST_INFO ("init finished");
+}
 
-  tags_found = NULL;
-  capture_count = 0;
-  image_filename = make_test_file_name (IMAGE_FILENAME, -1);
-  video_filename = make_test_file_name (VIDEO_FILENAME, -1);
+static void
+setup_test_camerasrc (void)
+{
+  GstElement *vfbin;
+  GstElement *fakevideosink;
+  GstElement *src;
+  GstElement *audiosrc;
+
+  GST_INFO ("init");
+
+  setup_camerabin_common ();
+
+  fakevideosink = gst_element_factory_make ("fakesink", NULL);
+  fail_unless (fakevideosink != NULL, "failed to create fakesink element");
+  src = gst_element_factory_make ("wrappercamerabinsrc", NULL);
+  fail_unless (src != NULL, "failed to create wrappercamerabinsrc element");
+  testsrc = g_object_new (GST_TYPE_TEST_VIDEO_SRC, NULL);
+  fail_unless (testsrc != NULL, "failed to create testvideosrc element");
+  g_object_set (testsrc, "name", "testsrc", NULL);
+  audiosrc = gst_element_factory_make ("audiotestsrc", NULL);
+  fail_unless (audiosrc != NULL, "failed to create audiotestsrc element");
+
+  preview_caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT,
+      320, "height", G_TYPE_INT, 240, NULL);
+
+  g_object_set (G_OBJECT (audiosrc), "is-live", TRUE, NULL);
+  g_object_set (G_OBJECT (src), "video-source", testsrc, NULL);
+  g_object_set (G_OBJECT (camera), "camera-source", src, "preview-caps",
+      preview_caps, "post-previews", TRUE, "audio-source", audiosrc, NULL);
+  gst_object_unref (src);
+  gst_object_unref (testsrc);
+  gst_object_unref (audiosrc);
+
+  vfbin = gst_bin_get_by_name (GST_BIN (camera), "vf-bin");
+  g_object_set (G_OBJECT (vfbin), "video-sink", fakevideosink, NULL);
+  gst_object_unref (vfbin);
+  gst_object_unref (fakevideosink);
 
   GST_INFO ("init finished");
 }
@@ -707,7 +993,8 @@
   fail_unless (idle);
 }
 
-GST_START_TEST (test_single_image_capture)
+static void
+run_single_image_capture_test (GstCaps * viewfinder_caps, GstCaps * image_caps)
 {
   gboolean idle;
   GstMessage *msg;
@@ -717,6 +1004,11 @@
   /* set still image mode */
   g_object_set (camera, "mode", 1, "location", image_filename, NULL);
 
+  if (viewfinder_caps)
+    g_object_set (camera, "viewfinder-caps", viewfinder_caps, NULL);
+  if (image_caps)
+    g_object_set (camera, "image-capture-caps", image_caps, NULL);
+
   if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) ==
       GST_STATE_CHANGE_FAILURE) {
     GST_WARNING ("setting camerabin to PLAYING failed");
@@ -743,6 +1035,27 @@
   remove_file (image_filename, 0);
 }
 
+GST_START_TEST (test_single_image_capture)
+{
+  run_single_image_capture_test (NULL, NULL);
+}
+
+GST_END_TEST;
+
+
+/* Verify that incompatible caps can be used in viewfinder and image capture
+ * at the same time */
+GST_START_TEST (test_single_image_capture_with_different_caps)
+{
+  GstCaps *vf_caps =
+      gst_caps_from_string ("video/x-raw, width=480, height=320");
+  GstCaps *img_caps =
+      gst_caps_from_string ("video/x-raw, width=800, height=600");
+  run_single_image_capture_test (vf_caps, img_caps);
+  gst_caps_unref (vf_caps);
+  gst_caps_unref (img_caps);
+}
+
 GST_END_TEST;
 
 
@@ -1566,6 +1879,39 @@
 GST_END_TEST;
 
 
+GST_START_TEST (test_photography_iface_image_capture)
+{
+  run_single_image_capture_test (NULL, NULL);
+}
+
+GST_END_TEST;
+
+
+GST_START_TEST (test_photography_iface_image_capture_with_caps)
+{
+  GstCaps *caps = gst_caps_from_string ("video/x-raw, width=800, height=600");
+
+  run_single_image_capture_test (NULL, caps);
+  gst_caps_unref (caps);
+}
+
+GST_END_TEST;
+
+
+GST_START_TEST (test_photography_iface_image_capture_with_caps_and_restriction)
+{
+  GstCaps *caps = gst_caps_from_string ("video/x-raw, width=800, height=600");
+
+  /* the source will actually provide an image with 800x800 resolution */
+  GST_TEST_VIDEO_SRC (testsrc)->enable_resolution_restriction = TRUE;
+
+  run_single_image_capture_test (NULL, caps);
+  gst_caps_unref (caps);
+}
+
+GST_END_TEST;
+
+
 typedef struct _TestCaseDef
 {
   const gchar *name;
@@ -1583,6 +1929,7 @@
   Suite *s = suite_create ("camerabin");
   gint i;
   TCase *tc_generic = tcase_create ("generic");
+  TCase *tc_phography_iface = tcase_create ("photography-iface");
 
   jpegenc_factory = gst_element_factory_find ("jpegenc");
   if (jpegenc_factory == NULL) {
@@ -1604,14 +1951,10 @@
     tcase_add_checked_fixture (tc_basic, tests[i].setup_func, teardown);
 
     tcase_add_test (tc_basic, test_single_image_capture);
+    tcase_add_test (tc_basic, test_single_image_capture_with_different_caps);
     tcase_add_test (tc_basic, test_single_video_recording);
     tcase_add_test (tc_basic, test_image_video_cycle);
-    if (gst_plugin_feature_check_version ((GstPluginFeature *) jpegenc_factory,
-            0, 10, 27))
-      tcase_add_test (tc_basic, test_multiple_image_captures);
-    else
-      GST_WARNING ("Skipping image capture test because -good 0.10.27 is "
-          "needed");
+    tcase_add_test (tc_basic, test_multiple_image_captures);
     tcase_add_test (tc_basic, test_multiple_video_recordings);
 
     tcase_add_test (tc_basic, test_image_capture_previews);
@@ -1627,6 +1970,26 @@
     tcase_add_test (tc_basic, test_image_location_switching);
   }
 
+  /* This is the GstPhotography interface test case. It was added in 0.10
+   * to make it easy for integrating with hardware and providing lower
+   * delays from action to capture.
+   * There is also has a feature in wrappercamerabinsrc that allows
+   * captures with the interface to have a different(higher) resolution than
+   * requested and wrappercamerabinsrc will crop to the requested one.
+   * This doesn't make sense and seems to be very hardware specific but we
+   * can't simply remove it at this point.
+   *
+   * FIXME 2.0: revisit GstPhotography interface and its interaction with
+   * camerabin */
+  suite_add_tcase (s, tc_phography_iface);
+  tcase_add_checked_fixture (tc_phography_iface, setup_test_camerasrc,
+      teardown);
+  tcase_add_test (tc_phography_iface, test_photography_iface_image_capture);
+  tcase_add_test (tc_phography_iface,
+      test_photography_iface_image_capture_with_caps);
+  tcase_add_test (tc_phography_iface,
+      test_photography_iface_image_capture_with_caps_and_restriction);
+
 end:
   return s;
 }
diff --git a/tests/check/elements/compositor.c b/tests/check/elements/compositor.c
index dab259b..7ce637e 100644
--- a/tests/check/elements/compositor.c
+++ b/tests/check/elements/compositor.c
@@ -33,6 +33,7 @@
 
 #include <gst/check/gstcheck.h>
 #include <gst/check/gstconsistencychecker.h>
+#include <gst/video/gstvideometa.h>
 #include <gst/base/gstbasesrc.h>
 
 #define VIDEO_CAPS_STRING               \
@@ -1096,6 +1097,237 @@
 
 GST_END_TEST;
 
+static gboolean buffer_mapped;
+static gboolean (*default_map) (GstVideoMeta * meta, guint plane,
+    GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags);
+
+static gboolean
+test_obscured_new_videometa_map (GstVideoMeta * meta, guint plane,
+    GstMapInfo * info, gpointer * data, gint * stride, GstMapFlags flags)
+{
+  buffer_mapped = TRUE;
+  return default_map (meta, plane, info, data, stride, flags);
+}
+
+static GstPadProbeReturn
+test_obscured_pad_probe_cb (GstPad * srcpad, GstPadProbeInfo * info,
+    gpointer user_data)
+{
+  GstBuffer *obuf, *nbuf;
+  GstVideoMeta *meta;
+
+  GST_DEBUG ("pad probe called");
+  /* We need to deep-copy the buffer here because videotestsrc reuses buffers
+   * and hence the GstVideoMap associated with the buffers, and that causes a
+   * segfault inside videotestsrc when it tries to reuse the buffer */
+  obuf = GST_PAD_PROBE_INFO_BUFFER (info);
+  nbuf = gst_buffer_new ();
+  gst_buffer_copy_into (nbuf, obuf, GST_BUFFER_COPY_ALL | GST_BUFFER_COPY_DEEP,
+      0, -1);
+  meta = gst_buffer_get_video_meta (nbuf);
+  /* Override the default map() function to set also buffer_mapped */
+  default_map = meta->map;
+  meta->map = test_obscured_new_videometa_map;
+  /* Replace the buffer that's going downstream */
+  GST_PAD_PROBE_INFO_DATA (info) = nbuf;
+  gst_buffer_unref (obuf);
+
+  return GST_PAD_PROBE_PASS;
+}
+
+static void
+_test_obscured (const gchar * caps_str, gint xpos0, gint ypos0, gint width0,
+    gint height0, gdouble alpha0, gint xpos1, gint ypos1, gint width1,
+    gint height1, gdouble alpha1, gint out_width, gint out_height)
+{
+  GstElement *pipeline, *sink, *mix, *src0, *cfilter0, *src1, *cfilter1;
+  GstElement *out_cfilter;
+  GstPad *srcpad, *sinkpad;
+  GstSample *last_sample = NULL;
+  GstSample *sample;
+  GstCaps *caps;
+
+  GST_INFO ("preparing test");
+
+  pipeline = gst_pipeline_new ("pipeline");
+  src0 = gst_element_factory_make ("videotestsrc", "src0");
+  g_object_set (src0, "num-buffers", 5, NULL);
+  cfilter0 = gst_element_factory_make ("capsfilter", "capsfilter0");
+  caps = gst_caps_from_string (caps_str);
+  g_object_set (cfilter0, "caps", caps, NULL);
+  gst_caps_unref (caps);
+
+  src1 = gst_element_factory_make ("videotestsrc", "src1");
+  g_object_set (src1, "num-buffers", 5, NULL);
+  cfilter1 = gst_element_factory_make ("capsfilter", "capsfilter1");
+  caps = gst_caps_from_string (caps_str);
+  g_object_set (cfilter1, "caps", caps, NULL);
+  gst_caps_unref (caps);
+
+  mix = gst_element_factory_make ("compositor", "compositor");
+  out_cfilter = gst_element_factory_make ("capsfilter", "out_capsfilter");
+  caps = gst_caps_from_string (caps_str);
+  if (out_width > 0)
+    gst_caps_set_simple (caps, "width", G_TYPE_INT, out_width, NULL);
+  if (out_height > 0)
+    gst_caps_set_simple (caps, "height", G_TYPE_INT, out_height, NULL);
+  g_object_set (out_cfilter, "caps", caps, NULL);
+  gst_caps_unref (caps);
+  sink = gst_element_factory_make ("appsink", "sink");
+
+  gst_bin_add_many (GST_BIN (pipeline), src0, cfilter0, src1, cfilter1, mix,
+      out_cfilter, sink, NULL);
+  fail_unless (gst_element_link (src0, cfilter0));
+  fail_unless (gst_element_link (src1, cfilter1));
+  fail_unless (gst_element_link (mix, out_cfilter));
+  fail_unless (gst_element_link (out_cfilter, sink));
+
+  srcpad = gst_element_get_static_pad (cfilter0, "src");
+  sinkpad = gst_element_get_request_pad (mix, "sink_0");
+  g_object_set (sinkpad, "xpos", xpos0, "ypos", ypos0, "width", width0,
+      "height", height0, "alpha", alpha0, NULL);
+  fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK);
+  gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_BUFFER,
+      test_obscured_pad_probe_cb, NULL, NULL);
+  gst_object_unref (sinkpad);
+  gst_object_unref (srcpad);
+
+  srcpad = gst_element_get_static_pad (cfilter1, "src");
+  sinkpad = gst_element_get_request_pad (mix, "sink_1");
+  g_object_set (sinkpad, "xpos", xpos1, "ypos", ypos1, "width", width1,
+      "height", height1, "alpha", alpha1, NULL);
+  fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK);
+  gst_object_unref (sinkpad);
+  gst_object_unref (srcpad);
+
+  GST_INFO ("sample prepared");
+  gst_element_set_state (pipeline, GST_STATE_PLAYING);
+
+  do {
+    GST_DEBUG ("sample pulling");
+    g_signal_emit_by_name (sink, "pull-sample", &sample);
+    if (sample == NULL)
+      break;
+    if (last_sample)
+      gst_sample_unref (last_sample);
+    last_sample = sample;
+    GST_DEBUG ("sample pulled");
+  } while (TRUE);
+  gst_sample_unref (last_sample);
+
+  gst_element_set_state (pipeline, GST_STATE_NULL);
+  gst_object_unref (pipeline);
+}
+
+GST_START_TEST (test_obscured_skipped)
+{
+  gint xpos0, xpos1;
+  gint ypos0, ypos1;
+  gint width0, width1;
+  gint height0, height1;
+  gint out_width, out_height;
+  gdouble alpha0, alpha1;
+  const gchar *caps_str;
+
+  caps_str = "video/x-raw";
+  buffer_mapped = FALSE;
+  /* Set else to compositor defaults */
+  alpha0 = alpha1 = 1.0;
+  xpos0 = xpos1 = ypos0 = ypos1 = 0;
+  width0 = width1 = height0 = height1 = 0;
+  out_width = out_height = 0;
+
+  GST_INFO ("testing defaults");
+  /* With everything at defaults, sink_1 will obscure sink_0, so buffers from
+   * sink_0 will never get mapped by compositor. To verify, run with
+   * GST_DEBUG=compositor:6 and look for "Obscured by" messages */
+  _test_obscured (caps_str, xpos0, ypos0, width0, height0, alpha0, xpos1, ypos1,
+      width1, height1, alpha1, out_width, out_height);
+  fail_unless (buffer_mapped == FALSE);
+  buffer_mapped = FALSE;
+
+  caps_str = "video/x-raw,format=ARGB";
+  GST_INFO ("testing video with alpha channel");
+  _test_obscured (caps_str, xpos0, ypos0, width0, height0, alpha0, xpos1, ypos1,
+      width1, height1, alpha1, out_width, out_height);
+  fail_unless (buffer_mapped == TRUE);
+  caps_str = "video/x-raw";
+  buffer_mapped = FALSE;
+
+  alpha1 = 0.0;
+  GST_INFO ("testing alpha1 = %.2g", alpha1);
+  _test_obscured (caps_str, xpos0, ypos0, width0, height0, alpha0, xpos1, ypos1,
+      width1, height1, alpha1, out_width, out_height);
+  fail_unless (buffer_mapped == TRUE);
+  alpha1 = 1.0;
+  buffer_mapped = FALSE;
+
+  /* Test 0.1, ..., 0.9 */
+  for (alpha1 = 1; alpha1 < 10; alpha1 += 1) {
+    GST_INFO ("testing alpha1 = %.2g", alpha1 / 10);
+    _test_obscured (caps_str, xpos0, ypos0, width0, height0, alpha0, xpos1,
+        ypos1, width1, height1, alpha1 / 10, out_width, out_height);
+    fail_unless (buffer_mapped == TRUE);
+  }
+  alpha1 = 1.0;
+  buffer_mapped = FALSE;
+
+  width1 = height1 = 10;
+  GST_INFO ("testing smaller sink_1");
+  _test_obscured (caps_str, xpos0, ypos0, width0, height0, alpha0, xpos1, ypos1,
+      width1, height1, alpha1, out_width, out_height);
+  fail_unless (buffer_mapped == TRUE);
+  width1 = height1 = 0;
+  buffer_mapped = FALSE;
+
+  width0 = height0 = width1 = height1 = 10;
+  GST_INFO ("testing smaller sink_1 and sink0 (same sizes)");
+  _test_obscured (caps_str, xpos0, ypos0, width0, height0, alpha0, xpos1, ypos1,
+      width1, height1, alpha1, out_width, out_height);
+  fail_unless (buffer_mapped == FALSE);
+  width0 = height0 = width1 = height1 = 0;
+  buffer_mapped = FALSE;
+
+  width0 = height0 = 20;
+  width1 = height1 = 10;
+  GST_INFO ("testing smaller sink_1 and sink0 (sink_0 > sink_1)");
+  _test_obscured (caps_str, xpos0, ypos0, width0, height0, alpha0, xpos1, ypos1,
+      width1, height1, alpha1, out_width, out_height);
+  fail_unless (buffer_mapped == TRUE);
+  width0 = height0 = width1 = height1 = 0;
+  buffer_mapped = FALSE;
+
+  width0 = height0 = 10;
+  width1 = height1 = 20;
+  GST_INFO ("testing smaller sink_1 and sink0 (sink_0 < sink_1)");
+  _test_obscured (caps_str, xpos0, ypos0, width0, height0, alpha0, xpos1, ypos1,
+      width1, height1, alpha1, out_width, out_height);
+  fail_unless (buffer_mapped == FALSE);
+  width0 = height0 = width1 = height1 = 0;
+  buffer_mapped = FALSE;
+
+  xpos0 = ypos0 = 10;
+  xpos1 = ypos1 = 20;
+  GST_INFO ("testing offset");
+  _test_obscured (caps_str, xpos0, ypos0, width0, height0, alpha0, xpos1, ypos1,
+      width1, height1, alpha1, out_width, out_height);
+  fail_unless (buffer_mapped == TRUE);
+  xpos0 = ypos0 = xpos1 = ypos1 = 0;
+  buffer_mapped = FALSE;
+
+  xpos0 = ypos0 = 10000;
+  out_width = 320;
+  out_height = 240;
+  GST_INFO ("testing sink_0 outside the frame");
+  _test_obscured (caps_str, xpos0, ypos0, width0, height0, alpha0, xpos1, ypos1,
+      width1, height1, alpha1, out_width, out_height);
+  fail_unless (buffer_mapped == FALSE);
+  xpos0 = ypos0 = out_width = out_height = 0;
+  buffer_mapped = FALSE;
+}
+
+GST_END_TEST;
+
 static Suite *
 compositor_suite (void)
 {
@@ -1115,6 +1347,7 @@
   tcase_add_test (tc_chain, test_loop);
   tcase_add_test (tc_chain, test_flush_start_flush_stop);
   tcase_add_test (tc_chain, test_segment_base_handling);
+  tcase_add_test (tc_chain, test_obscured_skipped);
 
   /* Use a longer timeout */
 #ifdef HAVE_VALGRIND
diff --git a/tests/check/libs/aggregator.c b/tests/check/libs/aggregator.c
index 62be4ee..52bdd7f 100644
--- a/tests/check/libs/aggregator.c
+++ b/tests/check/libs/aggregator.c
@@ -49,12 +49,15 @@
 static GType gst_test_aggregator_get_type (void);
 
 #define BUFFER_DURATION 100000000       /* 10 frames per second */
+#define TEST_GAP_PTS 0
+#define TEST_GAP_DURATION (5 * GST_SECOND)
 
 struct _GstTestAggregator
 {
   GstAggregator parent;
 
   guint64 timestamp;
+  gboolean gap_expected;
 };
 
 struct _GstTestAggregatorClass
@@ -85,6 +88,18 @@
 
         if (gst_aggregator_pad_is_eos (pad) == FALSE)
           all_eos = FALSE;
+
+        if (testagg->gap_expected == TRUE) {
+          buf = gst_aggregator_pad_get_buffer (pad);
+          fail_unless (buf);
+          fail_unless (GST_BUFFER_PTS (buf) == TEST_GAP_PTS);
+          fail_unless (GST_BUFFER_DURATION (buf) == TEST_GAP_DURATION);
+          fail_unless (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_GAP));
+          fail_unless (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DROPPABLE));
+          gst_buffer_unref (buf);
+          testagg->gap_expected = FALSE;
+        }
+
         gst_aggregator_pad_drop_buffer (pad);
 
         g_value_reset (&value);
@@ -156,6 +171,7 @@
   GstAggregator *agg = GST_AGGREGATOR (self);
   gst_segment_init (&agg->segment, GST_FORMAT_BYTES);
   self->timestamp = 0;
+  self->gap_expected = FALSE;
 }
 
 static gboolean
@@ -221,13 +237,11 @@
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS_ANY);
 
-static gpointer
-push_buffer (gpointer user_data)
+static void
+start_flow (ChainData * chain_data)
 {
-  GstFlowReturn flow;
-  GstCaps *caps;
-  ChainData *chain_data = (ChainData *) user_data;
   GstSegment segment;
+  GstCaps *caps;
 
   gst_pad_push_event (chain_data->srcpad, gst_event_new_stream_start ("test"));
 
@@ -237,6 +251,15 @@
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
   gst_pad_push_event (chain_data->srcpad, gst_event_new_segment (&segment));
+}
+
+static gpointer
+push_buffer (gpointer user_data)
+{
+  GstFlowReturn flow;
+  ChainData *chain_data = (ChainData *) user_data;
+
+  start_flow (chain_data);
 
   GST_DEBUG ("Pushing buffer on pad: %s:%s",
       GST_DEBUG_PAD_NAME (chain_data->sinkpad));
@@ -254,12 +277,27 @@
 push_event (gpointer user_data)
 {
   ChainData *chain_data = (ChainData *) user_data;
+  GstTestAggregator *aggregator = (GstTestAggregator *) chain_data->aggregator;
+  GstEventType event_type;
+
+  start_flow (chain_data);
 
   GST_INFO_OBJECT (chain_data->srcpad, "Pushing event: %"
       GST_PTR_FORMAT, chain_data->event);
+
+  event_type = GST_EVENT_TYPE (chain_data->event);
+  switch (event_type) {
+    case GST_EVENT_GAP:
+      aggregator->gap_expected = TRUE;
+      break;
+    default:
+      break;
+  }
+
   fail_unless (gst_pad_push_event (chain_data->srcpad,
           chain_data->event) == TRUE);
 
+
   return NULL;
 }
 
@@ -285,7 +323,7 @@
 static GstPadProbeReturn
 _aggregated_cb (GstPad * pad, GstPadProbeInfo * info, GMainLoop * ml)
 {
-  GST_DEBUG ("SHould quit ML");
+  GST_DEBUG ("Should quit ML");
   g_idle_add ((GSourceFunc) _quit, ml);
 
   return GST_PAD_PROBE_REMOVE;
@@ -451,6 +489,33 @@
 
 GST_END_TEST;
 
+GST_START_TEST (test_aggregate_gap)
+{
+  GThread *thread;
+
+  ChainData data = { 0, };
+  TestData test = { 0, };
+
+  _test_data_init (&test, FALSE);
+  _chain_data_init (&data, test.aggregator);
+
+  data.event = gst_event_new_gap (TEST_GAP_PTS, TEST_GAP_DURATION);
+
+  thread = g_thread_try_new ("gst-check", push_event, &data, NULL);
+
+  g_main_loop_run (test.ml);
+  g_source_remove (test.timeout_id);
+
+  /* these will return immediately as when the data is popped the threads are
+   * unlocked and will terminate */
+  g_thread_join (thread);
+
+  _chain_data_clear (&data);
+  _test_data_clear (&test);
+}
+
+GST_END_TEST;
+
 #define NUM_BUFFERS 3
 static void
 handoff (GstElement * fakesink, GstBuffer * buf, GstPad * pad, guint * count)
@@ -1099,6 +1164,7 @@
   suite_add_tcase (suite, general);
   tcase_add_test (general, test_aggregate);
   tcase_add_test (general, test_aggregate_eos);
+  tcase_add_test (general, test_aggregate_gap);
   tcase_add_test (general, test_flushing_seek);
   tcase_add_test (general, test_infinite_seek);
   tcase_add_test (general, test_infinite_seek_50_src);
diff --git a/tests/examples/camerabin2/Makefile.am b/tests/examples/camerabin2/Makefile.am
index d29e679..56f5769 100644
--- a/tests/examples/camerabin2/Makefile.am
+++ b/tests/examples/camerabin2/Makefile.am
@@ -2,7 +2,7 @@
 
 AM_CPPFLAGS = -DCAMERA_APPS_UIDIR=\""$(srcdir)"\"
 
-if HAVE_GTK
+if HAVE_GTK3
 
 GST_CAMERABIN_GTK_EXAMPLES = gst-camera2
 
@@ -10,7 +10,7 @@
 gst_camera2_CFLAGS  = \
         $(GST_PLUGINS_BAD_CFLAGS) \
         $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
-	$(GTK_CFLAGS) \
+	$(GTK3_CFLAGS) \
 	$(GMODULE_EXPORT_CFLAGS) \
         -DGST_USE_UNSTABLE_API
 gst_camera2_LDADD   = \
@@ -21,7 +21,7 @@
         -lgstpbutils-@GST_API_VERSION@ \
 	-lgstvideo-@GST_API_VERSION@ \
         $(GST_LIBS) \
-	$(GTK_LIBS) \
+	$(GTK3_LIBS) \
 	$(GMODULE_EXPORT_LIBS)
 
 noinst_DATA = $(GST_CAMERABIN_UI_FILES)
diff --git a/tests/examples/camerabin2/Makefile.in b/tests/examples/camerabin2/Makefile.in
index f2bf263..7ee393e 100644
--- a/tests/examples/camerabin2/Makefile.in
+++ b/tests/examples/camerabin2/Makefile.in
@@ -125,18 +125,18 @@
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
-@HAVE_GTK_TRUE@am__EXEEXT_1 = gst-camera2$(EXEEXT)
+@HAVE_GTK3_TRUE@am__EXEEXT_1 = gst-camera2$(EXEEXT)
 @HAVE_X11_TRUE@am__EXEEXT_2 = gst-camerabin2-test$(EXEEXT)
 PROGRAMS = $(noinst_PROGRAMS)
 am__gst_camera2_SOURCES_DIST = gst-camera2.h gst-camera2.c
-@HAVE_GTK_TRUE@am_gst_camera2_OBJECTS =  \
-@HAVE_GTK_TRUE@	gst_camera2-gst-camera2.$(OBJEXT)
+@HAVE_GTK3_TRUE@am_gst_camera2_OBJECTS =  \
+@HAVE_GTK3_TRUE@	gst_camera2-gst-camera2.$(OBJEXT)
 gst_camera2_OBJECTS = $(am_gst_camera2_OBJECTS)
 am__DEPENDENCIES_1 =
-@HAVE_GTK_TRUE@gst_camera2_DEPENDENCIES = $(top_builddir)/gst-libs/gst/interfaces/libgstphotography-@GST_API_VERSION@.la \
-@HAVE_GTK_TRUE@	$(top_builddir)/gst-libs/gst/basecamerabinsrc/libgstbasecamerabinsrc-@GST_API_VERSION@.la \
-@HAVE_GTK_TRUE@	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
-@HAVE_GTK_TRUE@	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+@HAVE_GTK3_TRUE@gst_camera2_DEPENDENCIES = $(top_builddir)/gst-libs/gst/interfaces/libgstphotography-@GST_API_VERSION@.la \
+@HAVE_GTK3_TRUE@	$(top_builddir)/gst-libs/gst/basecamerabinsrc/libgstbasecamerabinsrc-@GST_API_VERSION@.la \
+@HAVE_GTK3_TRUE@	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@HAVE_GTK3_TRUE@	$(am__DEPENDENCIES_1) $(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
@@ -725,28 +725,28 @@
 wayland_scanner = @wayland_scanner@
 GST_CAMERABIN_UI_FILES = gst-camera2.ui
 AM_CPPFLAGS = -DCAMERA_APPS_UIDIR=\""$(srcdir)"\"
-@HAVE_GTK_FALSE@GST_CAMERABIN_GTK_EXAMPLES = 
-@HAVE_GTK_TRUE@GST_CAMERABIN_GTK_EXAMPLES = gst-camera2
-@HAVE_GTK_TRUE@gst_camera2_SOURCES = gst-camera2.h gst-camera2.c
-@HAVE_GTK_TRUE@gst_camera2_CFLAGS = \
-@HAVE_GTK_TRUE@        $(GST_PLUGINS_BAD_CFLAGS) \
-@HAVE_GTK_TRUE@        $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
-@HAVE_GTK_TRUE@	$(GTK_CFLAGS) \
-@HAVE_GTK_TRUE@	$(GMODULE_EXPORT_CFLAGS) \
-@HAVE_GTK_TRUE@        -DGST_USE_UNSTABLE_API
+@HAVE_GTK3_FALSE@GST_CAMERABIN_GTK_EXAMPLES = 
+@HAVE_GTK3_TRUE@GST_CAMERABIN_GTK_EXAMPLES = gst-camera2
+@HAVE_GTK3_TRUE@gst_camera2_SOURCES = gst-camera2.h gst-camera2.c
+@HAVE_GTK3_TRUE@gst_camera2_CFLAGS = \
+@HAVE_GTK3_TRUE@        $(GST_PLUGINS_BAD_CFLAGS) \
+@HAVE_GTK3_TRUE@        $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
+@HAVE_GTK3_TRUE@	$(GTK3_CFLAGS) \
+@HAVE_GTK3_TRUE@	$(GMODULE_EXPORT_CFLAGS) \
+@HAVE_GTK3_TRUE@        -DGST_USE_UNSTABLE_API
 
-@HAVE_GTK_TRUE@gst_camera2_LDADD = \
-@HAVE_GTK_TRUE@        $(top_builddir)/gst-libs/gst/interfaces/libgstphotography-@GST_API_VERSION@.la \
-@HAVE_GTK_TRUE@        $(top_builddir)/gst-libs/gst/basecamerabinsrc/libgstbasecamerabinsrc-@GST_API_VERSION@.la \
-@HAVE_GTK_TRUE@        $(GST_PLUGINS_BAD_LIBS) \
-@HAVE_GTK_TRUE@        $(GST_PLUGINS_BASE_LIBS) \
-@HAVE_GTK_TRUE@        -lgstpbutils-@GST_API_VERSION@ \
-@HAVE_GTK_TRUE@	-lgstvideo-@GST_API_VERSION@ \
-@HAVE_GTK_TRUE@        $(GST_LIBS) \
-@HAVE_GTK_TRUE@	$(GTK_LIBS) \
-@HAVE_GTK_TRUE@	$(GMODULE_EXPORT_LIBS)
+@HAVE_GTK3_TRUE@gst_camera2_LDADD = \
+@HAVE_GTK3_TRUE@        $(top_builddir)/gst-libs/gst/interfaces/libgstphotography-@GST_API_VERSION@.la \
+@HAVE_GTK3_TRUE@        $(top_builddir)/gst-libs/gst/basecamerabinsrc/libgstbasecamerabinsrc-@GST_API_VERSION@.la \
+@HAVE_GTK3_TRUE@        $(GST_PLUGINS_BAD_LIBS) \
+@HAVE_GTK3_TRUE@        $(GST_PLUGINS_BASE_LIBS) \
+@HAVE_GTK3_TRUE@        -lgstpbutils-@GST_API_VERSION@ \
+@HAVE_GTK3_TRUE@	-lgstvideo-@GST_API_VERSION@ \
+@HAVE_GTK3_TRUE@        $(GST_LIBS) \
+@HAVE_GTK3_TRUE@	$(GTK3_LIBS) \
+@HAVE_GTK3_TRUE@	$(GMODULE_EXPORT_LIBS)
 
-@HAVE_GTK_TRUE@noinst_DATA = $(GST_CAMERABIN_UI_FILES)
+@HAVE_GTK3_TRUE@noinst_DATA = $(GST_CAMERABIN_UI_FILES)
 @HAVE_X11_FALSE@GST_CAMERABIN_X11_EXAMPLES = 
 @HAVE_X11_TRUE@GST_CAMERABIN_X11_EXAMPLES = gst-camerabin2-test
 @HAVE_X11_TRUE@gst_camerabin2_test_SOURCES = gst-camerabin2-test.c
diff --git a/tests/examples/camerabin2/gst-camera2.c b/tests/examples/camerabin2/gst-camera2.c
index 0bb9869..5104d3b 100644
--- a/tests/examples/camerabin2/gst-camera2.c
+++ b/tests/examples/camerabin2/gst-camera2.c
@@ -170,9 +170,7 @@
 void
 on_viewfinderArea_realize (GtkWidget * widget, gpointer data)
 {
-#if GTK_CHECK_VERSION (2, 18, 0)
   gdk_window_ensure_native (gtk_widget_get_window (widget));
-#endif
 }
 
 void
@@ -205,6 +203,13 @@
   }
 }
 
+void
+on_zoomScale_value_changed (GtkWidget * widget, gpointer data)
+{
+  g_object_set (camera, "zoom",
+      (gfloat) gtk_range_get_value (GTK_RANGE (widget)), NULL);
+}
+
 static GstBusSyncReply
 bus_sync_callback (GstBus * bus, GstMessage * message, gpointer data)
 {
@@ -219,11 +224,7 @@
   /* FIXME: make sure to get XID in main thread */
   ui_drawing = GTK_WIDGET (gtk_builder_get_object (builder, "viewfinderArea"));
   gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (message->src),
-#if GTK_CHECK_VERSION (2, 91, 6)
       GDK_WINDOW_XID (gtk_widget_get_window (ui_drawing)));
-#else
-      GDK_WINDOW_XWINDOW (gtk_widget_get_window (ui_drawing)));
-#endif
 
   gst_message_unref (message);
   return GST_BUS_DROP;
@@ -276,7 +277,6 @@
 static gboolean
 init_gtkwidgets_data (void)
 {
-#if GTK_CHECK_VERSION(2,24,0)
   gint i;
   GtkComboBoxText *combobox =
       GTK_COMBO_BOX_TEXT (gtk_builder_get_object (builder, "formatComboBox"));
@@ -291,10 +291,6 @@
   /* default to the first one -> ogg */
   gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), 0);
   return TRUE;
-#else
-  g_warning ("This needs a newer version of GTK (2.24 at least)");
-  return FALSE;
-#endif
 }
 
 int
diff --git a/tests/examples/camerabin2/gst-camera2.h b/tests/examples/camerabin2/gst-camera2.h
index 8477dac..825d10a 100644
--- a/tests/examples/camerabin2/gst-camera2.h
+++ b/tests/examples/camerabin2/gst-camera2.h
@@ -48,4 +48,7 @@
 void
 on_formatComboBox_changed (GtkWidget * widget, gpointer data);
 
+void
+on_zoomScale_value_changed (GtkWidget * widget, gpointer data);
+
 #endif /* __GST_CAMERA_BIN_H__ */
diff --git a/tests/examples/camerabin2/gst-camera2.ui b/tests/examples/camerabin2/gst-camera2.ui
index 9dc1fee..52bcfc6 100644
--- a/tests/examples/camerabin2/gst-camera2.ui
+++ b/tests/examples/camerabin2/gst-camera2.ui
@@ -1,17 +1,26 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
 <interface>
-  <requires lib="gtk+" version="2.16"/>
+  <requires lib="gtk+" version="3.0"/>
+  <object class="GtkAdjustment" id="zoomadjustment">
+    <property name="lower">1</property>
+    <property name="upper">10</property>
+    <property name="value">1</property>
+    <property name="step_increment">0.10000000000000001</property>
+    <property name="page_increment">1</property>
+  </object>
   <object class="GtkWindow" id="mainWindow">
     <property name="can_focus">False</property>
     <property name="default_width">800</property>
     <property name="default_height">600</property>
     <signal name="delete-event" handler="on_mainWindow_delete_event" swapped="no"/>
     <child>
-      <object class="GtkVBox" id="vbox1">
+      <object class="GtkBox" id="box1">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
         <child>
-          <object class="GtkHBox" id="hbox1">
+          <object class="GtkBox" id="box3">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <child>
@@ -21,7 +30,7 @@
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">False</property>
-                <property name="use_action_appearance">False</property>
+                <property name="xalign">0</property>
                 <property name="active">True</property>
                 <property name="draw_indicator">True</property>
                 <signal name="toggled" handler="on_imageRButton_toggled" swapped="no"/>
@@ -39,7 +48,7 @@
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">False</property>
-                <property name="use_action_appearance">False</property>
+                <property name="xalign">0</property>
                 <property name="active">True</property>
                 <property name="draw_indicator">True</property>
                 <property name="group">imageRButton</property>
@@ -55,11 +64,11 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">False</property>
-            <property name="position">0</property>
+            <property name="position">1</property>
           </packing>
         </child>
         <child>
-          <object class="GtkHBox" id="hbox2">
+          <object class="GtkBox" id="box2">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <child>
@@ -71,13 +80,14 @@
               <packing>
                 <property name="expand">True</property>
                 <property name="fill">True</property>
-                <property name="position">0</property>
+                <property name="position">1</property>
               </packing>
             </child>
             <child>
-              <object class="GtkVBox" id="vbox2">
+              <object class="GtkBox" id="box4">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <property name="orientation">vertical</property>
                 <child>
                   <object class="GtkLabel" id="label4">
                     <property name="visible">True</property>
@@ -97,7 +107,6 @@
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
-                    <property name="use_action_appearance">False</property>
                     <signal name="clicked" handler="on_captureButton_clicked" swapped="no"/>
                   </object>
                   <packing>
@@ -113,7 +122,6 @@
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
-                    <property name="use_action_appearance">False</property>
                     <signal name="clicked" handler="on_stopCaptureButton_clicked" swapped="no"/>
                   </object>
                   <packing>
@@ -147,10 +155,38 @@
                     <property name="position">4</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Zoom</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">5</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkScale" id="zoomScale">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="adjustment">zoomadjustment</property>
+                    <property name="fill_level">10</property>
+                    <property name="round_digits">1</property>
+                    <property name="value_pos">right</property>
+                    <signal name="value-changed" handler="on_zoomScale_value_changed" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">6</property>
+                  </packing>
+                </child>
               </object>
               <packing>
                 <property name="expand">False</property>
-                <property name="fill">False</property>
+                <property name="fill">True</property>
                 <property name="position">1</property>
               </packing>
             </child>
@@ -158,7 +194,7 @@
           <packing>
             <property name="expand">True</property>
             <property name="fill">True</property>
-            <property name="position">1</property>
+            <property name="position">2</property>
           </packing>
         </child>
       </object>
diff --git a/tests/examples/opencv/Makefile.am b/tests/examples/opencv/Makefile.am
index 9db9da4..27dbfb3 100644
--- a/tests/examples/opencv/Makefile.am
+++ b/tests/examples/opencv/Makefile.am
@@ -1,9 +1,7 @@
 noinst_PROGRAMS = gstmotioncells_dynamic_test \
 		  gsthanddetect_test
 
-gstmotioncells_dynamic_test_SOURCES = 	\
-	gstmotioncells_dynamic_test.c	\
-	gst_element_print_properties.c
+gstmotioncells_dynamic_test_SOURCES = gstmotioncells_dynamic_test.c
 gsthanddetect_test_SOURCES = gsthanddetect_test.c
 
 gstmotioncells_dynamic_test_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS)
@@ -11,6 +9,4 @@
 
 gsthanddetect_test_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS)
 gsthanddetect_test_LDFLAGS = $(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GSTPB_BASE_LIBS)
-noinst_HEADERS = 			\
-	gstmotioncells_dynamic_test.h	\
-	gst_element_print_properties.h
+	
diff --git a/tests/examples/opencv/Makefile.in b/tests/examples/opencv/Makefile.in
index 9396b67..bbb7942 100644
--- a/tests/examples/opencv/Makefile.in
+++ b/tests/examples/opencv/Makefile.in
@@ -14,7 +14,6 @@
 
 @SET_MAKE@
 
-
 VPATH = @srcdir@
 am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
 am__make_running_with_option = \
@@ -84,7 +83,7 @@
 	gsthanddetect_test$(EXEEXT)
 subdir = tests/examples/opencv
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
-	$(top_srcdir)/depcomp $(noinst_HEADERS)
+	$(top_srcdir)/depcomp
 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 \
@@ -139,8 +138,7 @@
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
 	$(gsthanddetect_test_CFLAGS) $(CFLAGS) \
 	$(gsthanddetect_test_LDFLAGS) $(LDFLAGS) -o $@
-am_gstmotioncells_dynamic_test_OBJECTS = gstmotioncells_dynamic_test-gstmotioncells_dynamic_test.$(OBJEXT) \
-	gstmotioncells_dynamic_test-gst_element_print_properties.$(OBJEXT)
+am_gstmotioncells_dynamic_test_OBJECTS = gstmotioncells_dynamic_test-gstmotioncells_dynamic_test.$(OBJEXT)
 gstmotioncells_dynamic_test_OBJECTS =  \
 	$(am_gstmotioncells_dynamic_test_OBJECTS)
 gstmotioncells_dynamic_test_LDADD = $(LDADD)
@@ -191,7 +189,6 @@
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
-HEADERS = $(noinst_HEADERS)
 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
@@ -718,19 +715,12 @@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 wayland_scanner = @wayland_scanner@
-gstmotioncells_dynamic_test_SOURCES = \
-	gstmotioncells_dynamic_test.c	\
-	gst_element_print_properties.c
-
+gstmotioncells_dynamic_test_SOURCES = gstmotioncells_dynamic_test.c
 gsthanddetect_test_SOURCES = gsthanddetect_test.c
 gstmotioncells_dynamic_test_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS)
 gstmotioncells_dynamic_test_LDFLAGS = $(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GSTPB_BASE_LIBS)
 gsthanddetect_test_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS)
 gsthanddetect_test_LDFLAGS = $(GST_LIBS) $(GST_BASE_LIBS) $(GST_PLUGINS_BASE_LIBS) $(GSTPB_BASE_LIBS)
-noinst_HEADERS = \
-	gstmotioncells_dynamic_test.h	\
-	gst_element_print_properties.h
-
 all: all-am
 
 .SUFFIXES:
@@ -790,7 +780,6 @@
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsthanddetect_test-gsthanddetect_test.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gstmotioncells_dynamic_test-gst_element_print_properties.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gstmotioncells_dynamic_test-gstmotioncells_dynamic_test.Po@am__quote@
 
 .c.o:
@@ -845,20 +834,6 @@
 @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) $(gstmotioncells_dynamic_test_CFLAGS) $(CFLAGS) -c -o gstmotioncells_dynamic_test-gstmotioncells_dynamic_test.obj `if test -f 'gstmotioncells_dynamic_test.c'; then $(CYGPATH_W) 'gstmotioncells_dynamic_test.c'; else $(CYGPATH_W) '$(srcdir)/gstmotioncells_dynamic_test.c'; fi`
 
-gstmotioncells_dynamic_test-gst_element_print_properties.o: gst_element_print_properties.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gstmotioncells_dynamic_test_CFLAGS) $(CFLAGS) -MT gstmotioncells_dynamic_test-gst_element_print_properties.o -MD -MP -MF $(DEPDIR)/gstmotioncells_dynamic_test-gst_element_print_properties.Tpo -c -o gstmotioncells_dynamic_test-gst_element_print_properties.o `test -f 'gst_element_print_properties.c' || echo '$(srcdir)/'`gst_element_print_properties.c
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/gstmotioncells_dynamic_test-gst_element_print_properties.Tpo $(DEPDIR)/gstmotioncells_dynamic_test-gst_element_print_properties.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gst_element_print_properties.c' object='gstmotioncells_dynamic_test-gst_element_print_properties.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) $(gstmotioncells_dynamic_test_CFLAGS) $(CFLAGS) -c -o gstmotioncells_dynamic_test-gst_element_print_properties.o `test -f 'gst_element_print_properties.c' || echo '$(srcdir)/'`gst_element_print_properties.c
-
-gstmotioncells_dynamic_test-gst_element_print_properties.obj: gst_element_print_properties.c
-@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gstmotioncells_dynamic_test_CFLAGS) $(CFLAGS) -MT gstmotioncells_dynamic_test-gst_element_print_properties.obj -MD -MP -MF $(DEPDIR)/gstmotioncells_dynamic_test-gst_element_print_properties.Tpo -c -o gstmotioncells_dynamic_test-gst_element_print_properties.obj `if test -f 'gst_element_print_properties.c'; then $(CYGPATH_W) 'gst_element_print_properties.c'; else $(CYGPATH_W) '$(srcdir)/gst_element_print_properties.c'; fi`
-@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/gstmotioncells_dynamic_test-gst_element_print_properties.Tpo $(DEPDIR)/gstmotioncells_dynamic_test-gst_element_print_properties.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='gst_element_print_properties.c' object='gstmotioncells_dynamic_test-gst_element_print_properties.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) $(gstmotioncells_dynamic_test_CFLAGS) $(CFLAGS) -c -o gstmotioncells_dynamic_test-gst_element_print_properties.obj `if test -f 'gst_element_print_properties.c'; then $(CYGPATH_W) 'gst_element_print_properties.c'; else $(CYGPATH_W) '$(srcdir)/gst_element_print_properties.c'; fi`
-
 mostlyclean-libtool:
 	-rm -f *.lo
 
@@ -949,7 +924,7 @@
 	done
 check-am: all-am
 check: check-am
-all-am: Makefile $(PROGRAMS) $(HEADERS)
+all-am: Makefile $(PROGRAMS)
 installdirs:
 install: install-am
 install-exec: install-exec-am
diff --git a/tests/examples/opencv/gst_element_print_properties.c b/tests/examples/opencv/gst_element_print_properties.c
deleted file mode 100644
index b1b9dda..0000000
--- a/tests/examples/opencv/gst_element_print_properties.c
+++ /dev/null
@@ -1,607 +0,0 @@
-/* GStreamer
- * Copyright (C) 2010 Wesley Miller <wmiller@sdr.com>
- *
- *
- *  gst_element_print_properties(): a tool to inspect GStreamer
- *                                  element properties
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
- * with newer GLib versions (>= 2.31.0) */
-#define GLIB_DISABLE_DEPRECATION_WARNINGS
-
-#include <gst/gst.h>
-#include <string.h>
-#include <stdio.h>
-#include <locale.h>
-
-#include "gst_element_print_properties.h"
-
-
-void
-gst_element_print_properties (GstElement * element)
-{
-  /////////////////////////////////////////////////////////////////////////////
-  //
-  // Formatting setup
-  //
-  //    Change the valuses of c2w, c3w and c4w to adjust the 2nd, 3rd and 4th
-  //    column widths, respectively.  The gutter width is fixed at 3 and
-  //    alwasys prints as " | ".  Column 1 has a fixed width of 3.
-  //
-  //    The first two rows for each element's output are its element class
-  //    name (e.g. "GstAudioResample") and its element factory name
-  //    ("audioresample").  The long element factory name ("Audio resampler")
-  //    is in column 4 following the element factory name.
-  //
-  //    Most properties use this format.  Multivalued items like CAPS, certain
-  //    GST_TYPEs and enums are different.
-  //
-  //      Column 1  contains the rwc, "readable", "writable", "controllable"
-  //                flags of the property.
-  //      Column 2  contains the property name
-  //      Column 3  contains the current value
-  //      Column 4  contains the property type, e.g. G_TYPE_INT
-  //      Column 5  contains the range, if there is one, and the default.
-  //                The range is encosed in parentheses. e.g.  "(1-10)   5"
-  //
-  //    CAPS, enums, flags and some undefined items have no columns 4 or 5 and
-  //    column 3 will contain a description of the item.  Additional rows may
-  //    list specific valused (CAPS and flags).
-  //
-  //    String values are enclosed in double quotes.  A missing right quote
-  //    inidicates the string had been truncated.
-  //
-  //  Screen column
-  //  ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9--->
-  //
-  //  formatted columns with built in gutters
-  //  --- | ---------c2---------- | ---------c3-------- | -----------c4---------- | --> unspecified
-  //
-  //  <-->|<--- property name --->|<-- current value -->|<-------- type --------->|<----- range and default ----->
-  //      | ELEMENT CLASS NAME    | GstAudioResample    |                         |
-  //      | ELEMENT FACTORY NAME  | audioresample       | Audio resampler         |
-  //  RW- | name                  | "audioResampler"    | G_TYPE_STRING           | null
-  //  RW- | qos                   | false               | G_TYPE_BOOLEAN          | false
-  //  RW- | quality               | 8                   | G_TYPE_INT              | (0 - 10)   4
-  //
-  /////////////////////////////////////////////////////////////////////////////
-
-  const guint c2w = 21;         // column 2 width
-  const guint c3w = 19;         // column 3 width
-  const guint c4w = 23;         // column 4 width
-
-  /////////////////////////////////////////////////////////////////////////////
-  // end configuration variables.
-  /////////////////////////////////////////////////////////////////////////////
-
-  GParamSpec **property_specs;
-  guint num_properties, i;
-  gboolean readable;
-
-
-  g_return_if_fail (element != NULL);
-
-  property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (element),
-      &num_properties);
-
-   /*--- draw the header information ---*/
-  print_column_titles (c2w, c3w, c4w);
-  print_element_info (element, c2w, c3w, c4w);
-
-
-  for (i = 0; i < num_properties; i++) {
-    gchar flags[4];
-    GValue value = { 0, };
-    GParamSpec *param = property_specs[i];
-
-    readable = FALSE;
-
-    g_value_init (&value, param->value_type);
-
-    flags[0] = '-';
-    flags[1] = '-';
-    flags[2] = '-';
-    flags[3] = 0x0;
-
-    if (param->flags & G_PARAM_READABLE) {
-      g_object_get_property (G_OBJECT (element), param->name, &value);
-      readable = TRUE;
-      flags[0] = 'r';
-    }
-
-    if (param->flags & G_PARAM_WRITABLE)
-      flags[1] = 'w';
-
-    if (param->flags & GST_PARAM_CONTROLLABLE)
-      flags[2] = 'c';
-
-    g_print ("%s |", flags);
-    g_print (" %-*s | ", c2w, g_param_spec_get_name (param));
-
-    switch (G_VALUE_TYPE (&value)) {
-      case G_TYPE_STRING:      // String
-      {
-        GParamSpecString *pstring = G_PARAM_SPEC_STRING (param);
-        if (readable) {         /* current */
-          const char *string_val = g_value_get_string (&value);
-          gchar work_string[100];
-
-          if (string_val == NULL)
-            g_snprintf (work_string, sizeof (work_string), "\"%s\"", "null");
-          else
-            g_snprintf (work_string, sizeof (work_string), "\"%s\"",
-                string_val);
-          g_print ("%-*.*s", c3w, c3w, work_string);
-        } else {
-          g_print ("%-*s", c3w, "<not readable>");      /* alt current */
-        }
-        g_print (" | %-*s", c4w, "G_TYPE_STRING");      /* type */
-
-        if (pstring->default_value == NULL)
-          g_print (" | %s", "null");    /* default */
-        else
-          g_print (" | \"%s\"", pstring->default_value);        /* default */
-        break;
-      }
-
-      case G_TYPE_BOOLEAN:     //  Boolean
-      {
-        GParamSpecBoolean *pboolean = G_PARAM_SPEC_BOOLEAN (param);
-        if (readable)           /* current */
-          g_print ("%-*s", c3w,
-              (g_value_get_boolean (&value) ? "true" : "false"));
-        else
-          g_print ("%-*s", c3w, "<not readable>");
-        g_print (" | %-*s", c4w, "G_TYPE_BOOLEAN");     /* type */
-        g_print (" | %s ",      /* default */
-            (pboolean->default_value ? "true" : "false"));
-        break;
-      }
-
-      case G_TYPE_ULONG:       //  Unsigned Long
-      {
-        GParamSpecULong *pulong = G_PARAM_SPEC_ULONG (param);
-        if (readable)           /* current */
-          g_print ("%-*lu", c3w, g_value_get_ulong (&value));
-        else
-          g_print ("%-*s", c3w, "<not readable>");
-        g_print (" | %-*s", c4w, "G_TYPE_ULONG");       /* type */
-        g_print (" | (%lu - %lu)   %lu ", pulong->minimum, pulong->maximum,     /* range */
-            pulong->default_value);     /* default */
-        break;
-      }
-
-      case G_TYPE_LONG:        //  Long
-      {
-        GParamSpecLong *plong = G_PARAM_SPEC_LONG (param);
-        if (readable)           /* current */
-          g_print ("%-*ld", c3w, g_value_get_long (&value));
-        else
-          g_print ("%-*s", c3w, "<not readable>");
-        g_print (" | %-*s", c4w, "G_TYPE_LONG");        /* type */
-        g_print (" | (%ld - %ld)   %ld ", plong->minimum, plong->maximum,       /* range */
-            plong->default_value);      /* default */
-        break;
-      }
-
-      case G_TYPE_UINT:        //  Unsigned Integer
-      {
-        GParamSpecUInt *puint = G_PARAM_SPEC_UINT (param);
-        if (readable)           /* current */
-          g_print ("%-*u", c3w, g_value_get_uint (&value));
-        else
-          g_print ("%-*s", c3w, "<not readable>");
-        g_print (" | %-*s", c4w, "G_TYPE_UINT");        /* type */
-        g_print (" | (%u - %u)   %u ", puint->minimum, puint->maximum,  /* range */
-            puint->default_value);      /* default */
-        break;
-      }
-
-      case G_TYPE_INT:         //  Integer
-      {
-        GParamSpecInt *pint = G_PARAM_SPEC_INT (param);
-        if (readable)           /* current */
-          g_print ("%-*d", c3w, g_value_get_int (&value));
-        else
-          g_print ("%-*s", c3w, "<not readable>");
-        g_print (" | %-*s", c4w, "G_TYPE_INT"); /* type */
-        g_print (" | (%d - %d)   %d ", pint->minimum, pint->maximum,    /* range */
-            pint->default_value);       /* default */
-        break;
-      }
-
-      case G_TYPE_UINT64:      //  Unsigned Integer64.
-      {
-        GParamSpecUInt64 *puint64 = G_PARAM_SPEC_UINT64 (param);
-        if (readable)           /* current */
-          g_print ("%-*" G_GUINT64_FORMAT, c3w, g_value_get_uint64 (&value));
-        else
-          g_print ("%-*s", c3w, "<not readable>");
-        g_print (" | %-*s", c4w, "G_TYPE_UINT64");      /* type */
-        g_print (" | (%" G_GUINT64_FORMAT " - %" G_GUINT64_FORMAT ")" "   %" G_GUINT64_FORMAT " ", puint64->minimum, puint64->maximum,  /* range */
-            puint64->default_value);    /* default */
-        break;
-      }
-
-      case G_TYPE_INT64:       // Integer64
-      {
-        GParamSpecInt64 *pint64 = G_PARAM_SPEC_INT64 (param);
-        if (readable)           /* current */
-          g_print ("%-*" G_GINT64_FORMAT, c3w, g_value_get_int64 (&value));
-        else
-          g_print ("%-*s", c3w, "<not readable>");
-        g_print (" | %-*s", c4w, "G_TYPE_INT64");       /* type */
-        g_print (" | (%" G_GINT64_FORMAT " - %" G_GINT64_FORMAT ")" "   %" G_GINT64_FORMAT " ", pint64->minimum, pint64->maximum,       /* range */
-            pint64->default_value);     /* default */
-        break;
-      }
-
-      case G_TYPE_FLOAT:       //  Float.
-      {
-        GParamSpecFloat *pfloat = G_PARAM_SPEC_FLOAT (param);
-        if (readable)           /* current */
-          g_print ("%-*g", c3w, g_value_get_float (&value));
-        else
-          g_print ("%-*s", c3w, "<not readable>");
-        g_print (" | %-*s", c4w, "G_TYPE_FLOAT");       /* type */
-        g_print (" | (%g - %g)   %g ", pfloat->minimum, pfloat->maximum,        /* range */
-            pfloat->default_value);     /* default */
-        break;
-      }
-
-      case G_TYPE_DOUBLE:      //  Double
-      {
-        GParamSpecDouble *pdouble = G_PARAM_SPEC_DOUBLE (param);
-        if (readable)           /* current */
-          g_print ("%-*g", c3w, g_value_get_double (&value));
-        else
-          g_print ("%-*s", c3w, "<not readable>");
-        g_print (" | %-*s", c4w, "G_TYPE_DOUBLE");      /* type */
-        g_print (" | (%g - %g)   %g ", pdouble->minimum, pdouble->maximum,      /* range */
-            pdouble->default_value);    /* default */
-        break;
-      }
-
-      default:
-        if (param->value_type == GST_TYPE_CAPS) {
-          const GstCaps *caps = gst_value_get_caps (&value);
-          if (!caps)
-            g_print ("%-*s | %-*.*s |", c3w, "Caps (NULL)", c4w, c4w, " ");
-          else {
-            gchar prefix_string[100];
-            g_snprintf (prefix_string, sizeof (prefix_string),
-                "    | %-*.*s | ", c2w, c2w, " ");
-            print_caps (caps, prefix_string);
-          }
-        }
-
-        else if (G_IS_PARAM_SPEC_ENUM (param)) {
-          GParamSpecEnum *penum = G_PARAM_SPEC_ENUM (param);
-          GEnumValue *values;
-          guint j = 0;
-          gint enum_value;
-          const gchar *def_val_nick = "", *cur_val_nick = "";
-          gchar work_string[100];
-
-          values = G_ENUM_CLASS (g_type_class_ref (param->value_type))->values;
-          enum_value = g_value_get_enum (&value);
-
-          while (values[j].value_name) {
-            if (values[j].value == enum_value)
-              cur_val_nick = values[j].value_nick;
-            if (values[j].value == penum->default_value)
-              def_val_nick = values[j].value_nick;
-            j++;
-          }
-
-          g_snprintf (work_string, sizeof (work_string), "%d, \"%s\"",
-              enum_value, cur_val_nick);
-          g_print ("%-*.*s", c3w, c3w, work_string);
-          g_print (" | Enum \"%s\" : %d, \"%s\"",
-              g_type_name (G_VALUE_TYPE (&value)),
-              penum->default_value, def_val_nick);
-        }
-
-        else if (G_IS_PARAM_SPEC_FLAGS (param)) {
-          GParamSpecFlags *pflags = G_PARAM_SPEC_FLAGS (param);
-          GFlagsValue *vals;
-          gchar *cur, *def;
-          gchar work_string[100];
-
-          vals = pflags->flags_class->values;
-          cur = flags_to_string (vals, g_value_get_flags (&value));     /* current */
-          def = flags_to_string (vals, pflags->default_value);  /* default */
-
-          /* current */
-          g_snprintf (work_string, sizeof (work_string), "0x%08x, \"%s\"",
-              g_value_get_flags (&value), cur);
-          g_print ("%-*.*s", c3w, c3w, work_string);
-
-          /* type */
-          g_snprintf (work_string, sizeof (work_string), "Flags \"%s\"",
-              g_type_name (G_VALUE_TYPE (&value)));
-          g_print ("%-*.*s", c4w, c4w, work_string);
-
-          /* default */
-          g_print (" | 0x%08x, \"%s\"", pflags->default_value, def);
-
-          /* values list */
-          while (vals[0].value_name) {
-            g_snprintf (work_string, sizeof (work_string),
-                "\n    | %-*.*s |   (0x%08x): %-16s - %s", c2w, c2w, "",
-                vals[0].value, vals[0].value_nick, vals[0].value_name);
-            g_print ("%s", work_string);
-            ++vals;
-          }
-
-          g_free (cur);
-          g_free (def);
-        }
-
-        else if (G_IS_PARAM_SPEC_OBJECT (param)) {
-          g_print ("%-*.*s | Object of type \"%s\"",
-              c3w, c3w,
-              g_type_name (param->value_type), g_type_name (param->value_type));
-        }
-
-        else if (G_IS_PARAM_SPEC_BOXED (param)) {
-          g_print ("%-*.*s | Boxed pointer of type \"%s\"",
-              c3w, c3w,
-              g_type_name (param->value_type), g_type_name (param->value_type));
-        }
-
-        else if (G_IS_PARAM_SPEC_POINTER (param)) {
-          if (param->value_type != G_TYPE_POINTER) {
-            g_print ("%-*.*s | Pointer of type \"%s\"",
-                c3w, c3w,
-                g_type_name (param->value_type),
-                g_type_name (param->value_type));
-          } else {
-            g_print ("%-*.*s |", c3w, c3w, "Pointer.");
-          }
-        }
-
-        else if (param->value_type == G_TYPE_VALUE_ARRAY) {
-          GParamSpecValueArray *pvarray = G_PARAM_SPEC_VALUE_ARRAY (param);
-          if (pvarray->element_spec) {
-            g_print ("%-*.*s :Array of GValues of type \"%s\"",
-                c3w, c3w,
-                g_type_name (pvarray->element_spec->value_type),
-                g_type_name (pvarray->element_spec->value_type));
-          } else {
-            g_print ("%-*.*s :", c3w, c3w, "Array of GValues");
-          }
-        }
-
-        else if (GST_IS_PARAM_SPEC_FRACTION (param)) {
-          GstParamSpecFraction *pfraction = GST_PARAM_SPEC_FRACTION (param);
-          gchar work_string[100];
-
-          if (readable) {       /* current */
-            g_snprintf (work_string, sizeof (work_string), "%d/%d",
-                gst_value_get_fraction_numerator (&value),
-                gst_value_get_fraction_denominator (&value));
-            g_print ("%-*.*s", c3w, c3w, work_string);
-          } else
-            g_print ("%-*s", c3w, "<not readable>");
-
-          g_print (" | %-*.*s", /* type */
-              c3w, c3w, " Fraction. ");
-          g_print (" | (%d/%d - %d/%d)",        /* range */
-              pfraction->min_num, pfraction->min_den,
-              pfraction->max_num, pfraction->max_den);
-          g_print ("   %d/%d ", /* default */
-              pfraction->def_num, pfraction->def_den);
-        }
-
-        else if (G_IS_PARAM_SPEC_BOXED (param)) {
-          g_print ("%-*.*s | Boxed of type \"%s\"",
-              c3w, c3w,
-              g_type_name (param->value_type), g_type_name (param->value_type));
-        }
-
-        else {
-          g_print ("Unknown type %ld \"%s\"",
-              (glong) param->value_type, g_type_name (param->value_type));
-
-        }
-        break;
-    }
-
-    if (!readable)
-      g_print (" Write only\n");
-    else
-      g_print ("\n");
-
-    g_value_reset (&value);
-  }
-
-  if (0 == num_properties)
-    g_print ("  none\n");
-
-  g_free (property_specs);
-}
-
-//------------------------------------------------------------------------------
-void
-print_column_titles (guint c2w, guint c3w, guint c4w)
-{
-  //////////////////////////////////////////////////////////////////////////
-  //
-  // Create Header for property listing
-  // RWF | --- element name ---- | ---------c3-------- | -----------c4---------- | --> unspecified
-  //
-  //////////////////////////////////////////////////////////////////////////
-  gchar work_string[200];
-  gchar dashes[] = "-----------------------------";
-  gint llen = 0;
-  gint rlen = 0;
-
-      /*--- column 1 - RWC ---*/
-  g_snprintf (work_string, sizeof (work_string), "<-->|<");
-
-      /*--- column 2 - property name ---*/
-  llen = (c2w - 15) / 2;        /* width of " property name " = 15 */
-  rlen = c2w - 15 - llen;
-
-  strncat (work_string, dashes, llen);
-  strcat (work_string, " property name ");
-  strncat (work_string, dashes, rlen);
-  strcat (work_string, ">|<");
-
-      /*--- column 3 - current value ---*/
-  llen = (c3w - 15) / 2;        /* width of " current value " = 15 */
-  rlen = c3w - 15 - llen;
-
-  strncat (work_string, dashes, llen);
-  strcat (work_string, " current value ");
-  strncat (work_string, dashes, rlen);
-  strcat (work_string, ">|<");
-
-      /*--- column 4 - type ---*/
-  llen = (c4w - 6) / 2;         /* width of " type " = 6 */
-  rlen = c4w - 6 - llen;
-
-  strncat (work_string, dashes, llen);
-  strcat (work_string, " type ");
-  strncat (work_string, dashes, rlen);
-  strcat (work_string, ">|<");
-
-      /*--- column 5 - range and default ---*/
-  strcat (work_string, "----- range and default ----->");
-
-  g_print ("\n%s\n", work_string);
-}
-
-//------------------------------------------------------------------------------
-void
-print_element_info (GstElement * element, guint c2w, guint c3w, guint c4w)
-{
-  /////////////////////////////////////////////////////////////////////////////
-  //
-  // Print element factory and class information as part of each header
-  //
-  /////////////////////////////////////////////////////////////////////////////
-  gchar work_string[100];
-  GstElementFactory *factory = gst_element_get_factory (element);
-
-  g_snprintf (work_string, sizeof (work_string), "ELEMENT CLASS NAME");
-  g_print ("    | %-*s", c2w, work_string);
-  g_print (" | %-*s", c3w, g_type_name (G_OBJECT_TYPE (element)));
-  g_print (" | %-*s | \n", c4w, "");
-
-
-  g_snprintf (work_string, sizeof (work_string), "ELEMENT FACTORY NAME");
-  g_print ("    | %-*s", c2w, work_string);
-
-  g_print (" | %-*s", c3w,
-      gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
-  g_print (" | %-*s | \n", c4w,
-      gst_element_factory_get_metadata (factory,
-          GST_ELEMENT_METADATA_LONGNAME));
-
-// "Audio Resampler"   g_print( " | %-*s",      c3w, gst_element_factory_get_longname( gst_element_get_factory( element )) );
-
-
-}
-
-//------------------------------------------------------------------------------
-gchar *
-flags_to_string (GFlagsValue * vals, guint flags)
-{
-  /////////////////////////////////////////////////////////////////////////////
-  //
-  // List individual flags in separate rows
-  //
-  /////////////////////////////////////////////////////////////////////////////
-  GString *s = NULL;
-  guint flags_left, i;
-
-  /* first look for an exact match and count the number of values */
-  for (i = 0; vals[i].value_name != NULL; ++i) {
-    if (vals[i].value == flags)
-      return g_strdup (vals[i].value_nick);
-  }
-
-  s = g_string_new (NULL);
-
-  /* we assume the values are sorted from lowest to highest value */
-  flags_left = flags;
-  while (i > 0) {
-    --i;
-    if (0 != vals[i].value && (flags_left & vals[i].value) == vals[i].value) {
-      if (0 < s->len)
-        g_string_append (s, " | ");
-      g_string_append (s, vals[i].value_nick);
-      flags_left -= vals[i].value;
-      if (0 == flags_left)
-        break;
-    }
-  }
-
-  if (0 == s->len)
-    g_string_assign (s, "(none)");
-
-  return g_string_free (s, FALSE);
-}
-
-
-//------------------------------------------------------------------------------
-void
-print_caps (const GstCaps * caps, const gchar * pfx)
-{
-  /////////////////////////////////////////////////////////////////////////////
-  //
-  // Print each caps value on a separate line
-  //
-  /////////////////////////////////////////////////////////////////////////////
-  guint i;
-
-  g_return_if_fail (caps != NULL);
-
-  if (gst_caps_is_any (caps)) {
-    g_print ("%s | %s", pfx, "ANY                 |                     |");
-    return;
-  }
-  if (gst_caps_is_empty (caps)) {
-    g_print ("%s | %s", pfx, "EMPTY               |                     |");
-    return;
-  }
-
-  for (i = 0; i < gst_caps_get_size (caps); i++) {
-    GstStructure *structure = gst_caps_get_structure (caps, i);
-    g_print ("%s", gst_structure_get_name (structure));
-    gst_structure_foreach (structure, print_field, (gpointer) pfx);
-  }
-}
-
-//------------------------------------------------------------------------------
-gboolean
-print_field (GQuark field, const GValue * value, gpointer pfx)
-{
-  /////////////////////////////////////////////////////////////////////////////
-  //
-  // printing function for individual caps fields
-  //
-  /////////////////////////////////////////////////////////////////////////////
-  gchar *str = gst_value_serialize (value);
-  g_print ("\n%s  %-15.15s - %s",
-      (gchar *) pfx, g_quark_to_string (field), str);
-  g_free (str);
-  return TRUE;
-}
diff --git a/tests/examples/opencv/gst_element_print_properties.h b/tests/examples/opencv/gst_element_print_properties.h
deleted file mode 100644
index 49beee3..0000000
--- a/tests/examples/opencv/gst_element_print_properties.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* GStreamer
- * Copyright (C) 2010 Wesley Miller <wmiller@sdr.com>
- *
- *
- *  gst_element_print_properties(): a tool to inspect GStreamer
- *                                  element properties
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef GST_ELEMENT_PRINT_PROPERTIES_H
-#define GST_ELEMENT_PRINT_PROPERTIES_H
-
-extern void gst_element_print_properties (GstElement * element);
-extern void print_column_titles (guint c2w, guint c3w, guint c4w);
-extern void print_element_info (GstElement * element, guint c2w, guint c3w,
-    guint c4w);
-extern gchar *flags_to_string (GFlagsValue * vals, guint flags);
-extern void print_caps (const GstCaps * caps, const gchar * pfx);
-extern gboolean print_field (GQuark field, const GValue * value, gpointer pfx);
-
-#endif
diff --git a/tests/examples/opencv/gstmotioncells_dynamic_test.c b/tests/examples/opencv/gstmotioncells_dynamic_test.c
index ad779cc..46720f8 100644
--- a/tests/examples/opencv/gstmotioncells_dynamic_test.c
+++ b/tests/examples/opencv/gstmotioncells_dynamic_test.c
@@ -1,237 +1,158 @@
 /* GStreamer
  * Copyright (C) 2011 Robert Jobbagy <jobbagy.robert@gmail.com>
+ * Copyright (C) 2014 Tim-Philipp Müller <tim centricular com>
  *
+ * motioncells_dynamic_test: test to show effect of property changes at runtime
  *
- *  gst_motioncells_dynamic_test(): a test tool what can to do dynamic change properties
+ * 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.
  *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * 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 <gst/gst.h>
-#include <glib.h>
-#include <glib/gprintf.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
-#include <locale.h>
-#include "gstmotioncells_dynamic_test.h"
-#include "gst_element_print_properties.h"
 
-const guint c2w = 21;           // column 2 width
-const guint c3w = 19;           // column 3 width
-const guint c4w = 23;           // column 4 width
-
-void
-setProperty (GstElement * mcells, char *property, char *prop_value, GType type,
-    GValue * value)
+static void
+print_element_properties (GstElement * element)
 {
+  GParamSpec **pspecs, *pspec;
+  guint num, i;
 
-  switch (type) {
-    case G_TYPE_STRING:
-    {
-      g_object_set (G_OBJECT (mcells), property, prop_value, NULL);
-      break;
+  g_print ("\tProperty : value (type)\n");
+
+  pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (element), &num);
+  for (i = 0; i < num; ++i) {
+    GValue val = G_VALUE_INIT;
+    const gchar *type_name;
+    gchar *s;
+
+    pspec = pspecs[i];
+
+    /* only care about properties we can read and write */
+    if ((pspec->flags & G_PARAM_READWRITE) != G_PARAM_READWRITE)
+      continue;
+    /* and which can be changed after construction */
+    if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY))
+      continue;
+    /* ignore some GstObject properties which are not interesting */
+    if (!strcmp (pspec->name, "name") || !strcmp (pspec->name, "parent"))
+      continue;
+    /* ignore properties we can't change in a meaningful way */
+    if (G_IS_PARAM_SPEC_BOXED (pspec) || G_IS_PARAM_SPEC_OBJECT (pspec)
+        || G_IS_PARAM_SPEC_POINTER (pspec))
+      continue;
+
+    g_value_init (&val, G_PARAM_SPEC_VALUE_TYPE (pspec));
+    g_object_get_property (G_OBJECT (element), pspec->name, &val);
+    s = gst_value_serialize (&val);
+
+    if (G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_STRING) {
+      type_name = "string";
+      g_free (s);
+      g_object_get (G_OBJECT (element), pspec->name, &s, NULL);
+      if (s == NULL)
+        s = g_strdup ("(null)");
+    } else {
+      type_name = g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec));
     }
-    case G_TYPE_BOOLEAN:
-    {
-      gboolean flag = (g_strcmp0 (prop_value, "true") == 0) ? TRUE : FALSE;
-      g_object_set (G_OBJECT (mcells), property, flag, NULL);
-      break;
-    }
-    case G_TYPE_ULONG:
-    {
-      unsigned long ulongval = strtoul (prop_value, NULL, 0);
-      g_object_set (G_OBJECT (mcells), property, ulongval, NULL);
-      break;
-    }
-    case G_TYPE_LONG:
-    {
-      long longval = atol (prop_value);
-      g_object_set (G_OBJECT (mcells), property, longval, NULL);
-      break;
-    }
-    case G_TYPE_UINT:
-    {
-      unsigned int uintval = atoi (prop_value);
-      g_object_set (G_OBJECT (mcells), property, uintval, NULL);
-      break;
-    }
-    case G_TYPE_INT:
-    {
-      int intval = atoi (prop_value);
-      g_object_set (G_OBJECT (mcells), property, intval, NULL);
-      break;
-    }
-    case G_TYPE_UINT64:
-    {
-      guint64 guint64val = atoi (prop_value);
-      g_object_set (G_OBJECT (mcells), property, guint64val, NULL);
-      break;
-    }
-    case G_TYPE_INT64:
-    {
-      gint64 gint64val = atoi (prop_value);
-      g_object_set (G_OBJECT (mcells), property, gint64val, NULL);
-      break;
-    }
-    case G_TYPE_FLOAT:
-    {
-      float floatval = atof (prop_value);
-      g_object_set (G_OBJECT (mcells), property, floatval, NULL);
-      break;
-    }
-    case G_TYPE_DOUBLE:
-    {
-      double doubleval = strtod (prop_value, NULL);
-      g_object_set (G_OBJECT (mcells), property, doubleval, NULL);
-      break;
-    }
-    default:
-      fprintf (stderr, "You gave me something wrong type of data !!! \n");
-      break;
+
+    g_print ("\t%s: %s (%s)\n", pspec->name, s, type_name);
+    g_free (s);
+    g_value_unset (&val);
   }
+
+  g_free (pspecs);
 }
 
-// gst-launch v4l2src ! videoscale ! videorate ! capsfilter "caps=video/x-raw-yuv,width=320,height=240,framerate=10/1" ! videoconvert ! motioncells ! videoconvert ! xvimagesink
 int
 main (int argc, char *argv[])
 {
-  GstElement *pipeline, *source, *videor, *videos, *decodebin, *capsf,
-      *colorsp0, *colorsp1, *mcells, *sink;
+  GstElement *pipeline, *source, *videor, *capsf;
+  GstElement *colorsp0, *colorsp1, *mcells, *sink;
   GstCaps *caps;
-  gchar property[20];
-  gchar prop_value[100];
-  GParamSpec **property_specs;
-  guint num_properties, i;
-  GValue value = { 0, };
-  gboolean found_property = FALSE;
-  int ret;
 
-  // Initialisation //
   gst_init (&argc, &argv);
-  fprintf (stderr, "Usage: %s test or rtsp rtsp://your/cam/address\n", argv[0]);
-  // Create gstreamer elements //
-  pipeline = gst_pipeline_new ("moitoncells-pipeline");
-  if (argc == 2 && (g_strcmp0 (argv[1], "test") == 0))
-    source = gst_element_factory_make ("videotestsrc", "vidsrc");
-  else if (argc == 3 && (g_strcmp0 (argv[1], "rtsp") == 0))
-    source = gst_element_factory_make ("rtspsrc", "rtspsrc0");
-  else if (argc == 1)
-    source = gst_element_factory_make ("v4l2src", "v4l2");
-  else {
-    fprintf (stderr, "Usage: %s test or rtsp rtsp://your/cam/address\n",
-        argv[0]);
+
+  pipeline = gst_pipeline_new ("motioncells-pipeline");
+  if (argc == 2 && strcmp (argv[1], "test") == 0) {
+    source = gst_element_factory_make ("videotestsrc", NULL);
+    gst_util_set_object_arg (G_OBJECT (source), "pattern", "ball");
+  } else if (argc == 1 || strncmp (argv[1], "v4l", 3) == 0) {
+    source = gst_element_factory_make ("v4l2src", NULL);
+  } else {
+    g_printerr ("Usage: %s [v4l2|test]\n", argv[0]);
     exit (-1);
   }
 
-  videor = gst_element_factory_make ("videorate", "videor");
-  videos = gst_element_factory_make ("videoscale", "videos");
-  capsf = gst_element_factory_make ("capsfilter", "capsf");
-  if (argc == 3 && (g_strcmp0 (argv[1], "rtsp") == 0))
-    decodebin = gst_element_factory_make ("decodebin", "decode");
-  else
-    decodebin = NULL;
-  colorsp0 = gst_element_factory_make ("videoconvert", "colorspace0");
-  mcells = gst_element_factory_make ("motioncells", "mcells");
-  colorsp1 = gst_element_factory_make ("videoconvert", "colorspace1");
-  sink = gst_element_factory_make ("xvimagesink", "xv-image-sink");
-  if (!pipeline || !source || !videor || !videos || !capsf || !colorsp0
+  videor = gst_element_factory_make ("videorate", NULL);
+  capsf = gst_element_factory_make ("capsfilter", NULL);
+  colorsp0 = gst_element_factory_make ("videoconvert", NULL);
+  mcells = gst_element_factory_make ("motioncells", NULL);
+  colorsp1 = gst_element_factory_make ("videoconvert", NULL);
+  sink = gst_element_factory_make ("autovideosink", "videosink");
+  if (!pipeline || !source || !videor || !capsf || !colorsp0
       || !mcells || !colorsp1 || !sink) {
     g_printerr ("One element could not be created. Exiting.\n");
     return -1;
   }
-  if (argc == 3 && (g_strcmp0 (argv[1], "rtsp") == 0) && !decodebin) {
-    g_printerr ("Decodebin could not be created. Exiting.\n");
-    return -1;
-  }
-  if ((g_strcmp0 (argv[1], "rtsp") == 0)) {
-    g_object_set (G_OBJECT (source), "location", argv[2], NULL);
-    g_object_set (G_OBJECT (source), "latency", 1000, NULL);
-  } else if ((g_strcmp0 (argv[1], "test") == 0))
-    g_object_set (G_OBJECT (source), "pattern", 18, NULL);
 
-  caps =
-      gst_caps_from_string
-      ("video/x-raw-yuv,width=320,height=240,framerate=10/1");
+  caps = gst_caps_from_string ("video/x-raw,framerate=10/1");
   g_object_set (G_OBJECT (capsf), "caps", caps, NULL);
-  //g_object_set (G_OBJECT (sink), "sync",FALSE,NULL);
 
-  if (argc > 1) {
-    if (g_strcmp0 (argv[1], "test") == 0) {
-      gst_bin_add_many (GST_BIN (pipeline),
-          source, videor, videos, capsf, colorsp0, mcells, colorsp1, sink,
-          NULL);
+  gst_bin_add_many (GST_BIN (pipeline), source, videor, capsf, colorsp0, mcells,
+      colorsp1, sink, NULL);
 
-      gst_element_link_many (source, videor, videos, capsf, colorsp0, mcells,
-          colorsp1, sink, NULL);
-    } else if (g_strcmp0 (argv[1], "rtsp") == 0) {
-      gst_bin_add_many (GST_BIN (pipeline),
-          source, videor, videos, capsf, decodebin, colorsp0, mcells, colorsp1,
-          sink, NULL);
+  gst_element_link_many (source, videor, capsf, colorsp0, mcells, colorsp1,
+      sink, NULL);
 
-      gst_element_link_many (source, videor, videos, capsf, decodebin, colorsp0,
-          mcells, colorsp1, sink, NULL);
-    }
-  } else {                      //default
-    gst_bin_add_many (GST_BIN (pipeline),
-        source, videor, videos, capsf, colorsp0, mcells, colorsp1, sink, NULL);
-
-    gst_element_link_many (source, videor, videos, capsf, colorsp0, mcells,
-        colorsp1, sink, NULL);
-  }
-
-  g_print ("Now playing\n");
+  g_print ("Going to playing..\n");
   gst_element_set_state (pipeline, GST_STATE_PLAYING);
-  g_print ("Running...\n");
-  g_print ("You can use these properties : \n");
-  gst_element_print_properties (mcells);
-  g_print ("change property here: example  some_property property_value \n");
-  g_print ("Quit with 'q' \n");
-  //get all properties
-  property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (mcells),
-      &num_properties);
+
+  g_print ("You can use these properties: \n\n");
+
+  print_element_properties (mcells);
+
+  g_print ("\nSee 'gst-inspect-1.0 motioncells' for all the details.\n");
+  g_print ("Change properties like this: propertyname=value\n");
+  g_print ("Quit with 'q'\n");
+
+  /* Read command line input */
   while (TRUE) {
-    found_property = FALSE;
-    i = 0;
+    gchar *prop_name, *prop_value;
+    gchar input_buf[1024];
 
-    ret = scanf ("%19s %99s", property, prop_value);
-
-    if (ret < 1)
-      g_printerr ("Error parsing command.\n");
-
-    if ((g_strcmp0 (property, "q") == 0) || (g_strcmp0 (prop_value, "q") == 0))
+    memset (input_buf, 0, sizeof (input_buf));
+    if (fgets (input_buf, sizeof (input_buf), stdin) == NULL)
       break;
-    printf ("property: %s -> value: %s \n", property, prop_value);
-    for (i = 0; i < num_properties; i++) {
-      GParamSpec *param = property_specs[i];
-      g_value_init (&value, param->value_type);
-      g_object_get_property (G_OBJECT (mcells), param->name, &value);
-      //fprintf(stderr,"property: %s and param name: %s and property value: %s \n",property,param->name,prop_value);
-      if ((g_strcmp0 (property, param->name) == 0) && !found_property &&
-          (g_strcmp0 (prop_value, "") != 0)
-          && (g_strcmp0 (prop_value, "\"") != 0)
-          && (g_strcmp0 (prop_value, "\'") != 0)) {
-        GType type;
-        found_property = TRUE;
-        type = param->value_type;
-        setProperty (mcells, property, prop_value, type, &value);
-      }
-      g_value_unset (&value);
-      if (found_property)
-        break;
+
+    /* strip off trailing newline */
+    g_strdelimit (input_buf, "\n", '\0');
+
+    if (strcmp (input_buf, "q") == 0 || strcmp (input_buf, "quit") == 0)
+      break;
+
+    prop_value = strchr (input_buf, '=');
+    if (prop_value == NULL) {
+      g_printerr ("Please enter either 'property=value' or 'quit'.\n");
+      continue;
     }
+    *prop_value++ = '\0';
+    prop_name = input_buf;
+
+    gst_util_set_object_arg (G_OBJECT (mcells), prop_name, prop_value);
   }
 
   gst_element_set_state (pipeline, GST_STATE_NULL);
diff --git a/tests/examples/opencv/gstmotioncells_dynamic_test.h b/tests/examples/opencv/gstmotioncells_dynamic_test.h
deleted file mode 100644
index 6760c66..0000000
--- a/tests/examples/opencv/gstmotioncells_dynamic_test.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* GStreamer
- * Copyright (C) 2011 Robert Jobbagy <jobbagy.robert@gmail.com>
- *
- *
- *  gst_motioncells_dynamic_test(): a test tool what can to do dynamic change properties
- *
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef GST_MOTIONCELLS_DYNAMIC_TEST_H
-#define GST_MOTIONCELLS_DYNAMIC_TEST_H
-
-extern void setProperty (GstElement * mcells, char *property, char *prop_value,
-    GType type, GValue * value);
-
-
-#endif