Update to debian 1.14.4

* Update to debian 1.14.4-1
* For Day release
* Remove Plugin doc for a smaller package

Bug: 148502049
Change-Id: I9002ffe7430808a815af212a5413e773154c958b
diff --git a/debian/build-deps b/debian/build-deps
index a64dd32..d971fbe 100644
--- a/debian/build-deps
+++ b/debian/build-deps
@@ -1,6 +1,6 @@
 @GST_LIB_DEV_DEP@
 @GST_EXTRA_BUILD_DEPENDS@
-libgstreamer-plugins-base@GST_ABI@-dev (>= 1.10.0)
+libgstreamer-plugins-base@GST_ABI@-dev (>= 1.14.4)
 autotools-dev
 dh-autoreconf
 automake (>= 1.14)
@@ -8,7 +8,7 @@
 libtool (>= 2.2.6)
 autopoint (>= 0.17)
 cdbs (>= 0.4.93)
-debhelper (>= 9)
+debhelper (>= 10)
 dpkg-dev (>= 1.15.1)
 pkg-config (>= 0.11.0)
 gtk-doc-tools (>= 1.12)
@@ -27,10 +27,10 @@
 libxext-dev
 libxfixes-dev
 libxv-dev
-libgtk-3-dev
+libgtk-3-dev (>= 3.15)
 libtag1-dev (>= 1.5)
 libwavpack-dev (>= 4.60)
-gstreamer@GST_ABI@-plugins-base (>= 1.10.0)
+gstreamer@GST_ABI@-plugins-base (>= 1.14.4)
 libsoup2.4-dev (>= 2.48)
 libpulse-dev (>= 2.0)
 libbz2-dev
@@ -38,3 +38,7 @@
 gstreamer@GST_ABI@-plugins-base-doc
 libjack-jackd2-dev
 libvpx-dev (>= 1.3.0)
+libmp3lame-dev
+libmpg123-dev (>= 1.13)
+libtwolame-dev (>= 0.3.10)
+
diff --git a/debian/build-deps.in b/debian/build-deps.in
index a64dd32..2a7ef91 100644
--- a/debian/build-deps.in
+++ b/debian/build-deps.in
@@ -1,6 +1,6 @@
 @GST_LIB_DEV_DEP@
 @GST_EXTRA_BUILD_DEPENDS@
-libgstreamer-plugins-base@GST_ABI@-dev (>= 1.10.0)
+libgstreamer-plugins-base@GST_ABI@-dev (>= 1.14.4)
 autotools-dev
 dh-autoreconf
 automake (>= 1.14)
@@ -27,10 +27,10 @@
 libxext-dev
 libxfixes-dev
 libxv-dev
-libgtk-3-dev
+libgtk-3-dev (>= 3.15)
 libtag1-dev (>= 1.5)
 libwavpack-dev (>= 4.60)
-gstreamer@GST_ABI@-plugins-base (>= 1.10.0)
+gstreamer@GST_ABI@-plugins-base (>= 1.14.4)
 libsoup2.4-dev (>= 2.48)
 libpulse-dev (>= 2.0)
 libbz2-dev
@@ -38,3 +38,9 @@
 gstreamer@GST_ABI@-plugins-base-doc
 libjack-jackd2-dev
 libvpx-dev (>= 1.3.0)
+libmp3lame-dev
+libmpg123-dev (>= 1.13)
+libtwolame-dev (>= 0.3.10)
+qtbase5-dev
+qtdeclarative5-dev
+libqt5x11extras5-dev
diff --git a/debian/changelog b/debian/changelog
index 2d1d3c7..3a15e0c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+gst-plugins-good1.0 (1.14.4-1+mtk) mendel-day; urgency=medium
+
+  * Update to debian 1.14.4-1
+  * Update to Day release
+  * Remove doc from package
+  * Remove qt5 from package
+
+ -- Coral Team <coral-support@google.com>  Wed, 29 Jan 2020 20:01:36 -0800
+
 gst-plugins-good1.0 (1.10.4-1+mtk) mendel-chef; urgency=medium
 
   * Add Mediatek patches
diff --git a/debian/control b/debian/control
index e2f2a6a..33e5f22 100644
--- a/debian/control
+++ b/debian/control
@@ -1,33 +1,15 @@
 Source: gst-plugins-good1.0
 Section: libs
 Priority: optional
-Maintainer: Maintainers of GStreamer packages <pkg-gstreamer-maintainers@lists.alioth.debian.org>
+Maintainer: Maintainers of GStreamer packages <gst-plugins-good1.0@packages.debian.org>
 Uploaders: Loic Minier <lool@dooz.org>,
            Sebastian Dröge <slomo@debian.org>,
            Sjoerd Simons <sjoerd@debian.org>
-Build-Depends: libgstreamer1.0-dev (>= 1.10.0),  libraw1394-dev (>= 2.0.0) [linux-any] , libiec61883-dev (>= 1.0.0) [linux-any] , libavc1394-dev [linux-any] , libv4l-dev [linux-any] , libgudev-1.0-dev (>= 143) [linux-any], libgstreamer-plugins-base1.0-dev (>= 1.10.4-1+mtk), autotools-dev, dh-autoreconf, automake (>= 1.14), autoconf (>= 2.69), libtool (>= 2.2.6), autopoint (>= 0.17), cdbs (>= 0.4.93), debhelper (>= 9), dpkg-dev (>= 1.15.1), pkg-config (>= 0.11.0), gtk-doc-tools (>= 1.12), libglib2.0-dev (>= 2.40), liborc-0.4-dev (>= 1:0.4.17), libcairo2-dev (>= 1.10.0), libcaca-dev, libspeex-dev (>= 1.1.6), libpng-dev, libshout3-dev, libjpeg-dev, libaa1-dev (>= 1.4p5), libflac-dev (>= 1.1.4), libdv4-dev | libdv-dev, libxdamage-dev, libxext-dev, libxfixes-dev, libxv-dev, libgtk-3-dev, libtag1-dev (>= 1.5), libwavpack-dev (>= 4.60), gstreamer1.0-plugins-base (>= 1.10.0), libsoup2.4-dev (>= 2.48), libpulse-dev (>= 2.0), libbz2-dev, gstreamer1.0-doc, gstreamer1.0-plugins-base-doc, libjack-jackd2-dev, libvpx-dev (>= 1.3.0)
+Build-Depends: libgstreamer1.0-dev (>= 1.14.4),  libraw1394-dev (>= 2.0.0) [linux-any] , libiec61883-dev (>= 1.0.0) [linux-any] , libavc1394-dev [linux-any] , libv4l-dev [linux-any] , libgudev-1.0-dev (>= 143) [linux-any], libgstreamer-plugins-base1.0-dev (>= 1.14.4-2+mtk), autotools-dev, dh-autoreconf, automake (>= 1.14), autoconf (>= 2.69), libtool (>= 2.2.6), autopoint (>= 0.17), cdbs (>= 0.4.93), debhelper (>= 9), dpkg-dev (>= 1.15.1), pkg-config (>= 0.11.0), libglib2.0-dev (>= 2.40), liborc-0.4-dev (>= 1:0.4.17), libcairo2-dev (>= 1.10.0), libcaca-dev, libspeex-dev (>= 1.1.6), libpng-dev, libshout3-dev, libjpeg-dev, libaa1-dev (>= 1.4p5), libflac-dev (>= 1.1.4), libdv4-dev | libdv-dev, libxdamage-dev, libxext-dev, libxfixes-dev, libxv-dev, libgtk-3-dev (>= 3.15), libtag1-dev (>= 1.5), libwavpack-dev (>= 4.60), gstreamer1.0-plugins-base (>= 1.14.4), libsoup2.4-dev (>= 2.48), libpulse-dev (>= 2.0), libbz2-dev, libjack-jackd2-dev, libvpx-dev (>= 1.3.0), libmp3lame-dev, libmpg123-dev (>= 1.13), libtwolame-dev (>= 0.3.10)
 Standards-Version: 3.9.8
-Vcs-Git: git://anonscm.debian.org/pkg-gstreamer/gst-plugins-good1.0.git
-Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-gstreamer/gst-plugins-good1.0.git;a=summary
-Homepage: http://gstreamer.freedesktop.org/modules/gst-plugins-good.html
-
-Package: gstreamer1.0-plugins-good-doc
-Architecture: all
-Multi-Arch: foreign
-Section: doc
-Depends: gstreamer1.0-doc,
-         gstreamer1.0-plugins-base-doc,
-         ${misc:Depends}
-Description: GStreamer documentation for plugins from the "good" set
- GStreamer is a streaming media framework, based on graphs of filters
- which operate on media data.  Applications using this library can do
- anything from real-time sound processing to playing videos, and just
- about anything else media-related.  Its plugin-based architecture means
- that new data types or processing capabilities can be added simply by
- installing new plug-ins.
- .
- This package contains documentation for plugins from the "good" set,
- a set of good-quality plug-ins under the LGPL license.
+Vcs-Git: https://salsa.debian.org/gstreamer-team/gst-plugins-good1.0.git
+Vcs-Browser: https://salsa.debian.org/gstreamer-team/gst-plugins-good1.0/
+Homepage: https://gstreamer.freedesktop.org
 
 Package: gstreamer1.0-pulseaudio
 Architecture: any
@@ -53,6 +35,31 @@
  This package contains the GStreamer plugin for PulseAudio, a sound server
  for POSIX and WIN32 systems.
 
+Package: gstreamer1.0-gtk3
+Architecture: any
+Multi-Arch: same
+Section: graphics
+Depends: ${misc:Depends},
+         ${shlibs:Depends}
+XB-GStreamer-Version: ${gstreamer:Version}
+XB-GStreamer-Elements: ${gstreamer:Elements}
+XB-GStreamer-URI-Sources: ${gstreamer:URISources}
+XB-GStreamer-URI-Sinks: ${gstreamer:URISinks}
+XB-GStreamer-Encoders: ${gstreamer:Encoders}
+XB-GStreamer-Decoders: ${gstreamer:Decoders}
+Provides: ${gstreamer:Provides}
+Replaces: gstreamer1.0-plugins-bad (<< 1.13.1)
+Breaks: gstreamer1.0-plugins-bad (<< 1.13.1)
+Description: GStreamer plugin for GTK+3
+ GStreamer is a streaming media framework, based on graphs of filters
+ which operate on media data.  Applications using this library can do
+ anything from real-time sound processing to playing videos, and just
+ about anything else media-related.  Its plugin-based architecture means
+ that new data types or processing capabilities can be added simply by
+ installing new plug-ins.
+ .
+ This package contains the GStreamer plugin for GTK+3.
+
 Package: gstreamer1.0-plugins-good
 Architecture: any
 Multi-Arch: same
@@ -62,8 +69,10 @@
          gstreamer1.0-pulseaudio | gstreamer1.0-audiosink,
          gstreamer1.0-plugins-base,
 Recommends: gstreamer1.0-x
-Replaces: gstreamer1.0-plugins-bad (<< 1.1.2)
-Breaks: gstreamer1.0-plugins-bad (<< 1.7.90)
+Replaces: gstreamer1.0-plugins-bad (<< 1.13.1),
+          gstreamer1.0-plugins-ugly (<< 1.13.1)
+Breaks: gstreamer1.0-plugins-bad (<< 1.13.1),
+        gstreamer1.0-plugins-ugly (<< 1.13.1)
 XB-GStreamer-Version: ${gstreamer:Version}
 XB-GStreamer-Elements: ${gstreamer:Elements}
 XB-GStreamer-URI-Sources: ${gstreamer:URISources}
@@ -86,12 +95,13 @@
 Architecture: any
 Multi-Arch: same
 Section: debug
-Priority: extra
+Priority: optional
 Depends: gstreamer1.0-plugins-good (= ${binary:Version}),
          gstreamer1.0-pulseaudio (= ${binary:Version}),
+         gstreamer1.0-gtk3 (= ${binary:Version}),
          ${misc:Depends}
-Replaces: gstreamer1.0-plugins-bad (<< 1.1.2)
-Breaks: gstreamer1.0-plugins-bad (<< 1.7.90)
+Replaces: gstreamer1.0-plugins-bad (<< 1.13.1)
+Breaks: gstreamer1.0-plugins-bad (<< 1.13.1)
 Description: GStreamer plugins from the "good" set
  GStreamer is a streaming media framework, based on graphs of filters
  which operate on media data.  Applications using this library can do
diff --git a/debian/control.in b/debian/control.in
index f48a908..afef58c 100644
--- a/debian/control.in
+++ b/debian/control.in
@@ -1,15 +1,15 @@
 Source: gst-plugins-good@GST_ABI@
 Section: libs
 Priority: optional
-Maintainer: Maintainers of GStreamer packages <pkg-gstreamer-maintainers@lists.alioth.debian.org>
+Maintainer: Maintainers of GStreamer packages <gst-plugins-good1.0@packages.debian.org>
 Uploaders: Loic Minier <lool@dooz.org>,
            Sebastian Dröge <slomo@debian.org>,
            Sjoerd Simons <sjoerd@debian.org>
 Build-Depends: BUILDDEPS
 Standards-Version: 3.9.3
-Vcs-Git: git://anonscm.debian.org/pkg-gstreamer/gst-plugins-good@GST_ABI@.git
-Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-gstreamer/gst-plugins-good@GST_ABI@.git;a=summary
-Homepage: http://gstreamer.freedesktop.org/modules/gst-plugins-good.html
+Vcs-Git: https://salsa.debian.org/gstreamer-team/gst-plugins-good1.0.git
+Vcs-Browser: https://salsa.debian.org/gstreamer-team/gst-plugins-good1.0/
+Homepage: https://gstreamer.freedesktop.org
 
 Package: @GST_PKGNAME@-plugins-good-doc
 Architecture: all
@@ -53,6 +53,57 @@
  This package contains the GStreamer plugin for PulseAudio, a sound server
  for POSIX and WIN32 systems.
 
+Package: @GST_PKGNAME@-qt5
+#Architecture: any
+Architecture: any-amd64 any-arm64 any-i386 any-mips any-mips64el any-mipsel any-ppc64el any-s390x any-alpha any-hppa any-ia64 any-m68k any-powerpc any-powerpcspe any-ppc64 any-riscv64 any-sh4 any-sparc64 any-x32
+Multi-Arch: same
+Section: graphics
+Depends: ${misc:Depends},
+         ${shlibs:Depends}
+XB-GStreamer-Version: ${gstreamer:Version}
+XB-GStreamer-Elements: ${gstreamer:Elements}
+XB-GStreamer-URI-Sources: ${gstreamer:URISources}
+XB-GStreamer-URI-Sinks: ${gstreamer:URISinks}
+XB-GStreamer-Encoders: ${gstreamer:Encoders}
+XB-GStreamer-Decoders: ${gstreamer:Decoders}
+Provides: ${gstreamer:Provides}
+Replaces: gstreamer1.0-plugins-bad (<< 1.13.1)
+Breaks: gstreamer1.0-plugins-bad (<< 1.13.1)
+Description: GStreamer plugin for Qt5
+ GStreamer is a streaming media framework, based on graphs of filters
+ which operate on media data.  Applications using this library can do
+ anything from real-time sound processing to playing videos, and just
+ about anything else media-related.  Its plugin-based architecture means
+ that new data types or processing capabilities can be added simply by
+ installing new plug-ins.
+ .
+ This package contains the GStreamer plugin for Qt5.
+
+Package: @GST_PKGNAME@-gtk3
+Architecture: any
+Multi-Arch: same
+Section: graphics
+Depends: ${misc:Depends},
+         ${shlibs:Depends}
+XB-GStreamer-Version: ${gstreamer:Version}
+XB-GStreamer-Elements: ${gstreamer:Elements}
+XB-GStreamer-URI-Sources: ${gstreamer:URISources}
+XB-GStreamer-URI-Sinks: ${gstreamer:URISinks}
+XB-GStreamer-Encoders: ${gstreamer:Encoders}
+XB-GStreamer-Decoders: ${gstreamer:Decoders}
+Provides: ${gstreamer:Provides}
+Replaces: gstreamer1.0-plugins-bad (<< 1.13.1)
+Breaks: gstreamer1.0-plugins-bad (<< 1.13.1)
+Description: GStreamer plugin for GTK+3
+ GStreamer is a streaming media framework, based on graphs of filters
+ which operate on media data.  Applications using this library can do
+ anything from real-time sound processing to playing videos, and just
+ about anything else media-related.  Its plugin-based architecture means
+ that new data types or processing capabilities can be added simply by
+ installing new plug-ins.
+ .
+ This package contains the GStreamer plugin for GTK+3.
+
 Package: @GST_PKGNAME@-plugins-good
 Architecture: any
 Multi-Arch: same
@@ -62,8 +113,10 @@
          @GST_PKGNAME@-pulseaudio | @GST_PKGNAME@-audiosink,
          gstreamer@GST_ABI@-plugins-base,
 Recommends: @GST_PKGNAME@-x
-Replaces: gstreamer1.0-plugins-bad (<< 1.1.2)
-Breaks: gstreamer1.0-plugins-bad (<< 1.7.90)
+Replaces: gstreamer1.0-plugins-bad (<< 1.13.1),
+          gstreamer1.0-plugins-ugly (<< 1.13.1)
+Breaks: gstreamer1.0-plugins-bad (<< 1.13.1),
+        gstreamer1.0-plugins-ugly (<< 1.13.1)
 XB-GStreamer-Version: ${gstreamer:Version}
 XB-GStreamer-Elements: ${gstreamer:Elements}
 XB-GStreamer-URI-Sources: ${gstreamer:URISources}
@@ -89,9 +142,11 @@
 Priority: extra
 Depends: @GST_PKGNAME@-plugins-good (= ${binary:Version}),
          @GST_PKGNAME@-pulseaudio (= ${binary:Version}),
+         @GST_PKGNAME@-qt5 (= ${binary:Version}) [any-amd64 any-arm64 any-i386 any-mips any-mips64el any-mipsel any-ppc64el any-s390x any-alpha any-hppa any-ia64 any-m68k any-powerpc any-powerpcspe any-ppc64 any-riscv64 any-sh4 any-sparc64 any-x32],
+         @GST_PKGNAME@-gtk3 (= ${binary:Version}),
          ${misc:Depends}
-Replaces: gstreamer1.0-plugins-bad (<< 1.1.2)
-Breaks: gstreamer1.0-plugins-bad (<< 1.7.90)
+Replaces: gstreamer1.0-plugins-bad (<< 1.13.1)
+Breaks: gstreamer1.0-plugins-bad (<< 1.13.1)
 Description: GStreamer plugins from the "good" set
  GStreamer is a streaming media framework, based on graphs of filters
  which operate on media data.  Applications using this library can do
diff --git a/debian/gstreamer-gtk3.install b/debian/gstreamer-gtk3.install
new file mode 100644
index 0000000..6573ec6
--- /dev/null
+++ b/debian/gstreamer-gtk3.install
@@ -0,0 +1 @@
+debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstgtk.so
diff --git a/debian/gstreamer-plugins-good.install b/debian/gstreamer-plugins-good.install
index 047470c..b2bcd0a 100644
--- a/debian/gstreamer-plugins-good.install
+++ b/debian/gstreamer-plugins-good.install
@@ -31,9 +31,11 @@
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstid3demux.so
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstjack.so
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstjpeg.so
+debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstlame.so
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstlevel.so
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmatroska.so
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmonoscope.so
+debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmpg123.so
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmulaw.so
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmultifile.so
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstmultipart.so
@@ -49,10 +51,11 @@
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstshapewipe.so
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstshout2.so
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstsmpte.so
-debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstsouphttpsrc.so
+debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstsoup.so
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstspectrum.so
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstspeex.so
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgsttaglib.so
+debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgsttwolame.so
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstudp.so
 @video4linux2@
 debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstvideobox.so
diff --git a/debian/gstreamer-pulseaudio.install b/debian/gstreamer-pulseaudio.install
index 49032e9..3b31a5a 100644
--- a/debian/gstreamer-pulseaudio.install
+++ b/debian/gstreamer-pulseaudio.install
@@ -1 +1 @@
-debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstpulse.so
+debian/tmp/usr/lib/*/gstreamer-@GST_ABI@/libgstpulseaudio.so
diff --git a/debian/gstreamer1.0-plugins-good-doc.lintian-overrides b/debian/gstreamer1.0-plugins-good-doc.lintian-overrides
deleted file mode 100644
index c9b84c4..0000000
--- a/debian/gstreamer1.0-plugins-good-doc.lintian-overrides
+++ /dev/null
@@ -1 +0,0 @@
-gstreamer1.0-plugins-good-doc: spelling-error-in-readme-debian *
diff --git a/debian/gstreamer1.0-plugins-good.lintian-overrides b/debian/gstreamer1.0-plugins-good.lintian-overrides
index 32b3da4..60773a5 100644
--- a/debian/gstreamer1.0-plugins-good.lintian-overrides
+++ b/debian/gstreamer1.0-plugins-good.lintian-overrides
@@ -1 +1,2 @@
 gstreamer1.0-plugins-good: spelling-error-in-readme-debian *
+gstreamer1.0-plugins-good: library-not-linked-against-libc *
diff --git a/debian/patches/0001-mtk.patch b/debian/patches/0001-mtk.patch
index 806e01b..f8c66d3 100644
--- a/debian/patches/0001-mtk.patch
+++ b/debian/patches/0001-mtk.patch
@@ -1,5 +1,39 @@
+From 1d8405c4d342d73d844e326d51cca559cce3accc Mon Sep 17 00:00:00 2001
+From: Qian Hu <Qian.Hu@mediatek.com>
+Date: Mon, 23 Sep 2019 19:13:31 +0800
+Subject: [PATCH] update gstreamer good to 1.14.4
+
+Signed-off-by: Qian Hu <Qian.Hu@mediatek.com>
+---
+ ext/pulse/pulsesink.c         |   7 +
+ gst/avi/gstavidemux.c         | 120 +++++++-
+ gst/avi/gstavidemux.h         |   4 +
+ gst/isomp4/qtdemux.c          |   8 +-
+ gst/matroska/matroska-demux.c |  15 +-
+ sys/v4l2/Makefile.am          |   8 +-
+ sys/v4l2/ext/videodev2.h      |  19 ++
+ sys/v4l2/gstv4l2.c            |  27 +-
+ sys/v4l2/gstv4l2bufferpool.c  |   5 +-
+ sys/v4l2/gstv4l2mtkjpegdec.c  | 183 ++++++++++++
+ sys/v4l2/gstv4l2mtkjpegdec.h  |  63 ++++
+ sys/v4l2/gstv4l2mtkvpudec.c   | 181 ++++++++++++
+ sys/v4l2/gstv4l2mtkvpudec.h   |  63 ++++
+ sys/v4l2/gstv4l2object.c      | 657 +++++++++++++++++++++++++++++++++++++++++-
+ sys/v4l2/gstv4l2object.h      |  21 ++
+ sys/v4l2/gstv4l2src.c         |   4 +-
+ sys/v4l2/gstv4l2videodec.c    | 237 ++++++++++++++-
+ sys/v4l2/gstv4l2videoenc.h    |  22 +-
+ sys/v4l2/v4l2_calls.c         |  29 +-
+ sys/v4l2/v4l2_calls.h         | 138 +++++++++
+ 20 files changed, 1775 insertions(+), 36 deletions(-)
+ create mode 100644 sys/v4l2/gstv4l2mtkjpegdec.c
+ create mode 100644 sys/v4l2/gstv4l2mtkjpegdec.h
+ create mode 100644 sys/v4l2/gstv4l2mtkvpudec.c
+ create mode 100644 sys/v4l2/gstv4l2mtkvpudec.h
+ create mode 100644 sys/v4l2/v4l2_calls.h
+
 diff --git a/ext/pulse/pulsesink.c b/ext/pulse/pulsesink.c
-index 521c4a60..d72e0186 100644
+index 521c4a6..d4c1ae2 100644
 --- a/ext/pulse/pulsesink.c
 +++ b/ext/pulse/pulsesink.c
 @@ -1265,6 +1265,13 @@ gst_pulseringbuffer_pause (GstAudioRingBuffer * buf)
@@ -7,20 +41,20 @@
    /* make sure the commit method stops writing */
    pbuf->paused = TRUE;
 +
-+  if (pbuf->in_commit) {
-+    /* we are waiting in a commit, signal */
-+    GST_DEBUG_OBJECT (psink, "signal commit before pause");
-+    pa_threaded_mainloop_signal (mainloop, 0);
++   if (pbuf->in_commit) {
++   /* we are waiting in a commit, signal */
++   GST_DEBUG_OBJECT (psink, "signal commit before pause");
++   pa_threaded_mainloop_signal (mainloop, 0);
 +  }
 +
    res = gst_pulsering_set_corked (pbuf, TRUE, TRUE);
    if (pbuf->in_commit) {
      /* we are waiting in a commit, signal */
 diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c
-index 768630c1..62bb7703 100644
+index c02ee89..f723509 100644
 --- a/gst/avi/gstavidemux.c
 +++ b/gst/avi/gstavidemux.c
-@@ -939,6 +939,21 @@ gst_avi_demux_handle_src_event (GstPad * pad, GstObject * parent,
+@@ -945,6 +945,22 @@ gst_avi_demux_handle_src_event (GstPad * pad, GstObject * parent,
  
  /* streaming helper (push) */
  
@@ -39,15 +73,16 @@
 +  return buffer;
 +}
 +
++
  /*
   * gst_avi_demux_peek_chunk_info:
   * @avi: Avi object
-@@ -1949,7 +1964,23 @@ gst_avi_demux_check_caps (GstAviDemux * avi, GstAviStream * stream,
+@@ -1965,7 +1981,23 @@ gst_avi_demux_check_caps (GstAviDemux * avi, GstAviStream * stream,
        gst_structure_remove_field (s, "palette_data");
        return caps;
      }
 -  } else if (!gst_structure_has_name (s, "video/x-h264")) {
-+  }
++    }
 +  else if (gst_structure_has_name (s, "video/x-wmv")) {
 +    if (gst_structure_has_field_typed (s, "format", G_TYPE_STRING)) {
 +      gchar *format_value;
@@ -67,19 +102,19 @@
      return caps;
    }
  
-@@ -2109,8 +2140,42 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf)
+@@ -2125,8 +2157,42 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf)
          switch (stream->strh->type) {
            case GST_RIFF_FCC_vids:
              stream->is_vbr = TRUE;
-+	     /*read videostream header*/
-+	     stream->video_header = gst_buffer_copy_region (sub, GST_BUFFER_COPY_ALL,
++			/*read videostream header*/
++        stream->video_header = gst_buffer_copy_region (sub, GST_BUFFER_COPY_ALL,
 +               0, sizeof (gst_riff_strf_vids));
-+	     stream->video_header_send_flag = TRUE;
++        stream->video_header_send_flag = TRUE;
 +
              res = gst_riff_parse_strf_vids (element, sub,
                  &stream->strf.vids, &stream->extradata);
 +
-+            if (stream->extradata != NULL) {
++			if (stream->extradata != NULL) {
 +              guint32 fourcc;
 +
 +              fourcc = (stream->strf.vids->compression) ?
@@ -110,7 +145,7 @@
              sub = NULL;
              GST_DEBUG_OBJECT (element, "marking video as VBR, res %d", res);
              break;
-@@ -5197,6 +5262,7 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
+@@ -5222,6 +5288,7 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
    GstAviStream *stream;
    gboolean processed = FALSE;
    GstBuffer *buf;
@@ -118,7 +153,7 @@
    guint64 offset, size;
    GstClockTime timestamp, duration;
    guint64 out_offset, out_offset_end;
-@@ -5275,13 +5341,12 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
+@@ -5300,13 +5367,12 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
      /* mark non-keyframes */
      if (keyframe || stream->is_raw) {
        GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
@@ -129,11 +164,11 @@
      }
  
      GST_BUFFER_DTS (buf) = timestamp;
-+    GST_BUFFER_PTS (buf) = timestamp;
++	GST_BUFFER_PTS (buf) = timestamp;
  
      GST_BUFFER_DURATION (buf) = duration;
      GST_BUFFER_OFFSET (buf) = out_offset;
-@@ -5302,6 +5367,54 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
+@@ -5327,6 +5393,54 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
      /* update current position in the segment */
      avi->segment.position = timestamp;
  
@@ -141,9 +176,9 @@
 +
 +	if (stream->strh->type == GST_RIFF_FCC_vids) {
 +	  guint32 fourcc;
-+      GstBuffer *frame_hdr = NULL;
++	  GstBuffer *frame_hdr = NULL;
 +	  fourcc = (stream->strf.vids->compression) ?
-+          stream->strf.vids->compression : stream->strh->fcc_handler;
++	      stream->strf.vids->compression : stream->strh->fcc_handler;
 +	  if (TRUE == stream->video_header_send_flag) {
 +		gchar *pad_name = NULL;
 +
@@ -160,7 +195,7 @@
 +			stream->video_header = NULL;
 +		  }
 +		  else {
-+                        gst_buffer_unref(stream->video_header);
++	                    gst_buffer_unref(stream->video_header);
 +			stream->video_header_send_flag = FALSE;
 +			stream->video_header = NULL;
 +		  }
@@ -169,15 +204,15 @@
 +
 +	  //add start code in WVC1 video, remove start code in WMV1/2/3 video
 +	  if (GST_MAKE_FOURCC ('W', 'V', 'C', '1') == fourcc) {
-+            frame_hdr = gst_avi_demux_get_frame_header(avi);
-+            buf = gst_buffer_append (frame_hdr, buf);
++	        frame_hdr = gst_avi_demux_get_frame_header(avi);
++	        buf = gst_buffer_append (frame_hdr, buf);
 +	  }
 +	  else if ((GST_MAKE_FOURCC ('W', 'M', 'V', '1') == fourcc) || (GST_MAKE_FOURCC ('W', 'M', 'V', '2') == fourcc)
-+                || (GST_MAKE_FOURCC ('W', 'M', 'V', '3') == fourcc) || (GST_MAKE_FOURCC ('W', 'M', 'V', 'A') == fourcc)) {
++	            || (GST_MAKE_FOURCC ('W', 'M', 'V', '3') == fourcc) || (GST_MAKE_FOURCC ('W', 'M', 'V', 'A') == fourcc)) {
 +		if (stream->extradata != NULL && stream->add_extra_data == TRUE) {
 +		  GstMapInfo info;
 +		  out = gst_buffer_copy_region (stream->extradata, GST_BUFFER_COPY_ALL,
-+                  gst_buffer_get_size (stream->extradata) - stream->ept_header_size, stream->ept_header_size);
++	              gst_buffer_get_size (stream->extradata) - stream->ept_header_size, stream->ept_header_size);
 +		  buf = gst_buffer_append (out, buf);
 +		  stream->add_extra_data = FALSE;
 +		  GST_DEBUG_OBJECT (avi, "add_extra_data");
@@ -189,7 +224,7 @@
          GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", off %" G_GUINT64_FORMAT
          ", off_end %" G_GUINT64_FORMAT,
 diff --git a/gst/avi/gstavidemux.h b/gst/avi/gstavidemux.h
-index 22e46a2e..669ee27b 100644
+index 22e46a2..669ee27 100644
 --- a/gst/avi/gstavidemux.h
 +++ b/gst/avi/gstavidemux.h
 @@ -120,6 +120,10 @@ typedef struct {
@@ -204,15 +239,15 @@
  } GstAviStream;
  
 diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
-index ba36a9e0..68caf62b 100644
+index 705bdf7..ef1236b 100644
 --- a/gst/isomp4/qtdemux.c
 +++ b/gst/isomp4/qtdemux.c
-@@ -12881,12 +12881,12 @@ gst_qtdemux_handle_esds (GstQTDemux * qtdemux, QtDemuxStream * stream,
+@@ -13568,12 +13568,12 @@ gst_qtdemux_handle_esds (GstQTDemux * qtdemux, QtDemuxStream * stream,
        caps = gst_caps_new_simple ("audio/x-dts",
            "framed", G_TYPE_BOOLEAN, TRUE, NULL);
        break;
 -    case 0xE1:                 /* QCELP */
-+      //case 0xE1:                 /* QCELP */
++    //case 0xE1:                 /* QCELP */
        /* QCELP, the codec_data is a riff tag (little endian) with
         * more info (http://ftp.3gpp2.org/TSGC/Working/2003/2003-05-SanDiego/TSG-C-2003-05-San%20Diego/WG1/SWG12/C12-20030512-006%20=%20C12-20030217-015_Draft_Baseline%20Text%20of%20FFMS_R2.doc). */
 -      caps = gst_caps_new_empty_simple ("audio/qcelp");
@@ -225,40 +260,41 @@
        break;
    }
 diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
-index e419a705..71f0e626 100644
+index 1b95451..878864d 100644
 --- a/gst/matroska/matroska-demux.c
 +++ b/gst/matroska/matroska-demux.c
-@@ -475,12 +475,13 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
+@@ -646,13 +646,13 @@ gst_matroska_demux_parse_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml,
+ 
          if ((ret = gst_ebml_read_uint (ebml, &id, &num)) != GST_FLOW_OK)
            break;
- 
-+        /*
+-
++	/*
          if (num == 0) {
            GST_ERROR_OBJECT (demux, "Invalid TrackUID 0");
            ret = GST_FLOW_ERROR;
            break;
          }
 -
-+        */
++	*/
          GST_DEBUG_OBJECT (demux, "TrackUID: %" G_GUINT64_FORMAT, num);
          context->uid = num;
          break;
-@@ -3650,6 +3651,10 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
+@@ -4043,6 +4043,10 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
            GST_BUFFER_PTS (sub) = lace_time;
        }
  
-+     if (!GST_BUFFER_PTS_IS_VALID (sub)) {
++	  if (!GST_BUFFER_PTS_IS_VALID (sub)) {
 +        GST_BUFFER_PTS (sub) = lace_time;
 +      }
 +
        buffer_timestamp = gst_matroska_track_get_buffer_timestamp (stream, sub);
  
        if (GST_CLOCK_TIME_IS_VALID (lace_time)) {
-@@ -5078,6 +5083,13 @@ gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
+@@ -5536,6 +5540,13 @@ gst_matroska_demux_video_caps (GstMatroskaTrackVideoContext *
        if (size > sizeof (gst_riff_strf_vids)) { /* some extra_data */
          gsize offset = sizeof (gst_riff_strf_vids);
  
-+        char * pDest = (char *)&(vids->compression);
++		char * pDest = (char *)&(vids->compression);
 +        int n_wmv = strncasecmp(pDest,"WMV",3);
 +        int n_wvc = strncasecmp(pDest,"WVC",3);
 +        if (!n_wmv || !n_wvc) {
@@ -269,47 +305,56 @@
              gst_buffer_new_wrapped (g_memdup ((guint8 *) vids + offset,
                  size - offset), size - offset);
 diff --git a/sys/v4l2/Makefile.am b/sys/v4l2/Makefile.am
-index 5ccea1a0..e507385e 100644
+index 3126c11..2e810fa 100644
 --- a/sys/v4l2/Makefile.am
 +++ b/sys/v4l2/Makefile.am
-@@ -14,6 +14,10 @@ libgstvideo4linux2_la_SOURCES = gstv4l2.c \
+@@ -14,13 +14,13 @@ libgstvideo4linux2_la_SOURCES = gstv4l2.c \
  				gstv4l2tuner.c \
  				gstv4l2transform.c \
  				gstv4l2videodec.c \
 +				gstv4l2mtkvpudec.c \
 +				gstv4l2mtkjpegdec.c \
-+				gstv4l2videoenc.c \
-+				gstv4l2h264enc.c \
+ 				gstv4l2videoenc.c \
+ 				gstv4l2h263enc.c \
+ 				gstv4l2h264enc.c \
+ 				gstv4l2mpeg4enc.c \
  				gstv4l2vidorient.c \
+-				gstv4l2vp8enc.c \
+-				gstv4l2vp9enc.c \
  				v4l2_calls.c \
  				v4l2-utils.c \
-@@ -55,6 +59,10 @@ noinst_HEADERS = \
+ 				tuner.c \
+@@ -60,13 +60,13 @@ noinst_HEADERS = \
  	gstv4l2tuner.h \
  	gstv4l2transform.h \
  	gstv4l2videodec.h \
 +	gstv4l2mtkvpudec.h \
 +	gstv4l2mtkjpegdec.h \
-+	gstv4l2videoenc.h \
-+	gstv4l2h264enc.h \
+ 	gstv4l2videoenc.h \
+ 	gstv4l2h263enc.h \
+ 	gstv4l2h264enc.h \
+ 	gstv4l2mpeg4enc.h \
  	gstv4l2vidorient.h \
- 	v4l2_calls.h \
+-	gstv4l2vp8enc.h \
+-	gstv4l2vp9enc.h \
  	v4l2-utils.h \
+ 	tuner.h \
+ 	tunerchannel.h \
 diff --git a/sys/v4l2/ext/videodev2.h b/sys/v4l2/ext/videodev2.h
-index 68e82be4..2cb753ac 100644
+index 59e1f3d..c0b023d 100644
 --- a/sys/v4l2/ext/videodev2.h
 +++ b/sys/v4l2/ext/videodev2.h
-@@ -526,6 +526,10 @@ struct v4l2_pix_format {
+@@ -557,6 +557,9 @@ struct v4l2_pix_format {
  #define V4L2_PIX_FMT_NV12MT  v4l2_fourcc('T', 'M', '1', '2') /* 12  Y/CbCr 4:2:0 64x32 macroblocks */
  #define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') /* 12  Y/CbCr 4:2:0 16x16 macroblocks */
  
 +#define V4L2_PIX_FMT_MT21    v4l2_fourcc('M', 'M', '2', '1')
 +#define V4L2_PIX_FMT_YUV422M v4l2_fourcc('Y', 'M', '1', '6') /* 16  YUV422 planar */
 +
-+
- /* three non contiguous planes - Y, Cb, Cr */
- #define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'M', '1', '2') /* 12  YUV420 planar */
- #define V4L2_PIX_FMT_YVU420M v4l2_fourcc('Y', 'M', '2', '1') /* 12  YVU420 planar */
-@@ -565,17 +569,27 @@ struct v4l2_pix_format {
+ /* three planes - Y Cb, Cr */
+ #define V4L2_PIX_FMT_YUV410  v4l2_fourcc('Y', 'U', 'V', '9') /*  9  YUV 4:1:0     */
+ #define V4L2_PIX_FMT_YVU410  v4l2_fourcc('Y', 'V', 'U', '9') /*  9  YVU 4:1:0     */
+@@ -615,14 +618,24 @@ struct v4l2_pix_format {
  #define V4L2_PIX_FMT_JPEG     v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG     */
  #define V4L2_PIX_FMT_DV       v4l2_fourcc('d', 'v', 's', 'd') /* 1394          */
  #define V4L2_PIX_FMT_MPEG     v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 Multiplexed */
@@ -330,70 +375,90 @@
 +#define V4L2_PIX_FMT_DIVX4    v4l2_fourcc('D', 'I', 'V', '4') /* Divx4           */
 +#define V4L2_PIX_FMT_DIVX5    v4l2_fourcc('D', 'I', 'V', '5') /* Divx5           */
 +#define V4L2_PIX_FMT_DIVX6    v4l2_fourcc('D', 'I', 'V', '6') /* Divx6           */
++
  #define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */
  #define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */
  #define V4L2_PIX_FMT_VP8      v4l2_fourcc('V', 'P', '8', '0') /* VP8 */
-+#define V4L2_PIX_FMT_VP9      v4l2_fourcc('V', 'P', '9', '0') /* VP9 */
- 
- /*  Vendor-specific formats   */
- #define V4L2_PIX_FMT_CPIA1    v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */
-@@ -605,6 +619,12 @@ struct v4l2_pix_format {
+@@ -655,6 +668,12 @@ struct v4l2_pix_format {
+ #define V4L2_PIX_FMT_JPGL	v4l2_fourcc('J', 'P', 'G', 'L') /* JPEG-Lite */
  #define V4L2_PIX_FMT_SE401      v4l2_fourcc('S', '4', '0', '1') /* se401 janggu compressed rgb */
  #define V4L2_PIX_FMT_S5C_UYVY_JPG v4l2_fourcc('S', '5', 'C', 'I') /* S5C73M3 interleaved UYVY/JPEG */
- 
 +#define V4L2_PIX_FMT_WMV1	v4l2_fourcc('W', 'M', 'V', '1') /* WMV7 */
 +#define V4L2_PIX_FMT_WMV2	v4l2_fourcc('W', 'M', 'V', '2') /* WMV8 */
 +#define V4L2_PIX_FMT_WMV3	v4l2_fourcc('W', 'M', 'V', '3') /* WMV9 */
 +#define V4L2_PIX_FMT_WMVA	v4l2_fourcc('W', 'M', 'V', 'A') /* WMVA */
 +#define V4L2_PIX_FMT_WVC1	v4l2_fourcc('W', 'V', 'C', '1') /* VC1 */
 +
- /* SDR formats - used only for Software Defined Radio devices */
- #define V4L2_SDR_FMT_CU8          v4l2_fourcc('C', 'U', '0', '8') /* IQ u8 */
- #define V4L2_SDR_FMT_CU16LE       v4l2_fourcc('C', 'U', '1', '6') /* IQ u16le */
+ #define V4L2_PIX_FMT_Y8I      v4l2_fourcc('Y', '8', 'I', ' ') /* Greyscale 8-bit L/R interleaved */
+ #define V4L2_PIX_FMT_Y12I     v4l2_fourcc('Y', '1', '2', 'I') /* Greyscale 12-bit L/R interleaved */
+ #define V4L2_PIX_FMT_Z16      v4l2_fourcc('Z', '1', '6', ' ') /* Depth data 16-bit */
 diff --git a/sys/v4l2/gstv4l2.c b/sys/v4l2/gstv4l2.c
-index b5e826a3..3722c82b 100644
+index 2674d9c..29e83a7 100644
 --- a/sys/v4l2/gstv4l2.c
 +++ b/sys/v4l2/gstv4l2.c
-@@ -49,6 +49,9 @@
- #include "gstv4l2videodec.h"
+@@ -54,6 +54,9 @@
+ #include "gstv4l2vp9enc.h"
  #include "gstv4l2deviceprovider.h"
  #include "gstv4l2transform.h"
 +#include "gstv4l2h264enc.h"
 +#include "gstv4l2mtkvpudec.h"
 +#include "gstv4l2mtkjpegdec.h"
  
- /* used in v4l2_calls.c and v4l2src_calls.c */
+ /* used in gstv4l2object.c and v4l2_calls.c */
  GST_DEBUG_CATEGORY (v4l2_debug);
-@@ -182,8 +185,14 @@ gst_v4l2_probe_and_register (GstPlugin * plugin)
+@@ -181,10 +184,16 @@ gst_v4l2_probe_and_register (GstPlugin * plugin)
  
      basename = g_path_get_basename (it->device_path);
  
--    if (gst_v4l2_is_video_dec (sink_caps, src_caps))
--      ret = gst_v4l2_video_dec_register (plugin, basename, it->device_path,
+-    if (gst_v4l2_is_video_dec (sink_caps, src_caps)) {
+-      gst_v4l2_video_dec_register (plugin, basename, it->device_path,
 +    if (gst_v4l2_is_mtk_jpeg_dec (sink_caps, src_caps))
-+      ret = gst_v4l2_mtk_jpeg_dec_register (plugin, basename, it->device_path,
++      gst_v4l2_mtk_jpeg_dec_register (plugin, basename, it->device_path,
 +          sink_caps, src_caps);
 +    else if (gst_v4l2_is_mtk_vpu_dec (sink_caps, src_caps))
-+      ret = gst_v4l2_mtk_vpu_dec_register (plugin, basename, it->device_path,
++      gst_v4l2_mtk_vpu_dec_register (plugin, basename, it->device_path,
 +          sink_caps, src_caps);
 +    else if (gst_v4l2_is_h264_enc (sink_caps, src_caps))
-+      ret = gst_v4l2_h264_enc_register (plugin, basename, it->device_path,
++      gst_v4l2_h264_enc_register (plugin, basename, it->device_path,
            sink_caps, src_caps);
-     else if (gst_v4l2_is_transform (sink_caps, src_caps))
-       ret = gst_v4l2_transform_register (plugin, basename, it->device_path,
+-    } else if (gst_v4l2_is_video_enc (sink_caps, src_caps, NULL)) {
++    else if (gst_v4l2_is_video_enc (sink_caps, src_caps, NULL)) {
+       if (gst_v4l2_is_h264_enc (sink_caps, src_caps))
+         gst_v4l2_h264_enc_register (plugin, basename, it->device_path,
+             sink_caps, src_caps);
+@@ -197,13 +206,13 @@ gst_v4l2_probe_and_register (GstPlugin * plugin)
+         gst_v4l2_h263_enc_register (plugin, basename, it->device_path,
+             sink_caps, src_caps);
+ 
+-      if (gst_v4l2_is_vp8_enc (sink_caps, src_caps))
+-        gst_v4l2_vp8_enc_register (plugin, basename, it->device_path,
+-            sink_caps, src_caps);
++      //if (gst_v4l2_is_vp8_enc (sink_caps, src_caps))
++        //gst_v4l2_vp8_enc_register (plugin, basename, it->device_path,
++            //sink_caps, src_caps);
+ 
+-      if (gst_v4l2_is_vp9_enc (sink_caps, src_caps))
+-        gst_v4l2_vp9_enc_register (plugin, basename, it->device_path,
+-            sink_caps, src_caps);
++      //if (gst_v4l2_is_vp9_enc (sink_caps, src_caps))
++        //gst_v4l2_vp9_enc_register (plugin, basename, it->device_path,
++            //sink_caps, src_caps);
+     } else if (gst_v4l2_is_transform (sink_caps, src_caps)) {
+       gst_v4l2_transform_register (plugin, basename, it->device_path,
+           sink_caps, src_caps);
 diff --git a/sys/v4l2/gstv4l2bufferpool.c b/sys/v4l2/gstv4l2bufferpool.c
-index e9aa8e66..03dfbe72 100644
+index 5a92dbb..124fef1 100644
 --- a/sys/v4l2/gstv4l2bufferpool.c
 +++ b/sys/v4l2/gstv4l2bufferpool.c
-@@ -1725,6 +1725,7 @@ gst_v4l2_buffer_pool_process (GstV4l2BufferPool * pool, GstBuffer ** buf)
+@@ -1715,6 +1715,7 @@ gst_v4l2_buffer_pool_process (GstV4l2BufferPool * pool, GstBuffer ** buf)
          case GST_V4L2_IO_DMABUF:
          {
            GstBuffer *tmp;
-+          struct v4l2_pix_format *pix_fmt = &(obj->format.fmt.pix);
++		  struct v4l2_pix_format *pix_fmt = &(obj->format.fmt.pix);
  
            if ((*buf)->pool == bpool) {
              guint num_queued;
-@@ -1759,7 +1760,7 @@ gst_v4l2_buffer_pool_process (GstV4l2BufferPool * pool, GstBuffer ** buf)
+@@ -1742,7 +1743,7 @@ gst_v4l2_buffer_pool_process (GstV4l2BufferPool * pool, GstBuffer ** buf)
              }
  
              /* start copying buffers when we are running low on buffers */
@@ -402,297 +467,18 @@
                GstBuffer *copy;
  
                if (GST_V4L2_ALLOCATOR_CAN_ALLOCATE (pool->vallocator, MMAP)) {
-@@ -1802,6 +1803,8 @@ gst_v4l2_buffer_pool_process (GstV4l2BufferPool * pool, GstBuffer ** buf)
+@@ -1781,6 +1782,8 @@ gst_v4l2_buffer_pool_process (GstV4l2BufferPool * pool, GstBuffer ** buf)
  
            ret = gst_v4l2_buffer_pool_copy_buffer (pool, *buf, tmp);
  
-+          GST_BUFFER_TIMESTAMP(*buf) = GST_BUFFER_TIMESTAMP(tmp);
++		  GST_BUFFER_TIMESTAMP(*buf) = GST_BUFFER_TIMESTAMP(tmp);
 +
            /* an queue the buffer again after the copy */
            gst_v4l2_buffer_pool_release_buffer (bpool, tmp);
  
-diff --git a/sys/v4l2/gstv4l2h264enc.c b/sys/v4l2/gstv4l2h264enc.c
-new file mode 100644
-index 00000000..bd7d34d7
---- /dev/null
-+++ b/sys/v4l2/gstv4l2h264enc.c
-@@ -0,0 +1,204 @@
-+/*
-+ * Copyright (C) 2014 ayaka <ayaka@soulik.info>
-+ * Copyright (C) 2016 Rick Chang <rick.chang@mediatek.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 <sys/stat.h>
-+#include <fcntl.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <string.h>
-+
-+#include "gstv4l2h264enc.h"
-+#include "v4l2_calls.h"
-+
-+#include <string.h>
-+#include <gst/gst-i18n-plugin.h>
-+
-+GST_DEBUG_CATEGORY_STATIC (gst_v4l2_h264_enc_debug);
-+#define GST_CAT_DEFAULT gst_v4l2_h264_enc_debug
-+
-+typedef struct
-+{
-+  gchar *device;
-+  GstCaps *sink_caps;
-+  GstCaps *src_caps;
-+} GstV4l2VideoEncCData;
-+
-+enum
-+{
-+  PROP_0,
-+  V4L2_STD_OBJECT_PROPS,
-+};
-+
-+static GstStaticPadTemplate src_template = 
-+GST_STATIC_PAD_TEMPLATE("src",
-+    GST_PAD_SRC,
-+    GST_PAD_ALWAYS,
-+    GST_STATIC_CAPS(
-+      "video/x-h264, "
-+      "stream-format = (string) byte-stream, "
-+      "alignment = (string) { au }; "
-+    )
-+);
-+
-+#define gst_v4l2_h264_enc_parent_class parent_class
-+G_DEFINE_TYPE (GstV4l2H264Enc, gst_v4l2_h264_enc, GST_TYPE_V4L2_VIDEO_ENC);
-+
-+static GstFlowReturn
-+gst_v4l2_h264_enc_handle_frame (GstVideoEncoder * encoder,
-+    GstVideoCodecFrame * frame)
-+{
-+  GstV4l2VideoEnc *parent = GST_V4L2_VIDEO_ENC (encoder);
-+  GstStructure *structure;
-+  GstCaps *outcaps;
-+
-+  if (G_UNLIKELY (!GST_V4L2_IS_ACTIVE (parent->v4l2capture))) {
-+    outcaps = gst_caps_new_empty_simple ("video/x-h264");
-+    structure = gst_caps_get_structure (outcaps, 0);
-+    gst_structure_set (structure, "stream-format",
-+        G_TYPE_STRING, "byte-stream", NULL);
-+    gst_structure_set (structure, "alignment", G_TYPE_STRING, "au", NULL);
-+    return GST_V4L2_VIDEO_ENC_CLASS (parent_class)->handle_frame
-+        (encoder, frame, outcaps);
-+  }
-+
-+  return GST_V4L2_VIDEO_ENC_CLASS (parent_class)->handle_frame
-+      (encoder, frame, NULL);
-+}
-+
-+static void
-+gst_v4l2_h264_enc_init (GstV4l2H264Enc * self)
-+{
-+
-+}
-+
-+static void
-+gst_v4l2_h264_enc_class_init (GstV4l2H264EncClass * klass)
-+{
-+  GstElementClass *element_class;
-+  GObjectClass *gobject_class;
-+  GstV4l2VideoEncClass *v4l2_encoder_class;
-+  GstVideoEncoderClass *baseclass;
-+
-+  parent_class = g_type_class_peek_parent (klass);
-+
-+  element_class = (GstElementClass *) klass;
-+  gobject_class = (GObjectClass *) klass;
-+  v4l2_encoder_class = GST_V4L2_VIDEO_ENC_CLASS (klass);
-+  baseclass = GST_VIDEO_ENCODER_CLASS (klass);
-+
-+  GST_DEBUG_CATEGORY_INIT (gst_v4l2_h264_enc_debug, "v4l2mtkh264enc", 0,
-+      "V4L2 Mtk H.264 HW Encoder");
-+
-+  gst_element_class_set_static_metadata (element_class,
-+      "V4L2 Mtk H.264 HW Encoder",
-+      "Codec/Encoder/Video",
-+      "MTK H.264 HW encode via V4L2 API",
-+      "ayaka <ayaka@soulik.info>\n"
-+      "Rick Chang <rick.chang@mediatek.com>");
-+
-+  /* FIXME propose_allocation or not ? */
-+  baseclass->handle_frame = GST_DEBUG_FUNCPTR (gst_v4l2_h264_enc_handle_frame);
-+}
-+
-+/* Probing functions */
-+gboolean
-+gst_v4l2_is_h264_enc (GstCaps * sink_caps, GstCaps * src_caps)
-+{
-+  gboolean ret = FALSE;
-+
-+  if (gst_caps_is_subset (sink_caps, gst_v4l2_object_get_raw_caps ())
-+      && gst_caps_can_intersect (src_caps,
-+          gst_caps_from_string ("video/x-h264")))
-+    ret = TRUE;
-+
-+  return ret;
-+}
-+
-+static void
-+gst_v4l2_h264_enc_subinstance_init (GTypeInstance * instance, gpointer g_class)
-+{
-+  GstV4l2VideoEncClass *klass = GST_V4L2_VIDEO_ENC_CLASS (g_class);
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (instance);
-+
-+  g_free (self->v4l2output->videodev);
-+  self->v4l2output->videodev = g_strdup (klass->default_device);
-+
-+  g_free (self->v4l2capture->videodev);
-+  self->v4l2capture->videodev = g_strdup (klass->default_device);
-+}
-+
-+static void
-+gst_v4l2_h264_enc_subclass_init (gpointer g_class, gpointer data)
-+{
-+  GstV4l2VideoEncClass *klass = GST_V4L2_VIDEO_ENC_CLASS (g_class);
-+  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-+  GstV4l2VideoEncCData *cdata = data;
-+
-+  klass->default_device = cdata->device;
-+
-+  /* Note: gst_pad_template_new() take the floating ref from the caps */
-+  gst_element_class_add_pad_template (element_class,
-+      gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
-+          cdata->sink_caps));
-+  gst_element_class_add_pad_template (element_class,
-+      gst_static_pad_template_get(&src_template));
-+
-+  g_free (cdata);
-+}
-+
-+gboolean
-+gst_v4l2_h264_enc_register (GstPlugin * plugin, const gchar * basename,
-+    const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps)
-+{
-+  GTypeQuery type_query;
-+  GTypeInfo type_info = { 0, };
-+  GType type, subtype;
-+  gchar *type_name;
-+  GstV4l2VideoEncCData *cdata;
-+
-+  cdata = g_new0 (GstV4l2VideoEncCData, 1);
-+  cdata->device = g_strdup (device_path);
-+  cdata->sink_caps = gst_caps_ref (sink_caps);
-+  cdata->src_caps = gst_caps_ref (src_caps);
-+
-+  type = gst_v4l2_h264_enc_get_type();
-+  g_type_query (type, &type_query);
-+  memset (&type_info, 0, sizeof (type_info));
-+  type_info.class_size = type_query.class_size;
-+  type_info.instance_size = type_query.instance_size;
-+  type_info.class_data = cdata;
-+
-+  type_info.class_init = gst_v4l2_h264_enc_subclass_init;
-+  type_info.instance_init = gst_v4l2_h264_enc_subinstance_init;
-+
-+  type_name = g_strdup_printf ("v4l2mtkh264enc");
-+  subtype = g_type_register_static (type, type_name, &type_info, 0);
-+
-+  gst_element_register (plugin, type_name, GST_RANK_PRIMARY + 1, subtype);
-+
-+  g_free (type_name);
-+
-+  return TRUE;
-+}
-diff --git a/sys/v4l2/gstv4l2h264enc.h b/sys/v4l2/gstv4l2h264enc.h
-new file mode 100644
-index 00000000..f0f6cbba
---- /dev/null
-+++ b/sys/v4l2/gstv4l2h264enc.h
-@@ -0,0 +1,63 @@
-+/*
-+ * Copyright (C) 2014 SUMOMO Computer Association.
-+ *     Author: ayaka <ayaka@soulik.info>
-+ *
-+ * 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_V4L2_H264_ENC_H__
-+#define __GST_V4L2_H264_ENC_H__
-+
-+#include <gst/gst.h>
-+#include "gstv4l2videoenc.h"
-+
-+GST_DEBUG_CATEGORY_EXTERN (v4l2h264enc_debug);
-+
-+G_BEGIN_DECLS
-+#define GST_TYPE_V4L2_H264_ENC \
-+  (gst_v4l2_h264_enc_get_type())
-+#define GST_V4L2_H264_ENC(obj) \
-+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_V4L2_H264_ENC,GstV4l2H264Enc))
-+#define GST_V4L2_H264_ENC_CLASS(klass) \
-+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_V4L2_H264_ENC,GstV4l2H264EncClass))
-+#define GST_IS_V4L2_H264_ENC(obj) \
-+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_V4L2_H264_ENC))
-+#define GST_IS_V4L2_H264_ENC_CLASS(obj) \
-+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_V4L2_H264_ENC))
-+typedef struct _GstV4l2H264Enc GstV4l2H264Enc;
-+typedef struct _GstV4l2H264EncClass GstV4l2H264EncClass;
-+
-+struct _GstV4l2H264Enc
-+{
-+  GstV4l2VideoEnc parent;
-+};
-+
-+struct _GstV4l2H264EncClass
-+{
-+  GstV4l2VideoEncClass parent_class;
-+};
-+
-+GType gst_v4l2_h264_enc_get_type (void);
-+
-+gboolean gst_v4l2_is_h264_enc (GstCaps * sink_caps, GstCaps * src_caps);
-+
-+gboolean gst_v4l2_h264_enc_register (GstPlugin * plugin,
-+    const gchar * basename,
-+    const gchar * device_path, GstCaps * sink_caps, GstCaps * src_caps);
-+
-+G_END_DECLS
-+#endif /* __GST_V4L2_H264_ENC_H__ */
 diff --git a/sys/v4l2/gstv4l2mtkjpegdec.c b/sys/v4l2/gstv4l2mtkjpegdec.c
 new file mode 100644
-index 00000000..e2aabe82
+index 0000000..a33d8f0
 --- /dev/null
 +++ b/sys/v4l2/gstv4l2mtkjpegdec.c
 @@ -0,0 +1,183 @@
@@ -775,13 +561,13 @@
 +  gst_video_decoder_set_packetized (decoder, TRUE);
 +
 +  self->v4l2output = gst_v4l2_object_new (GST_ELEMENT (self),
-+      V4L2_BUF_TYPE_VIDEO_OUTPUT, klass->default_device,
++      GST_VIDEO_DECODER_SINK_PAD (decoder), V4L2_BUF_TYPE_VIDEO_OUTPUT, klass->default_device,
 +      gst_v4l2_get_output, gst_v4l2_set_output, NULL);
 +  self->v4l2output->no_initial_format = TRUE;
 +  self->v4l2output->keep_aspect = FALSE;
 +
 +  self->v4l2capture = gst_v4l2_object_new (GST_ELEMENT (self),
-+      V4L2_BUF_TYPE_VIDEO_CAPTURE, klass->default_device,
++      GST_VIDEO_DECODER_SRC_PAD (decoder), V4L2_BUF_TYPE_VIDEO_CAPTURE, klass->default_device,
 +      gst_v4l2_get_input, gst_v4l2_set_input, NULL);
 +  self->v4l2capture->no_initial_format = TRUE;
 +  self->v4l2output->keep_aspect = FALSE;
@@ -879,9 +665,10 @@
 +
 +  return TRUE;
 +}
+\ No newline at end of file
 diff --git a/sys/v4l2/gstv4l2mtkjpegdec.h b/sys/v4l2/gstv4l2mtkjpegdec.h
 new file mode 100644
-index 00000000..365b2364
+index 0000000..9be6b04
 --- /dev/null
 +++ b/sys/v4l2/gstv4l2mtkjpegdec.h
 @@ -0,0 +1,63 @@
@@ -948,9 +735,10 @@
 +
 +G_END_DECLS
 +#endif /* __GST_V4L2_MTK_JPEG_DEC_H__ */
+\ No newline at end of file
 diff --git a/sys/v4l2/gstv4l2mtkvpudec.c b/sys/v4l2/gstv4l2mtkvpudec.c
 new file mode 100644
-index 00000000..fd09362d
+index 0000000..5c35961
 --- /dev/null
 +++ b/sys/v4l2/gstv4l2mtkvpudec.c
 @@ -0,0 +1,181 @@
@@ -1033,18 +821,18 @@
 +  gst_video_decoder_set_packetized (decoder, TRUE);
 +
 +  self->v4l2output = gst_v4l2_object_new (GST_ELEMENT (self),
-+      V4L2_BUF_TYPE_VIDEO_OUTPUT, klass->default_device,
++      GST_VIDEO_DECODER_SINK_PAD (decoder), V4L2_BUF_TYPE_VIDEO_OUTPUT, klass->default_device,
 +      gst_v4l2_get_output, gst_v4l2_set_output, NULL);
 +  self->v4l2output->no_initial_format = TRUE;
 +  self->v4l2output->keep_aspect = FALSE;
 +
 +  self->v4l2capture = gst_v4l2_object_new (GST_ELEMENT (self),
-+      V4L2_BUF_TYPE_VIDEO_CAPTURE, klass->default_device,
++      GST_VIDEO_DECODER_SRC_PAD (decoder), V4L2_BUF_TYPE_VIDEO_CAPTURE, klass->default_device,
 +      gst_v4l2_get_input, gst_v4l2_set_input, NULL);
 +  self->v4l2capture->no_initial_format = TRUE;
 +  self->v4l2output->keep_aspect = FALSE;
++  self->v4l2capture->req_mode = GST_V4L2_IO_MMAP;
 +}
-+
 +static void
 +gst_v4l2_mtk_vpu_dec_class_init (GstV4l2MtkVpuDecClass * klass)
 +{
@@ -1135,9 +923,10 @@
 +
 +  return TRUE;
 +}
+\ No newline at end of file
 diff --git a/sys/v4l2/gstv4l2mtkvpudec.h b/sys/v4l2/gstv4l2mtkvpudec.h
 new file mode 100644
-index 00000000..3ba72fc4
+index 0000000..3a6c736
 --- /dev/null
 +++ b/sys/v4l2/gstv4l2mtkvpudec.h
 @@ -0,0 +1,63 @@
@@ -1204,11 +993,12 @@
 +
 +G_END_DECLS
 +#endif /* __GST_V4L2_MTK_VPU_DEC_H__ */
+\ No newline at end of file
 diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c
-index 1e827b65..534d7e20 100644
+index 124c778..f567840 100644
 --- a/sys/v4l2/gstv4l2object.c
 +++ b/sys/v4l2/gstv4l2object.c
-@@ -43,6 +43,8 @@
+@@ -42,6 +42,8 @@
  #include "gst/gst-i18n-plugin.h"
  
  #include <gst/video/video.h>
@@ -1217,16 +1007,7 @@
  
  GST_DEBUG_CATEGORY_EXTERN (v4l2_debug);
  #define GST_CAT_DEFAULT v4l2_debug
-@@ -55,7 +57,7 @@ GST_DEBUG_CATEGORY_EXTERN (v4l2_debug);
- #define DEFAULT_PROP_FREQUENCY          0
- #define DEFAULT_PROP_IO_MODE            GST_V4L2_IO_AUTO
- 
--#define ENCODED_BUFFER_SIZE             (1 * 1024 * 1024)
-+#define ENCODED_BUFFER_SIZE             (2 * 1024 * 1024)
- 
- enum
- {
-@@ -141,6 +143,7 @@ static const GstV4L2FormatDesc gst_v4l2_formats[] = {
+@@ -138,6 +140,7 @@ static const GstV4L2FormatDesc gst_v4l2_formats[] = {
    {V4L2_PIX_FMT_YUV410, TRUE, GST_V4L2_RAW},
    {V4L2_PIX_FMT_YUV420, TRUE, GST_V4L2_RAW},
    {V4L2_PIX_FMT_YUV420M, TRUE, GST_V4L2_RAW},
@@ -1234,14 +1015,7 @@
    {V4L2_PIX_FMT_HI240, TRUE, GST_V4L2_RAW},
    {V4L2_PIX_FMT_HM12, TRUE, GST_V4L2_RAW},
    {V4L2_PIX_FMT_M420, TRUE, GST_V4L2_RAW},
-@@ -182,12 +185,30 @@ static const GstV4L2FormatDesc gst_v4l2_formats[] = {
-   {V4L2_PIX_FMT_VC1_ANNEX_G, FALSE, GST_V4L2_CODEC},
-   {V4L2_PIX_FMT_VC1_ANNEX_L, FALSE, GST_V4L2_CODEC},
-   {V4L2_PIX_FMT_VP8, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
-+  {V4L2_PIX_FMT_VP9, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},
- 
-   /*  Vendor-specific formats   */
-   {V4L2_PIX_FMT_WNVA, TRUE, GST_V4L2_CODEC},
+@@ -186,6 +189,23 @@ static const GstV4L2FormatDesc gst_v4l2_formats[] = {
    {V4L2_PIX_FMT_SN9C10X, TRUE, GST_V4L2_CODEC},
    {V4L2_PIX_FMT_PWC1, TRUE, GST_V4L2_CODEC},
    {V4L2_PIX_FMT_PWC2, TRUE, GST_V4L2_CODEC},
@@ -1265,7 +1039,7 @@
  };
  
  #define GST_V4L2_FORMAT_COUNT (G_N_ELEMENTS (gst_v4l2_formats))
-@@ -1007,6 +1028,7 @@ gst_v4l2_object_format_get_rank (const struct v4l2_fmtdesc *fmt)
+@@ -1055,6 +1075,7 @@ gst_v4l2_object_format_get_rank (const struct v4l2_fmtdesc *fmt)
      case V4L2_PIX_FMT_NV61:    /* 16  Y/CrCb 4:2:2  */
      case V4L2_PIX_FMT_NV61M:   /* Same as NV61      */
      case V4L2_PIX_FMT_NV24:    /* 24  Y/CrCb 4:4:4  */
@@ -1273,15 +1047,15 @@
        rank = YUV_ODD_BASE_RANK;
        break;
  
-@@ -1018,6 +1040,7 @@ gst_v4l2_object_format_get_rank (const struct v4l2_fmtdesc *fmt)
+@@ -1066,6 +1087,7 @@ gst_v4l2_object_format_get_rank (const struct v4l2_fmtdesc *fmt)
        break;
      case V4L2_PIX_FMT_YUV420:  /* I420, 12 bits per pixel */
      case V4L2_PIX_FMT_YUV420M:
-+    case V4L2_PIX_FMT_YUV422M:
++	case V4L2_PIX_FMT_YUV422M:
        rank = YUV_BASE_RANK + 7;
        break;
      case V4L2_PIX_FMT_YUYV:    /* YUY2, 16 bits per pixel */
-@@ -1281,10 +1304,14 @@ gst_v4l2_object_v4l2fourcc_to_video_format (guint32 fourcc)
+@@ -1329,10 +1351,14 @@ gst_v4l2_object_v4l2fourcc_to_video_format (guint32 fourcc)
      case V4L2_PIX_FMT_YUV420M:
        format = GST_VIDEO_FORMAT_I420;
        break;
@@ -1292,11 +1066,11 @@
        format = GST_VIDEO_FORMAT_YUY2;
        break;
      case V4L2_PIX_FMT_YVU420:
-+    case V4L2_PIX_FMT_YVU420M:
++	case V4L2_PIX_FMT_YVU420M:
        format = GST_VIDEO_FORMAT_YV12;
        break;
      case V4L2_PIX_FMT_UYVY:
-@@ -1310,6 +1337,9 @@ gst_v4l2_object_v4l2fourcc_to_video_format (guint32 fourcc)
+@@ -1358,6 +1384,9 @@ gst_v4l2_object_v4l2fourcc_to_video_format (guint32 fourcc)
      case V4L2_PIX_FMT_NV24:
        format = GST_VIDEO_FORMAT_NV24;
        break;
@@ -1306,7 +1080,7 @@
      default:
        format = GST_VIDEO_FORMAT_UNKNOWN;
        break;
-@@ -1359,18 +1389,45 @@ gst_v4l2_object_v4l2fourcc_to_bare_struct (guint32 fourcc)
+@@ -1407,18 +1436,45 @@ gst_v4l2_object_v4l2fourcc_to_bare_struct (guint32 fourcc)
        break;
      case V4L2_PIX_FMT_MPEG1:
        structure = gst_structure_new ("video/mpeg",
@@ -1354,13 +1128,10 @@
      case V4L2_PIX_FMT_H263:
        structure = gst_structure_new ("video/x-h263",
            "variant", G_TYPE_STRING, "itu", NULL);
-@@ -1393,6 +1450,23 @@ gst_v4l2_object_v4l2fourcc_to_bare_struct (guint32 fourcc)
-     case V4L2_PIX_FMT_VP8:
-       structure = gst_structure_new_empty ("video/x-vp8");
+@@ -1444,6 +1500,20 @@ gst_v4l2_object_v4l2fourcc_to_bare_struct (guint32 fourcc)
+     case V4L2_PIX_FMT_VP9:
+       structure = gst_structure_new_empty ("video/x-vp9");
        break;
-+    case V4L2_PIX_FMT_VP9:
-+      structure = gst_structure_new_empty ("video/x-vp9");
-+      break;
 +    case V4L2_PIX_FMT_WMV1:
 +    case V4L2_PIX_FMT_WMV2:
 +    case V4L2_PIX_FMT_WMV3:
@@ -1378,7 +1149,7 @@
      case V4L2_PIX_FMT_GREY:    /*  8  Greyscale     */
      case V4L2_PIX_FMT_Y16:
      case V4L2_PIX_FMT_Y16_BE:
-@@ -1423,6 +1497,8 @@ gst_v4l2_object_v4l2fourcc_to_bare_struct (guint32 fourcc)
+@@ -1474,6 +1544,8 @@ gst_v4l2_object_v4l2fourcc_to_bare_struct (guint32 fourcc)
      case V4L2_PIX_FMT_YUV410:
      case V4L2_PIX_FMT_YUV420:  /* I420/IYUV */
      case V4L2_PIX_FMT_YUV420M:
@@ -1387,7 +1158,7 @@
      case V4L2_PIX_FMT_YUYV:
      case V4L2_PIX_FMT_YVU420:
      case V4L2_PIX_FMT_UYVY:
-@@ -1629,6 +1705,7 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+@@ -1680,6 +1752,7 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
    guint32 fourcc = 0, fourcc_nc = 0;
    const gchar *mimetype;
    struct v4l2_fmtdesc *fmt = NULL;
@@ -1395,7 +1166,7 @@
  
    structure = gst_caps_get_structure (caps, 0);
  
-@@ -1643,6 +1720,9 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+@@ -1694,6 +1767,9 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
          fourcc = V4L2_PIX_FMT_YUV420;
          fourcc_nc = V4L2_PIX_FMT_YUV420M;
          break;
@@ -1405,24 +1176,26 @@
        case GST_VIDEO_FORMAT_YUY2:
          fourcc = V4L2_PIX_FMT_YUYV;
          break;
-@@ -1651,6 +1731,7 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+@@ -1702,6 +1778,7 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
          break;
        case GST_VIDEO_FORMAT_YV12:
          fourcc = V4L2_PIX_FMT_YVU420;
-+        fourcc_nc = V4L2_PIX_FMT_YVU420M;
++		fourcc_nc = V4L2_PIX_FMT_YVU420M;
          break;
        case GST_VIDEO_FORMAT_Y41B:
          fourcc = V4L2_PIX_FMT_YUV411P;
-@@ -1720,6 +1801,8 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+@@ -1771,7 +1848,9 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
          break;
        case GST_VIDEO_FORMAT_GRAY16_BE:
          fourcc = V4L2_PIX_FMT_Y16_BE;
+-        break;
 +      case GST_VIDEO_FORMAT_MT21:
-+	    fourcc = V4L2_PIX_FMT_MT21;
-         break;
++        fourcc = V4L2_PIX_FMT_MT21;
++		break;
        default:
          break;
-@@ -1778,10 +1861,54 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+     }
+@@ -1831,10 +1910,54 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
        fourcc = V4L2_PIX_FMT_PWC1;
      } else if (g_str_equal (mimetype, "video/x-pwc2")) {
        fourcc = V4L2_PIX_FMT_PWC2;
@@ -1478,17 +1251,17 @@
    /* Prefer the non-contiguous if supported */
    v4l2object->prefered_non_contiguous = TRUE;
  
-@@ -1792,7 +1919,8 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+@@ -1845,7 +1968,8 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
  
    if (fmt == NULL) {
      fmt = gst_v4l2_object_get_format_from_fourcc (v4l2object, fourcc);
 -    v4l2object->prefered_non_contiguous = FALSE;
-+    if (!prefered_non_contiguous)
++	if (!prefered_non_contiguous)
 +      v4l2object->prefered_non_contiguous = FALSE;
    }
  
    if (fmt == NULL)
-@@ -2241,6 +2369,12 @@ gst_v4l2_object_add_colorspace (GstV4l2Object * v4l2object, GstStructure * s,
+@@ -2264,6 +2388,12 @@ gst_v4l2_object_add_colorspace (GstV4l2Object * v4l2object, GstStructure * s,
    if (gst_v4l2_object_try_fmt (v4l2object, &fmt) == 0) {
      if (gst_v4l2_object_get_colorspace (&fmt, &cinfo))
        gst_v4l2_object_fill_colorimetry_list (&list, &cinfo);
@@ -1501,7 +1274,7 @@
    }
  
    /* step 2: probe all colorspace other than default
-@@ -2633,6 +2767,9 @@ gst_v4l2_object_probe_caps_for_format (GstV4l2Object * v4l2object,
+@@ -2660,6 +2790,9 @@ gst_v4l2_object_probe_caps_for_format (GstV4l2Object * v4l2object,
        gst_value_set_int_range_step (&step_range, h, maxh, step_h);
        gst_structure_take_value (tmp, "height", &step_range);
  
@@ -1511,7 +1284,7 @@
        /* no point using the results list here, since there's only one struct */
        gst_v4l2_object_update_and_append (v4l2object, pixelformat, ret, tmp);
      }
-@@ -3698,8 +3835,8 @@ gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object, GstVideoInfo * info)
+@@ -3935,8 +4068,8 @@ gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object, GstVideoInfo * info)
      align.padding_top = r->top;
      align.padding_right = width - r->width - r->left;
      align.padding_bottom = height - r->height - r->top;
@@ -1522,12 +1295,10 @@
    }
  
    gst_video_info_set_format (info, format, width, height);
-@@ -4270,3 +4407,514 @@ different_caps:
-     return FALSE;
-   }
+@@ -3995,6 +4128,516 @@ unsupported_format:
  }
-+
-+gboolean
+ 
+ gboolean
 +gst_v4l2_object_set_enc_format (GstV4l2Object * v4l2object, GstCaps * caps, gboolean active)
 +{
 +  gint fd = v4l2object->video_fd;
@@ -1681,7 +1452,7 @@
 +        colorspace);
 +  }
 +
-+  if (v4l2_ioctl (fd, VIDIOC_S_FMT, &format) < 0)
++  if (ioctl (fd, VIDIOC_S_FMT, &format) < 0)
 +    goto set_fmt_failed;
 +
 +  GST_DEBUG_OBJECT (v4l2object->element, "Got format of %dx%d, format "
@@ -1730,7 +1501,7 @@
 +    ctl.id = V4L2_CID_ALPHA_COMPONENT;
 +    ctl.value = 0xff;
 +
-+    if (v4l2_ioctl (fd, VIDIOC_S_CTRL, &ctl) < 0)
++    if (ioctl (fd, VIDIOC_S_CTRL, &ctl) < 0)
 +      GST_WARNING_OBJECT (v4l2object->element,
 +          "Failed to set alpha component value");
 +  }
@@ -1759,21 +1530,21 @@
 +
 +    bps_ctl.id = V4L2_CID_MPEG_VIDEO_BITRATE;
 +    bps_ctl.value = bitrate;
-+    if (v4l2_ioctl (fd, VIDIOC_S_CTRL, &bps_ctl) < 0) {
++    if (ioctl (fd, VIDIOC_S_CTRL, &bps_ctl) < 0) {
 +      GST_WARNING_OBJECT (v4l2object->element,
 +        "Failed to set bps_ctl component value");
 +    }
 +
 +    gop_ctl.id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
 +    gop_ctl.value = gop;
-+    if (v4l2_ioctl (fd, VIDIOC_S_CTRL, &gop_ctl) < 0) {
++    if (ioctl (fd, VIDIOC_S_CTRL, &gop_ctl) < 0) {
 +      GST_WARNING_OBJECT (v4l2object->element,
 +        "Failed to set gop_ctl component value");
 +    }
 +
 +    prepend_hdr_ctl.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
 +    prepend_hdr_ctl.value = prepend_hdr;
-+    if (v4l2_ioctl (fd, VIDIOC_S_CTRL, &prepend_hdr_ctl) < 0) {
++    if (ioctl (fd, VIDIOC_S_CTRL, &prepend_hdr_ctl) < 0) {
 +      GST_WARNING_OBJECT (v4l2object->element,
 +        "Failed to set prepend_hdr_ctl component value");
 +    }
@@ -1793,7 +1564,7 @@
 +     In encode flow, the frame rate is decided by client not driver.
 +  */
 +#if 0
-+  if (v4l2_ioctl (fd, VIDIOC_G_PARM, &streamparm) < 0)
++  if (ioctl (fd, VIDIOC_G_PARM, &streamparm) < 0)
 +    goto get_parm_failed;
 +
 +  GST_VIDEO_INFO_FPS_N (&info) =
@@ -1827,7 +1598,7 @@
 +      streamparm.parm.capture.timeperframe.denominator = fps_n;
 +
 +      /* some cheap USB cam's won't accept any change */
-+      if (v4l2_ioctl (fd, VIDIOC_S_PARM, &streamparm) < 0)
++      if (ioctl (fd, VIDIOC_S_PARM, &streamparm) < 0)
 +        goto set_parm_failed;
 +
 +      /* get new values */
@@ -1944,7 +1715,7 @@
 +
 +  crop.type = obj->type;
 +
-+  if (v4l2_ioctl (obj->video_fd, VIDIOC_G_CROP, &crop) < 0) {
++  if (ioctl (obj->video_fd, VIDIOC_G_CROP, &crop) < 0) {
 +    GST_WARNING_OBJECT (obj->element, "VIDIOC_G_CROP failed");
 +    return FALSE;
 +  }
@@ -1965,10 +1736,10 @@
 +  struct v4l2_event_subscription sub = { 0 };
 +
 +  sub.type = V4L2_EVENT_SOURCE_CHANGE;
-+  r = v4l2_ioctl (v4l2object->video_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
++  r = ioctl (v4l2object->video_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
 +
 +  sub.type = V4L2_EVENT_EOS;
-+  r = v4l2_ioctl (v4l2object->video_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
++  r = ioctl (v4l2object->video_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
 +
 +  return r;
 +}
@@ -1979,7 +1750,7 @@
 +  struct v4l2_event e = { 0 };
 +  __u32 change;
 +
-+  v4l2_ioctl (v4l2object->video_fd, VIDIOC_DQEVENT, &e);
++  ioctl (v4l2object->video_fd, VIDIOC_DQEVENT, &e);
 +  GST_LOG ("e.type=%d",e.type);
 +
 +  switch (e.type) {
@@ -2037,11 +1808,15 @@
 +    return GST_V4L2_RET_OK;
 +}
 +
++gboolean
+ gst_v4l2_object_set_crop (GstV4l2Object * obj)
+ {
+   struct v4l2_selection sel = { 0 };
 diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h
-index 5fff161d..91a0f939 100644
+index 7871eaf..92f22a7 100644
 --- a/sys/v4l2/gstv4l2object.h
 +++ b/sys/v4l2/gstv4l2object.h
-@@ -60,6 +60,16 @@ typedef enum {
+@@ -64,6 +64,17 @@ typedef enum {
    GST_V4L2_IO_DMABUF_IMPORT = 5
  } GstV4l2IOMode;
  
@@ -2055,12 +1830,13 @@
 +  GST_V4L2_RET_SRC_NOT_SUPPORT = -6,
 +};
 +
++
  typedef gboolean  (*GstV4l2GetInOutFunction)  (GstV4l2Object * v4l2object, gint * input);
  typedef gboolean  (*GstV4l2SetInOutFunction)  (GstV4l2Object * v4l2object, gint input);
  typedef gboolean  (*GstV4l2UpdateFpsFunction) (GstV4l2Object * v4l2object);
-@@ -323,6 +333,16 @@ interface_as_function ## _property_probe_interface_init (GstPropertyProbeInterfa
-   iface->get_values = interface_as_function ## _probe_get_values;                           \
- }
+@@ -324,6 +335,16 @@ gboolean     gst_v4l2_get_attribute   (GstV4l2Object * v4l2object, int attribute
+ gboolean     gst_v4l2_set_attribute   (GstV4l2Object * v4l2object, int attribute, const int value);
+ gboolean     gst_v4l2_set_controls    (GstV4l2Object * v4l2object, GstStructure * controls);
  
 +gboolean      gst_v4l2_object_get_crop (GstV4l2Object * obj, guint *crop_width, guint *crop_height);
 +
@@ -2076,10 +1852,10 @@
  
  #endif /* __GST_V4L2_OBJECT_H__ */
 diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c
-index 0149814f..11f9d6d2 100644
+index 88c813f..8aa501a 100644
 --- a/sys/v4l2/gstv4l2src.c
 +++ b/sys/v4l2/gstv4l2src.c
-@@ -62,7 +62,7 @@
+@@ -66,7 +66,7 @@
  GST_DEBUG_CATEGORY (v4l2src_debug);
  #define GST_CAT_DEFAULT v4l2src_debug
  
@@ -2088,16 +1864,17 @@
  
  enum
  {
-@@ -199,6 +199,7 @@ gst_v4l2src_init (GstV4l2Src * v4l2src)
-   v4l2src->v4l2object = gst_v4l2_object_new (GST_ELEMENT (v4l2src),
-       V4L2_BUF_TYPE_VIDEO_CAPTURE, DEFAULT_PROP_DEVICE,
-       gst_v4l2_get_input, gst_v4l2_set_input, NULL);
-+  v4l2src->v4l2object->prefered_non_contiguous = TRUE;
+@@ -200,6 +200,8 @@ gst_v4l2src_init (GstV4l2Src * v4l2src)
+       GST_OBJECT (GST_BASE_SRC_PAD (v4l2src)), V4L2_BUF_TYPE_VIDEO_CAPTURE,
+       DEFAULT_PROP_DEVICE, gst_v4l2_get_input, gst_v4l2_set_input, NULL);
  
-   gst_base_src_set_format (GST_BASE_SRC (v4l2src), GST_FORMAT_TIME);
-   gst_base_src_set_live (GST_BASE_SRC (v4l2src), TRUE);
++  v4l2src->v4l2object->prefered_non_contiguous = TRUE;
++
+   /* Avoid the slow probes */
+   v4l2src->v4l2object->skip_try_fmt_probes = TRUE;
+ 
 diff --git a/sys/v4l2/gstv4l2videodec.c b/sys/v4l2/gstv4l2videodec.c
-index d148b66a..f00a3a5f 100644
+index 838ebff..71ff764 100644
 --- a/sys/v4l2/gstv4l2videodec.c
 +++ b/sys/v4l2/gstv4l2videodec.c
 @@ -35,9 +35,20 @@
@@ -2117,27 +1894,32 @@
 +
 +static gint64 time_pre_frame = 0;
 +static guint32 video_count = 0;
-+
- static gboolean gst_v4l2_video_dec_flush (GstVideoDecoder * decoder);
- 
++static gboolean gst_v4l2_video_dec_flush (GstVideoDecoder * decoder);
  typedef struct
-@@ -113,6 +124,9 @@ static gboolean
+ {
+   gchar *device;
+@@ -111,7 +122,11 @@ static gboolean
  gst_v4l2_video_dec_open (GstVideoDecoder * decoder)
  {
    GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder);
++
+   GstCaps *codec_caps;
 +  GstCaps *src_caps, *caps;
 +  GstElementClass *element_class = GST_ELEMENT_GET_CLASS (decoder);
 +  GstPadTemplate *pad_template;
  
    GST_DEBUG_OBJECT (self, "Opening");
  
-@@ -128,8 +142,15 @@ gst_v4l2_video_dec_open (GstVideoDecoder * decoder)
+@@ -129,8 +144,17 @@ gst_v4l2_video_dec_open (GstVideoDecoder * decoder)
    if (gst_caps_is_empty (self->probed_sinkcaps))
      goto no_encoded_format;
  
--  self->probed_srccaps = gst_v4l2_object_get_caps (self->v4l2capture,
+-  self->probed_srccaps = gst_v4l2_object_probe_caps (self->v4l2capture,
+-      gst_v4l2_object_get_raw_caps ());
++//  self->probed_srccaps = gst_v4l2_object_probe_caps (self->v4l2capture,
++//      gst_v4l2_object_get_raw_caps ());
 +  src_caps = gst_v4l2_object_get_caps (self->v4l2capture,
-       gst_v4l2_object_get_raw_caps ());
++       gst_v4l2_object_get_raw_caps ());
 +  pad_template = gst_element_class_get_pad_template (element_class, "src");
 +  caps = gst_pad_template_get_caps (pad_template);
 +  self->probed_srccaps = gst_caps_intersect_full (src_caps, caps, GST_CAPS_INTERSECT_FIRST);
@@ -2148,11 +1930,10 @@
  
    if (gst_caps_is_empty (self->probed_srccaps))
      goto no_raw_format;
-@@ -408,6 +429,85 @@ gst_v4l2_video_dec_get_oldest_frame (GstVideoDecoder * decoder)
-   return frame;
+@@ -458,6 +482,86 @@ gst_v4l2_video_dec_get_oldest_frame (GstVideoDecoder * decoder)
  }
  
-+static void
+ static void
 +gst_v4l2_update_caps (GstVideoDecoder * decoder, guint width, guint height, guint crop_width, guint crop_height)
 +{
 +  GstCaps *prevcaps = NULL;
@@ -2182,7 +1963,7 @@
 +    if (s && gst_structure_has_field (s, "height"))
 +      gst_structure_get_int (s, "height", &pre_height);
 +
-+    GST_INFO("display_width=%d,display_height=%d,crop.width=%d,crop.height=%d,prewidth=%d,preheight=%d,width=%d,height=%d", 
++    GST_INFO("display_width=%d,display_height=%d,crop.width=%d,crop.height=%d,prewidth=%d,preheight=%d,width=%d,height=%d",
 +      disp_width, disp_height, crop_width, crop_height, pre_width, pre_height, width, height);
 +
 +    updatecaps = gst_caps_copy_nth (prevcaps, 0);
@@ -2231,10 +2012,12 @@
 +  return rtn;
 +}
 +
- static void
++
++static void
  gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
  {
-@@ -417,6 +517,9 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
+   GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder);
+@@ -466,6 +570,9 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
    GstVideoCodecFrame *frame;
    GstBuffer *buffer = NULL;
    GstFlowReturn ret;
@@ -2244,7 +2027,7 @@
  
    GST_LOG_OBJECT (decoder, "Allocate output buffer");
  
-@@ -425,6 +528,47 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
+@@ -475,6 +582,47 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
       * stream lock. we know that the acquire may need to poll until more frames
       * comes in and holding this lock would prevent that.
       */
@@ -2292,7 +2075,7 @@
      pool = gst_video_decoder_get_buffer_pool (decoder);
  
      /* Pool may be NULL if we started going to READY state */
-@@ -451,9 +595,34 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
+@@ -501,9 +649,34 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
  
    if (frame) {
      frame->output_buffer = buffer;
@@ -2320,14 +2103,14 @@
 +
 +    video_count++;
 +    gint64 time_cur = g_get_monotonic_time();
-+    GST_DEBUG_OBJECT (decoder, "[%d] frame time %lld us \n", 
++    GST_DEBUG_OBJECT (decoder, "[%d] frame time %lld us \n",
 +        video_count, (time_cur - time_pre_frame));
 +    time_pre_frame = time_cur;
 +
      if (ret != GST_FLOW_OK)
        goto beach;
    } else {
-@@ -463,6 +632,18 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
+@@ -513,6 +686,18 @@ gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
  
    return;
  
@@ -2346,7 +2129,7 @@
  beach:
    GST_DEBUG_OBJECT (decoder, "Leaving output thread: %s",
        gst_flow_get_name (ret));
-@@ -515,6 +696,7 @@ gst_v4l2_video_remove_padding (GstCapsFeatures * features,
+@@ -557,6 +742,7 @@ gst_v4l2_video_remove_padding (GstCapsFeatures * features,
    return TRUE;
  }
  
@@ -2354,16 +2137,16 @@
  static GstFlowReturn
  gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
      GstVideoCodecFrame * frame)
-@@ -524,6 +706,8 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
-   GstFlowReturn ret = GST_FLOW_OK;
+@@ -567,6 +753,8 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
    gboolean processed = FALSE;
    GstBuffer *tmp;
+   GstTaskState task_state;
 +  GstElementClass *element_class = GST_ELEMENT_GET_CLASS (decoder);
 +  GstPadTemplate *pad_template;
  
    GST_DEBUG_OBJECT (self, "Handling frame %d", frame->system_frame_number);
  
-@@ -541,6 +725,8 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
+@@ -584,6 +772,8 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
    if (G_UNLIKELY (!GST_V4L2_IS_ACTIVE (self->v4l2capture))) {
      GstBufferPool *pool = GST_BUFFER_POOL (self->v4l2output->pool);
      GstVideoInfo info;
@@ -2372,7 +2155,7 @@
      GstVideoCodecState *output_state;
      GstBuffer *codec_data;
      GstCaps *acquired_caps, *available_caps, *caps, *filter;
-@@ -576,6 +762,8 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
+@@ -619,6 +809,8 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
      }
  
      GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
@@ -2381,7 +2164,7 @@
      ret =
          gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL (self->
              v4l2output->pool), &codec_data);
-@@ -583,6 +771,9 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
+@@ -626,6 +818,9 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
  
      gst_buffer_unref (codec_data);
  
@@ -2391,19 +2174,19 @@
      /* For decoders G_FMT returns coded size, G_SELECTION returns visible size
       * in the compose rectangle. gst_v4l2_object_acquire_format() checks both
       * and returns the visible size as with/height and the coded size as
-@@ -592,9 +783,10 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
+@@ -635,9 +830,11 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
  
      /* Create caps from the acquired format, remove the format field */
      acquired_caps = gst_video_info_to_caps (&info);
 +    if (self->v4l2capture->format.fmt.pix.pixelformat == V4L2_PIX_FMT_MT21) {
+     GST_DEBUG_OBJECT (self, "Acquired caps: %" GST_PTR_FORMAT, acquired_caps);
      st = gst_caps_get_structure (acquired_caps, 0);
      gst_structure_remove_field (st, "format");
--
-+    }
++	}
+ 
      /* Probe currently available pixel formats */
      available_caps = gst_v4l2_object_probe_caps (self->v4l2capture, NULL);
-     available_caps = gst_caps_make_writable (available_caps);
-@@ -633,6 +825,22 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
+@@ -679,6 +876,23 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
  
      /* Copy the rest of the information, there might be more in the future */
      output_state->info.interlace_mode = info.interlace_mode;
@@ -2423,10 +2206,20 @@
 +    gst_caps_set_simple (output_state->caps, "display_width", G_TYPE_INT, input_info.width, NULL);
 +    gst_caps_set_simple (output_state->caps, "display_height", G_TYPE_INT, input_info.height, NULL);
 +
++
      gst_video_codec_state_unref (output_state);
  
      if (!gst_video_decoder_negotiate (decoder)) {
-@@ -733,6 +941,21 @@ process_failed:
+@@ -709,6 +923,8 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
+     /* Start the processing task, when it quits, the task will disable input
+      * processing to unlock input if draining, or prevent potential block */
+     self->output_flow = GST_FLOW_FLUSHING;
++    if (gst_v4l2_object_sub_event (self->v4l2capture) < 0)
++      goto register_sub_event_failed;
+     if (!gst_pad_start_task (decoder->srcpad,
+             (GstTaskFunction) gst_v4l2_video_dec_loop, self, NULL))
+       goto start_task_failed;
+@@ -779,6 +995,21 @@ process_failed:
      ret = GST_FLOW_ERROR;
      goto drop;
    }
@@ -2448,7 +2241,7 @@
  drop:
    {
      gst_video_decoder_drop_frame (decoder, frame);
-@@ -886,6 +1109,8 @@ static void
+@@ -939,6 +1170,8 @@ static void
  gst_v4l2_video_dec_init (GstV4l2VideoDec * self)
  {
    /* V4L2 object are created in subinstance_init */
@@ -2457,1115 +2250,111 @@
  }
  
  static void
-diff --git a/sys/v4l2/gstv4l2videoenc.c b/sys/v4l2/gstv4l2videoenc.c
-new file mode 100644
-index 00000000..31714be4
---- /dev/null
-+++ b/sys/v4l2/gstv4l2videoenc.c
-@@ -0,0 +1,959 @@
-+/*
-+ * Copyright (C) 2014 ayaka <ayaka@soulik.info>
-+ * Copyright (C) 2016 Rick Chang <rick.chang@mediatek.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 <sys/stat.h>
-+#include <fcntl.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <string.h>
-+
-+#include "gstv4l2videoenc.h"
-+#include "v4l2_calls.h"
-+
-+#include <string.h>
-+#include <gst/gst-i18n-plugin.h>
-+
-+#define DEFAULT_PROP_DEVICE "/dev/video1"
-+
-+GST_DEBUG_CATEGORY_STATIC (gst_v4l2_video_enc_debug);
-+#define GST_CAT_DEFAULT gst_v4l2_video_enc_debug
-+
-+#define MAX_CODEC_FRAME (2 * 1024 * 1024)
-+
-+static gboolean gst_v4l2_video_enc_flush (GstVideoEncoder * encoder);
-+
-+enum
-+{
-+  PROP_0,
-+  V4L2_STD_OBJECT_PROPS,
-+  PROP_BITRATE,
-+  PROP_GOP,
-+  PROP_PREPEND_HDR,
-+};
-+
-+#define gst_v4l2_video_enc_parent_class parent_class
-+G_DEFINE_ABSTRACT_TYPE (GstV4l2VideoEnc, gst_v4l2_video_enc,
-+    GST_TYPE_VIDEO_ENCODER);
-+
-+void
-+gst_v4l2_video_enc_set_property (GObject * object,
-+    guint prop_id, const GValue * value, GParamSpec * pspec)
-+{
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (object);
-+
-+  switch (prop_id) {
-+      /* Split IO mode so output is configure through 'io-mode' and capture
-+       * through 'capture-io-mode' */
-+    case PROP_IO_MODE:
-+      gst_v4l2_object_set_property_helper (self->v4l2output,
-+          PROP_IO_MODE, value, pspec);
-+      break;
-+    case PROP_CAPTURE_IO_MODE:
-+      gst_v4l2_object_set_property_helper (self->v4l2capture,
-+          prop_id, value, pspec);
-+      break;
-+
-+    case PROP_DEVICE:
-+      gst_v4l2_object_set_property_helper (self->v4l2output,
-+          prop_id, value, pspec);
-+      gst_v4l2_object_set_property_helper (self->v4l2capture,
-+          prop_id, value, pspec);
-+      break;
-+    case PROP_BITRATE:
-+      self->bitrate = g_value_get_int (value);
-+      break;
-+    case PROP_GOP:
-+      self->gop = g_value_get_int (value);
-+    break;
-+    case PROP_PREPEND_HDR:
-+      self->prepend_hdr = g_value_get_int (value);
-+      break;
-+
-+      /* By default, only set on output */
-+    default:
-+      if (!gst_v4l2_object_set_property_helper (self->v4l2output,
-+              prop_id, value, pspec)) {
-+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+      }
-+      break;
-+  }
-+}
-+
-+void
-+gst_v4l2_video_enc_get_property (GObject * object,
-+    guint prop_id, GValue * value, GParamSpec * pspec)
-+{
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (object);
-+
-+  switch (prop_id) {
-+    case PROP_IO_MODE:
-+      gst_v4l2_object_get_property_helper (self->v4l2output, prop_id, value,
-+          pspec);
-+      break;
-+    case PROP_CAPTURE_IO_MODE:
-+      gst_v4l2_object_get_property_helper (self->v4l2output, PROP_IO_MODE,
-+          value, pspec);
-+      break;
-+    case PROP_BITRATE:
-+      g_value_set_int (value, self->bitrate);
-+      break;
-+    case PROP_GOP:
-+      g_value_set_int (value, self->gop);
-+      break;
-+    case PROP_PREPEND_HDR:
-+      g_value_set_int (value, self->prepend_hdr);
-+      break;
-+
-+      /* By default read from output */
-+    default:
-+      if (!gst_v4l2_object_get_property_helper (self->v4l2output,
-+              prop_id, value, pspec)) {
-+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+      }
-+      break;
-+  }
-+}
-+
-+static gboolean
-+gst_v4l2_video_enc_open (GstVideoEncoder * encoder)
-+{
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
-+
-+  GST_DEBUG_OBJECT (self, "Opening");
-+
-+  if (!gst_v4l2_object_open (self->v4l2output))
-+    goto failure;
-+
-+  if (!gst_v4l2_object_open_shared (self->v4l2capture, self->v4l2output))
-+    goto failure;
-+
-+  self->probed_sinkcaps = gst_v4l2_object_get_caps (self->v4l2output,
-+      gst_v4l2_object_get_raw_caps ());
-+
-+  if (gst_caps_is_empty (self->probed_sinkcaps))
-+    goto no_raw_format;
-+
-+  self->probed_srccaps = gst_v4l2_object_get_caps (self->v4l2capture,
-+      gst_v4l2_object_get_codec_caps ());
-+
-+  if (gst_caps_is_empty (self->probed_srccaps))
-+    goto no_encoded_format;
-+
-+  return TRUE;
-+
-+no_encoded_format:
-+  GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS,
-+      (_("Encoder on device %s has no supported output format"),
-+          self->v4l2output->videodev), (NULL));
-+  goto failure;
-+
-+
-+no_raw_format:
-+  GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS,
-+      (_("Encoder on device %s has no supported input format"),
-+          self->v4l2output->videodev), (NULL));
-+  goto failure;
-+
-+failure:
-+  if (GST_V4L2_IS_OPEN (self->v4l2output))
-+    gst_v4l2_object_close (self->v4l2output);
-+
-+  if (GST_V4L2_IS_OPEN (self->v4l2capture))
-+    gst_v4l2_object_close (self->v4l2capture);
-+
-+  gst_caps_replace (&self->probed_srccaps, NULL);
-+  gst_caps_replace (&self->probed_sinkcaps, NULL);
-+
-+  return FALSE;
-+}
-+
-+static gboolean
-+gst_v4l2_video_enc_close (GstVideoEncoder * encoder)
-+{
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
-+
-+  GST_DEBUG_OBJECT (self, "Closing");
-+
-+  gst_v4l2_object_close (self->v4l2output);
-+  gst_v4l2_object_close (self->v4l2capture);
-+  gst_caps_replace (&self->probed_srccaps, NULL);
-+  gst_caps_replace (&self->probed_sinkcaps, NULL);
-+
-+  return TRUE;
-+}
-+
-+static gboolean
-+gst_v4l2_video_enc_start (GstVideoEncoder * encoder)
-+{
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
-+
-+  GST_DEBUG_OBJECT (self, "Starting");
-+
-+  g_atomic_int_set(&self->finish, FALSE);
-+  gst_v4l2_object_unlock (self->v4l2output);
-+  g_atomic_int_set (&self->active, TRUE);
-+  self->output_flow = GST_FLOW_OK;
-+
-+  return TRUE;
-+}
-+
-+static gboolean
-+gst_v4l2_video_enc_stop (GstVideoEncoder * encoder)
-+{
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
-+
-+  GST_DEBUG_OBJECT (self, "Stopping");
-+
-+  gst_v4l2_object_unlock (self->v4l2output);
-+  gst_v4l2_object_unlock (self->v4l2capture);
-+
-+  /* Wait for capture thread to stop */
-+  gst_pad_stop_task (encoder->srcpad);
-+
-+  GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
-+  self->output_flow = GST_FLOW_OK;
-+  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
-+
-+  /* Should have been flushed already */
-+  g_assert (g_atomic_int_get (&self->active) == FALSE);
-+  g_assert (g_atomic_int_get (&self->processing) == FALSE);
-+
-+  gst_v4l2_object_stop (self->v4l2output);
-+  gst_v4l2_object_stop (self->v4l2capture);
-+
-+  if (self->input_state) {
-+    gst_video_codec_state_unref (self->input_state);
-+    self->input_state = NULL;
-+  }
-+
-+  GST_DEBUG_OBJECT (self, "Stopped");
-+
-+  return TRUE;
-+}
-+
-+static gboolean
-+gst_v4l2_video_enc_set_format (GstVideoEncoder * encoder,
-+    GstVideoCodecState * state)
-+{
-+  gboolean ret = TRUE;
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
-+
-+  GST_DEBUG_OBJECT (self, "Setting format: %" GST_PTR_FORMAT, state->caps);
-+
-+  if (self->input_state) {
-+    if (gst_v4l2_object_caps_equal (self->v4l2output, state->caps)) {
-+      GST_DEBUG_OBJECT (self, "Compatible caps");
-+      goto done;
-+    }
-+    gst_video_codec_state_unref (self->input_state);
-+    self->input_state = NULL;
-+
-+    /* FIXME we probably need to do more work if pools are active */
-+  }
-+
-+  state->caps = gst_caps_make_writable (state->caps);
-+  gst_caps_set_simple (state->caps, "bitrate", G_TYPE_INT, self->bitrate, NULL);
-+  gst_caps_set_simple (state->caps, "gop", G_TYPE_INT, self->gop, NULL);
-+  gst_caps_set_simple (state->caps, "prepend_hdr", G_TYPE_INT, self->prepend_hdr, NULL);
-+
-+  ret = gst_v4l2_object_set_enc_format (self->v4l2output, state->caps, FALSE);
-+
-+  if (ret)
-+    self->input_state = gst_video_codec_state_ref (state);
-+
-+  GST_DEBUG_OBJECT (self, "output caps: %" GST_PTR_FORMAT, state->caps);
-+
-+done:
-+  return ret;
-+}
-+
-+static gboolean
-+gst_v4l2_video_enc_flush (GstVideoEncoder * encoder)
-+{
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
-+
-+  GST_DEBUG_OBJECT (self, "Flushing");
-+
-+  /* Ensure the processing thread has stopped for the reverse playback
-+   * iscount case */
-+  if (g_atomic_int_get (&self->processing)) {
-+    GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
-+
-+    gst_v4l2_object_unlock_stop (self->v4l2output);
-+    gst_v4l2_object_unlock_stop (self->v4l2capture);
-+    gst_pad_stop_task (encoder->srcpad);
-+
-+    GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
-+
-+  }
-+
-+  self->output_flow = GST_FLOW_OK;
-+
-+  gst_v4l2_object_unlock_stop (self->v4l2output);
-+  gst_v4l2_object_unlock_stop (self->v4l2capture);
-+
-+  return TRUE;
-+}
-+
-+static gboolean
-+gst_v4l2_video_enc_negotiate (GstVideoEncoder * encoder)
-+{
-+  return GST_VIDEO_ENCODER_CLASS (parent_class)->negotiate (encoder);
-+}
-+
-+static GstFlowReturn
-+gst_v4l2_video_enc_finish (GstVideoEncoder * encoder)
-+{
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
-+  GstFlowReturn ret = GST_FLOW_OK;
-+  GstBuffer *buffer;
-+  gint i;
-+
-+  if (!g_atomic_int_get (&self->processing))
-+    goto done;
-+
-+  GST_DEBUG_OBJECT (self, "Finishing encoding");
-+
-+  /* Keep queuing empty buffers until the processing thread has stopped,
-+   * _pool_process() will return FLUSHING when that happened */
-+  GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
-+  /*
-+  while (ret == GST_FLOW_OK) {
-+    buffer = gst_buffer_new ();
-+    ret =
-+        gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL
-+        (self->v4l2output->pool), &buffer);
-+    gst_buffer_unref (buffer);
-+  }
-+  */
-+  g_atomic_int_set(&self->finish, TRUE);
-+  for (i = 0; g_atomic_int_get (&self->processing) && i < 100; i++)
-+    g_usleep(1000);
-+  GST_INFO ("Close task. (%d)",i);
-+
-+  /* and ensure the processing thread has stopped in case another error
-+   * occured. */
-+  gst_v4l2_object_unlock (self->v4l2capture);
-+  gst_pad_stop_task (encoder->srcpad);
-+  GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
-+
-+  if (ret == GST_FLOW_FLUSHING)
-+    ret = self->output_flow;
-+
-+  GST_DEBUG_OBJECT (encoder, "Done draining buffers");
-+
-+done:
-+  return ret;
-+}
-+
-+static GstVideoCodecFrame *
-+gst_v4l2_video_enc_get_oldest_frame (GstVideoEncoder * encoder)
-+{
-+  GstVideoCodecFrame *frame = NULL;
-+  GList *frames, *l;
-+  gint count = 0;
-+
-+  frames = gst_video_encoder_get_frames (encoder);
-+
-+  for (l = frames; l != NULL; l = l->next) {
-+    GstVideoCodecFrame *f = l->data;
-+
-+    if (!frame || frame->pts > f->pts)
-+      frame = f;
-+
-+    count++;
-+  }
-+
-+  if (frame) {
-+    GST_LOG_OBJECT (encoder,
-+        "Oldest frame is %d %" GST_TIME_FORMAT
-+        " and %d frames left",
-+        frame->system_frame_number, GST_TIME_ARGS (frame->pts), count - 1);
-+    gst_video_codec_frame_ref (frame);
-+  }
-+
-+  g_list_free_full (frames, (GDestroyNotify) gst_video_codec_frame_unref);
-+
-+  return frame;
-+}
-+
-+static void
-+gst_v4l2_video_enc_loop (GstVideoEncoder * encoder)
-+{
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
-+  GstVideoCodecFrame *frame;
-+  GstBuffer *buffer = NULL;
-+  GstFlowReturn ret;
-+  gint i;
-+
-+  frame = gst_v4l2_video_enc_get_oldest_frame (encoder);
-+  if (!frame) {
-+    if (g_atomic_int_get (&self->finish))
-+      goto beach;
-+    GST_WARNING ("input too slow");
-+    g_usleep(1000);
-+    return;
-+  }
-+
-+  GST_LOG_OBJECT (encoder, "Allocate output buffer");
-+
-+  buffer = gst_video_encoder_allocate_output_buffer (encoder, MAX_CODEC_FRAME);
-+  if (NULL == buffer) {
-+    ret = GST_FLOW_FLUSHING;
-+    goto beach;
-+  }
-+
-+  if (frame->system_frame_number == 0) {
-+    GList *header = NULL;
-+
-+    GST_INFO ("send header");
-+    ret =
-+        gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL
-+        (self->v4l2capture->pool), &buffer);
-+    if (ret != GST_FLOW_OK) {
-+          gst_buffer_unref (buffer);
-+      goto beach;
-+    }
-+    header = g_list_prepend (header, buffer);
-+    gst_video_encoder_set_headers (encoder, header);
-+    buffer = gst_video_encoder_allocate_output_buffer (encoder, MAX_CODEC_FRAME);
-+    if (NULL == buffer) {
-+      ret = GST_FLOW_FLUSHING;
-+      goto beach;
-+    }
-+  }
-+
-+  /* FIXME Check if buffer isn't the last one here */
-+
-+  GST_LOG_OBJECT (encoder, "Process output buffer");
-+  ret =
-+      gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL
-+      (self->v4l2capture->pool), &buffer);
-+
-+  if (ret != GST_FLOW_OK)
-+    goto beach;
-+
-+  /* if (frame) { */
-+    frame->output_buffer = buffer;
-+    buffer = NULL;
-+    ret = gst_video_encoder_finish_frame (encoder, frame);
-+
-+    if (ret != GST_FLOW_OK)
-+      goto beach;
-+  /*
-+  } else {
-+    GST_WARNING_OBJECT (encoder, "Encoder is producing too many buffers");
-+    gst_buffer_unref (buffer);
-+  }
-+  */
-+  return;
-+
-+beach:
-+  GST_DEBUG_OBJECT (encoder, "Leaving output thread");
-+
-+  gst_buffer_replace (&buffer, NULL);
-+  self->output_flow = ret;
-+  g_atomic_int_set (&self->processing, FALSE);
-+  gst_v4l2_object_unlock (self->v4l2output);
-+  gst_pad_pause_task (encoder->srcpad);
-+}
-+
-+static void
-+gst_v4l2_video_enc_loop_stopped (GstV4l2VideoEnc * self)
-+{
-+  if (g_atomic_int_get (&self->processing)) {
-+    GST_DEBUG_OBJECT (self, "Early stop of encoding thread");
-+    self->output_flow = GST_FLOW_FLUSHING;
-+    g_atomic_int_set (&self->processing, FALSE);
-+  }
-+
-+  GST_DEBUG_OBJECT (self, "Encoding task destroyed: %s",
-+      gst_flow_get_name (self->output_flow));
-+
-+}
-+
-+static gboolean
-+gst_v4l2_video_enc_set_crop (GstV4l2Object * obj)
-+{
-+    struct v4l2_crop crop = { 0 };
-+
-+    crop.type = obj->type;
-+    crop.c.left = 0;
-+    crop.c.top = 0;
-+    crop.c.width = obj->info.width;
-+    crop.c.height = obj->info.height;
-+
-+    GST_DEBUG_OBJECT (obj->element,
-+          "Desired cropping left %u, top %u, size %ux%u", crop.c.left, crop.c.top,
-+          crop.c.width, crop.c.height);
-+
-+    if (v4l2_ioctl (obj->video_fd, VIDIOC_S_CROP, &crop) < 0) {
-+        GST_WARNING_OBJECT (obj->element, "VIDIOC_S_CROP failed");
-+        return FALSE;
-+    }
-+
-+    GST_DEBUG_OBJECT (obj->element,
-+          "Got cropping left %u, top %u, size %ux%u", crop.c.left, crop.c.top,
-+          crop.c.width, crop.c.height);
-+
-+    return TRUE;
-+}
-+
-+static GstFlowReturn
-+gst_v4l2_video_enc_handle_frame (GstVideoEncoder * encoder,
-+    GstVideoCodecFrame * frame, GstCaps * outcaps)
-+{
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
-+  GstFlowReturn ret = GST_FLOW_OK;
-+
-+  GST_DEBUG_OBJECT (self, "Handling frame %d", frame->system_frame_number);
-+
-+  if (G_UNLIKELY (!g_atomic_int_get (&self->active)))
-+    goto flushing;
-+
-+  if (NULL != outcaps) {
-+    GstBufferPool *pool;
-+  
-+    /* Set capture format first */
-+    if(!gst_v4l2_object_set_enc_format (self->v4l2capture, outcaps, TRUE))
-+      goto not_negotiated;
-+  
-+    if (G_UNLIKELY (!GST_V4L2_IS_ACTIVE (self->v4l2output))) {
-+      if (!self->input_state)
-+        goto not_negotiated;
-+      if (!gst_v4l2_object_set_enc_format (self->v4l2output, self->input_state->caps, TRUE))
-+        goto not_negotiated;
-+    }
-+
-+    gst_v4l2_video_enc_set_crop (self->v4l2output);
-+
-+    pool = GST_BUFFER_POOL (self->v4l2output->pool);
-+
-+    if (!gst_buffer_pool_is_active (pool)) {
-+      GstStructure *config = gst_buffer_pool_get_config (pool);
-+      gst_buffer_pool_config_set_params (config,
-+          self->input_state->caps, self->v4l2output->info.size, 2, 2);
-+
-+      if (!gst_buffer_pool_set_config (pool, config))
-+        goto activate_failed;
-+
-+      if (!gst_buffer_pool_set_active (pool, TRUE))
-+        goto activate_failed;
-+    }
-+
-+    gst_video_encoder_set_output_state (encoder, outcaps, self->input_state);
-+
-+    if (!gst_video_encoder_negotiate (encoder)) {
-+      if (GST_PAD_IS_FLUSHING (encoder->srcpad))
-+        goto flushing;
-+      else
-+        goto not_negotiated;
-+    }
-+
-+    if (!gst_buffer_pool_set_active
-+        (GST_BUFFER_POOL (self->v4l2capture->pool), TRUE)) {
-+      GST_DEBUG ("active capture pool failed");
-+      goto activate_failed;
-+    }
-+  }
-+
-+  if (g_atomic_int_get (&self->processing) == FALSE) {
-+    /* It possible that the processing thread stopped due to an error */
-+    if (self->output_flow != GST_FLOW_OK &&
-+        self->output_flow != GST_FLOW_FLUSHING) {
-+      GST_DEBUG_OBJECT (self, "Processing loop stopped with error, leaving");
-+      ret = self->output_flow;
-+      goto drop;
-+    }
-+
-+    GST_DEBUG_OBJECT (self, "Starting encoding thread");
-+
-+    /* Start the processing task, when it quits, the task will disable input
-+     * processing to unlock input if draining, or prevent potential block */
-+    g_atomic_int_set (&self->processing, TRUE);
-+    if (!gst_pad_start_task (encoder->srcpad,
-+            (GstTaskFunction) gst_v4l2_video_enc_loop, self,
-+            (GDestroyNotify) gst_v4l2_video_enc_loop_stopped))
-+      goto start_task_failed;
-+  }
-+
-+  if (frame->input_buffer) {
-+    GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
-+    ret =
-+        gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL
-+        (self->v4l2output->pool), &frame->input_buffer);
-+    GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
-+
-+    if (ret == GST_FLOW_FLUSHING) {
-+      if (g_atomic_int_get (&self->processing) == FALSE)
-+        ret = self->output_flow;
-+      goto drop;
-+    } else if (ret != GST_FLOW_OK) {
-+      goto process_failed;
-+    }
-+
-+    /* No need to keep input arround */
-+    gst_buffer_replace (&frame->input_buffer, NULL);
-+  }
-+
-+  gst_video_codec_frame_unref (frame);
-+  return ret;
-+  /* ERRORS */
-+not_negotiated:
-+  {
-+    GST_ERROR_OBJECT (self, "not negotiated");
-+    ret = GST_FLOW_NOT_NEGOTIATED;
-+    goto drop;
-+  }
-+activate_failed:
-+  {
-+    GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS,
-+        (_("Failed to allocate required memory.")),
-+        ("Buffer pool activation failed"));
-+    return GST_FLOW_ERROR;
-+
-+  }
-+flushing:
-+  {
-+    ret = GST_FLOW_FLUSHING;
-+    goto drop;
-+  }
-+start_task_failed:
-+  {
-+    GST_ELEMENT_ERROR (self, RESOURCE, FAILED,
-+        (_("Failed to start encoding thread.")), (NULL));
-+    g_atomic_int_set (&self->processing, FALSE);
-+    ret = GST_FLOW_ERROR;
-+    goto drop;
-+  }
-+process_failed:
-+  {
-+    GST_ELEMENT_ERROR (self, RESOURCE, FAILED,
-+        (_("Failed to process frame.")),
-+        ("Maybe be due to not enough memory or failing driver"));
-+    ret = GST_FLOW_ERROR;
-+    goto drop;
-+  }
-+drop:
-+  {
-+    gst_video_encoder_finish_frame (encoder, frame);
-+    return ret;
-+  }
-+}
-+
-+static gboolean
-+gst_v4l2_video_enc_decide_allocation (GstVideoEncoder *
-+    encoder, GstQuery * query)
-+{
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
-+  GstClockTime latency;
-+  gboolean ret = FALSE;
-+
-+  self->v4l2capture->info.size = MAX_CODEC_FRAME;
-+
-+  if (gst_v4l2_object_decide_allocation (self->v4l2capture, query))
-+    ret =
-+        GST_VIDEO_ENCODER_CLASS
-+        (parent_class)->decide_allocation (encoder, query);
-+  latency = self->v4l2capture->min_buffers * self->v4l2capture->duration;
-+  gst_video_encoder_set_latency (encoder, latency, latency);
-+  return ret;
-+}
-+
-+static gboolean
-+gst_v4l2_video_enc_propose_allocation (GstVideoEncoder *
-+    encoder, GstQuery * query)
-+{
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
-+  gboolean ret = FALSE;
-+
-+  GST_DEBUG_OBJECT (self, "called");
-+/*
-+  if (query == NULL)
-+    ret = TRUE;
-+  else
-+    ret = gst_v4l2_object_propose_allocation (self->v4l2output, query);
-+*/
-+  if (ret)
-+    ret = GST_VIDEO_ENCODER_CLASS (parent_class)->propose_allocation (encoder,
-+        query);
-+
-+  return ret;
-+}
-+
-+static gboolean
-+gst_v4l2_video_enc_src_query (GstVideoEncoder * encoder, GstQuery * query)
-+{
-+  gboolean ret = TRUE;
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
-+  switch (GST_QUERY_TYPE (query)) {
-+    case GST_QUERY_CAPS:{
-+      GstCaps *filter, *result = NULL;
-+      GstPad *pad = GST_VIDEO_ENCODER_SRC_PAD (encoder);
-+
-+      gst_query_parse_caps (query, &filter);
-+
-+      if (self->probed_srccaps)
-+        result = gst_caps_ref (self->probed_srccaps);
-+      else
-+        result = gst_pad_get_pad_template_caps (pad);
-+
-+      if (filter) {
-+        GstCaps *tmp = result;
-+        result =
-+            gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST);
-+        gst_caps_unref (tmp);
-+      }
-+
-+      GST_DEBUG_OBJECT (self, "Returning src caps %" GST_PTR_FORMAT, result);
-+
-+      gst_query_set_caps_result (query, result);
-+      gst_caps_unref (result);
-+      break;
-+    }
-+
-+    default:
-+      ret = GST_VIDEO_ENCODER_CLASS (parent_class)->src_query (encoder, query);
-+      break;
-+  }
-+
-+  return ret;
-+}
-+
-+static gboolean
-+gst_v4l2_video_enc_sink_query (GstVideoEncoder * encoder, GstQuery * query)
-+{
-+  gboolean ret = TRUE;
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
-+
-+  switch (GST_QUERY_TYPE (query)) {
-+    case GST_QUERY_CAPS:{
-+      GstCaps *filter, *result = NULL;
-+      GstPad *pad = GST_VIDEO_ENCODER_SINK_PAD (encoder);
-+
-+      gst_query_parse_caps (query, &filter);
-+
-+      if (self->probed_sinkcaps)
-+        result = gst_caps_ref (self->probed_sinkcaps);
-+      else
-+        result = gst_pad_get_pad_template_caps (pad);
-+
-+      if (filter) {
-+        GstCaps *tmp = result;
-+        result =
-+            gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST);
-+        gst_caps_unref (tmp);
-+      }
-+
-+      GST_DEBUG_OBJECT (self, "Returning sink caps %" GST_PTR_FORMAT, result);
-+
-+      gst_query_set_caps_result (query, result);
-+      gst_caps_unref (result);
-+      break;
-+    }
-+
-+    default:
-+      ret = GST_VIDEO_ENCODER_CLASS (parent_class)->sink_query (encoder, query);
-+      break;
-+  }
-+
-+  return ret;
-+}
-+
-+static gboolean
-+gst_v4l2_video_enc_sink_event (GstVideoEncoder * encoder, GstEvent * event)
-+{
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
-+  gboolean ret;
-+
-+  switch (GST_EVENT_TYPE (event)) {
-+    case GST_EVENT_FLUSH_START:
-+      GST_DEBUG_OBJECT (self, "flush start");
-+      gst_v4l2_object_unlock (self->v4l2output);
-+      gst_v4l2_object_unlock (self->v4l2capture);
-+      break;
-+    default:
-+      break;
-+  }
-+
-+  ret = GST_VIDEO_ENCODER_CLASS (parent_class)->sink_event (encoder, event);
-+
-+  switch (GST_EVENT_TYPE (event)) {
-+    case GST_EVENT_FLUSH_START:
-+      gst_pad_stop_task (encoder->srcpad);
-+      GST_DEBUG_OBJECT (self, "flush start done");
-+    default:
-+      break;
-+  }
-+
-+  return ret;
-+}
-+
-+static GstStateChangeReturn
-+gst_v4l2_video_enc_change_state (GstElement * element,
-+    GstStateChange transition)
-+{
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (element);
-+  GstVideoEncoder *encoder = GST_VIDEO_ENCODER (element);
-+
-+  if (transition == GST_STATE_CHANGE_PAUSED_TO_READY) {
-+    g_atomic_int_set (&self->active, FALSE);
-+    gst_v4l2_object_unlock (self->v4l2output);
-+    gst_v4l2_object_unlock (self->v4l2capture);
-+    gst_v4l2_video_enc_loop_stopped (self);
-+    gst_pad_stop_task (encoder->srcpad);
-+  }
-+
-+  return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-+}
-+
-+static void
-+gst_v4l2_video_enc_dispose (GObject * object)
-+{
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (object);
-+
-+  gst_caps_replace (&self->probed_sinkcaps, NULL);
-+  gst_caps_replace (&self->probed_srccaps, NULL);
-+
-+  G_OBJECT_CLASS (parent_class)->dispose (object);
-+}
-+
-+static void
-+gst_v4l2_video_enc_finalize (GObject * object)
-+{
-+  GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (object);
-+
-+  gst_v4l2_object_destroy (self->v4l2capture);
-+  gst_v4l2_object_destroy (self->v4l2output);
-+
-+  G_OBJECT_CLASS (parent_class)->finalize (object);
-+}
-+
-+static void
-+gst_v4l2_video_enc_init (GstV4l2VideoEnc * self)
-+{
-+  self->v4l2output = gst_v4l2_object_new (GST_ELEMENT (self),
-+      V4L2_BUF_TYPE_VIDEO_OUTPUT, DEFAULT_PROP_DEVICE,
-+      gst_v4l2_get_output, gst_v4l2_set_output, NULL);
-+  self->v4l2output->no_initial_format = TRUE;
-+  self->v4l2output->keep_aspect = FALSE;
-+
-+  self->v4l2capture = gst_v4l2_object_new (GST_ELEMENT (self),
-+      V4L2_BUF_TYPE_VIDEO_CAPTURE, DEFAULT_PROP_DEVICE,
-+      gst_v4l2_get_input, gst_v4l2_set_input, NULL);
-+  self->v4l2capture->no_initial_format = TRUE;
-+  self->v4l2output->keep_aspect = FALSE;
-+}
-+
-+static void
-+gst_v4l2_video_enc_class_init (GstV4l2VideoEncClass * klass)
-+{
-+  GstElementClass *element_class;
-+  GObjectClass *gobject_class;
-+  GstVideoEncoderClass *video_encoder_class;
-+
-+  parent_class = g_type_class_peek_parent (klass);
-+
-+  element_class = (GstElementClass *) klass;
-+  gobject_class = (GObjectClass *) klass;
-+  video_encoder_class = (GstVideoEncoderClass *) klass;
-+
-+  GST_DEBUG_CATEGORY_INIT (gst_v4l2_video_enc_debug, "v4l2videoenc", 0,
-+      "V4L2 Video Encoder");
-+
-+  gst_element_class_set_static_metadata (element_class,
-+      "V4L2 Video Encoder",
-+      "Codec/Encoder/Video",
-+      "Encode video streams via V4L2 API", "ayaka <ayaka@soulik.info>");
-+  
-+  gst_element_class_add_pad_template (element_class,
-+      gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
-+          gst_v4l2_object_get_raw_caps ()));
-+  gst_element_class_add_pad_template (element_class,
-+      gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
-+          gst_v4l2_object_get_codec_caps ()));
-+  
-+  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_dispose);
-+  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_finalize);
-+  gobject_class->set_property =
-+      GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_set_property);
-+  gobject_class->get_property =
-+      GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_get_property);
-+
-+  video_encoder_class->open = GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_open);
-+  video_encoder_class->close = GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_close);
-+  video_encoder_class->start = GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_start);
-+  video_encoder_class->stop = GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_stop);
-+  video_encoder_class->finish = GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_finish);
-+  video_encoder_class->flush = GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_flush);
-+  video_encoder_class->set_format =
-+      GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_set_format);
-+  video_encoder_class->negotiate =
-+      GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_negotiate);
-+  video_encoder_class->decide_allocation =
-+      GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_decide_allocation);
-+  video_encoder_class->propose_allocation =
-+       GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_propose_allocation);
-+  video_encoder_class->sink_query =
-+      GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_sink_query);
-+  video_encoder_class->src_query =
-+      GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_src_query);
-+  video_encoder_class->sink_event =
-+      GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_sink_event);
-+
-+
-+  klass->handle_frame = GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_handle_frame);
-+
-+  element_class->change_state =
-+      GST_DEBUG_FUNCPTR (gst_v4l2_video_enc_change_state);
-+
-+  gst_v4l2_object_install_m2m_properties_helper (gobject_class);
-+
-+  g_object_class_install_property (gobject_class, PROP_BITRATE,
-+        g_param_spec_int ("bitrate", "bitrate", "v4l2 encoder bitrate",
-+            0, G_MAXINT, 400000,
-+            G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
-+  g_object_class_install_property (gobject_class, PROP_PREPEND_HDR,
-+        g_param_spec_int ("prepend-hdr", "prepend-hdr", "v4l2 encoder prepend header",
-+            0, 1, 0,
-+            G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
-+  g_object_class_install_property (gobject_class, PROP_GOP,
-+        g_param_spec_int ("gop", "gop", "v4l2 encoder gop",
-+            0, G_MAXINT, 0,
-+            G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
-+}
-+
-+/* Probing functions */
-+gboolean
-+gst_v4l2_is_video_enc (GstCaps * sink_caps, GstCaps * src_caps)
-+{
-+  gboolean ret = FALSE;
-+
-+  if (gst_caps_is_subset (sink_caps, gst_v4l2_object_get_raw_caps ())
-+      && gst_caps_is_subset (src_caps, gst_v4l2_object_get_codec_caps ()))
-+    ret = TRUE;
-+
-+  return ret;
-+}
 diff --git a/sys/v4l2/gstv4l2videoenc.h b/sys/v4l2/gstv4l2videoenc.h
-new file mode 100644
-index 00000000..0ba47408
---- /dev/null
+index f03acd5..5d7be39 100644
+--- a/sys/v4l2/gstv4l2videoenc.h
 +++ b/sys/v4l2/gstv4l2videoenc.h
-@@ -0,0 +1,103 @@
-+/*
-+ * Copyright (C) 2014 SUMOMO Computer Association.
-+ *     Author: ayaka <ayaka@soulik.info>
-+ *
-+ * 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_V4L2_VIDEO_ENC_H__
-+#define __GST_V4L2_VIDEO_ENC_H__
-+
-+#include <gst/gst.h>
-+#include <gst/video/video.h>
-+#include <gst/video/gstvideoencoder.h>
-+#include <gst/video/gstvideometa.h>
-+
-+#include <gstv4l2object.h>
-+#include <gstv4l2bufferpool.h>
-+
+@@ -30,6 +30,8 @@
+ #include <gstv4l2object.h>
+ #include <gstv4l2bufferpool.h>
+ 
 +GST_DEBUG_CATEGORY_EXTERN (v4l2videoenc_debug);
 +
-+G_BEGIN_DECLS
-+#define GST_TYPE_V4L2_VIDEO_ENC \
-+  (gst_v4l2_video_enc_get_type())
-+#define GST_V4L2_VIDEO_ENC(obj) \
-+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_V4L2_VIDEO_ENC,GstV4l2VideoEnc))
-+#define GST_V4L2_VIDEO_ENC_CLASS(klass) \
-+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_V4L2_VIDEO_ENC,GstV4l2VideoEncClass))
-+#define GST_IS_V4L2_VIDEO_ENC(obj) \
-+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_V4L2_VIDEO_ENC))
-+#define GST_IS_V4L2_VIDEO_ENC_CLASS(obj) \
-+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_V4L2_VIDEO_ENC))
-+typedef struct _GstV4l2VideoEnc GstV4l2VideoEnc;
-+typedef struct _GstV4l2VideoEncClass GstV4l2VideoEncClass;
-+
-+struct _GstV4l2VideoEnc
-+{
-+  GstVideoEncoder parent;
-+
-+  /* < private > */
-+  GstV4l2Object *v4l2output;
-+  GstV4l2Object *v4l2capture;
-+
-+  /* pads */
-+  GstCaps *probed_srccaps;
-+  GstCaps *probed_sinkcaps;
-+
-+  /* State */
-+  GstVideoCodecState *input_state;
-+  gboolean active;
-+  gboolean processing;
+ G_BEGIN_DECLS
+ #define GST_TYPE_V4L2_VIDEO_ENC \
+   (gst_v4l2_video_enc_get_type())
+@@ -43,7 +45,6 @@ G_BEGIN_DECLS
+   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_V4L2_VIDEO_ENC))
+ #define GST_V4L2_VIDEO_ENC_GET_CLASS(obj) \
+   (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_V4L2_VIDEO_ENC, GstV4l2VideoEncClass))
+-
+ typedef struct _GstV4l2VideoEnc GstV4l2VideoEnc;
+ typedef struct _GstV4l2VideoEncClass GstV4l2VideoEncClass;
+ 
+@@ -63,8 +64,14 @@ struct _GstV4l2VideoEnc
+   GstVideoCodecState *input_state;
+   gboolean active;
+   gboolean processing;
 +  gboolean finish;
-+  GstFlowReturn output_flow;
-+
+   GstFlowReturn output_flow;
+ 
 +  /*properity*/
 +  gint bitrate;
 +  gint gop;
 +  gint prepend_hdr;
 +
-+};
-+
-+struct _GstV4l2VideoEncClass
-+{
-+  GstVideoEncoderClass parent_class;
-+
-+  gchar *default_device;
+ };
+ 
+ struct _GstV4l2VideoEncClass
+@@ -72,6 +79,9 @@ struct _GstV4l2VideoEncClass
+   GstVideoEncoderClass parent_class;
+ 
+   gchar *default_device;
 +
 +    GstFlowReturn (*handle_frame) (GstVideoEncoder * encoder,
 +      GstVideoCodecFrame * frame, GstCaps * outcaps);
-+};
-+
-+GType gst_v4l2_video_enc_get_type (void);
-+
-+gboolean gst_v4l2_is_video_enc (GstCaps * sink_caps, GstCaps * src_caps);
-+
-+void
+   const char *codec_name;
+ 
+   guint32 profile_cid;
+@@ -85,13 +95,20 @@ struct _GstV4l2VideoEncClass
+ 
+ GType gst_v4l2_video_enc_get_type (void);
+ 
+-
+ gboolean gst_v4l2_is_video_enc (GstCaps * sink_caps, GstCaps * src_caps,
+     GstCaps * codec_caps);
+ 
++static void
 +gst_v4l2_video_enc_set_property (GObject * object,
 +    guint prop_id, const GValue * value, GParamSpec * pspec);
 +
-+void
++static void
 +gst_v4l2_video_enc_get_property (GObject * object,
 +    guint prop_id, GValue * value, GParamSpec * pspec);
 +
-+gboolean gst_v4l2_video_enc_register (GstPlugin * plugin,
-+                                      const gchar *basename,
-+                                      const gchar *device_path,
-+                                      GstCaps * sink_caps, GstCaps * src_caps);
-+
-+G_END_DECLS
-+#endif /* __GST_V4L2_VIDEO_ENC_H__ */
+ void gst_v4l2_video_enc_register (GstPlugin * plugin, GType type,
+     const char *codec, const gchar * basename, const gchar * device_path,
+     GstCaps * sink_caps, GstCaps *codec_caps, GstCaps * src_caps);
+ 
+ G_END_DECLS
+ #endif /* __GST_V4L2_VIDEO_ENC_H__ */
 diff --git a/sys/v4l2/v4l2_calls.c b/sys/v4l2/v4l2_calls.c
-index 23581ff3..b99df20e 100644
+index d3dbd42..60fb6ce 100644
 --- a/sys/v4l2/v4l2_calls.c
 +++ b/sys/v4l2/v4l2_calls.c
-@@ -39,6 +39,7 @@
+@@ -38,6 +38,8 @@
+ #include <stropts.h>
  #include <sys/ioccom.h>
  #endif
- #include "v4l2_calls.h"
 +#include "v4l2-utils.h"
++
+ #include "gstv4l2object.h"
  #include "gstv4l2tuner.h"
- #if 0
- #include "gstv4l2xoverlay.h"
-@@ -519,6 +520,11 @@ gst_v4l2_open (GstV4l2Object * v4l2object)
- {
+ #include "gstv4l2colorbalance.h"
+@@ -520,6 +522,12 @@ gst_v4l2_open (GstV4l2Object * v4l2object)
    struct stat st;
-   int libv4l2_fd;
+   int libv4l2_fd = -1;
+ 
 +  GstV4l2Iterator *it;
 +  gboolean ret = TRUE;
 +  it = gst_v4l2_iterator_new ();
 +
 +retry:
- 
-   GST_DEBUG_OBJECT (v4l2object->element, "Trying to open device %s",
++
+   GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Trying to open device %s",
        v4l2object->videodev);
-@@ -563,7 +569,23 @@ gst_v4l2_open (GstV4l2Object * v4l2object)
+ 
+@@ -567,7 +575,23 @@ gst_v4l2_open (GstV4l2Object * v4l2object)
    if (GST_IS_V4L2SRC (v4l2object->element) &&
        !(v4l2object->device_caps & (V4L2_CAP_VIDEO_CAPTURE |
                V4L2_CAP_VIDEO_CAPTURE_MPLANE)))
 -    goto not_capture;
-+  {
++   {
 +        ret = gst_v4l2_iterator_next (it);
 +      if (ret) {
 +        v4l2object->videodev = it->device_path;
 +        if (GST_V4L2_IS_OPEN (v4l2object)) {
-+          v4l2_close (v4l2object->video_fd);
++          close (v4l2object->video_fd);
 +          v4l2object->video_fd = -1;
 +        }
 +        goto retry;
@@ -3580,7 +2369,7 @@
  
    if (GST_IS_V4L2SINK (v4l2object->element) &&
        !(v4l2object->device_caps & (V4L2_CAP_VIDEO_OUTPUT |
-@@ -591,6 +613,9 @@ gst_v4l2_open (GstV4l2Object * v4l2object)
+@@ -588,6 +612,9 @@ gst_v4l2_open (GstV4l2Object * v4l2object)
        "Opened device '%s' (%s) successfully",
        v4l2object->vcap.card, v4l2object->videodev);
  
@@ -3590,3 +2379,149 @@
    if (v4l2object->extra_controls)
      gst_v4l2_set_controls (v4l2object, v4l2object->extra_controls);
  
+diff --git a/sys/v4l2/v4l2_calls.h b/sys/v4l2/v4l2_calls.h
+new file mode 100644
+index 0000000..1560b9a
+--- /dev/null
++++ b/sys/v4l2/v4l2_calls.h
+@@ -0,0 +1,138 @@
++/* GStreamer
++ *
++ * Copyright (C) 2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
++ *               2006 Edgard Lima <edgard.lima@gmail.com>
++ *
++ * v4l2_calls.h - generic V4L2 calls handling
++ *
++ * 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 __V4L2_CALLS_H__
++#define __V4L2_CALLS_H__
++
++#include "gstv4l2object.h"
++
++#ifdef HAVE_LIBV4L2
++#  include <libv4l2.h>
++#else
++#  include "ext/videodev2.h"
++#  include <sys/ioctl.h>
++#  include <sys/mman.h>
++#  include <unistd.h>
++#  define v4l2_fd_open(fd, flags) (fd)
++#  define v4l2_close    close
++#  define v4l2_dup      dup
++#  define v4l2_ioctl    ioctl
++#  define v4l2_read     read
++#  define v4l2_mmap     mmap
++#  define v4l2_munmap   munmap
++#endif
++
++#define GST_V4L2_IS_OVERLAY(v4l2object) \
++  (v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_OVERLAY)
++
++/* checks whether the current v4lv4l2object has already been open()'ed or not */
++#define GST_V4L2_CHECK_OPEN(v4l2object)				\
++  if (!GST_V4L2_IS_OPEN(v4l2object))				\
++  {								\
++    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,	\
++      (_("Device is not open.")), (NULL));                      \
++    return FALSE;						\
++  }
++
++/* checks whether the current v4lv4l2object is close()'ed or whether it is still open */
++#define GST_V4L2_CHECK_NOT_OPEN(v4l2object)			\
++  if (GST_V4L2_IS_OPEN(v4l2object))				\
++  {								\
++    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,	\
++      (_("Device is open.")), (NULL));                          \
++    return FALSE;						\
++  }
++
++/* checks whether the current v4lv4l2object does video overlay */
++#define GST_V4L2_CHECK_OVERLAY(v4l2object)			\
++  if (!GST_V4L2_IS_OVERLAY(v4l2object))				\
++  {								\
++    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, \
++      (NULL), ("Device cannot handle overlay"));                \
++    return FALSE;						\
++  }
++
++/* checks whether we're in capture mode or not */
++#define GST_V4L2_CHECK_ACTIVE(v4l2object)			\
++  if (!GST_V4L2_IS_ACTIVE(v4l2object))				\
++  {								\
++    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, \
++      (NULL), ("Device is not in streaming mode"));             \
++    return FALSE;						\
++  }
++
++/* checks whether we're out of capture mode or not */
++#define GST_V4L2_CHECK_NOT_ACTIVE(v4l2object)			\
++  if (GST_V4L2_IS_ACTIVE(v4l2object))				\
++  {								\
++    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS, \
++      (NULL), ("Device is in streaming mode"));                 \
++    return FALSE;						\
++  }
++
++
++/* open/close the device */
++gboolean	gst_v4l2_open			(GstV4l2Object *v4l2object);
++gboolean	gst_v4l2_dup			(GstV4l2Object *v4l2object, GstV4l2Object *other);
++gboolean	gst_v4l2_close			(GstV4l2Object *v4l2object);
++
++/* norm/input/output */
++gboolean	gst_v4l2_get_norm		(GstV4l2Object *v4l2object,
++						 v4l2_std_id    *norm);
++gboolean	gst_v4l2_set_norm		(GstV4l2Object *v4l2object,
++						 v4l2_std_id     norm);
++gboolean        gst_v4l2_get_input              (GstV4l2Object * v4l2object,
++                                                 gint * input);
++gboolean        gst_v4l2_set_input              (GstV4l2Object * v4l2object,
++                                                 gint input);
++gboolean	gst_v4l2_get_output		(GstV4l2Object *v4l2object,
++						 gint           *output);
++gboolean	gst_v4l2_set_output		(GstV4l2Object *v4l2object,
++						 gint            output);
++
++/* frequency control */
++gboolean	gst_v4l2_get_frequency		(GstV4l2Object *v4l2object,
++						 gint            tunernum,
++            gulong         *frequency);
++gboolean	gst_v4l2_set_frequency		(GstV4l2Object *v4l2object,
++						 gint            tunernum,
++            gulong          frequency);
++gboolean	gst_v4l2_signal_strength	(GstV4l2Object *v4l2object,
++						 gint            tunernum,
++						 gulong         *signal);
++
++/* attribute control */
++gboolean	gst_v4l2_get_attribute		(GstV4l2Object *v4l2object,
++						 int             attribute,
++						 int            *value);
++gboolean	gst_v4l2_set_attribute		(GstV4l2Object *v4l2object,
++						 int             attribute,
++						 const int       value);
++
++gboolean	gst_v4l2_set_controls		(GstV4l2Object * v4l2object,
++						 GstStructure * controls);
++
++gboolean        gst_v4l2_get_capabilities       (GstV4l2Object * v4l2object);
++
++
++#endif /* __V4L2_CALLS_H__ */
+-- 
+2.6.4
diff --git a/debian/rules b/debian/rules
index 37bdce8..6842368 100755
--- a/debian/rules
+++ b/debian/rules
@@ -45,7 +45,7 @@
 gst_lib=libgstreamer$(gst_abi)-0
 gst_lib_dev=libgstreamer$(gst_abi)-dev
 # what gstreamer version is needed
-gst_lib_dev_dep=$(gst_lib_dev) (>= 1.10.0)
+gst_lib_dev_dep=$(gst_lib_dev) (>= 1.14.4)
 
 gst_pkgname=gstreamer$(gst_abi)
 gst_deb_abi=$(gst_abi)-0
@@ -71,7 +71,7 @@
 # Link special names to a template file.
 # still need "*.install" to be done by hand
 
-PLUGINS += pulseaudio plugins-good
+PLUGINS += pulseaudio gtk3 plugins-good
 CONFIG_ARGS :=
 ifeq ($(DEB_HOST_ARCH_OS),linux)
 PLUGINS +=
@@ -87,7 +87,7 @@
 ifeq ($(DEB_HOST_ARCH_OS),hurd)
 CONFIG_ARGS += --disable-oss4
 else
-oss4 = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/gstreamer-$(gst_abi)/libgstoss4audio.so
+oss4 = debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/gstreamer-$(gst_abi)/libgstoss4.so
 endif
 
 ifeq ($(DEB_HOST_ARCH_OS),linux)
@@ -148,7 +148,7 @@
 	--enable-debug \
 	--with-package-name=$(GST_PACKAGE_NAME) \
 	--with-package-origin=$(GST_PACKAGE_ORIGIN) \
-	--enable-gtk-doc \
+	--disable-gtk-doc \
 	--enable-experimental \
 	--with-default-audiosink=$(DEFAULT_AUDIOSINK) \
 	--with-default-audiosrc=$(DEFAULT_AUDIOSRC) \
diff --git a/debian/source/lintian-overrides b/debian/source/lintian-overrides
new file mode 100644
index 0000000..f5ecee6
--- /dev/null
+++ b/debian/source/lintian-overrides
@@ -0,0 +1 @@
+gst-plugins-good1.0 source: debian-rules-sets-dpkg-architecture-variable *
\ No newline at end of file