All of lore.kernel.org
 help / color / mirror / Atom feed
* [meta-qt5][PATCH v2 1/8] qtwebengine: Add a missing build dependency on libcap
@ 2015-02-11  1:43 Otavio Salvador
  2015-02-11  1:43 ` [meta-qt5][PATCH v2 2/8] qtmultimedia: Fix floating dependency gst-plugins-bad Otavio Salvador
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Otavio Salvador @ 2015-02-11  1:43 UTC (permalink / raw)
  To: Meta-OpenEmbedded Mailing listing; +Cc: Otavio Salvador

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
---
 recipes-qt/qt5/qtwebengine.inc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/recipes-qt/qt5/qtwebengine.inc b/recipes-qt/qt5/qtwebengine.inc
index 51beac3..f6b1304 100644
--- a/recipes-qt/qt5/qtwebengine.inc
+++ b/recipes-qt/qt5/qtwebengine.inc
@@ -8,6 +8,7 @@ DEPENDS += " \
     ninja-native \
     qtbase qtdeclarative qtxmlpatterns qtquickcontrols \
     libdrm fontconfig pixman openssl pango cairo icu pciutils \
+    libcap \
 "
 
 COMPATIBLE_MACHINE = "(-)"
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [meta-qt5][PATCH v2 2/8] qtmultimedia: Fix floating dependency gst-plugins-bad
  2015-02-11  1:43 [meta-qt5][PATCH v2 1/8] qtwebengine: Add a missing build dependency on libcap Otavio Salvador
@ 2015-02-11  1:43 ` Otavio Salvador
  2015-02-11  1:43 ` [meta-qt5][PATCH v2 3/8] qtmultimedia: Use 'qtCompileTest' mechanism for GStreamer Otavio Salvador
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Otavio Salvador @ 2015-02-11  1:43 UTC (permalink / raw)
  To: Meta-OpenEmbedded Mailing listing; +Cc: Otavio Salvador

When using GStreamer 0.10 support, QMake detects if GStreamer
Photography interface is available. To avoid a floating dependency we
add the gst-plugins-bad as dependency so it is always present.

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
---
 recipes-qt/qt5/qtmultimedia.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/recipes-qt/qt5/qtmultimedia.inc b/recipes-qt/qt5/qtmultimedia.inc
index 427f688..e85d202 100644
--- a/recipes-qt/qt5/qtmultimedia.inc
+++ b/recipes-qt/qt5/qtmultimedia.inc
@@ -7,7 +7,7 @@ PACKAGECONFIG ??= "${@bb.utils.contains('DISTRO_FEATURES', 'alsa', 'alsa', '', d
 PACKAGECONFIG[alsa] = ",,alsa-lib"
 PACKAGECONFIG[pulseaudio] = ",,pulseaudio"
 PACKAGECONFIG[openal] = ",,openal-soft"
-PACKAGECONFIG[gstreamer010] = ",,gstreamer gst-plugins-base"
+PACKAGECONFIG[gstreamer010] = ",,gstreamer gst-plugins-base gst-plugins-bad"
 
 EXTRA_QMAKEVARS_PRE += "${@base_contains('PACKAGECONFIG', 'alsa', '', 'CONFIG+=done_config_alsa', d)}"
 EXTRA_QMAKEVARS_PRE += "${@base_contains('PACKAGECONFIG', 'pulseaudio', '', 'CONFIG+=done_config_pulseaudio', d)}"
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [meta-qt5][PATCH v2 3/8] qtmultimedia: Use 'qtCompileTest' mechanism for GStreamer
  2015-02-11  1:43 [meta-qt5][PATCH v2 1/8] qtwebengine: Add a missing build dependency on libcap Otavio Salvador
  2015-02-11  1:43 ` [meta-qt5][PATCH v2 2/8] qtmultimedia: Fix floating dependency gst-plugins-bad Otavio Salvador
@ 2015-02-11  1:43 ` Otavio Salvador
  2015-02-11  1:43 ` [meta-qt5][PATCH v2 4/8] qtmultimedia: Use 'bb.utils.contains' function Otavio Salvador
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Otavio Salvador @ 2015-02-11  1:43 UTC (permalink / raw)
  To: Meta-OpenEmbedded Mailing listing; +Cc: Otavio Salvador

We can use the 'done_config_openal' and 'done_config_gstreamer' trick
to avoid the respective features it to be enabled.

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
---
 recipes-qt/qt5/qtmultimedia.inc                    |  5 +-
 ...a.pro-Respect-OE_GSTREAMER_ENABLED-OE_GST.patch | 53 ----------------------
 2 files changed, 2 insertions(+), 56 deletions(-)
 delete mode 100644 recipes-qt/qt5/qtmultimedia/0002-qtmultimedia.pro-Respect-OE_GSTREAMER_ENABLED-OE_GST.patch

diff --git a/recipes-qt/qt5/qtmultimedia.inc b/recipes-qt/qt5/qtmultimedia.inc
index e85d202..cd89583 100644
--- a/recipes-qt/qt5/qtmultimedia.inc
+++ b/recipes-qt/qt5/qtmultimedia.inc
@@ -11,12 +11,11 @@ PACKAGECONFIG[gstreamer010] = ",,gstreamer gst-plugins-base gst-plugins-bad"
 
 EXTRA_QMAKEVARS_PRE += "${@base_contains('PACKAGECONFIG', 'alsa', '', 'CONFIG+=done_config_alsa', d)}"
 EXTRA_QMAKEVARS_PRE += "${@base_contains('PACKAGECONFIG', 'pulseaudio', '', 'CONFIG+=done_config_pulseaudio', d)}"
-EXTRA_QMAKEVARS_PRE += "${@base_contains('PACKAGECONFIG', 'openal', 'CONFIG+=OE_OPENAL_ENABLED', '', d)}"
-EXTRA_QMAKEVARS_PRE += "${@base_contains('PACKAGECONFIG', 'gstreamer010', 'CONFIG+=OE_GSTREAMER010_ENABLED', '', d)}"
+EXTRA_QMAKEVARS_PRE += "${@base_contains('PACKAGECONFIG', 'openal', '', 'CONFIG+=done_config_openal', d)}"
+EXTRA_QMAKEVARS_PRE += "${@base_contains('PACKAGECONFIG', 'gstreamer010', 'GST_VERSION=0.10', 'done_config_gstreamer', d)}"
 
 SRC_URI += "\
     file://0001-Initial-porting-effort-to-GStreamer-1.0.patch \
-    file://0002-qtmultimedia.pro-Respect-OE_GSTREAMER_ENABLED-OE_GST.patch \
 "
 
 LICENSE += "| GPL-2.0"
diff --git a/recipes-qt/qt5/qtmultimedia/0002-qtmultimedia.pro-Respect-OE_GSTREAMER_ENABLED-OE_GST.patch b/recipes-qt/qt5/qtmultimedia/0002-qtmultimedia.pro-Respect-OE_GSTREAMER_ENABLED-OE_GST.patch
deleted file mode 100644
index 1654e00..0000000
--- a/recipes-qt/qt5/qtmultimedia/0002-qtmultimedia.pro-Respect-OE_GSTREAMER_ENABLED-OE_GST.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From b5c058f62a79efa213e4492ac7209b3a92f45e3b Mon Sep 17 00:00:00 2001
-From: Martin Jansa <Martin.Jansa@gmail.com>
-Date: Sat, 5 Jul 2014 09:10:02 +0200
-Subject: [PATCH 2/2] qtmultimedia.pro: Respect
- OE_GSTREAMER_ENABLED,OE_GSTREAMER010_ENABLED and OE_OPENAL_ENABLED
-
-Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
----
- qtmultimedia.pro | 21 ++++++++++++---------
- 1 file changed, 12 insertions(+), 9 deletions(-)
-
-diff --git a/qtmultimedia.pro b/qtmultimedia.pro
-index 109dd81..54b67a8 100644
---- a/qtmultimedia.pro
-+++ b/qtmultimedia.pro
-@@ -1,7 +1,7 @@
- requires(qtHaveModule(gui))
- 
- load(configure)
--qtCompileTest(openal)
-+OE_OPENAL_ENABLED:qtCompileTest(openal)
- win32 {
-     qtCompileTest(directshow) {
-         qtCompileTest(wshellitem)
-@@ -18,14 +18,17 @@ win32 {
-     qtCompileTest(alsa)
-     qtCompileTest(pulseaudio)
-     !done_config_gstreamer {
--        gstver=1.0
--        cache(GST_VERSION, set, gstver);
--        qtCompileTest(gstreamer) {
--            qtCompileTest(gstreamer_photography)
--            qtCompileTest(gstreamer_encodingprofiles)
--            qtCompileTest(gstreamer_appsrc)
--            qtCompileTest(linux_v4l)
--        } else {
-+        OE_GSTREAMER_ENABLED {
-+            gstver=1.0
-+            cache(GST_VERSION, set, gstver);
-+            qtCompileTest(gstreamer) {
-+                qtCompileTest(gstreamer_photography)
-+                qtCompileTest(gstreamer_encodingprofiles)
-+                qtCompileTest(gstreamer_appsrc)
-+                qtCompileTest(linux_v4l)
-+            }
-+        }
-+        !OE_GSTREAMER_ENABLED:OE_GSTREAMER010_ENABLED {
-             gstver=0.10
-             cache(GST_VERSION, set, gstver);
-             # Force a re-run of the test
--- 
-2.1.3
-
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [meta-qt5][PATCH v2 4/8] qtmultimedia: Use 'bb.utils.contains' function
  2015-02-11  1:43 [meta-qt5][PATCH v2 1/8] qtwebengine: Add a missing build dependency on libcap Otavio Salvador
  2015-02-11  1:43 ` [meta-qt5][PATCH v2 2/8] qtmultimedia: Fix floating dependency gst-plugins-bad Otavio Salvador
  2015-02-11  1:43 ` [meta-qt5][PATCH v2 3/8] qtmultimedia: Use 'qtCompileTest' mechanism for GStreamer Otavio Salvador
@ 2015-02-11  1:43 ` Otavio Salvador
  2015-02-11  1:43 ` [meta-qt5][PATCH v2 5/8] qtmultimedia: Easy use of GStreamer 1.0 support Otavio Salvador
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Otavio Salvador @ 2015-02-11  1:43 UTC (permalink / raw)
  To: Meta-OpenEmbedded Mailing listing; +Cc: Otavio Salvador

The 'base_contains' function is deprecated and we should to use the
bb.utils.contains one instead. Update the code accordingly.

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
---
 recipes-qt/qt5/qtmultimedia.inc | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/recipes-qt/qt5/qtmultimedia.inc b/recipes-qt/qt5/qtmultimedia.inc
index cd89583..1be4e85 100644
--- a/recipes-qt/qt5/qtmultimedia.inc
+++ b/recipes-qt/qt5/qtmultimedia.inc
@@ -9,10 +9,10 @@ PACKAGECONFIG[pulseaudio] = ",,pulseaudio"
 PACKAGECONFIG[openal] = ",,openal-soft"
 PACKAGECONFIG[gstreamer010] = ",,gstreamer gst-plugins-base gst-plugins-bad"
 
-EXTRA_QMAKEVARS_PRE += "${@base_contains('PACKAGECONFIG', 'alsa', '', 'CONFIG+=done_config_alsa', d)}"
-EXTRA_QMAKEVARS_PRE += "${@base_contains('PACKAGECONFIG', 'pulseaudio', '', 'CONFIG+=done_config_pulseaudio', d)}"
-EXTRA_QMAKEVARS_PRE += "${@base_contains('PACKAGECONFIG', 'openal', '', 'CONFIG+=done_config_openal', d)}"
-EXTRA_QMAKEVARS_PRE += "${@base_contains('PACKAGECONFIG', 'gstreamer010', 'GST_VERSION=0.10', 'done_config_gstreamer', d)}"
+EXTRA_QMAKEVARS_PRE += "${@bb.utils.contains('PACKAGECONFIG', 'alsa', '', 'CONFIG+=done_config_alsa', d)}"
+EXTRA_QMAKEVARS_PRE += "${@bb.utils.contains('PACKAGECONFIG', 'pulseaudio', '', 'CONFIG+=done_config_pulseaudio', d)}"
+EXTRA_QMAKEVARS_PRE += "${@bb.utils.contains('PACKAGECONFIG', 'openal', '', 'CONFIG+=done_config_openal', d)}"
+EXTRA_QMAKEVARS_PRE += "${@bb.utils.contains('PACKAGECONFIG', 'gstreamer010', 'GST_VERSION=0.10', 'done_config_gstreamer', d)}"
 
 SRC_URI += "\
     file://0001-Initial-porting-effort-to-GStreamer-1.0.patch \
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [meta-qt5][PATCH v2 5/8] qtmultimedia: Easy use of GStreamer 1.0 support
  2015-02-11  1:43 [meta-qt5][PATCH v2 1/8] qtwebengine: Add a missing build dependency on libcap Otavio Salvador
                   ` (2 preceding siblings ...)
  2015-02-11  1:43 ` [meta-qt5][PATCH v2 4/8] qtmultimedia: Use 'bb.utils.contains' function Otavio Salvador
@ 2015-02-11  1:43 ` Otavio Salvador
  2015-02-11  1:43 ` [meta-qt5][PATCH v2 6/8] qtmultimedia: Update the GStreamer 1.0 support patch Otavio Salvador
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Otavio Salvador @ 2015-02-11  1:43 UTC (permalink / raw)
  To: Meta-OpenEmbedded Mailing listing; +Cc: Otavio Salvador

This rework how we add the GStreamer 1.0 support in the code. A new
PACKAGECONFIG option called 'gstreamer' has been added for it.

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
---
 recipes-qt/qt5/qtmultimedia.inc | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/recipes-qt/qt5/qtmultimedia.inc b/recipes-qt/qt5/qtmultimedia.inc
index 1be4e85..c4792e6 100644
--- a/recipes-qt/qt5/qtmultimedia.inc
+++ b/recipes-qt/qt5/qtmultimedia.inc
@@ -7,12 +7,18 @@ PACKAGECONFIG ??= "${@bb.utils.contains('DISTRO_FEATURES', 'alsa', 'alsa', '', d
 PACKAGECONFIG[alsa] = ",,alsa-lib"
 PACKAGECONFIG[pulseaudio] = ",,pulseaudio"
 PACKAGECONFIG[openal] = ",,openal-soft"
+PACKAGECONFIG[gstreamer] = ",,gstreamer1.0 gstreamer1.0-plugins-base gstreamer1.0-plugins-bad"
 PACKAGECONFIG[gstreamer010] = ",,gstreamer gst-plugins-base gst-plugins-bad"
 
 EXTRA_QMAKEVARS_PRE += "${@bb.utils.contains('PACKAGECONFIG', 'alsa', '', 'CONFIG+=done_config_alsa', d)}"
 EXTRA_QMAKEVARS_PRE += "${@bb.utils.contains('PACKAGECONFIG', 'pulseaudio', '', 'CONFIG+=done_config_pulseaudio', d)}"
 EXTRA_QMAKEVARS_PRE += "${@bb.utils.contains('PACKAGECONFIG', 'openal', '', 'CONFIG+=done_config_openal', d)}"
-EXTRA_QMAKEVARS_PRE += "${@bb.utils.contains('PACKAGECONFIG', 'gstreamer010', 'GST_VERSION=0.10', 'done_config_gstreamer', d)}"
+
+# Handles GStreamer support
+EXTRA_QMAKEVARS_PRE += "${@bb.utils.contains('PACKAGECONFIG', 'gstreamer', 'GST_VERSION=1.0', '', d)}"
+EXTRA_QMAKEVARS_PRE += "${@bb.utils.contains('PACKAGECONFIG', 'gstreamer010', 'GST_VERSION=0.10', '', d)}"
+# Disable GStreamer if completely disabled
+EXTRA_QMAKEVARS_PRE += "${@bb.utils.contains_any('PACKAGECONFIG', 'gstreamer gstreamer010', '', 'CONFIG+=done_config_streamer', d)}"
 
 SRC_URI += "\
     file://0001-Initial-porting-effort-to-GStreamer-1.0.patch \
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [meta-qt5][PATCH v2 6/8] qtmultimedia: Update the GStreamer 1.0 support patch
  2015-02-11  1:43 [meta-qt5][PATCH v2 1/8] qtwebengine: Add a missing build dependency on libcap Otavio Salvador
                   ` (3 preceding siblings ...)
  2015-02-11  1:43 ` [meta-qt5][PATCH v2 5/8] qtmultimedia: Easy use of GStreamer 1.0 support Otavio Salvador
@ 2015-02-11  1:43 ` Otavio Salvador
  2015-02-13 12:02   ` Otavio Salvador
  2015-02-11  1:43 ` [meta-qt5][PATCH v2 7/8] qtwebengine: Add missing runtime dependencies for examples Otavio Salvador
  2015-02-11  1:43 ` [meta-qt5][PATCH v2 8/8] qt5.inc: Fix packaging of architecture independent data Otavio Salvador
  6 siblings, 1 reply; 9+ messages in thread
From: Otavio Salvador @ 2015-02-11  1:43 UTC (permalink / raw)
  To: Meta-OpenEmbedded Mailing listing; +Cc: Otavio Salvador

This updates the patch which adds support for GStreamer 1.0 to the one
merged in the 5.5 development branch. For instance it fixes a color
mismatch in one of our devices.

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
---
 recipes-qt/qt5/qtmultimedia.inc                    |    4 +-
 .../qtmultimedia/0001-GStreamer-port-to-1.0.patch  | 7648 ++++++++++++++++++++
 ...1-Initial-porting-effort-to-GStreamer-1.0.patch | 2369 ------
 3 files changed, 7650 insertions(+), 2371 deletions(-)
 create mode 100644 recipes-qt/qt5/qtmultimedia/0001-GStreamer-port-to-1.0.patch
 delete mode 100644 recipes-qt/qt5/qtmultimedia/0001-Initial-porting-effort-to-GStreamer-1.0.patch

diff --git a/recipes-qt/qt5/qtmultimedia.inc b/recipes-qt/qt5/qtmultimedia.inc
index c4792e6..16bd7c4 100644
--- a/recipes-qt/qt5/qtmultimedia.inc
+++ b/recipes-qt/qt5/qtmultimedia.inc
@@ -18,10 +18,10 @@ EXTRA_QMAKEVARS_PRE += "${@bb.utils.contains('PACKAGECONFIG', 'openal', '', 'CON
 EXTRA_QMAKEVARS_PRE += "${@bb.utils.contains('PACKAGECONFIG', 'gstreamer', 'GST_VERSION=1.0', '', d)}"
 EXTRA_QMAKEVARS_PRE += "${@bb.utils.contains('PACKAGECONFIG', 'gstreamer010', 'GST_VERSION=0.10', '', d)}"
 # Disable GStreamer if completely disabled
-EXTRA_QMAKEVARS_PRE += "${@bb.utils.contains_any('PACKAGECONFIG', 'gstreamer gstreamer010', '', 'CONFIG+=done_config_streamer', d)}"
+EXTRA_QMAKEVARS_PRE += "${@bb.utils.contains_any('PACKAGECONFIG', 'gstreamer gstreamer010', '', 'CONFIG+=done_config_gstreamer', d)}"
 
 SRC_URI += "\
-    file://0001-Initial-porting-effort-to-GStreamer-1.0.patch \
+    file://0001-GStreamer-port-to-1.0.patch \
 "
 
 LICENSE += "| GPL-2.0"
diff --git a/recipes-qt/qt5/qtmultimedia/0001-GStreamer-port-to-1.0.patch b/recipes-qt/qt5/qtmultimedia/0001-GStreamer-port-to-1.0.patch
new file mode 100644
index 0000000..65281a6
--- /dev/null
+++ b/recipes-qt/qt5/qtmultimedia/0001-GStreamer-port-to-1.0.patch
@@ -0,0 +1,7648 @@
+From: Yoann Lopes <yoann.lopes@theqtcompany.com>
+Subject: [PATCH] GStreamer: port to 1.0.
+
+0.10 is still used by default.
+To enable GStreamer 1.0, pass GST_VERSION=1.0 to qmake
+for qtmultimedia.pro.
+
+Contributions from:
+Andrew den Exter <andrew.den.exter@qinetic.com.au>
+Ilya Smelykh <ilya@videoexpertsgroup.com>
+Jim Hodapp <jim.hodapp@canonical.com>
+Sergio Schvezov <sergio.schvezov@canonical.com>
+
+Upstream-Status: Backport [5.5]
+
+Change-Id: I72a46d1170a8794a149bdb5e20767afcc5b7587c
+Reviewed-by: Andrew den Exter <andrew.den.exter@qinetic.com.au>
+---
+ config.tests/gstreamer/gstreamer.pro               |  11 +-
+ config.tests/gstreamer_appsrc/gstreamer_appsrc.pro |  13 +-
+ .../gstreamer_encodingprofiles.pro                 |  13 +-
+ .../gstreamer_photography.pro                      |  15 +-
+ .../declarative-camera/declarative-camera.qml      |   2 +-
+ qtmultimedia.pro                                   |  26 +-
+ src/gsttools/gsttools.pro                          |  72 +-
+ src/gsttools/qgstappsrc.cpp                        |  29 +-
+ src/gsttools/qgstcodecsinfo.cpp                    |   8 +-
+ src/gsttools/qgstreameraudioprobecontrol.cpp       |  47 +-
+ src/gsttools/qgstreamerbufferprobe.cpp             | 174 +++++
+ src/gsttools/qgstreamerbushelper.cpp               |   8 +
+ src/gsttools/qgstreamermirtexturerenderer.cpp      | 351 +++++++++
+ src/gsttools/qgstreamervideoprobecontrol.cpp       |  58 +-
+ src/gsttools/qgstreamervideorenderer.cpp           |   3 +-
+ src/gsttools/qgstreamervideowidget.cpp             |  29 +-
+ src/gsttools/qgstreamervideowindow.cpp             | 105 ++-
+ src/gsttools/qgstutils.cpp                         | 785 ++++++++++++++++++++-
+ src/gsttools/qgstvideobuffer.cpp                   |  70 +-
+ src/gsttools/qgstvideorendererplugin.cpp           |  53 ++
+ src/gsttools/qgstvideorenderersink.cpp             | 605 ++++++++++++++++
+ src/gsttools/qvideosurfacegstsink.cpp              | 232 +-----
+ src/multimedia/gsttools_headers/qgstappsrc_p.h     |   3 +
+ .../qgstreameraudioprobecontrol_p.h                |  13 +-
+ .../gsttools_headers/qgstreamerbufferprobe_p.h     |  86 +++
+ .../qgstreamermirtexturerenderer_p.h               | 102 +++
+ .../qgstreamervideoprobecontrol_p.h                |  23 +-
+ .../gsttools_headers/qgstreamervideowindow_p.h     |   9 +-
+ src/multimedia/gsttools_headers/qgstutils_p.h      |  55 +-
+ .../gsttools_headers/qgstvideobuffer_p.h           |  23 +-
+ .../gsttools_headers/qgstvideorendererplugin_p.h   | 111 +++
+ .../gsttools_headers/qgstvideorenderersink_p.h     | 183 +++++
+ .../gsttools_headers/qvideosurfacegstsink_p.h      |  19 +-
+ src/multimedia/multimedia.pro                      |   2 +
+ .../qgstreameraudiodecoderserviceplugin.cpp        |  89 +--
+ .../audiodecoder/qgstreameraudiodecodersession.cpp |  36 +-
+ .../audiodecoder/qgstreameraudiodecodersession.h   |   2 +-
+ src/plugins/gstreamer/camerabin/camerabin.pro      |   2 +-
+ .../gstreamer/camerabin/camerabincontainer.cpp     |   2 +-
+ .../gstreamer/camerabin/camerabincontrol.cpp       |   7 +-
+ .../gstreamer/camerabin/camerabinexposure.cpp      |   8 +-
+ src/plugins/gstreamer/camerabin/camerabinflash.cpp |   8 +-
+ src/plugins/gstreamer/camerabin/camerabinfocus.cpp |  15 +-
+ .../gstreamer/camerabin/camerabinimagecapture.cpp  | 146 ++--
+ .../gstreamer/camerabin/camerabinimagecapture.h    |  50 +-
+ .../gstreamer/camerabin/camerabinimageencoder.cpp  |   1 -
+ .../camerabin/camerabinimageprocessing.cpp         |   8 +-
+ .../gstreamer/camerabin/camerabinimageprocessing.h |   7 +-
+ .../gstreamer/camerabin/camerabinmetadata.cpp      |   5 +-
+ .../gstreamer/camerabin/camerabinrecorder.cpp      |   9 +-
+ .../gstreamer/camerabin/camerabinservice.cpp       |   7 +-
+ .../gstreamer/camerabin/camerabinsession.cpp       | 339 ++++-----
+ src/plugins/gstreamer/common.pri                   |  22 +-
+ src/plugins/gstreamer/gstreamer.pro                |   4 +-
+ .../gstreamer/mediacapture/mediacapturecamera.json |   2 +-
+ .../mediacapture/qgstreameraudioencode.cpp         |   3 +-
+ .../mediacapture/qgstreamercaptureservice.cpp      |  58 +-
+ .../mediacapture/qgstreamercaptureservice.h        |   3 +
+ .../qgstreamercaptureserviceplugin.cpp             |  90 +--
+ .../mediacapture/qgstreamercapturesession.cpp      | 285 +++-----
+ .../mediacapture/qgstreamercapturesession.h        |  19 +-
+ .../mediacapture/qgstreamervideoencode.cpp         |  39 +-
+ src/plugins/gstreamer/mediaplayer/mediaplayer.pro  |   1 -
+ .../mediaplayer/qgstreamerplayercontrol.cpp        |   1 -
+ .../mediaplayer/qgstreamerplayerservice.cpp        |  65 +-
+ .../mediaplayer/qgstreamerplayerservice.h          |   5 +
+ .../mediaplayer/qgstreamerplayerserviceplugin.cpp  |  88 +--
+ .../mediaplayer/qgstreamerplayersession.cpp        | 238 ++++---
+ .../mediaplayer/qgstreamerplayersession.h          |  19 +-
+ .../qcamerabackend/tst_qcamerabackend.cpp          |  10 +-
+ .../tst_qmediaplayerbackend.cpp                    |   4 +-
+ 71 files changed, 3661 insertions(+), 1374 deletions(-)
+ create mode 100644 src/gsttools/qgstreamerbufferprobe.cpp
+ create mode 100644 src/gsttools/qgstreamermirtexturerenderer.cpp
+ create mode 100644 src/gsttools/qgstvideorendererplugin.cpp
+ create mode 100644 src/gsttools/qgstvideorenderersink.cpp
+ create mode 100644 src/multimedia/gsttools_headers/qgstreamerbufferprobe_p.h
+ create mode 100644 src/multimedia/gsttools_headers/qgstreamermirtexturerenderer_p.h
+ create mode 100644 src/multimedia/gsttools_headers/qgstvideorendererplugin_p.h
+ create mode 100644 src/multimedia/gsttools_headers/qgstvideorenderersink_p.h
+
+diff --git a/config.tests/gstreamer/gstreamer.pro b/config.tests/gstreamer/gstreamer.pro
+index 02a7e34..6b9843a 100644
+--- a/config.tests/gstreamer/gstreamer.pro
++++ b/config.tests/gstreamer/gstreamer.pro
+@@ -3,11 +3,10 @@ SOURCES += main.cpp
+ CONFIG += link_pkgconfig
+ 
+ PKGCONFIG += \
+-    gstreamer-0.10 \
+-    gstreamer-base-0.10 \
+-    gstreamer-interfaces-0.10 \
+-    gstreamer-audio-0.10 \
+-    gstreamer-video-0.10 \
+-    gstreamer-pbutils-0.10
++    gstreamer-$$GST_VERSION \
++    gstreamer-base-$$GST_VERSION \
++    gstreamer-audio-$$GST_VERSION \
++    gstreamer-video-$$GST_VERSION \
++    gstreamer-pbutils-$$GST_VERSION
+ 
+ 
+diff --git a/config.tests/gstreamer_appsrc/gstreamer_appsrc.pro b/config.tests/gstreamer_appsrc/gstreamer_appsrc.pro
+index 9f61703..0f3ca2b 100644
+--- a/config.tests/gstreamer_appsrc/gstreamer_appsrc.pro
++++ b/config.tests/gstreamer_appsrc/gstreamer_appsrc.pro
+@@ -3,11 +3,8 @@ SOURCES += main.cpp
+ CONFIG += link_pkgconfig
+ 
+ PKGCONFIG += \
+-    gstreamer-0.10 \
+-    gstreamer-base-0.10 \
+-    gstreamer-interfaces-0.10 \
+-    gstreamer-audio-0.10 \
+-    gstreamer-video-0.10 \
+-    gstreamer-app-0.10
+-
+-
++    gstreamer-$$GST_VERSION \
++    gstreamer-base-$$GST_VERSION \
++    gstreamer-audio-$$GST_VERSION \
++    gstreamer-video-$$GST_VERSION \
++    gstreamer-pbutils-$$GST_VERSION
+diff --git a/config.tests/gstreamer_encodingprofiles/gstreamer_encodingprofiles.pro b/config.tests/gstreamer_encodingprofiles/gstreamer_encodingprofiles.pro
+index 7e8a9e7..fad40b0 100644
+--- a/config.tests/gstreamer_encodingprofiles/gstreamer_encodingprofiles.pro
++++ b/config.tests/gstreamer_encodingprofiles/gstreamer_encodingprofiles.pro
+@@ -2,11 +2,10 @@ SOURCES += main.cpp
+ 
+ CONFIG += link_pkgconfig
+ 
+-PKGCONFIG += \
+-    gstreamer-0.10 \
+-    gstreamer-base-0.10 \
+-    gstreamer-interfaces-0.10 \
+-    gstreamer-audio-0.10 \
+-    gstreamer-video-0.10 \
+-    gstreamer-pbutils-0.10
+ 
++PKGCONFIG += \
++    gstreamer-$$GST_VERSION \
++    gstreamer-base-$$GST_VERSION \
++    gstreamer-audio-$$GST_VERSION \
++    gstreamer-video-$$GST_VERSION \
++    gstreamer-pbutils-$$GST_VERSION
+diff --git a/config.tests/gstreamer_photography/gstreamer_photography.pro b/config.tests/gstreamer_photography/gstreamer_photography.pro
+index 6b530cb..975991f 100644
+--- a/config.tests/gstreamer_photography/gstreamer_photography.pro
++++ b/config.tests/gstreamer_photography/gstreamer_photography.pro
+@@ -3,12 +3,11 @@ SOURCES += main.cpp
+ CONFIG += link_pkgconfig
+ 
+ PKGCONFIG += \
+-    gstreamer-0.10 \
+-    gstreamer-base-0.10 \
+-    gstreamer-interfaces-0.10 \
+-    gstreamer-audio-0.10 \
+-    gstreamer-video-0.10 \
+-    gstreamer-pbutils-0.10
+-
+-LIBS += -lgstphotography-0.10
++    gstreamer-$$GST_VERSION \
++    gstreamer-base-$$GST_VERSION \
++    gstreamer-audio-$$GST_VERSION \
++    gstreamer-video-$$GST_VERSION \
++    gstreamer-pbutils-$$GST_VERSION
++
++LIBS += -lgstphotography-$$GST_VERSION
+ 
+diff --git a/examples/multimedia/declarative-camera/declarative-camera.qml b/examples/multimedia/declarative-camera/declarative-camera.qml
+index 751b38d..251df34 100644
+--- a/examples/multimedia/declarative-camera/declarative-camera.qml
++++ b/examples/multimedia/declarative-camera/declarative-camera.qml
+@@ -96,7 +96,7 @@ Rectangle {
+ 
+         videoRecorder {
+              resolution: "640x480"
+-             frameRate: 15
++             frameRate: 30
+         }
+     }
+ 
+diff --git a/qtmultimedia.pro b/qtmultimedia.pro
+index 3cec526..84f2548 100644
+--- a/qtmultimedia.pro
++++ b/qtmultimedia.pro
+@@ -17,11 +17,27 @@ win32 {
+ } else {
+     qtCompileTest(alsa)
+     qtCompileTest(pulseaudio)
+-    qtCompileTest(gstreamer) {
+-        qtCompileTest(gstreamer_photography)
+-        qtCompileTest(gstreamer_encodingprofiles)
+-        qtCompileTest(gstreamer_appsrc)
+-        qtCompileTest(linux_v4l)
++    !done_config_gstreamer {
++        gstver=0.10
++        !isEmpty(GST_VERSION): gstver=$$GST_VERSION
++        cache(GST_VERSION, set, gstver);
++        qtCompileTest(gstreamer) {
++            qtCompileTest(gstreamer_photography)
++            qtCompileTest(gstreamer_encodingprofiles)
++            qtCompileTest(gstreamer_appsrc)
++            qtCompileTest(linux_v4l)
++        } else {
++            gstver=1.0
++            cache(GST_VERSION, set, gstver);
++            # Force a re-run of the test
++            CONFIG -= done_config_gstreamer
++            qtCompileTest(gstreamer) {
++                qtCompileTest(gstreamer_photography)
++                qtCompileTest(gstreamer_encodingprofiles)
++                qtCompileTest(gstreamer_appsrc)
++                qtCompileTest(linux_v4l)
++            }
++        }
+     }
+     qtCompileTest(resourcepolicy)
+     qtCompileTest(gpu_vivante)
+diff --git a/src/gsttools/gsttools.pro b/src/gsttools/gsttools.pro
+index 7c809a7..7c41f1a 100644
+--- a/src/gsttools/gsttools.pro
++++ b/src/gsttools/gsttools.pro
+@@ -2,6 +2,7 @@ TEMPLATE = lib
+ 
+ TARGET = qgsttools_p
+ QPRO_PWD = $$PWD
++
+ QT = core-private multimedia-private gui-private
+ 
+ !static:DEFINES += QT_MAKEDLL
+@@ -15,15 +16,17 @@ LIBS_PRIVATE += \
+ 
+ CONFIG += link_pkgconfig
+ 
+-PKGCONFIG_PRIVATE += \
+-    gstreamer-0.10 \
+-    gstreamer-base-0.10 \
+-    gstreamer-interfaces-0.10 \
+-    gstreamer-audio-0.10 \
+-    gstreamer-video-0.10 \
+-    gstreamer-pbutils-0.10
++PKGCONFIG += \
++    gstreamer-$$GST_VERSION \
++    gstreamer-base-$$GST_VERSION \
++    gstreamer-audio-$$GST_VERSION \
++    gstreamer-video-$$GST_VERSION \
++    gstreamer-pbutils-$$GST_VERSION
+ 
+-maemo*: PKGCONFIG_PRIVATE +=gstreamer-plugins-bad-0.10
++equals(GST_VERSION,"0.10") {
++    PKGCONFIG_PRIVATE += gstreamer-interfaces-0.10
++    maemo*: PKGCONFIG_PRIVATE +=gstreamer-plugins-bad-0.10
++}
+ 
+ config_resourcepolicy {
+     DEFINES += HAVE_RESOURCE_POLICY
+@@ -33,38 +36,36 @@ config_resourcepolicy {
+ # Header files must go inside source directory of a module
+ # to be installed by syncqt.
+ INCLUDEPATH += ../multimedia/gsttools_headers/
++INCLUDEPATH += ../plugins/gstreamer/mediaplayer/
+ VPATH += ../multimedia/gsttools_headers/
+ 
+ PRIVATE_HEADERS += \
+-    qgstbufferpoolinterface_p.h \
+     qgstreamerbushelper_p.h \
+     qgstreamermessage_p.h \
+     qgstutils_p.h \
+     qgstvideobuffer_p.h \
+     qvideosurfacegstsink_p.h \
++    qgstreamerbufferprobe_p.h \
+     qgstreamervideorendererinterface_p.h \
+     qgstreameraudioinputselector_p.h \
+     qgstreamervideorenderer_p.h \
+     qgstreamervideoinputdevicecontrol_p.h \
+-    gstvideoconnector_p.h \
+     qgstcodecsinfo_p.h \
+     qgstreamervideoprobecontrol_p.h \
+     qgstreameraudioprobecontrol_p.h \
+     qgstreamervideowindow_p.h
+ 
+ SOURCES += \
+-    qgstbufferpoolinterface.cpp \
+     qgstreamerbushelper.cpp \
+     qgstreamermessage.cpp \
+     qgstutils.cpp \
+     qgstvideobuffer.cpp \
+-    qvideosurfacegstsink.cpp \
++    qgstreamerbufferprobe.cpp \
+     qgstreamervideorendererinterface.cpp \
+     qgstreameraudioinputselector.cpp \
+     qgstreamervideorenderer.cpp \
+     qgstreamervideoinputdevicecontrol.cpp \
+     qgstcodecsinfo.cpp \
+-    gstvideoconnector.c \
+     qgstreamervideoprobecontrol.cpp \
+     qgstreameraudioprobecontrol.cpp \
+     qgstreamervideowindow.cpp
+@@ -79,25 +80,54 @@ qtHaveModule(widgets) {
+         qgstreamervideowidget.cpp
+ }
+ 
+-maemo6 {
+-    PKGCONFIG_PRIVATE += qmsystem2
++equals(GST_VERSION,"0.10") {
++    PRIVATE_HEADERS += \
++        qgstbufferpoolinterface_p.h \
++        gstvideoconnector_p.h \
++
++    SOURCES += \
++        qgstbufferpoolinterface.cpp \
++        qvideosurfacegstsink.cpp \
++        gstvideoconnector.c
++
++    maemo6 {
++        PKGCONFIG_PRIVATE += qmsystem2
++
++        contains(QT_CONFIG, opengles2):qtHaveModule(widgets) {
++            PRIVATE_HEADERS += qgstreamergltexturerenderer_p.h
++            SOURCES += qgstreamergltexturerenderer.cpp
++            QT += opengl
++            LIBS_PRIVATE += -lEGL -lgstmeegointerfaces-0.10
++        }
++    }
++} else {
++    PRIVATE_HEADERS += \
++        qgstvideorendererplugin_p.h \
++        qgstvideorenderersink_p.h
++
++    SOURCES += \
++        qgstvideorendererplugin.cpp \
++        qgstvideorenderersink.cpp
++}
+ 
++mir: {
+     contains(QT_CONFIG, opengles2):qtHaveModule(widgets) {
+-        PRIVATE_HEADERS += qgstreamergltexturerenderer_p.h
+-        SOURCES += qgstreamergltexturerenderer.cpp
+-        QT += opengl
+-        LIBS_PRIVATE += -lEGL -lgstmeegointerfaces-0.10
++        PRIVATE_HEADERS += qgstreamermirtexturerenderer_p.h
++        SOURCES += qgstreamermirtexturerenderer.cpp
++        QT += opengl quick
++        LIBS += -lEGL
+     }
++    DEFINES += HAVE_MIR
+ }
+ 
+ config_gstreamer_appsrc {
+-    PKGCONFIG_PRIVATE += gstreamer-app-0.10
++    PKGCONFIG_PRIVATE += gstreamer-app-$$GST_VERSION
+     PRIVATE_HEADERS += qgstappsrc_p.h
+     SOURCES += qgstappsrc.cpp
+ 
+     DEFINES += HAVE_GST_APPSRC
+ 
+-    LIBS_PRIVATE += -lgstapp-0.10
++    LIBS_PRIVATE += -lgstapp-$$GST_VERSION
+ }
+ 
+ config_linux_v4l: DEFINES += USE_V4L
+diff --git a/src/gsttools/qgstappsrc.cpp b/src/gsttools/qgstappsrc.cpp
+index 148366b..57eaacd 100644
+--- a/src/gsttools/qgstappsrc.cpp
++++ b/src/gsttools/qgstappsrc.cpp
+@@ -147,23 +147,44 @@ void QGstAppSrc::pushDataToAppSrc()
+             size = qMin(m_stream->bytesAvailable(), (qint64)m_dataRequestSize);
+ 
+         if (size) {
+-            void *data = g_malloc(size);
+-            GstBuffer* buffer = gst_app_buffer_new(data, size, g_free, data);
++            GstBuffer* buffer = gst_buffer_new_and_alloc(size);
++
++#if GST_CHECK_VERSION(1,0,0)
++            GstMapInfo mapInfo;
++            gst_buffer_map(buffer, &mapInfo, GST_MAP_WRITE);
++            void* bufferData = mapInfo.data;
++#else
++            void* bufferData = GST_BUFFER_DATA(buffer);
++#endif
++
+             buffer->offset = m_stream->pos();
+-            qint64 bytesRead = m_stream->read((char*)GST_BUFFER_DATA(buffer), size);
++            qint64 bytesRead = m_stream->read((char*)bufferData, size);
+             buffer->offset_end =  buffer->offset + bytesRead - 1;
+ 
++#if GST_CHECK_VERSION(1,0,0)
++            gst_buffer_unmap(buffer, &mapInfo);
++#endif
++
+             if (bytesRead > 0) {
+                 m_dataRequested = false;
+                 m_enoughData = false;
+                 GstFlowReturn ret = gst_app_src_push_buffer (GST_APP_SRC (element()), buffer);
+                 if (ret == GST_FLOW_ERROR) {
+                     qWarning()<<"appsrc: push buffer error";
++#if GST_CHECK_VERSION(1,0,0)
++                } else if (ret == GST_FLOW_FLUSHING) {
++                    qWarning()<<"appsrc: push buffer wrong state";
++                }
++#else
+                 } else if (ret == GST_FLOW_WRONG_STATE) {
+                     qWarning()<<"appsrc: push buffer wrong state";
+-                } else if (ret == GST_FLOW_RESEND) {
++                }
++#endif
++#if GST_VERSION_MAJOR < 1
++                else if (ret == GST_FLOW_RESEND) {
+                     qWarning()<<"appsrc: push buffer resend";
+                 }
++#endif
+             }
+         } else {
+             sendEOS();
+diff --git a/src/gsttools/qgstcodecsinfo.cpp b/src/gsttools/qgstcodecsinfo.cpp
+index f584fbe..888722a 100644
+--- a/src/gsttools/qgstcodecsinfo.cpp
++++ b/src/gsttools/qgstcodecsinfo.cpp
+@@ -32,7 +32,7 @@
+ ****************************************************************************/
+ 
+ #include "qgstcodecsinfo_p.h"
+-
++#include "qgstutils_p.h"
+ #include <QtCore/qset.h>
+ 
+ #ifdef QMEDIA_GSTREAMER_CAMERABIN
+@@ -146,7 +146,7 @@ GstCaps* QGstCodecsInfo::supportedElementCaps(GstElementFactoryListType elementT
+                     if (fakeEncoderMimeTypes.contains(gst_structure_get_name(structure)))
+                         continue;
+ 
+-                    GstStructure *newStructure = gst_structure_new(gst_structure_get_name(structure), NULL);
++                    GstStructure *newStructure = qt_gst_structure_new_empty(gst_structure_get_name(structure));
+ 
+                     //add structure fields to distinguish between formats with similar mime types,
+                     //like audio/mpeg
+@@ -166,7 +166,11 @@ GstCaps* QGstCodecsInfo::supportedElementCaps(GstElementFactoryListType elementT
+                         }
+                     }
+ 
++#if GST_CHECK_VERSION(1,0,0)
++                    res =
++#endif
+                     gst_caps_merge_structure(res, newStructure);
++
+                 }
+                 gst_caps_unref(caps);
+             }
+diff --git a/src/gsttools/qgstreameraudioprobecontrol.cpp b/src/gsttools/qgstreameraudioprobecontrol.cpp
+index 3baca53..9670d0f 100644
+--- a/src/gsttools/qgstreameraudioprobecontrol.cpp
++++ b/src/gsttools/qgstreameraudioprobecontrol.cpp
+@@ -37,32 +37,48 @@
+ QGstreamerAudioProbeControl::QGstreamerAudioProbeControl(QObject *parent)
+     : QMediaAudioProbeControl(parent)
+ {
+-
+ }
+ 
+ QGstreamerAudioProbeControl::~QGstreamerAudioProbeControl()
+ {
+-
+ }
+ 
+-void QGstreamerAudioProbeControl::bufferProbed(GstBuffer* buffer)
++void QGstreamerAudioProbeControl::probeCaps(GstCaps *caps)
+ {
+-    GstCaps* caps = gst_buffer_get_caps(buffer);
+-    if (!caps)
+-        return;
+-
+     QAudioFormat format = QGstUtils::audioFormatForCaps(caps);
+-    gst_caps_unref(caps);
+-    if (!format.isValid())
+-        return;
+ 
+-    QAudioBuffer audioBuffer = QAudioBuffer(QByteArray((const char*)buffer->data, buffer->size), format);
++    QMutexLocker locker(&m_bufferMutex);
++    m_format = format;
++}
+ 
+-    {
+-        QMutexLocker locker(&m_bufferMutex);
+-        m_pendingBuffer = audioBuffer;
+-        QMetaObject::invokeMethod(this, "bufferProbed", Qt::QueuedConnection);
++bool QGstreamerAudioProbeControl::probeBuffer(GstBuffer *buffer)
++{
++    qint64 position = GST_BUFFER_TIMESTAMP(buffer);
++    position = position >= 0
++            ? position / G_GINT64_CONSTANT(1000) // microseconds
++            : -1;
++
++    QByteArray data;
++#if GST_CHECK_VERSION(1,0,0)
++    GstMapInfo info;
++    if (gst_buffer_map(buffer, &info, GST_MAP_READ)) {
++        data = QByteArray(reinterpret_cast<const char *>(info.data), info.size);
++        gst_buffer_unmap(buffer, &info);
++    } else {
++        return true;
++    }
++#else
++    data = QByteArray(reinterpret_cast<const char *>(buffer->data), buffer->size);
++#endif
++
++    QMutexLocker locker(&m_bufferMutex);
++    if (m_format.isValid()) {
++        if (!m_pendingBuffer.isValid())
++            QMetaObject::invokeMethod(this, "bufferProbed", Qt::QueuedConnection);
++        m_pendingBuffer = QAudioBuffer(data, m_format, position);
+     }
++
++    return true;
+ }
+ 
+ void QGstreamerAudioProbeControl::bufferProbed()
+@@ -73,6 +89,7 @@ void QGstreamerAudioProbeControl::bufferProbed()
+         if (!m_pendingBuffer.isValid())
+             return;
+         audioBuffer = m_pendingBuffer;
++        m_pendingBuffer = QAudioBuffer();
+     }
+     emit audioBufferProbed(audioBuffer);
+ }
+diff --git a/src/gsttools/qgstreamerbufferprobe.cpp b/src/gsttools/qgstreamerbufferprobe.cpp
+new file mode 100644
+index 0000000..91f8126
+--- /dev/null
++++ b/src/gsttools/qgstreamerbufferprobe.cpp
+@@ -0,0 +1,174 @@
++/****************************************************************************
++**
++** Copyright (C) 2014 Jolla Ltd.
++** Contact: http://www.qt-project.org/legal
++**
++** This file is part of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and Digia.  For licensing terms and
++** conditions see http://qt.digia.com/licensing.  For further information
++** use the contact form at http://qt.digia.com/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 2.1 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL included in the
++** packaging of this file.  Please review the following information to
++** ensure the GNU Lesser General Public License version 2.1 requirements
++** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
++**
++** In addition, as a special exception, Digia gives you certain additional
++** rights.  These rights are described in the Digia Qt LGPL Exception
++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 3.0 as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL included in the
++** packaging of this file.  Please review the following information to
++** ensure the GNU General Public License version 3.0 requirements will be
++** met: http://www.gnu.org/copyleft/gpl.html.
++**
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include "qgstreamerbufferprobe_p.h"
++#include "qgstutils_p.h"
++
++QT_BEGIN_NAMESPACE
++
++QGstreamerBufferProbe::QGstreamerBufferProbe(Flags flags)
++#if GST_CHECK_VERSION(1,0,0)
++    : m_capsProbeId(-1)
++#else
++    : m_caps(0)
++#endif
++    , m_bufferProbeId(-1)
++    , m_flags(flags)
++{
++}
++
++QGstreamerBufferProbe::~QGstreamerBufferProbe()
++{
++#if !GST_CHECK_VERSION(1,0,0)
++    if (m_caps)
++        gst_caps_unref(m_caps);
++#endif
++}
++
++void QGstreamerBufferProbe::addProbeToPad(GstPad *pad, bool downstream)
++{
++    if (GstCaps *caps = qt_gst_pad_get_current_caps(pad)) {
++        probeCaps(caps);
++        gst_caps_unref(caps);
++    }
++#if GST_CHECK_VERSION(1,0,0)
++    if (m_flags & ProbeCaps) {
++        m_capsProbeId = gst_pad_add_probe(
++                    pad,
++                    downstream
++                        ? GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM
++                        : GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
++                    capsProbe,
++                    this,
++                    NULL);
++    }
++    if (m_flags & ProbeBuffers) {
++        m_bufferProbeId = gst_pad_add_probe(
++                    pad, GST_PAD_PROBE_TYPE_BUFFER, bufferProbe, this, NULL);
++    }
++#else
++    Q_UNUSED(downstream);
++
++    m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(bufferProbe), this);
++#endif
++}
++
++void QGstreamerBufferProbe::removeProbeFromPad(GstPad *pad)
++{
++#if GST_CHECK_VERSION(1,0,0)
++    if (m_capsProbeId != -1) {
++        gst_pad_remove_probe(pad, m_capsProbeId);
++        m_capsProbeId = -1;
++    }
++    if (m_bufferProbeId != -1) {
++        gst_pad_remove_probe(pad, m_bufferProbeId);
++        m_bufferProbeId = -1;
++    }
++#else
++    if (m_bufferProbeId != -1) {
++        gst_pad_remove_buffer_probe(pad, m_bufferProbeId);
++        m_bufferProbeId = -1;
++        if (m_caps) {
++            gst_caps_unref(m_caps);
++            m_caps = 0;
++        }
++    }
++#endif
++}
++
++void QGstreamerBufferProbe::probeCaps(GstCaps *)
++{
++}
++
++bool QGstreamerBufferProbe::probeBuffer(GstBuffer *)
++{
++    return true;
++}
++
++#if GST_CHECK_VERSION(1,0,0)
++GstPadProbeReturn QGstreamerBufferProbe::capsProbe(
++        GstPad *, GstPadProbeInfo *info, gpointer user_data)
++{
++    QGstreamerBufferProbe * const control = static_cast<QGstreamerBufferProbe *>(user_data);
++
++    if (GstEvent * const event = gst_pad_probe_info_get_event(info)) {
++        if (GST_EVENT_TYPE(event) == GST_EVENT_CAPS) {
++            GstCaps *caps;
++            gst_event_parse_caps(event, &caps);
++
++            control->probeCaps(caps);
++        }
++    }
++    return GST_PAD_PROBE_OK;
++}
++
++GstPadProbeReturn QGstreamerBufferProbe::bufferProbe(
++        GstPad *, GstPadProbeInfo *info, gpointer user_data)
++{
++    QGstreamerBufferProbe * const control = static_cast<QGstreamerBufferProbe *>(user_data);
++    if (GstBuffer * const buffer = gst_pad_probe_info_get_buffer(info))
++        return control->probeBuffer(buffer) ? GST_PAD_PROBE_OK : GST_PAD_PROBE_DROP;
++    return GST_PAD_PROBE_OK;
++}
++#else
++gboolean QGstreamerBufferProbe::bufferProbe(GstElement *, GstBuffer *buffer, gpointer user_data)
++{
++    QGstreamerBufferProbe * const control = static_cast<QGstreamerBufferProbe *>(user_data);
++
++    if (control->m_flags & ProbeCaps) {
++        GstCaps *caps = gst_buffer_get_caps(buffer);
++        if (caps && (!control->m_caps || !gst_caps_is_equal(control->m_caps, caps))) {
++            qSwap(caps, control->m_caps);
++            control->probeCaps(control->m_caps);
++        }
++        if (caps)
++            gst_caps_unref(caps);
++    }
++
++    if (control->m_flags & ProbeBuffers) {
++        return control->probeBuffer(buffer) ? TRUE : FALSE;
++    } else {
++        return TRUE;
++    }
++}
++#endif
++
++QT_END_NAMESPACE
+diff --git a/src/gsttools/qgstreamerbushelper.cpp b/src/gsttools/qgstreamerbushelper.cpp
+index 84eda46..eb1fc36 100644
+--- a/src/gsttools/qgstreamerbushelper.cpp
++++ b/src/gsttools/qgstreamerbushelper.cpp
+@@ -154,13 +154,21 @@ QGstreamerBusHelper::QGstreamerBusHelper(GstBus* bus, QObject* parent):
+     QObject(parent)
+ {
+     d = new QGstreamerBusHelperPrivate(this, bus);
++#if GST_CHECK_VERSION(1,0,0)
++    gst_bus_set_sync_handler(bus, (GstBusSyncHandler)syncGstBusFilter, d, 0);
++#else
+     gst_bus_set_sync_handler(bus, (GstBusSyncHandler)syncGstBusFilter, d);
++#endif
+     gst_object_ref(GST_OBJECT(bus));
+ }
+ 
+ QGstreamerBusHelper::~QGstreamerBusHelper()
+ {
++#if GST_CHECK_VERSION(1,0,0)
++    gst_bus_set_sync_handler(d->bus(), 0, 0, 0);
++#else
+     gst_bus_set_sync_handler(d->bus(),0,0);
++#endif
+     gst_object_unref(GST_OBJECT(d->bus()));
+ }
+ 
+diff --git a/src/gsttools/qgstreamermirtexturerenderer.cpp b/src/gsttools/qgstreamermirtexturerenderer.cpp
+new file mode 100644
+index 0000000..39e0db7
+--- /dev/null
++++ b/src/gsttools/qgstreamermirtexturerenderer.cpp
+@@ -0,0 +1,351 @@
++/****************************************************************************
++**
++** Copyright (C) 2014 Canonical Ltd.
++** Contact: http://www.qt-project.org/legal
++**
++** This file is part of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL21$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and Digia. For licensing terms and
++** conditions see http://qt.digia.com/licensing. For further information
++** use the contact form at http://qt.digia.com/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 2.1 or version 3 as published by the Free
++** Software Foundation and appearing in the file LICENSE.LGPLv21 and
++** LICENSE.LGPLv3 included in the packaging of this file. Please review the
++** following information to ensure the GNU Lesser General Public License
++** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
++** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
++**
++** In addition, as a special exception, Digia gives you certain additional
++** rights. These rights are described in the Digia Qt LGPL Exception
++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include "qgstreamermirtexturerenderer_p.h"
++
++#include <qgstreamerplayersession.h>
++#include <private/qvideosurfacegstsink_p.h>
++#include <private/qgstutils_p.h>
++#include <qabstractvideosurface.h>
++
++#include <QAbstractVideoBuffer>
++#include <QGuiApplication>
++#include <QDebug>
++#include <QtQuick/QQuickWindow>
++#include <QOpenGLContext>
++#include <QGLContext>
++#include <QGuiApplication>
++#include <qgl.h>
++
++#include <gst/gst.h>
++
++static QGstreamerMirTextureRenderer *rendererInstance = NULL;
++
++class QGstreamerMirTextureBuffer : public QAbstractVideoBuffer
++{
++public:
++    QGstreamerMirTextureBuffer(GLuint textureId) :
++        QAbstractVideoBuffer(QAbstractVideoBuffer::GLTextureHandle),
++        m_textureId(textureId)
++    {
++    }
++
++    MapMode mapMode() const { return NotMapped; }
++
++    uchar *map(MapMode mode, int *numBytes, int *bytesPerLine)
++    {
++        qDebug() << Q_FUNC_INFO;
++        Q_UNUSED(mode);
++        Q_UNUSED(numBytes);
++        Q_UNUSED(bytesPerLine);
++
++        return NULL;
++    }
++
++    void unmap() { qDebug() << Q_FUNC_INFO; }
++
++    QVariant handle() const { return QVariant::fromValue<unsigned int>(m_textureId); }
++
++    GLuint textureId() { return m_textureId; }
++
++private:
++    GLuint m_textureId;
++};
++
++QGstreamerMirTextureRenderer::QGstreamerMirTextureRenderer(QObject *parent
++        , const QGstreamerPlayerSession *playerSession)
++    : QVideoRendererControl(0), m_videoSink(0), m_surface(0),
++      m_glSurface(0),
++      m_context(0),
++      m_glContext(0),
++      m_textureId(0),
++      m_offscreenSurface(0),
++      m_textureBuffer(0)
++{
++    Q_UNUSED(parent);
++    setPlayerSession(playerSession);
++}
++
++QGstreamerMirTextureRenderer::~QGstreamerMirTextureRenderer()
++{
++    if (m_videoSink)
++        gst_object_unref(GST_OBJECT(m_videoSink));
++
++    delete m_glContext;
++    delete m_offscreenSurface;
++}
++
++GstElement *QGstreamerMirTextureRenderer::videoSink()
++{
++    qDebug() << Q_FUNC_INFO;
++
++    // FIXME: Ugly hack until I figure out why passing this segfaults in the g_signal handler
++    rendererInstance = const_cast<QGstreamerMirTextureRenderer*>(this);
++
++    if (!m_videoSink && m_surface) {
++        qDebug() << Q_FUNC_INFO << ": using mirsink, (this: " << this << ")";
++
++        m_videoSink = gst_element_factory_make("mirsink", "video-output");
++
++        connect(QGuiApplication::instance(), SIGNAL(focusWindowChanged(QWindow*)),
++                this, SLOT(handleFocusWindowChanged(QWindow*)), Qt::QueuedConnection);
++
++        g_signal_connect(G_OBJECT(m_videoSink), "frame-ready", G_CALLBACK(handleFrameReady),
++                (gpointer)this);
++    }
++
++    if (m_videoSink) {
++        gst_object_ref_sink(GST_OBJECT(m_videoSink));
++
++        GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink");
++        gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER,
++                padBufferProbe, this, NULL);
++    }
++
++    return m_videoSink;
++}
++
++QWindow *QGstreamerMirTextureRenderer::createOffscreenWindow(const QSurfaceFormat &format)
++{
++    QWindow *w = new QWindow();
++    w->setSurfaceType(QWindow::OpenGLSurface);
++    w->setFormat(format);
++    w->setGeometry(0, 0, 1, 1);
++    w->setFlags(w->flags() | Qt::WindowTransparentForInput);
++    w->create();
++
++    return w;
++}
++
++void QGstreamerMirTextureRenderer::handleFrameReady(gpointer userData)
++{
++    QGstreamerMirTextureRenderer *renderer = reinterpret_cast<QGstreamerMirTextureRenderer*>(userData);
++#if 1
++    QMutexLocker locker(&rendererInstance->m_mutex);
++    QMetaObject::invokeMethod(rendererInstance, "renderFrame", Qt::QueuedConnection);
++#else
++    // FIXME!
++    //QMutexLocker locker(&renderer->m_mutex);
++    QMetaObject::invokeMethod(renderer, "renderFrame", Qt::QueuedConnection);
++#endif
++}
++
++void QGstreamerMirTextureRenderer::renderFrame()
++{
++    //qDebug() << Q_FUNC_INFO;
++
++    if (m_context)
++        m_context->makeCurrent();
++
++    GstState pendingState = GST_STATE_NULL;
++    GstState newState = GST_STATE_NULL;
++    // Don't block and return immediately:
++    GstStateChangeReturn ret = gst_element_get_state(m_videoSink, &newState,
++                                                     &pendingState, 0);
++    if (ret == GST_STATE_CHANGE_FAILURE || newState == GST_STATE_NULL||
++            pendingState == GST_STATE_NULL) {
++        qWarning() << "Invalid state change for renderer, aborting";
++        stopRenderer();
++        return;
++    }
++
++    if (!m_surface->isActive()) {
++        qDebug() << "m_surface is not active";
++        GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink");
++        GstCaps *caps = gst_pad_get_current_caps(pad);
++
++        if (caps) {
++            // Get the native video size from the video sink
++            QSize newNativeSize = QGstUtils::capsCorrectedResolution(caps);
++            if (m_nativeSize != newNativeSize) {
++                m_nativeSize = newNativeSize;
++                emit nativeSizeChanged();
++            }
++            gst_caps_unref(caps);
++        }
++
++        // Start the surface
++        QVideoSurfaceFormat format(m_nativeSize, QVideoFrame::Format_RGB32, QAbstractVideoBuffer::GLTextureHandle);
++        qDebug() << "m_nativeSize: " << m_nativeSize;
++        qDebug() << "format: " << format;
++        if (!m_surface->start(format)) {
++            qWarning() << Q_FUNC_INFO << ": failed to start the video surface " << format;
++            return;
++        }
++    }
++
++    QGstreamerMirTextureBuffer *buffer = new QGstreamerMirTextureBuffer(m_textureId);
++    //qDebug() << "frameSize: " << m_surface->surfaceFormat().frameSize();
++    QVideoFrame frame(buffer, m_surface->surfaceFormat().frameSize(),
++                      m_surface->surfaceFormat().pixelFormat());
++
++    frame.setMetaData("TextureId", m_textureId);
++
++    // Display the video frame on the surface:
++    m_surface->present(frame);
++}
++
++GstPadProbeReturn QGstreamerMirTextureRenderer::padBufferProbe(GstPad *pad, GstPadProbeInfo *info, gpointer userData)
++{
++    Q_UNUSED(pad);
++    Q_UNUSED(info);
++
++    QGstreamerMirTextureRenderer *control = reinterpret_cast<QGstreamerMirTextureRenderer*>(userData);
++    QMetaObject::invokeMethod(control, "updateNativeVideoSize", Qt::QueuedConnection);
++
++    return GST_PAD_PROBE_REMOVE;
++}
++
++void QGstreamerMirTextureRenderer::stopRenderer()
++{
++    if (m_surface)
++        m_surface->stop();
++}
++
++QAbstractVideoSurface *QGstreamerMirTextureRenderer::surface() const
++{
++    return m_surface;
++}
++
++void QGstreamerMirTextureRenderer::setSurface(QAbstractVideoSurface *surface)
++{
++    qDebug() << Q_FUNC_INFO;
++
++    if (m_surface != surface) {
++        qDebug() << "Saving current QGLContext";
++        m_context = const_cast<QGLContext*>(QGLContext::currentContext());
++
++        if (m_videoSink)
++            gst_object_unref(GST_OBJECT(m_videoSink));
++
++        m_videoSink = 0;
++
++        if (m_surface) {
++            disconnect(m_surface.data(), SIGNAL(supportedFormatsChanged()),
++                       this, SLOT(handleFormatChange()));
++        }
++
++        bool wasReady = isReady();
++
++        m_surface = surface;
++
++        if (m_surface) {
++            connect(m_surface.data(), SIGNAL(supportedFormatsChanged()),
++                    this, SLOT(handleFormatChange()));
++        }
++
++        if (wasReady != isReady())
++            emit readyChanged(isReady());
++
++        emit sinkChanged();
++    }
++}
++
++void QGstreamerMirTextureRenderer::setPlayerSession(const QGstreamerPlayerSession *playerSession)
++{
++    m_playerSession = const_cast<QGstreamerPlayerSession*>(playerSession);
++}
++
++void QGstreamerMirTextureRenderer::handleFormatChange()
++{
++    qDebug() << "Supported formats list has changed, reload video output";
++
++    if (m_videoSink)
++        gst_object_unref(GST_OBJECT(m_videoSink));
++
++    m_videoSink = 0;
++    emit sinkChanged();
++}
++
++void QGstreamerMirTextureRenderer::updateNativeVideoSize()
++{
++    //qDebug() << Q_FUNC_INFO;
++    const QSize oldSize = m_nativeSize;
++
++    if (m_videoSink) {
++        // Find video native size to update video widget size hint
++        GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
++        GstCaps *caps = gst_pad_get_current_caps(pad);
++
++        if (caps) {
++            m_nativeSize = QGstUtils::capsCorrectedResolution(caps);
++            gst_caps_unref(caps);
++        }
++    } else {
++        m_nativeSize = QSize();
++    }
++    qDebug() << Q_FUNC_INFO << oldSize << m_nativeSize << m_videoSink;
++
++    if (m_nativeSize != oldSize)
++        emit nativeSizeChanged();
++}
++
++void QGstreamerMirTextureRenderer::handleFocusWindowChanged(QWindow *window)
++{
++    qDebug() << Q_FUNC_INFO;
++
++    QOpenGLContext *currContext = QOpenGLContext::currentContext();
++
++    QQuickWindow *w = dynamic_cast<QQuickWindow*>(window);
++    // If we don't have a GL context in the current thread, create one and share it
++    // with the render thread GL context
++    if (!currContext && !m_glContext) {
++        // This emulates the new QOffscreenWindow class with Qt5.1
++        m_offscreenSurface = createOffscreenWindow(w->openglContext()->surface()->format());
++        m_offscreenSurface->setParent(window);
++
++        QOpenGLContext *shareContext = 0;
++        if (m_surface)
++            shareContext = qobject_cast<QOpenGLContext*>(m_surface->property("GLContext").value<QObject*>());
++        m_glContext = new QOpenGLContext;
++        m_glContext->setFormat(m_offscreenSurface->requestedFormat());
++
++        if (shareContext)
++            m_glContext->setShareContext(shareContext);
++
++        if (!m_glContext->create())
++        {
++            qWarning() << "Failed to create new shared context.";
++            return;
++        }
++    }
++
++    if (m_glContext)
++        m_glContext->makeCurrent(m_offscreenSurface);
++
++    if (m_textureId == 0) {
++        glGenTextures(1, &m_textureId);
++        qDebug() << "texture_id (handleFocusWindowChanged): " << m_textureId << endl;
++        g_object_set(G_OBJECT(m_videoSink), "texture-id", m_textureId, (char*)NULL);
++    }
++}
+diff --git a/src/gsttools/qgstreamervideoprobecontrol.cpp b/src/gsttools/qgstreamervideoprobecontrol.cpp
+index a78a9da..71a402d 100644
+--- a/src/gsttools/qgstreamervideoprobecontrol.cpp
++++ b/src/gsttools/qgstreamervideoprobecontrol.cpp
+@@ -32,7 +32,8 @@
+ ****************************************************************************/
+ 
+ #include "qgstreamervideoprobecontrol_p.h"
+-#include <private/qvideosurfacegstsink_p.h>
++
++#include "qgstutils_p.h"
+ #include <private/qgstvideobuffer_p.h>
+ 
+ QGstreamerVideoProbeControl::QGstreamerVideoProbeControl(QObject *parent)
+@@ -40,12 +41,10 @@ QGstreamerVideoProbeControl::QGstreamerVideoProbeControl(QObject *parent)
+     , m_flushing(false)
+     , m_frameProbed(false)
+ {
+-
+ }
+ 
+ QGstreamerVideoProbeControl::~QGstreamerVideoProbeControl()
+ {
+-
+ }
+ 
+ void QGstreamerVideoProbeControl::startFlushing()
+@@ -67,33 +66,49 @@ void QGstreamerVideoProbeControl::stopFlushing()
+     m_flushing = false;
+ }
+ 
+-void QGstreamerVideoProbeControl::bufferProbed(GstBuffer* buffer)
++void QGstreamerVideoProbeControl::probeCaps(GstCaps *caps)
+ {
+-    if (m_flushing)
+-        return;
+-
+-    GstCaps* caps = gst_buffer_get_caps(buffer);
+-    if (!caps)
+-        return;
++#if GST_CHECK_VERSION(1,0,0)
++    GstVideoInfo videoInfo;
++    QVideoSurfaceFormat format = QGstUtils::formatForCaps(caps, &videoInfo);
+ 
++    QMutexLocker locker(&m_frameMutex);
++    m_videoInfo = videoInfo;
++#else
+     int bytesPerLine = 0;
+-    QVideoSurfaceFormat format = QVideoSurfaceGstSink::formatForCaps(caps, &bytesPerLine);
+-    gst_caps_unref(caps);
+-    if (!format.isValid() || !bytesPerLine)
+-        return;
++    QVideoSurfaceFormat format = QGstUtils::formatForCaps(caps, &bytesPerLine);
++
++    QMutexLocker locker(&m_frameMutex);
++    m_bytesPerLine = bytesPerLine;
++#endif
++    m_format = format;
++}
++
++bool QGstreamerVideoProbeControl::probeBuffer(GstBuffer *buffer)
++{
++    QMutexLocker locker(&m_frameMutex);
++
++    if (m_flushing || !m_format.isValid())
++        return true;
+ 
+-    QVideoFrame frame = QVideoFrame(new QGstVideoBuffer(buffer, bytesPerLine),
+-                                    format.frameSize(), format.pixelFormat());
++    QVideoFrame frame(
++#if GST_CHECK_VERSION(1,0,0)
++                new QGstVideoBuffer(buffer, m_videoInfo),
++#else
++                new QGstVideoBuffer(buffer, m_bytesPerLine),
++#endif
++                m_format.frameSize(),
++                m_format.pixelFormat());
+ 
+-    QVideoSurfaceGstSink::setFrameTimeStamps(&frame, buffer);
++    QGstUtils::setFrameTimeStamps(&frame, buffer);
+ 
+     m_frameProbed = true;
+ 
+-    {
+-        QMutexLocker locker(&m_frameMutex);
+-        m_pendingFrame = frame;
++    if (!m_pendingFrame.isValid())
+         QMetaObject::invokeMethod(this, "frameProbed", Qt::QueuedConnection);
+-    }
++    m_pendingFrame = frame;
++
++    return true;
+ }
+ 
+ void QGstreamerVideoProbeControl::frameProbed()
+@@ -104,6 +119,7 @@ void QGstreamerVideoProbeControl::frameProbed()
+         if (!m_pendingFrame.isValid())
+             return;
+         frame = m_pendingFrame;
++        m_pendingFrame = QVideoFrame();
+     }
+     emit videoFrameProbed(frame);
+ }
+diff --git a/src/gsttools/qgstreamervideorenderer.cpp b/src/gsttools/qgstreamervideorenderer.cpp
+index 2b66f76..804dce9 100644
+--- a/src/gsttools/qgstreamervideorenderer.cpp
++++ b/src/gsttools/qgstreamervideorenderer.cpp
+@@ -35,8 +35,7 @@
+ #include <private/qvideosurfacegstsink_p.h>
+ #include <private/qgstutils_p.h>
+ #include <qabstractvideosurface.h>
+-
+-#include <QDebug>
++#include <QtCore/qdebug.h>
+ 
+ #include <gst/gst.h>
+ 
+diff --git a/src/gsttools/qgstreamervideowidget.cpp b/src/gsttools/qgstreamervideowidget.cpp
+index aa2e2a3..1ae57a0 100644
+--- a/src/gsttools/qgstreamervideowidget.cpp
++++ b/src/gsttools/qgstreamervideowidget.cpp
+@@ -40,8 +40,13 @@
+ #include <QtGui/qpainter.h>
+ 
+ #include <gst/gst.h>
++
++#if !GST_CHECK_VERSION(1,0,0)
+ #include <gst/interfaces/xoverlay.h>
+ #include <gst/interfaces/propertyprobe.h>
++#else
++#include <gst/video/videooverlay.h>
++#endif
+ 
+ QT_BEGIN_NAMESPACE
+ 
+@@ -130,8 +135,6 @@ void QGstreamerVideoWidgetControl::createVideoWidget()
+         m_videoSink = gst_element_factory_make ("ximagesink", NULL);
+ 
+     qt_gst_object_ref_sink(GST_OBJECT (m_videoSink)); //Take ownership
+-
+-
+ }
+ 
+ GstElement *QGstreamerVideoWidgetControl::videoSink()
+@@ -169,9 +172,13 @@ bool QGstreamerVideoWidgetControl::processSyncMessage(const QGstreamerMessage &m
+ {
+     GstMessage* gm = message.rawMessage();
+ 
++#if !GST_CHECK_VERSION(1,0,0)
+     if (gm && (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) &&
+             gst_structure_has_name(gm->structure, "prepare-xwindow-id")) {
+-
++#else
++      if (gm && (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) &&
++              gst_structure_has_name(gst_message_get_structure(gm), "prepare-window-handle")) {
++#endif
+         setOverlay();
+         QMetaObject::invokeMethod(this, "updateNativeVideoSize", Qt::QueuedConnection);
+         return true;
+@@ -199,17 +206,24 @@ bool QGstreamerVideoWidgetControl::processBusMessage(const QGstreamerMessage &me
+ 
+ void QGstreamerVideoWidgetControl::setOverlay()
+ {
++#if !GST_CHECK_VERSION(1,0,0)
+     if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
+         gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_windowId);
+     }
++#else
++    if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) {
++        gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(m_videoSink), m_windowId);
++    }
++#endif
+ }
+ 
+ void QGstreamerVideoWidgetControl::updateNativeVideoSize()
+ {
+     if (m_videoSink) {
+         //find video native size to update video widget size hint
+-        GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
+-        GstCaps *caps = gst_pad_get_negotiated_caps(pad);
++        GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink");
++        GstCaps *caps = qt_gst_pad_get_current_caps(pad);
++
+         gst_object_unref(GST_OBJECT(pad));
+ 
+         if (caps) {
+@@ -225,8 +239,13 @@ void QGstreamerVideoWidgetControl::updateNativeVideoSize()
+ 
+ void QGstreamerVideoWidgetControl::windowExposed()
+ {
++#if !GST_CHECK_VERSION(1,0,0)
+     if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink))
+         gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink));
++#else
++    if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink))
++        gst_video_overlay_expose(GST_VIDEO_OVERLAY(m_videoSink));
++#endif
+ }
+ 
+ QWidget *QGstreamerVideoWidgetControl::videoWidget()
+diff --git a/src/gsttools/qgstreamervideowindow.cpp b/src/gsttools/qgstreamervideowindow.cpp
+index a373dcc..8011349 100644
+--- a/src/gsttools/qgstreamervideowindow.cpp
++++ b/src/gsttools/qgstreamervideowindow.cpp
+@@ -37,36 +37,49 @@
+ #include <QtCore/qdebug.h>
+ 
+ #include <gst/gst.h>
++
++#if !GST_CHECK_VERSION(1,0,0)
+ #include <gst/interfaces/xoverlay.h>
+ #include <gst/interfaces/propertyprobe.h>
++#else
++#include <gst/video/videooverlay.h>
++#endif
+ 
+ 
+ QGstreamerVideoWindow::QGstreamerVideoWindow(QObject *parent, const char *elementName)
+     : QVideoWindowControl(parent)
++    , QGstreamerBufferProbe(QGstreamerBufferProbe::ProbeCaps)
+     , m_videoSink(0)
+     , m_windowId(0)
+     , m_aspectRatioMode(Qt::KeepAspectRatio)
+     , m_fullScreen(false)
+     , m_colorKey(QColor::Invalid)
+ {
+-    if (elementName)
++    if (elementName) {
+         m_videoSink = gst_element_factory_make(elementName, NULL);
+-    else
++    } else {
+         m_videoSink = gst_element_factory_make("xvimagesink", NULL);
++    }
+ 
+     if (m_videoSink) {
+         qt_gst_object_ref_sink(GST_OBJECT(m_videoSink)); //Take ownership
+ 
+-        GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
+-        m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padBufferProbe), this);
++        GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink");
++        addProbeToPad(pad);
+         gst_object_unref(GST_OBJECT(pad));
+     }
++    else
++        qDebug() << "No m_videoSink available!";
+ }
+ 
+ QGstreamerVideoWindow::~QGstreamerVideoWindow()
+ {
+-    if (m_videoSink)
++    if (m_videoSink) {
++        GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
++        removeProbeFromPad(pad);
++        gst_object_unref(GST_OBJECT(pad));
+         gst_object_unref(GST_OBJECT(m_videoSink));
++    }
+ }
+ 
+ WId QGstreamerVideoWindow::winId() const
+@@ -82,11 +95,15 @@ void QGstreamerVideoWindow::setWinId(WId id)
+     WId oldId = m_windowId;
+ 
+     m_windowId = id;
+-
++#if GST_CHECK_VERSION(1,0,0)
++    if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) {
++        gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(m_videoSink), m_windowId);
++    }
++#else
+     if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
+         gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_windowId);
+     }
+-
++#endif
+     if (!oldId)
+         emit readyChanged(true);
+ 
+@@ -97,20 +114,26 @@ void QGstreamerVideoWindow::setWinId(WId id)
+ bool QGstreamerVideoWindow::processSyncMessage(const QGstreamerMessage &message)
+ {
+     GstMessage* gm = message.rawMessage();
++#if GST_CHECK_VERSION(1,0,0)
++    const GstStructure *s = gst_message_get_structure(gm);
++    if ((GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) &&
++            gst_structure_has_name(s, "prepare-window-handle") &&
++            m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) {
++
++        gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(m_videoSink), m_windowId);
+ 
++        return true;
++    }
++#else
+     if ((GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) &&
+             gst_structure_has_name(gm->structure, "prepare-xwindow-id") &&
+             m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
+ 
+         gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_windowId);
+ 
+-        GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
+-        m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padBufferProbe), this);
+-        gst_object_unref(GST_OBJECT(pad));
+-
+         return true;
+     }
+-
++#endif
+     return false;
+ }
+ 
+@@ -122,7 +145,19 @@ QRect QGstreamerVideoWindow::displayRect() const
+ void QGstreamerVideoWindow::setDisplayRect(const QRect &rect)
+ {
+     m_displayRect = rect;
+-
++#if GST_CHECK_VERSION(1,0,0)
++    if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) {
++        if (m_displayRect.isEmpty())
++            gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(m_videoSink), -1, -1, -1, -1);
++        else
++            gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(m_videoSink),
++                                               m_displayRect.x(),
++                                               m_displayRect.y(),
++                                               m_displayRect.width(),
++                                               m_displayRect.height());
++        repaint();
++    }
++#else
+     if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
+ #if GST_VERSION_MICRO >= 29
+         if (m_displayRect.isEmpty())
+@@ -136,6 +171,7 @@ void QGstreamerVideoWindow::setDisplayRect(const QRect &rect)
+         repaint();
+ #endif
+     }
++#endif
+ }
+ 
+ Qt::AspectRatioMode QGstreamerVideoWindow::aspectRatioMode() const
+@@ -157,6 +193,16 @@ void QGstreamerVideoWindow::setAspectRatioMode(Qt::AspectRatioMode mode)
+ 
+ void QGstreamerVideoWindow::repaint()
+ {
++#if GST_CHECK_VERSION(1,0,0)
++    if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) {
++        //don't call gst_x_overlay_expose if the sink is in null state
++        GstState state = GST_STATE_NULL;
++        GstStateChangeReturn res = gst_element_get_state(m_videoSink, &state, NULL, 1000000);
++        if (res != GST_STATE_CHANGE_FAILURE && state != GST_STATE_NULL) {
++            gst_video_overlay_expose(GST_VIDEO_OVERLAY(m_videoSink));
++        }
++    }
++#else
+     if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
+         //don't call gst_x_overlay_expose if the sink is in null state
+         GstState state = GST_STATE_NULL;
+@@ -165,6 +211,7 @@ void QGstreamerVideoWindow::repaint()
+             gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink));
+         }
+     }
++#endif
+ }
+ 
+ QColor QGstreamerVideoWindow::colorKey() const
+@@ -296,32 +343,22 @@ QSize QGstreamerVideoWindow::nativeSize() const
+     return m_nativeSize;
+ }
+ 
+-void QGstreamerVideoWindow::padBufferProbe(GstPad *pad, GstBuffer * /* buffer */, gpointer user_data)
++void QGstreamerVideoWindow::probeCaps(GstCaps *caps)
+ {
+-    QGstreamerVideoWindow *control = reinterpret_cast<QGstreamerVideoWindow*>(user_data);
+-    QMetaObject::invokeMethod(control, "updateNativeVideoSize", Qt::QueuedConnection);
+-    gst_pad_remove_buffer_probe(pad, control->m_bufferProbeId);
++    QSize resolution = QGstUtils::capsCorrectedResolution(caps);
++    QMetaObject::invokeMethod(
++                this,
++                "updateNativeVideoSize",
++                Qt::QueuedConnection,
++                Q_ARG(QSize, resolution));
+ }
+ 
+-void QGstreamerVideoWindow::updateNativeVideoSize()
++void QGstreamerVideoWindow::updateNativeVideoSize(const QSize &size)
+ {
+-    const QSize oldSize = m_nativeSize;
+-    m_nativeSize = QSize();
+-
+-    if (m_videoSink) {
+-        //find video native size to update video widget size hint
+-        GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
+-        GstCaps *caps = gst_pad_get_negotiated_caps(pad);
+-        gst_object_unref(GST_OBJECT(pad));
+-
+-        if (caps) {
+-            m_nativeSize = QGstUtils::capsCorrectedResolution(caps);
+-            gst_caps_unref(caps);
+-        }
+-    }
+-
+-    if (m_nativeSize != oldSize)
++    if (m_nativeSize != size) {
++        m_nativeSize = size;
+         emit nativeSizeChanged();
++    }
+ }
+ 
+ GstElement *QGstreamerVideoWindow::videoSink()
+diff --git a/src/gsttools/qgstutils.cpp b/src/gsttools/qgstutils.cpp
+index 556fc03..65124c9 100644
+--- a/src/gsttools/qgstutils.cpp
++++ b/src/gsttools/qgstutils.cpp
+@@ -40,7 +40,14 @@
+ #include <QtCore/qsize.h>
+ #include <QtCore/qset.h>
+ #include <QtCore/qstringlist.h>
++#include <QtGui/qimage.h>
+ #include <qaudioformat.h>
++#include <QtMultimedia/qvideosurfaceformat.h>
++
++#include <gst/audio/audio.h>
++#include <gst/video/video.h>
++
++template<typename T, int N> static int lengthOf(const T (&)[N]) { return N; }
+ 
+ #ifdef USE_V4L
+ #  include <private/qcore_unix_p.h>
+@@ -82,15 +89,24 @@ static void addTagToMap(const GstTagList *list,
+             map->insert(QByteArray(tag), g_value_get_boolean(&val));
+             break;
+         case G_TYPE_CHAR:
++#if GLIB_CHECK_VERSION(2,32,0)
++            map->insert(QByteArray(tag), g_value_get_schar(&val));
++#else
+             map->insert(QByteArray(tag), g_value_get_char(&val));
++#endif
+             break;
+         case G_TYPE_DOUBLE:
+             map->insert(QByteArray(tag), g_value_get_double(&val));
+             break;
+         default:
+             // GST_TYPE_DATE is a function, not a constant, so pull it out of the switch
++#if GST_CHECK_VERSION(1,0,0)
++            if (G_VALUE_TYPE(&val) == G_TYPE_DATE) {
++                const GDate *date = (const GDate *)g_value_get_boxed(&val);
++#else
+             if (G_VALUE_TYPE(&val) == GST_TYPE_DATE) {
+                 const GDate *date = gst_value_get_date(&val);
++#endif
+                 if (g_date_valid(date)) {
+                     int year = g_date_get_year(date);
+                     int month = g_date_get_month(date);
+@@ -169,6 +185,42 @@ QSize QGstUtils::capsCorrectedResolution(const GstCaps *caps)
+     return size;
+ }
+ 
++
++#if GST_CHECK_VERSION(1,0,0)
++namespace {
++
++struct AudioFormat
++{
++    GstAudioFormat format;
++    QAudioFormat::SampleType sampleType;
++    QAudioFormat::Endian byteOrder;
++    int sampleSize;
++};
++static const AudioFormat qt_audioLookup[] =
++{
++    { GST_AUDIO_FORMAT_S8   , QAudioFormat::SignedInt  , QAudioFormat::LittleEndian, 8  },
++    { GST_AUDIO_FORMAT_U8   , QAudioFormat::UnSignedInt, QAudioFormat::LittleEndian, 8  },
++    { GST_AUDIO_FORMAT_S16LE, QAudioFormat::SignedInt  , QAudioFormat::LittleEndian, 16 },
++    { GST_AUDIO_FORMAT_S16BE, QAudioFormat::SignedInt  , QAudioFormat::BigEndian   , 16 },
++    { GST_AUDIO_FORMAT_U16LE, QAudioFormat::UnSignedInt, QAudioFormat::LittleEndian, 16 },
++    { GST_AUDIO_FORMAT_U16BE, QAudioFormat::UnSignedInt, QAudioFormat::BigEndian   , 16 },
++    { GST_AUDIO_FORMAT_S32LE, QAudioFormat::SignedInt  , QAudioFormat::LittleEndian, 32 },
++    { GST_AUDIO_FORMAT_S32BE, QAudioFormat::SignedInt  , QAudioFormat::BigEndian   , 32 },
++    { GST_AUDIO_FORMAT_U32LE, QAudioFormat::UnSignedInt, QAudioFormat::LittleEndian, 32 },
++    { GST_AUDIO_FORMAT_U32BE, QAudioFormat::UnSignedInt, QAudioFormat::BigEndian   , 32 },
++    { GST_AUDIO_FORMAT_S24LE, QAudioFormat::SignedInt  , QAudioFormat::LittleEndian, 24 },
++    { GST_AUDIO_FORMAT_S24BE, QAudioFormat::SignedInt  , QAudioFormat::BigEndian   , 24 },
++    { GST_AUDIO_FORMAT_U24LE, QAudioFormat::UnSignedInt, QAudioFormat::LittleEndian, 24 },
++    { GST_AUDIO_FORMAT_U24BE, QAudioFormat::UnSignedInt, QAudioFormat::BigEndian   , 24 },
++    { GST_AUDIO_FORMAT_F32LE, QAudioFormat::Float      , QAudioFormat::LittleEndian, 32 },
++    { GST_AUDIO_FORMAT_F32BE, QAudioFormat::Float      , QAudioFormat::BigEndian   , 32 },
++    { GST_AUDIO_FORMAT_F64LE, QAudioFormat::Float      , QAudioFormat::LittleEndian, 64 },
++    { GST_AUDIO_FORMAT_F64BE, QAudioFormat::Float      , QAudioFormat::BigEndian   , 64 }
++};
++
++}
++#endif
++
+ /*!
+   Returns audio format for caps.
+   If caps doesn't have a valid audio format, an empty QAudioFormat is returned.
+@@ -176,9 +228,26 @@ QSize QGstUtils::capsCorrectedResolution(const GstCaps *caps)
+ 
+ QAudioFormat QGstUtils::audioFormatForCaps(const GstCaps *caps)
+ {
+-    const GstStructure *structure = gst_caps_get_structure(caps, 0);
+-
+     QAudioFormat format;
++#if GST_CHECK_VERSION(1,0,0)
++    GstAudioInfo info;
++    if (gst_audio_info_from_caps(&info, caps)) {
++        for (int i = 0; i < lengthOf(qt_audioLookup); ++i) {
++            if (qt_audioLookup[i].format != info.finfo->format)
++                continue;
++
++            format.setSampleType(qt_audioLookup[i].sampleType);
++            format.setByteOrder(qt_audioLookup[i].byteOrder);
++            format.setSampleSize(qt_audioLookup[i].sampleSize);
++            format.setSampleRate(info.rate);
++            format.setChannelCount(info.channels);
++            format.setCodec(QStringLiteral("audio/pcm"));
++
++            return format;
++        }
++    }
++#else
++    const GstStructure *structure = gst_caps_get_structure(caps, 0);
+ 
+     if (qstrcmp(gst_structure_get_name(structure), "audio/x-raw-int") == 0) {
+ 
+@@ -249,16 +318,28 @@ QAudioFormat QGstUtils::audioFormatForCaps(const GstCaps *caps)
+     } else {
+         return QAudioFormat();
+     }
+-
++#endif
+     return format;
+ }
+ 
++#if GST_CHECK_VERSION(1,0,0)
++/*!
++  Returns audio format for a sample.
++  If the buffer doesn't have a valid audio format, an empty QAudioFormat is returned.
++*/
++QAudioFormat QGstUtils::audioFormatForSample(GstSample *sample)
++{
++    GstCaps* caps = gst_sample_get_caps(sample);
++    if (!caps)
++        return QAudioFormat();
+ 
++    return QGstUtils::audioFormatForCaps(caps);
++}
++#else
+ /*!
+   Returns audio format for a buffer.
+   If the buffer doesn't have a valid audio format, an empty QAudioFormat is returned.
+ */
+-
+ QAudioFormat QGstUtils::audioFormatForBuffer(GstBuffer *buffer)
+ {
+     GstCaps* caps = gst_buffer_get_caps(buffer);
+@@ -269,7 +350,7 @@ QAudioFormat QGstUtils::audioFormatForBuffer(GstBuffer *buffer)
+     gst_caps_unref(caps);
+     return format;
+ }
+-
++#endif
+ 
+ /*!
+   Builds GstCaps for an audio format.
+@@ -277,8 +358,32 @@ QAudioFormat QGstUtils::audioFormatForBuffer(GstBuffer *buffer)
+   Caller must unref GstCaps.
+ */
+ 
+-GstCaps *QGstUtils::capsForAudioFormat(QAudioFormat format)
++GstCaps *QGstUtils::capsForAudioFormat(const QAudioFormat &format)
+ {
++    if (!format.isValid())
++        return 0;
++
++#if GST_CHECK_VERSION(1,0,0)
++    const QAudioFormat::SampleType sampleType = format.sampleType();
++    const QAudioFormat::Endian byteOrder = format.byteOrder();
++    const int sampleSize = format.sampleSize();
++
++    for (int i = 0; i < lengthOf(qt_audioLookup); ++i) {
++        if (qt_audioLookup[i].sampleType != sampleType
++                || qt_audioLookup[i].byteOrder != byteOrder
++                || qt_audioLookup[i].sampleSize != sampleSize) {
++            continue;
++        }
++
++        return gst_caps_new_simple(
++                    "audio/x-raw",
++                    "format"  , G_TYPE_STRING, gst_audio_format_to_string(qt_audioLookup[i].format),
++                    "rate"    , G_TYPE_INT   , format.sampleRate(),
++                    "channels", G_TYPE_INT   , format.channelCount(),
++                    NULL);
++    }
++    return 0;
++#else
+     GstStructure *structure = 0;
+ 
+     if (format.isValid()) {
+@@ -313,6 +418,7 @@ GstCaps *QGstUtils::capsForAudioFormat(QAudioFormat format)
+     }
+ 
+     return caps;
++#endif
+ }
+ 
+ void QGstUtils::initializeGst()
+@@ -576,10 +682,629 @@ QByteArray QGstUtils::cameraDriver(const QString &device, GstElementFactory *fac
+     return QByteArray();
+ }
+ 
++QSet<QString> QGstUtils::supportedMimeTypes(bool (*isValidFactory)(GstElementFactory *factory))
++{
++    QSet<QString> supportedMimeTypes;
++
++    //enumerate supported mime types
++    gst_init(NULL, NULL);
++
++#if GST_CHECK_VERSION(1,0,0)
++    GstRegistry *registry = gst_registry_get();
++    GList *orig_plugins = gst_registry_get_plugin_list(registry);
++#else
++    GstRegistry *registry = gst_registry_get_default();
++    GList *orig_plugins = gst_default_registry_get_plugin_list ();
++#endif
++    for (GList *plugins = orig_plugins; plugins; plugins = g_list_next(plugins)) {
++        GstPlugin *plugin = (GstPlugin *) (plugins->data);
++#if GST_CHECK_VERSION(1,0,0)
++        if (GST_OBJECT_FLAG_IS_SET(GST_OBJECT(plugin), GST_PLUGIN_FLAG_BLACKLISTED))
++            continue;
++#else
++        if (plugin->flags & (1<<1)) //GST_PLUGIN_FLAG_BLACKLISTED
++            continue;
++#endif
++
++        GList *orig_features = gst_registry_get_feature_list_by_plugin(
++                    registry, gst_plugin_get_name(plugin));
++        for (GList *features = orig_features; features; features = g_list_next(features)) {
++            if (G_UNLIKELY(features->data == NULL))
++                continue;
++
++            GstPluginFeature *feature = GST_PLUGIN_FEATURE(features->data);
++            GstElementFactory *factory;
++
++            if (GST_IS_TYPE_FIND_FACTORY(feature)) {
++                QString name(gst_plugin_feature_get_name(feature));
++                if (name.contains('/')) //filter out any string without '/' which is obviously not a mime type
++                    supportedMimeTypes.insert(name.toLower());
++                continue;
++            } else if (!GST_IS_ELEMENT_FACTORY (feature)
++                        || !(factory = GST_ELEMENT_FACTORY(gst_plugin_feature_load(feature)))) {
++                continue;
++            } else if (!isValidFactory(factory)) {
++                // Do nothing
++            } else for (const GList *pads = gst_element_factory_get_static_pad_templates(factory);
++                        pads;
++                        pads = g_list_next(pads)) {
++                GstStaticPadTemplate *padtemplate = static_cast<GstStaticPadTemplate *>(pads->data);
++
++                if (padtemplate->direction == GST_PAD_SINK && padtemplate->static_caps.string) {
++                    GstCaps *caps = gst_static_caps_get(&padtemplate->static_caps);
++                    if (gst_caps_is_any(caps) || gst_caps_is_empty(caps)) {
++                    } else for (guint i = 0; i < gst_caps_get_size(caps); i++) {
++                        GstStructure *structure = gst_caps_get_structure(caps, i);
++                        QString nameLowcase = QString(gst_structure_get_name(structure)).toLower();
++
++                        supportedMimeTypes.insert(nameLowcase);
++                        if (nameLowcase.contains("mpeg")) {
++                            //Because mpeg version number is only included in the detail
++                            //description,  it is necessary to manually extract this information
++                            //in order to match the mime type of mpeg4.
++                            const GValue *value = gst_structure_get_value(structure, "mpegversion");
++                            if (value) {
++                                gchar *str = gst_value_serialize(value);
++                                QString versions(str);
++                                QStringList elements = versions.split(QRegExp("\\D+"), QString::SkipEmptyParts);
++                                foreach (const QString &e, elements)
++                                    supportedMimeTypes.insert(nameLowcase + e);
++                                g_free(str);
++                            }
++                        }
++                    }
++                }
++            }
++            gst_object_unref(factory);
++        }
++        gst_plugin_feature_list_free(orig_features);
++    }
++    gst_plugin_list_free (orig_plugins);
++
++#if defined QT_SUPPORTEDMIMETYPES_DEBUG
++    QStringList list = supportedMimeTypes.toList();
++    list.sort();
++    if (qgetenv("QT_DEBUG_PLUGINS").toInt() > 0) {
++        foreach (const QString &type, list)
++            qDebug() << type;
++    }
++#endif
++    return supportedMimeTypes;
++}
++
++namespace {
++
++struct ColorFormat { QImage::Format imageFormat; GstVideoFormat gstFormat; };
++static const ColorFormat qt_colorLookup[] =
++{
++    { QImage::Format_RGBX8888, GST_VIDEO_FORMAT_RGBx  },
++    { QImage::Format_RGBA8888, GST_VIDEO_FORMAT_RGBA  },
++    { QImage::Format_RGB888  , GST_VIDEO_FORMAT_RGB   },
++    { QImage::Format_RGB16   , GST_VIDEO_FORMAT_RGB16 }
++};
++
++}
++
++#if GST_CHECK_VERSION(1,0,0)
++QImage QGstUtils::bufferToImage(GstBuffer *buffer, const GstVideoInfo &videoInfo)
++#else
++QImage QGstUtils::bufferToImage(GstBuffer *buffer)
++#endif
++{
++    QImage img;
++
++#if GST_CHECK_VERSION(1,0,0)
++    GstVideoInfo info = videoInfo;
++    GstVideoFrame frame;
++    if (!gst_video_frame_map(&frame, &info, buffer, GST_MAP_READ))
++        return img;
++#else
++    GstCaps *caps = gst_buffer_get_caps(buffer);
++    if (!caps)
++        return img;
++
++    GstStructure *structure = gst_caps_get_structure (caps, 0);
++    gint width = 0;
++    gint height = 0;
++
++    if (!structure
++            || !gst_structure_get_int(structure, "width", &width)
++            || !gst_structure_get_int(structure, "height", &height)
++            || width <= 0
++            || height <= 0) {
++        gst_caps_unref(caps);
++        return img;
++    }
++    gst_caps_unref(caps);
++#endif
++
++#if GST_CHECK_VERSION(1,0,0)
++    if (videoInfo.finfo->format == GST_VIDEO_FORMAT_I420) {
++        const int width = videoInfo.width;
++        const int height = videoInfo.height;
++
++        const int stride[] = { frame.info.stride[0], frame.info.stride[1], frame.info.stride[2] };
++        const uchar *data[] = {
++            static_cast<const uchar *>(frame.data[0]),
++            static_cast<const uchar *>(frame.data[1]),
++            static_cast<const uchar *>(frame.data[2])
++        };
++#else
++    if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-yuv") == 0) {
++        const int stride[] = { width, width / 2, width / 2 };
++        const uchar *data[] = {
++            (const uchar *)buffer->data,
++            (const uchar *)buffer->data + width * height,
++            (const uchar *)buffer->data + width * height * 5 / 4
++        };
++#endif
++        img = QImage(width/2, height/2, QImage::Format_RGB32);
++
++        for (int y=0; y<height; y+=2) {
++            const uchar *yLine = data[0] + (y * stride[0]);
++            const uchar *uLine = data[1] + (y * stride[1] / 2);
++            const uchar *vLine = data[2] + (y * stride[2] / 2);
++
++            for (int x=0; x<width; x+=2) {
++                const qreal Y = 1.164*(yLine[x]-16);
++                const int U = uLine[x/2]-128;
++                const int V = vLine[x/2]-128;
++
++                int b = qBound(0, int(Y + 2.018*U), 255);
++                int g = qBound(0, int(Y - 0.813*V - 0.391*U), 255);
++                int r = qBound(0, int(Y + 1.596*V), 255);
++
++                img.setPixel(x/2,y/2,qRgb(r,g,b));
++            }
++        }
++#if GST_CHECK_VERSION(1,0,0)
++    } else for (int i = 0; i < lengthOf(qt_colorLookup); ++i) {
++        if (qt_colorLookup[i].gstFormat != videoInfo.finfo->format)
++            continue;
++
++        const QImage image(
++                    static_cast<const uchar *>(frame.data[0]),
++                    videoInfo.width,
++                    videoInfo.height,
++                    frame.info.stride[0],
++                    qt_colorLookup[i].imageFormat);
++        img = image;
++        img.detach();
++
++        break;
++    }
++
++    gst_video_frame_unmap(&frame);
++#else
++    } else if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-rgb") == 0) {
++        QImage::Format format = QImage::Format_Invalid;
++        int bpp = 0;
++        gst_structure_get_int(structure, "bpp", &bpp);
++
++        if (bpp == 24)
++            format = QImage::Format_RGB888;
++        else if (bpp == 32)
++            format = QImage::Format_RGB32;
++
++        if (format != QImage::Format_Invalid) {
++            img = QImage((const uchar *)buffer->data,
++                         width,
++                         height,
++                         format);
++            img.bits(); //detach
++        }
++    }
++#endif
++    return img;
++}
++
++
++namespace {
++
++#if GST_CHECK_VERSION(1,0,0)
++
++struct VideoFormat
++{
++    QVideoFrame::PixelFormat pixelFormat;
++    GstVideoFormat gstFormat;
++};
++
++static const VideoFormat qt_videoFormatLookup[] =
++{
++    { QVideoFrame::Format_YUV420P, GST_VIDEO_FORMAT_I420 },
++    { QVideoFrame::Format_YV12   , GST_VIDEO_FORMAT_YV12 },
++    { QVideoFrame::Format_UYVY   , GST_VIDEO_FORMAT_UYVY },
++    { QVideoFrame::Format_YUYV   , GST_VIDEO_FORMAT_YUY2 },
++    { QVideoFrame::Format_NV12   , GST_VIDEO_FORMAT_NV12 },
++    { QVideoFrame::Format_NV21   , GST_VIDEO_FORMAT_NV21 },
++    { QVideoFrame::Format_AYUV444, GST_VIDEO_FORMAT_AYUV },
++#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
++    { QVideoFrame::Format_RGB32 ,  GST_VIDEO_FORMAT_BGRx },
++    { QVideoFrame::Format_BGR32 ,  GST_VIDEO_FORMAT_RGBx },
++    { QVideoFrame::Format_ARGB32,  GST_VIDEO_FORMAT_BGRA },
++    { QVideoFrame::Format_BGRA32,  GST_VIDEO_FORMAT_ARGB },
++#else
++    { QVideoFrame::Format_RGB32 ,  GST_VIDEO_FORMAT_xRGB },
++    { QVideoFrame::Format_BGR32 ,  GST_VIDEO_FORMAT_xBGR },
++    { QVideoFrame::Format_ARGB32,  GST_VIDEO_FORMAT_ARGB },
++    { QVideoFrame::Format_BGRA32,  GST_VIDEO_FORMAT_BGRA },
++#endif
++    { QVideoFrame::Format_RGB24 ,  GST_VIDEO_FORMAT_RGB },
++    { QVideoFrame::Format_BGR24 ,  GST_VIDEO_FORMAT_BGR },
++    { QVideoFrame::Format_RGB565,  GST_VIDEO_FORMAT_RGB16 }
++};
++
++static int indexOfVideoFormat(QVideoFrame::PixelFormat format)
++{
++    for (int i = 0; i < lengthOf(qt_videoFormatLookup); ++i)
++        if (qt_videoFormatLookup[i].pixelFormat == format)
++            return i;
++
++    return -1;
++}
++
++static int indexOfVideoFormat(GstVideoFormat format)
++{
++    for (int i = 0; i < lengthOf(qt_videoFormatLookup); ++i)
++        if (qt_videoFormatLookup[i].gstFormat == format)
++            return i;
++
++    return -1;
++}
++
++#else
++
++struct YuvFormat
++{
++    QVideoFrame::PixelFormat pixelFormat;
++    guint32 fourcc;
++    int bitsPerPixel;
++};
++
++static const YuvFormat qt_yuvColorLookup[] =
++{
++    { QVideoFrame::Format_YUV420P, GST_MAKE_FOURCC('I','4','2','0'), 8 },
++    { QVideoFrame::Format_YV12,    GST_MAKE_FOURCC('Y','V','1','2'), 8 },
++    { QVideoFrame::Format_UYVY,    GST_MAKE_FOURCC('U','Y','V','Y'), 16 },
++    { QVideoFrame::Format_YUYV,    GST_MAKE_FOURCC('Y','U','Y','2'), 16 },
++    { QVideoFrame::Format_NV12,    GST_MAKE_FOURCC('N','V','1','2'), 8 },
++    { QVideoFrame::Format_NV21,    GST_MAKE_FOURCC('N','V','2','1'), 8 },
++    { QVideoFrame::Format_AYUV444, GST_MAKE_FOURCC('A','Y','U','V'), 32 }
++};
++
++static int indexOfYuvColor(QVideoFrame::PixelFormat format)
++{
++    const int count = sizeof(qt_yuvColorLookup) / sizeof(YuvFormat);
++
++    for (int i = 0; i < count; ++i)
++        if (qt_yuvColorLookup[i].pixelFormat == format)
++            return i;
++
++    return -1;
++}
++
++static int indexOfYuvColor(guint32 fourcc)
++{
++    const int count = sizeof(qt_yuvColorLookup) / sizeof(YuvFormat);
++
++    for (int i = 0; i < count; ++i)
++        if (qt_yuvColorLookup[i].fourcc == fourcc)
++            return i;
++
++    return -1;
++}
++
++struct RgbFormat
++{
++    QVideoFrame::PixelFormat pixelFormat;
++    int bitsPerPixel;
++    int depth;
++    int endianness;
++    int red;
++    int green;
++    int blue;
++    int alpha;
++};
++
++static const RgbFormat qt_rgbColorLookup[] =
++{
++    { QVideoFrame::Format_RGB32 , 32, 24, 4321, 0x0000FF00, 0x00FF0000, int(0xFF000000), 0x00000000 },
++    { QVideoFrame::Format_RGB32 , 32, 24, 1234, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 },
++    { QVideoFrame::Format_BGR32 , 32, 24, 4321, int(0xFF000000), 0x00FF0000, 0x0000FF00, 0x00000000 },
++    { QVideoFrame::Format_BGR32 , 32, 24, 1234, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 },
++    { QVideoFrame::Format_ARGB32, 32, 24, 4321, 0x0000FF00, 0x00FF0000, int(0xFF000000), 0x000000FF },
++    { QVideoFrame::Format_ARGB32, 32, 24, 1234, 0x00FF0000, 0x0000FF00, 0x000000FF, int(0xFF000000) },
++    { QVideoFrame::Format_RGB24 , 24, 24, 4321, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 },
++    { QVideoFrame::Format_BGR24 , 24, 24, 4321, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 },
++    { QVideoFrame::Format_RGB565, 16, 16, 1234, 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }
++};
++
++static int indexOfRgbColor(
++        int bits, int depth, int endianness, int red, int green, int blue, int alpha)
++{
++    const int count = sizeof(qt_rgbColorLookup) / sizeof(RgbFormat);
++
++    for (int i = 0; i < count; ++i) {
++        if (qt_rgbColorLookup[i].bitsPerPixel == bits
++            && qt_rgbColorLookup[i].depth == depth
++            && qt_rgbColorLookup[i].endianness == endianness
++            && qt_rgbColorLookup[i].red == red
++            && qt_rgbColorLookup[i].green == green
++            && qt_rgbColorLookup[i].blue == blue
++            && qt_rgbColorLookup[i].alpha == alpha) {
++            return i;
++        }
++    }
++    return -1;
++}
++#endif
++
++}
++
++#if GST_CHECK_VERSION(1,0,0)
++
++QVideoSurfaceFormat QGstUtils::formatForCaps(
++        GstCaps *caps, GstVideoInfo *info, QAbstractVideoBuffer::HandleType handleType)
++{
++    if (gst_video_info_from_caps(info, caps)) {
++        int index = indexOfVideoFormat(info->finfo->format);
++
++        if (index != -1) {
++            QVideoSurfaceFormat format(
++                        QSize(info->width, info->height),
++                        qt_videoFormatLookup[index].pixelFormat,
++                        handleType);
++
++            if (info->fps_d > 0)
++                format.setFrameRate(qreal(info->fps_d) / info->fps_n);
++
++            if (info->par_d > 0)
++                format.setPixelAspectRatio(info->par_n, info->par_d);
++
++            return format;
++        }
++    }
++    return QVideoSurfaceFormat();
++}
++
++#else
++
++QVideoSurfaceFormat QGstUtils::formatForCaps(
++        GstCaps *caps, int *bytesPerLine, QAbstractVideoBuffer::HandleType handleType)
++{
++    const GstStructure *structure = gst_caps_get_structure(caps, 0);
++
++    QVideoFrame::PixelFormat pixelFormat = QVideoFrame::Format_Invalid;
++    int bitsPerPixel = 0;
++
++    QSize size;
++    gst_structure_get_int(structure, "width", &size.rwidth());
++    gst_structure_get_int(structure, "height", &size.rheight());
++
++    if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-yuv") == 0) {
++        guint32 fourcc = 0;
++        gst_structure_get_fourcc(structure, "format", &fourcc);
++
++        int index = indexOfYuvColor(fourcc);
++        if (index != -1) {
++            pixelFormat = qt_yuvColorLookup[index].pixelFormat;
++            bitsPerPixel = qt_yuvColorLookup[index].bitsPerPixel;
++        }
++    } else if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-rgb") == 0) {
++        int depth = 0;
++        int endianness = 0;
++        int red = 0;
++        int green = 0;
++        int blue = 0;
++        int alpha = 0;
++
++        gst_structure_get_int(structure, "bpp", &bitsPerPixel);
++        gst_structure_get_int(structure, "depth", &depth);
++        gst_structure_get_int(structure, "endianness", &endianness);
++        gst_structure_get_int(structure, "red_mask", &red);
++        gst_structure_get_int(structure, "green_mask", &green);
++        gst_structure_get_int(structure, "blue_mask", &blue);
++        gst_structure_get_int(structure, "alpha_mask", &alpha);
++
++        int index = indexOfRgbColor(bitsPerPixel, depth, endianness, red, green, blue, alpha);
++
++        if (index != -1)
++            pixelFormat = qt_rgbColorLookup[index].pixelFormat;
++    }
++
++    if (pixelFormat != QVideoFrame::Format_Invalid) {
++        QVideoSurfaceFormat format(size, pixelFormat, handleType);
++
++        QPair<int, int> rate;
++        gst_structure_get_fraction(structure, "framerate", &rate.first, &rate.second);
++
++        if (rate.second)
++            format.setFrameRate(qreal(rate.first)/rate.second);
++
++        gint aspectNum = 0;
++        gint aspectDenum = 0;
++        if (gst_structure_get_fraction(
++                structure, "pixel-aspect-ratio", &aspectNum, &aspectDenum)) {
++            if (aspectDenum > 0)
++                format.setPixelAspectRatio(aspectNum, aspectDenum);
++        }
++
++        if (bytesPerLine)
++            *bytesPerLine = ((size.width() * bitsPerPixel / 8) + 3) & ~3;
++
++        return format;
++    }
++    return QVideoSurfaceFormat();
++}
++
++#endif
++
++GstCaps *QGstUtils::capsForFormats(const QList<QVideoFrame::PixelFormat> &formats)
++{
++    GstCaps *caps = gst_caps_new_empty();
++
++#if GST_CHECK_VERSION(1,0,0)
++    foreach (QVideoFrame::PixelFormat format, formats) {
++        int index = indexOfVideoFormat(format);
++
++        if (index != -1) {
++            gst_caps_append_structure(caps, gst_structure_new(
++                    "video/x-raw",
++                    "format"   , G_TYPE_STRING, gst_video_format_to_string(qt_videoFormatLookup[index].gstFormat),
++                    NULL));
++        }
++    }
++#else
++    foreach (QVideoFrame::PixelFormat format, formats) {
++        int index = indexOfYuvColor(format);
++
++        if (index != -1) {
++            gst_caps_append_structure(caps, gst_structure_new(
++                    "video/x-raw-yuv",
++                    "format", GST_TYPE_FOURCC, qt_yuvColorLookup[index].fourcc,
++                    NULL));
++            continue;
++        }
++
++        const int count = sizeof(qt_rgbColorLookup) / sizeof(RgbFormat);
++
++        for (int i = 0; i < count; ++i) {
++            if (qt_rgbColorLookup[i].pixelFormat == format) {
++                GstStructure *structure = gst_structure_new(
++                        "video/x-raw-rgb",
++                        "bpp"       , G_TYPE_INT, qt_rgbColorLookup[i].bitsPerPixel,
++                        "depth"     , G_TYPE_INT, qt_rgbColorLookup[i].depth,
++                        "endianness", G_TYPE_INT, qt_rgbColorLookup[i].endianness,
++                        "red_mask"  , G_TYPE_INT, qt_rgbColorLookup[i].red,
++                        "green_mask", G_TYPE_INT, qt_rgbColorLookup[i].green,
++                        "blue_mask" , G_TYPE_INT, qt_rgbColorLookup[i].blue,
++                        NULL);
++
++                if (qt_rgbColorLookup[i].alpha != 0) {
++                    gst_structure_set(
++                            structure, "alpha_mask", G_TYPE_INT, qt_rgbColorLookup[i].alpha, NULL);
++                }
++                gst_caps_append_structure(caps, structure);
++            }
++        }
++    }
++#endif
++
++    gst_caps_set_simple(
++                caps,
++                "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, INT_MAX, 1,
++                "width"    , GST_TYPE_INT_RANGE, 1, INT_MAX,
++                "height"   , GST_TYPE_INT_RANGE, 1, INT_MAX,
++                NULL);
++
++    return caps;
++}
++
++void QGstUtils::setFrameTimeStamps(QVideoFrame *frame, GstBuffer *buffer)
++{
++    // GStreamer uses nanoseconds, Qt uses microseconds
++    qint64 startTime = GST_BUFFER_TIMESTAMP(buffer);
++    if (startTime >= 0) {
++        frame->setStartTime(startTime/G_GINT64_CONSTANT (1000));
++
++        qint64 duration = GST_BUFFER_DURATION(buffer);
++        if (duration >= 0)
++            frame->setEndTime((startTime + duration)/G_GINT64_CONSTANT (1000));
++    }
++}
++
++void QGstUtils::setMetaData(GstElement *element, const QMap<QByteArray, QVariant> &data)
++{
++    if (!GST_IS_TAG_SETTER(element))
++        return;
++
++    gst_tag_setter_reset_tags(GST_TAG_SETTER(element));
++
++    QMapIterator<QByteArray, QVariant> it(data);
++    while (it.hasNext()) {
++        it.next();
++        const QString tagName = it.key();
++        const QVariant tagValue = it.value();
++
++        switch (tagValue.type()) {
++            case QVariant::String:
++                gst_tag_setter_add_tags(GST_TAG_SETTER(element),
++                    GST_TAG_MERGE_REPLACE,
++                    tagName.toUtf8().constData(),
++                    tagValue.toString().toUtf8().constData(),
++                    NULL);
++                break;
++            case QVariant::Int:
++            case QVariant::LongLong:
++                gst_tag_setter_add_tags(GST_TAG_SETTER(element),
++                    GST_TAG_MERGE_REPLACE,
++                    tagName.toUtf8().constData(),
++                    tagValue.toInt(),
++                    NULL);
++                break;
++            case QVariant::Double:
++                gst_tag_setter_add_tags(GST_TAG_SETTER(element),
++                    GST_TAG_MERGE_REPLACE,
++                    tagName.toUtf8().constData(),
++                    tagValue.toDouble(),
++                    NULL);
++                break;
++            case QVariant::DateTime: {
++                QDateTime date = tagValue.toDateTime().toLocalTime();
++                gst_tag_setter_add_tags(GST_TAG_SETTER(element),
++                    GST_TAG_MERGE_REPLACE,
++                    tagName.toUtf8().constData(),
++                    gst_date_time_new_local_time(
++                                date.date().year(), date.date().month(), date.date().day(),
++                                date.time().hour(), date.time().minute(), date.time().second()),
++                    NULL);
++                break;
++            }
++            default:
++                break;
++        }
++    }
++}
++
++void QGstUtils::setMetaData(GstBin *bin, const QMap<QByteArray, QVariant> &data)
++{
++    GstIterator *elements = gst_bin_iterate_all_by_interface(bin, GST_TYPE_TAG_SETTER);
++#if GST_CHECK_VERSION(1,0,0)
++    GValue item = G_VALUE_INIT;
++    while (gst_iterator_next(elements, &item) == GST_ITERATOR_OK) {
++        GstElement * const element = GST_ELEMENT(g_value_get_object(&item));
++#else
++    GstElement *element = 0;
++    while (gst_iterator_next(elements, (void**)&element) == GST_ITERATOR_OK) {
++#endif
++        setMetaData(element, data);
++    }
++    gst_iterator_free(elements);
++}
++
++
++GstCaps *QGstUtils::videoFilterCaps()
++{
++    static GstStaticCaps staticCaps = GST_STATIC_CAPS(
++#if GST_CHECK_VERSION(1,2,0)
++        "video/x-raw(ANY);"
++#elif GST_CHECK_VERSION(1,0,0)
++        "video/x-raw;"
++#else
++        "video/x-raw-yuv;"
++        "video/x-raw-rgb;"
++        "video/x-raw-data;"
++        "video/x-android-buffer;"
++#endif
++        "image/jpeg;"
++        "video/x-h264");
++
++    return gst_caps_make_writable(gst_static_caps_get(&staticCaps));
++}
+ 
+ void qt_gst_object_ref_sink(gpointer object)
+ {
+-#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 24)
++#if GST_CHECK_VERSION(0,10,24)
+     gst_object_ref_sink(object);
+ #else
+     g_return_if_fail (GST_IS_OBJECT(object));
+@@ -595,4 +1320,50 @@ void qt_gst_object_ref_sink(gpointer object)
+ #endif
+ }
+ 
++GstCaps *qt_gst_pad_get_current_caps(GstPad *pad)
++{
++#if GST_CHECK_VERSION(1,0,0)
++    return gst_pad_get_current_caps(pad);
++#else
++    return gst_pad_get_negotiated_caps(pad);
++#endif
++}
++
++GstStructure *qt_gst_structure_new_empty(const char *name)
++{
++#if GST_CHECK_VERSION(1,0,0)
++    return gst_structure_new_empty(name);
++#else
++    return gst_structure_new(name, NULL);
++#endif
++}
++
++gboolean qt_gst_element_query_position(GstElement *element, GstFormat format, gint64 *cur)
++{
++#if GST_CHECK_VERSION(1,0,0)
++    return gst_element_query_position(element, format, cur);
++#else
++    return gst_element_query_position(element, &format, cur);
++#endif
++}
++
++gboolean qt_gst_element_query_duration(GstElement *element, GstFormat format, gint64 *cur)
++{
++#if GST_CHECK_VERSION(1,0,0)
++    return gst_element_query_duration(element, format, cur);
++#else
++    return gst_element_query_duration(element, &format, cur);
++#endif
++}
++
++QDebug operator <<(QDebug debug, GstCaps *caps)
++{
++    if (caps) {
++        gchar *string = gst_caps_to_string(caps);
++        debug = debug << string;
++        g_free(string);
++    }
++    return debug;
++}
++
+ QT_END_NAMESPACE
+diff --git a/src/gsttools/qgstvideobuffer.cpp b/src/gsttools/qgstvideobuffer.cpp
+index 18702ec..1ce07ca 100644
+--- a/src/gsttools/qgstvideobuffer.cpp
++++ b/src/gsttools/qgstvideobuffer.cpp
+@@ -35,21 +35,35 @@
+ 
+ QT_BEGIN_NAMESPACE
+ 
++#if GST_CHECK_VERSION(1,0,0)
++QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, const GstVideoInfo &info)
++    : QAbstractPlanarVideoBuffer(NoHandle)
++    , m_videoInfo(info)
++#else
+ QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, int bytesPerLine)
+     : QAbstractVideoBuffer(NoHandle)
+-    , m_buffer(buffer)
+     , m_bytesPerLine(bytesPerLine)
++#endif
++    , m_buffer(buffer)
+     , m_mode(NotMapped)
+ {
+     gst_buffer_ref(m_buffer);
+ }
+ 
++#if GST_CHECK_VERSION(1,0,0)
++QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, const GstVideoInfo &info,
++                QGstVideoBuffer::HandleType handleType,
++                const QVariant &handle)
++    : QAbstractPlanarVideoBuffer(handleType)
++    , m_videoInfo(info)
++#else
+ QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, int bytesPerLine,
+                 QGstVideoBuffer::HandleType handleType,
+                 const QVariant &handle)
+     : QAbstractVideoBuffer(handleType)
+-    , m_buffer(buffer)
+     , m_bytesPerLine(bytesPerLine)
++#endif
++    , m_buffer(buffer)
+     , m_mode(NotMapped)
+     , m_handle(handle)
+ {
+@@ -58,6 +72,8 @@ QGstVideoBuffer::QGstVideoBuffer(GstBuffer *buffer, int bytesPerLine,
+ 
+ QGstVideoBuffer::~QGstVideoBuffer()
+ {
++    unmap();
++
+     gst_buffer_unref(m_buffer);
+ }
+ 
+@@ -67,12 +83,49 @@ QAbstractVideoBuffer::MapMode QGstVideoBuffer::mapMode() const
+     return m_mode;
+ }
+ 
++#if GST_CHECK_VERSION(1,0,0)
++
++int QGstVideoBuffer::map(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])
++{
++    const GstMapFlags flags = GstMapFlags(((mode & ReadOnly) ? GST_MAP_READ : 0)
++                | ((mode & WriteOnly) ? GST_MAP_WRITE : 0));
++
++    if (mode == NotMapped || m_mode != NotMapped) {
++        return 0;
++    } else if (m_videoInfo.finfo->n_planes == 0) {         // Encoded
++        if (gst_buffer_map(m_buffer, &m_frame.map[0], flags)) {
++            if (numBytes)
++                *numBytes = m_frame.map[0].size;
++            bytesPerLine[0] = -1;
++            data[0] = static_cast<uchar *>(m_frame.map[0].data);
++
++            m_mode = mode;
++
++            return 1;
++        }
++    } else if (gst_video_frame_map(&m_frame, &m_videoInfo, m_buffer, flags)) {
++        if (numBytes)
++            *numBytes = m_frame.info.size;
++
++        for (guint i = 0; i < m_frame.info.finfo->n_planes; ++i) {
++            bytesPerLine[i] = m_frame.info.stride[i];
++            data[i] = static_cast<uchar *>(m_frame.data[i]);
++        }
++
++        m_mode = mode;
++
++        return m_frame.info.finfo->n_planes;
++    }
++    return 0;
++}
++
++#else
++
+ uchar *QGstVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
+ {
+     if (mode != NotMapped && m_mode == NotMapped) {
+         if (numBytes)
+             *numBytes = m_buffer->size;
+-
+         if (bytesPerLine)
+             *bytesPerLine = m_bytesPerLine;
+ 
+@@ -83,8 +136,19 @@ uchar *QGstVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
+         return 0;
+     }
+ }
++
++#endif
++
+ void QGstVideoBuffer::unmap()
+ {
++#if GST_CHECK_VERSION(1,0,0)
++    if (m_mode != NotMapped) {
++        if (m_videoInfo.finfo->n_planes == 0)
++            gst_buffer_unmap(m_buffer, &m_frame.map[0]);
++        else
++            gst_video_frame_unmap(&m_frame);
++    }
++#endif
+     m_mode = NotMapped;
+ }
+ 
+diff --git a/src/gsttools/qgstvideorendererplugin.cpp b/src/gsttools/qgstvideorendererplugin.cpp
+new file mode 100644
+index 0000000..5eda85a
+--- /dev/null
++++ b/src/gsttools/qgstvideorendererplugin.cpp
+@@ -0,0 +1,53 @@
++/****************************************************************************
++**
++** Copyright (C) 2014 Jolla Ltd.
++** Contact: http://www.qt-project.org/legal
++**
++** This file is part of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and Digia.  For licensing terms and
++** conditions see http://qt.digia.com/licensing.  For further information
++** use the contact form at http://qt.digia.com/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 2.1 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL included in the
++** packaging of this file.  Please review the following information to
++** ensure the GNU Lesser General Public License version 2.1 requirements
++** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
++**
++** In addition, as a special exception, Digia gives you certain additional
++** rights.  These rights are described in the Digia Qt LGPL Exception
++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 3.0 as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL included in the
++** packaging of this file.  Please review the following information to
++** ensure the GNU General Public License version 3.0 requirements will be
++** met: http://www.gnu.org/copyleft/gpl.html.
++**
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include "qgstvideorendererplugin_p.h"
++
++QT_BEGIN_NAMESPACE
++
++QGstVideoRendererPlugin::QGstVideoRendererPlugin(QObject *parent) :
++    QObject(parent)
++{
++}
++
++QT_END_NAMESPACE
++
++#include "moc_qgstvideorendererplugin_p.cpp"
+diff --git a/src/gsttools/qgstvideorenderersink.cpp b/src/gsttools/qgstvideorenderersink.cpp
+new file mode 100644
+index 0000000..1102c2a
+--- /dev/null
++++ b/src/gsttools/qgstvideorenderersink.cpp
+@@ -0,0 +1,605 @@
++/****************************************************************************
++**
++** Copyright (C) 2014 Jolla Ltd.
++** Contact: http://www.qt-project.org/legal
++**
++** This file is part of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and Digia.  For licensing terms and
++** conditions see http://qt.digia.com/licensing.  For further information
++** use the contact form at http://qt.digia.com/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 2.1 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL included in the
++** packaging of this file.  Please review the following information to
++** ensure the GNU Lesser General Public License version 2.1 requirements
++** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
++**
++** In addition, as a special exception, Digia gives you certain additional
++** rights.  These rights are described in the Digia Qt LGPL Exception
++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 3.0 as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL included in the
++** packaging of this file.  Please review the following information to
++** ensure the GNU General Public License version 3.0 requirements will be
++** met: http://www.gnu.org/copyleft/gpl.html.
++**
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include <qabstractvideosurface.h>
++#include <qvideoframe.h>
++#include <QDebug>
++#include <QMap>
++#include <QThread>
++#include <QEvent>
++#include <QCoreApplication>
++
++#include <private/qmediapluginloader_p.h>
++#include "qgstvideobuffer_p.h"
++
++#include "qgstvideorenderersink_p.h"
++
++#include <gst/video/video.h>
++
++#include "qgstutils_p.h"
++
++//#define DEBUG_VIDEO_SURFACE_SINK
++
++QT_BEGIN_NAMESPACE
++
++QGstDefaultVideoRenderer::QGstDefaultVideoRenderer()
++    : m_flushed(true)
++{
++}
++
++QGstDefaultVideoRenderer::~QGstDefaultVideoRenderer()
++{
++}
++
++GstCaps *QGstDefaultVideoRenderer::getCaps(QAbstractVideoSurface *surface)
++{
++    return QGstUtils::capsForFormats(surface->supportedPixelFormats());
++}
++
++bool QGstDefaultVideoRenderer::start(QAbstractVideoSurface *surface, GstCaps *caps)
++{
++    m_flushed = true;
++    m_format = QGstUtils::formatForCaps(caps, &m_videoInfo);
++
++    return m_format.isValid() && surface->start(m_format);
++}
++
++void QGstDefaultVideoRenderer::stop(QAbstractVideoSurface *surface)
++{
++    m_flushed = true;
++    if (surface)
++        surface->stop();
++}
++
++bool QGstDefaultVideoRenderer::present(QAbstractVideoSurface *surface, GstBuffer *buffer)
++{
++    m_flushed = false;
++    QVideoFrame frame(
++                new QGstVideoBuffer(buffer, m_videoInfo),
++                m_format.frameSize(),
++                m_format.pixelFormat());
++    QGstUtils::setFrameTimeStamps(&frame, buffer);
++
++    return surface->present(frame);
++}
++
++void QGstDefaultVideoRenderer::flush(QAbstractVideoSurface *surface)
++{
++    if (surface && !m_flushed)
++        surface->present(QVideoFrame());
++    m_flushed = true;
++}
++
++bool QGstDefaultVideoRenderer::proposeAllocation(GstQuery *)
++{
++    return true;
++}
++
++Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, rendererLoader,
++        (QGstVideoRendererInterface_iid, QLatin1String("video/gstvideorenderer"), Qt::CaseInsensitive))
++
++QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(QAbstractVideoSurface *surface)
++    : m_surface(surface)
++    , m_renderer(0)
++    , m_activeRenderer(0)
++    , m_surfaceCaps(0)
++    , m_startCaps(0)
++    , m_lastBuffer(0)
++    , m_notified(false)
++    , m_stop(false)
++    , m_render(false)
++    , m_flush(false)
++{
++    foreach (QObject *instance, rendererLoader()->instances(QGstVideoRendererPluginKey)) {
++        QGstVideoRendererInterface* plugin = qobject_cast<QGstVideoRendererInterface*>(instance);
++        if (QGstVideoRenderer *renderer = plugin ? plugin->createRenderer() : 0)
++            m_renderers.append(renderer);
++    }
++
++    m_renderers.append(new QGstDefaultVideoRenderer);
++    updateSupportedFormats();
++    connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(updateSupportedFormats()));
++}
++
++QVideoSurfaceGstDelegate::~QVideoSurfaceGstDelegate()
++{
++    qDeleteAll(m_renderers);
++
++    if (m_surfaceCaps)
++        gst_caps_unref(m_surfaceCaps);
++}
++
++GstCaps *QVideoSurfaceGstDelegate::caps()
++{
++    QMutexLocker locker(&m_mutex);
++
++    gst_caps_ref(m_surfaceCaps);
++
++    return m_surfaceCaps;
++}
++
++bool QVideoSurfaceGstDelegate::start(GstCaps *caps)
++{
++    QMutexLocker locker(&m_mutex);
++
++    if (m_activeRenderer) {
++        m_flush = true;
++        m_stop = true;
++    }
++
++    m_render = false;
++
++    if (m_lastBuffer) {
++        gst_buffer_unref(m_lastBuffer);
++        m_lastBuffer = 0;
++    }
++
++    if (m_startCaps)
++        gst_caps_unref(m_startCaps);
++    m_startCaps = caps;
++    gst_caps_ref(m_startCaps);
++
++    /*
++    Waiting for start() to be invoked in the main thread may block
++    if gstreamer blocks the main thread until this call is finished.
++    This situation is rare and usually caused by setState(Null)
++    while pipeline is being prerolled.
++
++    The proper solution to this involves controlling gstreamer pipeline from
++    other thread than video surface.
++
++    Currently start() fails if wait() timed out.
++    */
++    if (!waitForAsyncEvent(&locker, &m_setupCondition, 1000) && m_startCaps) {
++        qWarning() << "Failed to start video surface due to main thread blocked.";
++        gst_caps_unref(m_startCaps);
++        m_startCaps = 0;
++    }
++
++    return m_activeRenderer != 0;
++}
++
++void QVideoSurfaceGstDelegate::stop()
++{
++    QMutexLocker locker(&m_mutex);
++
++    if (!m_activeRenderer)
++        return;
++
++    m_flush = true;
++    m_stop = true;
++
++    if (m_startCaps) {
++        gst_caps_unref(m_startCaps);
++        m_startCaps = 0;
++    }
++
++    if (m_lastBuffer) {
++        gst_buffer_unref(m_lastBuffer);
++        m_lastBuffer = 0;
++    }
++
++    waitForAsyncEvent(&locker, &m_setupCondition, 500);
++}
++
++bool QVideoSurfaceGstDelegate::proposeAllocation(GstQuery *query)
++{
++    QMutexLocker locker(&m_mutex);
++
++    if (QGstVideoRenderer *pool = m_activeRenderer) {
++        locker.unlock();
++
++        return pool->proposeAllocation(query);
++    } else {
++        return false;
++    }
++}
++
++void QVideoSurfaceGstDelegate::flush()
++{
++    QMutexLocker locker(&m_mutex);
++
++    m_flush = true;
++    m_render = false;
++
++    if (m_lastBuffer) {
++        gst_buffer_unref(m_lastBuffer);
++        m_lastBuffer = 0;
++    }
++
++    notify();
++}
++
++GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer, bool show)
++{
++    QMutexLocker locker(&m_mutex);
++
++    if (m_lastBuffer)
++        gst_buffer_unref(m_lastBuffer);
++    m_lastBuffer = buffer;
++    gst_buffer_ref(m_lastBuffer);
++
++    if (show) {
++        m_render = true;
++
++        return waitForAsyncEvent(&locker, &m_renderCondition, 300)
++                ? m_renderReturn
++                : GST_FLOW_ERROR;
++    } else {
++        return GST_FLOW_OK;
++    }
++}
++
++void QVideoSurfaceGstDelegate::handleShowPrerollChange(GObject *object, GParamSpec *, gpointer d)
++{
++    QVideoSurfaceGstDelegate * const delegate = static_cast<QVideoSurfaceGstDelegate *>(d);
++
++    gboolean showPreroll = true; // "show-preroll-frame" property is true by default
++    g_object_get(object, "show-preroll-frame", &showPreroll, NULL);
++
++    GstState state = GST_STATE_NULL;
++    GstState pendingState = GST_STATE_NULL;
++    gst_element_get_state(GST_ELEMENT(object), &state, &pendingState, 0);
++
++    const bool paused
++                = (pendingState == GST_STATE_VOID_PENDING && state == GST_STATE_PAUSED)
++                || pendingState == GST_STATE_PAUSED;
++
++    if (paused) {
++        QMutexLocker locker(&delegate->m_mutex);
++
++        if (!showPreroll && delegate->m_lastBuffer) {
++            delegate->m_render = false;
++            delegate->m_flush = true;
++            delegate->notify();
++        } else if (delegate->m_lastBuffer) {
++            delegate->m_render = true;
++            delegate->notify();
++        }
++    }
++}
++
++bool QVideoSurfaceGstDelegate::event(QEvent *event)
++{
++    if (event->type() == QEvent::UpdateRequest) {
++        QMutexLocker locker(&m_mutex);
++
++        if (m_notified) {
++            while (handleEvent(&locker)) {}
++            m_notified = false;
++        }
++        return true;
++    } else {
++        return QObject::event(event);
++    }
++}
++
++bool QVideoSurfaceGstDelegate::handleEvent(QMutexLocker *locker)
++{
++    if (m_flush) {
++        m_flush = false;
++        if (m_activeRenderer) {
++            locker->unlock();
++
++            m_activeRenderer->flush(m_surface);
++        }
++    } else if (m_stop) {
++        m_stop = false;
++
++        if (QGstVideoRenderer * const activePool = m_activeRenderer) {
++            m_activeRenderer = 0;
++            locker->unlock();
++
++            activePool->stop(m_surface);
++
++            locker->relock();
++        }
++    } else if (m_startCaps) {
++        Q_ASSERT(!m_activeRenderer);
++
++        GstCaps * const startCaps = m_startCaps;
++        m_startCaps = 0;
++
++        if (m_renderer && m_surface) {
++            locker->unlock();
++
++            const bool started = m_renderer->start(m_surface, startCaps);
++
++            locker->relock();
++
++            m_activeRenderer = started
++                    ? m_renderer
++                    : 0;
++        } else if (QGstVideoRenderer * const activePool = m_activeRenderer) {
++            m_activeRenderer = 0;
++            locker->unlock();
++
++            activePool->stop(m_surface);
++
++            locker->relock();
++        }
++
++        gst_caps_unref(startCaps);
++    } else if (m_render) {
++        m_render = false;
++
++        if (m_activeRenderer && m_surface && m_lastBuffer) {
++            GstBuffer *buffer = m_lastBuffer;
++            gst_buffer_ref(buffer);
++
++            locker->unlock();
++
++            const bool rendered = m_activeRenderer->present(m_surface, buffer);
++
++            gst_buffer_unref(buffer);
++
++            locker->relock();
++
++            m_renderReturn = rendered
++                    ? GST_FLOW_OK
++                    : GST_FLOW_ERROR;
++
++            m_renderCondition.wakeAll();
++        } else {
++            m_renderReturn = GST_FLOW_ERROR;
++            m_renderCondition.wakeAll();
++        }
++    } else {
++        m_setupCondition.wakeAll();
++
++        return false;
++    }
++    return true;
++}
++
++void QVideoSurfaceGstDelegate::notify()
++{
++    if (!m_notified) {
++        m_notified = true;
++        QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
++    }
++}
++
++bool QVideoSurfaceGstDelegate::waitForAsyncEvent(
++        QMutexLocker *locker, QWaitCondition *condition, unsigned long time)
++{
++    if (QThread::currentThread() == thread()) {
++        while (handleEvent(locker)) {}
++        m_notified = false;
++
++        return true;
++    } else {
++        notify();
++
++        return condition->wait(&m_mutex, time);
++    }
++}
++
++void QVideoSurfaceGstDelegate::updateSupportedFormats()
++{
++    if (m_surfaceCaps) {
++        gst_caps_unref(m_surfaceCaps);
++        m_surfaceCaps = 0;
++    }
++
++    foreach (QGstVideoRenderer *pool, m_renderers) {
++        if (GstCaps *caps = pool->getCaps(m_surface)) {
++            if (gst_caps_is_empty(caps)) {
++                gst_caps_unref(caps);
++                continue;
++            }
++
++            if (m_surfaceCaps)
++                gst_caps_unref(m_surfaceCaps);
++
++            m_renderer = pool;
++            m_surfaceCaps = caps;
++            break;
++        } else {
++            gst_caps_unref(caps);
++        }
++    }
++}
++
++static GstVideoSinkClass *sink_parent_class;
++
++#define VO_SINK(s) QGstVideoRendererSink *sink(reinterpret_cast<QGstVideoRendererSink *>(s))
++
++QGstVideoRendererSink *QGstVideoRendererSink::createSink(QAbstractVideoSurface *surface)
++{
++    QGstVideoRendererSink *sink = reinterpret_cast<QGstVideoRendererSink *>(
++            g_object_new(QGstVideoRendererSink::get_type(), 0));
++
++    sink->delegate = new QVideoSurfaceGstDelegate(surface);
++
++    g_signal_connect(
++                G_OBJECT(sink),
++                "notify::show-preroll-frame",
++                G_CALLBACK(QVideoSurfaceGstDelegate::handleShowPrerollChange),
++                sink->delegate);
++
++    return sink;
++}
++
++GType QGstVideoRendererSink::get_type()
++{
++    static GType type = 0;
++
++    if (type == 0) {
++        static const GTypeInfo info =
++        {
++            sizeof(QGstVideoRendererSinkClass),                    // class_size
++            base_init,                                         // base_init
++            NULL,                                              // base_finalize
++            class_init,                                        // class_init
++            NULL,                                              // class_finalize
++            NULL,                                              // class_data
++            sizeof(QGstVideoRendererSink),                         // instance_size
++            0,                                                 // n_preallocs
++            instance_init,                                     // instance_init
++            0                                                  // value_table
++        };
++
++        type = g_type_register_static(
++                GST_TYPE_VIDEO_SINK, "QGstVideoRendererSink", &info, GTypeFlags(0));
++    }
++
++    return type;
++}
++
++void QGstVideoRendererSink::class_init(gpointer g_class, gpointer class_data)
++{
++    Q_UNUSED(class_data);
++
++    sink_parent_class = reinterpret_cast<GstVideoSinkClass *>(g_type_class_peek_parent(g_class));
++
++    GstBaseSinkClass *base_sink_class = reinterpret_cast<GstBaseSinkClass *>(g_class);
++    base_sink_class->get_caps = QGstVideoRendererSink::get_caps;
++    base_sink_class->set_caps = QGstVideoRendererSink::set_caps;
++    base_sink_class->propose_allocation = QGstVideoRendererSink::propose_allocation;
++    base_sink_class->preroll = QGstVideoRendererSink::preroll;
++    base_sink_class->render = QGstVideoRendererSink::render;
++
++    GstElementClass *element_class = reinterpret_cast<GstElementClass *>(g_class);
++    element_class->change_state = QGstVideoRendererSink::change_state;
++
++    GObjectClass *object_class = reinterpret_cast<GObjectClass *>(g_class);
++    object_class->finalize = QGstVideoRendererSink::finalize;
++}
++
++void QGstVideoRendererSink::base_init(gpointer g_class)
++{
++    static GstStaticPadTemplate sink_pad_template = GST_STATIC_PAD_TEMPLATE(
++            "sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS(
++                    "video/x-raw, "
++                    "framerate = (fraction) [ 0, MAX ], "
++                    "width = (int) [ 1, MAX ], "
++                    "height = (int) [ 1, MAX ]"));
++
++    gst_element_class_add_pad_template(
++            GST_ELEMENT_CLASS(g_class), gst_static_pad_template_get(&sink_pad_template));
++}
++
++void QGstVideoRendererSink::instance_init(GTypeInstance *instance, gpointer g_class)
++{
++    VO_SINK(instance);
++
++    Q_UNUSED(g_class);
++
++    sink->delegate = 0;
++}
++
++void QGstVideoRendererSink::finalize(GObject *object)
++{
++    VO_SINK(object);
++
++    delete sink->delegate;
++
++    // Chain up
++    G_OBJECT_CLASS(sink_parent_class)->finalize(object);
++}
++
++GstStateChangeReturn QGstVideoRendererSink::change_state(
++        GstElement *element, GstStateChange transition)
++{
++    Q_UNUSED(element);
++
++    return GST_ELEMENT_CLASS(sink_parent_class)->change_state(
++            element, transition);
++}
++
++GstCaps *QGstVideoRendererSink::get_caps(GstBaseSink *base, GstCaps *filter)
++{
++    VO_SINK(base);
++
++    GstCaps *caps = sink->delegate->caps();
++    GstCaps *unfiltered = caps;
++    if (filter) {
++        caps = gst_caps_intersect(unfiltered, filter);
++        gst_caps_unref(unfiltered);
++    }
++
++    return caps;
++}
++
++gboolean QGstVideoRendererSink::set_caps(GstBaseSink *base, GstCaps *caps)
++{
++    VO_SINK(base);
++
++#ifdef DEBUG_VIDEO_SURFACE_SINK
++    qDebug() << "set_caps:";
++    qDebug() << caps;
++#endif
++
++    if (!caps) {
++        sink->delegate->stop();
++
++        return TRUE;
++    } else if (sink->delegate->start(caps)) {
++        return TRUE;
++    } else {
++        return FALSE;
++    }
++}
++
++gboolean QGstVideoRendererSink::propose_allocation(GstBaseSink *base, GstQuery *query)
++{
++    VO_SINK(base);
++    return sink->delegate->proposeAllocation(query);
++}
++
++GstFlowReturn QGstVideoRendererSink::preroll(GstBaseSink *base, GstBuffer *buffer)
++{
++    VO_SINK(base);
++
++    gboolean showPreroll = true; // "show-preroll-frame" property is true by default
++    g_object_get(G_OBJECT(base), "show-preroll-frame", &showPreroll, NULL);
++
++    return sink->delegate->render(buffer, showPreroll); // display frame
++}
++
++GstFlowReturn QGstVideoRendererSink::render(GstBaseSink *base, GstBuffer *buffer)
++{
++    VO_SINK(base);
++    return sink->delegate->render(buffer, true);
++}
++
++QT_END_NAMESPACE
+diff --git a/src/gsttools/qvideosurfacegstsink.cpp b/src/gsttools/qvideosurfacegstsink.cpp
+index f3e2d88..147db66 100644
+--- a/src/gsttools/qvideosurfacegstsink.cpp
++++ b/src/gsttools/qvideosurfacegstsink.cpp
+@@ -41,8 +41,13 @@
+ #include <private/qmediapluginloader_p.h>
+ #include "qgstvideobuffer_p.h"
+ 
++#include "qgstutils_p.h"
+ #include "qvideosurfacegstsink_p.h"
+ 
++#if GST_VERSION_MAJOR >=1
++#include <gst/video/video.h>
++#endif
++
+ //#define DEBUG_VIDEO_SURFACE_SINK
+ 
+ QT_BEGIN_NAMESPACE
+@@ -62,10 +67,12 @@ QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(
+     if (m_surface) {
+         foreach (QObject *instance, bufferPoolLoader()->instances(QGstBufferPoolPluginKey)) {
+             QGstBufferPoolInterface* plugin = qobject_cast<QGstBufferPoolInterface*>(instance);
++
+             if (plugin) {
+                 m_pools.append(plugin);
+             }
+         }
++
+         updateSupportedFormats();
+         connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(updateSupportedFormats()));
+     }
+@@ -191,13 +198,15 @@ GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer)
+             m_format.frameSize(),
+             m_format.pixelFormat());
+ 
+-    QVideoSurfaceGstSink::setFrameTimeStamps(&m_frame, buffer);
++    QGstUtils::setFrameTimeStamps(&m_frame, buffer);
+ 
+     m_renderReturn = GST_FLOW_OK;
+ 
+     if (QThread::currentThread() == thread()) {
+         if (!m_surface.isNull())
+             m_surface->present(m_frame);
++        else
++            qWarning() << "m_surface.isNull().";
+     } else {
+         QMetaObject::invokeMethod(this, "queuedRender", Qt::QueuedConnection);
+         m_renderCondition.wait(&m_mutex, 300);
+@@ -283,90 +292,6 @@ void QVideoSurfaceGstDelegate::updateSupportedFormats()
+     }
+ }
+ 
+-struct YuvFormat
+-{
+-    QVideoFrame::PixelFormat pixelFormat;
+-    guint32 fourcc;
+-    int bitsPerPixel;
+-};
+-
+-static const YuvFormat qt_yuvColorLookup[] =
+-{
+-    { QVideoFrame::Format_YUV420P, GST_MAKE_FOURCC('I','4','2','0'), 8 },
+-    { QVideoFrame::Format_YV12,    GST_MAKE_FOURCC('Y','V','1','2'), 8 },
+-    { QVideoFrame::Format_UYVY,    GST_MAKE_FOURCC('U','Y','V','Y'), 16 },
+-    { QVideoFrame::Format_YUYV,    GST_MAKE_FOURCC('Y','U','Y','2'), 16 },
+-    { QVideoFrame::Format_NV12,    GST_MAKE_FOURCC('N','V','1','2'), 8 },
+-    { QVideoFrame::Format_NV21,    GST_MAKE_FOURCC('N','V','2','1'), 8 },
+-    { QVideoFrame::Format_AYUV444, GST_MAKE_FOURCC('A','Y','U','V'), 32 }
+-};
+-
+-static int indexOfYuvColor(QVideoFrame::PixelFormat format)
+-{
+-    const int count = sizeof(qt_yuvColorLookup) / sizeof(YuvFormat);
+-
+-    for (int i = 0; i < count; ++i)
+-        if (qt_yuvColorLookup[i].pixelFormat == format)
+-            return i;
+-
+-    return -1;
+-}
+-
+-static int indexOfYuvColor(guint32 fourcc)
+-{
+-    const int count = sizeof(qt_yuvColorLookup) / sizeof(YuvFormat);
+-
+-    for (int i = 0; i < count; ++i)
+-        if (qt_yuvColorLookup[i].fourcc == fourcc)
+-            return i;
+-
+-    return -1;
+-}
+-
+-struct RgbFormat
+-{
+-    QVideoFrame::PixelFormat pixelFormat;
+-    int bitsPerPixel;
+-    int depth;
+-    int endianness;
+-    int red;
+-    int green;
+-    int blue;
+-    int alpha;
+-};
+-
+-static const RgbFormat qt_rgbColorLookup[] =
+-{
+-    { QVideoFrame::Format_RGB32 , 32, 24, 4321, 0x0000FF00, 0x00FF0000, int(0xFF000000), 0x00000000 },
+-    { QVideoFrame::Format_RGB32 , 32, 24, 1234, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 },
+-    { QVideoFrame::Format_BGR32 , 32, 24, 4321, int(0xFF000000), 0x00FF0000, 0x0000FF00, 0x00000000 },
+-    { QVideoFrame::Format_BGR32 , 32, 24, 1234, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 },
+-    { QVideoFrame::Format_ARGB32, 32, 24, 4321, 0x0000FF00, 0x00FF0000, int(0xFF000000), 0x000000FF },
+-    { QVideoFrame::Format_ARGB32, 32, 24, 1234, 0x00FF0000, 0x0000FF00, 0x000000FF, int(0xFF000000) },
+-    { QVideoFrame::Format_RGB24 , 24, 24, 4321, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 },
+-    { QVideoFrame::Format_BGR24 , 24, 24, 4321, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 },
+-    { QVideoFrame::Format_RGB565, 16, 16, 1234, 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }
+-};
+-
+-static int indexOfRgbColor(
+-        int bits, int depth, int endianness, int red, int green, int blue, int alpha)
+-{
+-    const int count = sizeof(qt_rgbColorLookup) / sizeof(RgbFormat);
+-
+-    for (int i = 0; i < count; ++i) {
+-        if (qt_rgbColorLookup[i].bitsPerPixel == bits
+-            && qt_rgbColorLookup[i].depth == depth
+-            && qt_rgbColorLookup[i].endianness == endianness
+-            && qt_rgbColorLookup[i].red == red
+-            && qt_rgbColorLookup[i].green == green
+-            && qt_rgbColorLookup[i].blue == blue
+-            && qt_rgbColorLookup[i].alpha == alpha) {
+-            return i;
+-        }
+-    }
+-    return -1;
+-}
+-
+ static GstVideoSinkClass *sink_parent_class;
+ 
+ #define VO_SINK(s) QVideoSurfaceGstSink *sink(reinterpret_cast<QVideoSurfaceGstSink *>(s))
+@@ -494,8 +419,6 @@ GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base)
+ {
+     VO_SINK(base);
+ 
+-    GstCaps *caps = gst_caps_new_empty();
+-
+     // Find the supported pixel formats
+     // with buffer pool specific formats listed first
+     QList<QVideoFrame::PixelFormat> supportedFormats;
+@@ -503,6 +426,7 @@ GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base)
+     QList<QVideoFrame::PixelFormat> poolHandleFormats;
+     sink->delegate->poolMutex()->lock();
+     QGstBufferPoolInterface *pool = sink->delegate->pool();
++
+     if (pool)
+         poolHandleFormats = sink->delegate->supportedPixelFormats(pool->handleType());
+     sink->delegate->poolMutex()->unlock();
+@@ -513,47 +437,7 @@ GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base)
+             supportedFormats.append(format);
+     }
+ 
+-    foreach (QVideoFrame::PixelFormat format, supportedFormats) {
+-        int index = indexOfYuvColor(format);
+-
+-        if (index != -1) {
+-            gst_caps_append_structure(caps, gst_structure_new(
+-                    "video/x-raw-yuv",
+-                    "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, INT_MAX, 1,
+-                    "width"    , GST_TYPE_INT_RANGE, 1, INT_MAX,
+-                    "height"   , GST_TYPE_INT_RANGE, 1, INT_MAX,
+-                    "format"   , GST_TYPE_FOURCC, qt_yuvColorLookup[index].fourcc,
+-                    NULL));
+-            continue;
+-        }
+-
+-        const int count = sizeof(qt_rgbColorLookup) / sizeof(RgbFormat);
+-
+-        for (int i = 0; i < count; ++i) {
+-            if (qt_rgbColorLookup[i].pixelFormat == format) {
+-                GstStructure *structure = gst_structure_new(
+-                        "video/x-raw-rgb",
+-                        "framerate" , GST_TYPE_FRACTION_RANGE, 0, 1, INT_MAX, 1,
+-                        "width"     , GST_TYPE_INT_RANGE, 1, INT_MAX,
+-                        "height"    , GST_TYPE_INT_RANGE, 1, INT_MAX,
+-                        "bpp"       , G_TYPE_INT, qt_rgbColorLookup[i].bitsPerPixel,
+-                        "depth"     , G_TYPE_INT, qt_rgbColorLookup[i].depth,
+-                        "endianness", G_TYPE_INT, qt_rgbColorLookup[i].endianness,
+-                        "red_mask"  , G_TYPE_INT, qt_rgbColorLookup[i].red,
+-                        "green_mask", G_TYPE_INT, qt_rgbColorLookup[i].green,
+-                        "blue_mask" , G_TYPE_INT, qt_rgbColorLookup[i].blue,
+-                        NULL);
+-
+-                if (qt_rgbColorLookup[i].alpha != 0) {
+-                    gst_structure_set(
+-                            structure, "alpha_mask", G_TYPE_INT, qt_rgbColorLookup[i].alpha, NULL);
+-                }
+-                gst_caps_append_structure(caps, structure);
+-            }
+-        }
+-    }
+-
+-    return caps;
++    return QGstUtils::capsForFormats(supportedFormats);
+ }
+ 
+ gboolean QVideoSurfaceGstSink::set_caps(GstBaseSink *base, GstCaps *caps)
+@@ -575,7 +459,7 @@ gboolean QVideoSurfaceGstSink::set_caps(GstBaseSink *base, GstCaps *caps)
+         QAbstractVideoBuffer::HandleType handleType =
+                 pool ? pool->handleType() : QAbstractVideoBuffer::NoHandle;
+ 
+-        QVideoSurfaceFormat format = formatForCaps(caps, &bytesPerLine, handleType);
++        QVideoSurfaceFormat format = QGstUtils::formatForCaps(caps, &bytesPerLine, handleType);
+ 
+         if (sink->delegate->isActive()) {
+             QVideoSurfaceFormat surfaceFormst = sink->delegate->surfaceFormat();
+@@ -592,7 +476,7 @@ gboolean QVideoSurfaceGstSink::set_caps(GstBaseSink *base, GstCaps *caps)
+         sink->lastRequestedCaps = 0;
+ 
+ #ifdef DEBUG_VIDEO_SURFACE_SINK
+-        qDebug() << "Staring video surface, format:";
++        qDebug() << "Starting video surface, format:";
+         qDebug() << format;
+         qDebug() << "bytesPerLine:" << bytesPerLine;
+ #endif
+@@ -606,87 +490,6 @@ gboolean QVideoSurfaceGstSink::set_caps(GstBaseSink *base, GstCaps *caps)
+     return FALSE;
+ }
+ 
+-QVideoSurfaceFormat QVideoSurfaceGstSink::formatForCaps(GstCaps *caps, int *bytesPerLine, QAbstractVideoBuffer::HandleType handleType)
+-{
+-    const GstStructure *structure = gst_caps_get_structure(caps, 0);
+-
+-    QVideoFrame::PixelFormat pixelFormat = QVideoFrame::Format_Invalid;
+-    int bitsPerPixel = 0;
+-
+-    QSize size;
+-    gst_structure_get_int(structure, "width", &size.rwidth());
+-    gst_structure_get_int(structure, "height", &size.rheight());
+-
+-    if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-yuv") == 0) {
+-        guint32 fourcc = 0;
+-        gst_structure_get_fourcc(structure, "format", &fourcc);
+-
+-        int index = indexOfYuvColor(fourcc);
+-        if (index != -1) {
+-            pixelFormat = qt_yuvColorLookup[index].pixelFormat;
+-            bitsPerPixel = qt_yuvColorLookup[index].bitsPerPixel;
+-        }
+-    } else if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-rgb") == 0) {
+-        int depth = 0;
+-        int endianness = 0;
+-        int red = 0;
+-        int green = 0;
+-        int blue = 0;
+-        int alpha = 0;
+-
+-        gst_structure_get_int(structure, "bpp", &bitsPerPixel);
+-        gst_structure_get_int(structure, "depth", &depth);
+-        gst_structure_get_int(structure, "endianness", &endianness);
+-        gst_structure_get_int(structure, "red_mask", &red);
+-        gst_structure_get_int(structure, "green_mask", &green);
+-        gst_structure_get_int(structure, "blue_mask", &blue);
+-        gst_structure_get_int(structure, "alpha_mask", &alpha);
+-
+-        int index = indexOfRgbColor(bitsPerPixel, depth, endianness, red, green, blue, alpha);
+-
+-        if (index != -1)
+-            pixelFormat = qt_rgbColorLookup[index].pixelFormat;
+-    }
+-
+-    if (pixelFormat != QVideoFrame::Format_Invalid) {
+-        QVideoSurfaceFormat format(size, pixelFormat, handleType);
+-
+-        QPair<int, int> rate;
+-        gst_structure_get_fraction(structure, "framerate", &rate.first, &rate.second);
+-
+-        if (rate.second)
+-            format.setFrameRate(qreal(rate.first)/rate.second);
+-
+-        gint aspectNum = 0;
+-        gint aspectDenum = 0;
+-        if (gst_structure_get_fraction(
+-                structure, "pixel-aspect-ratio", &aspectNum, &aspectDenum)) {
+-            if (aspectDenum > 0)
+-                format.setPixelAspectRatio(aspectNum, aspectDenum);
+-        }
+-
+-        if (bytesPerLine)
+-            *bytesPerLine = ((size.width() * bitsPerPixel / 8) + 3) & ~3;
+-
+-        return format;
+-    }
+-
+-    return QVideoSurfaceFormat();
+-}
+-
+-void QVideoSurfaceGstSink::setFrameTimeStamps(QVideoFrame *frame, GstBuffer *buffer)
+-{
+-    // GStreamer uses nanoseconds, Qt uses microseconds
+-    qint64 startTime = GST_BUFFER_TIMESTAMP(buffer);
+-    if (startTime >= 0) {
+-        frame->setStartTime(startTime/G_GINT64_CONSTANT (1000));
+-
+-        qint64 duration = GST_BUFFER_DURATION(buffer);
+-        if (duration >= 0)
+-            frame->setEndTime((startTime + duration)/G_GINT64_CONSTANT (1000));
+-    }
+-}
+-
+ GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
+         GstBaseSink *base, guint64 offset, guint size, GstCaps *caps, GstBuffer **buffer)
+ {
+@@ -731,7 +534,7 @@ GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
+ 
+     if (sink->delegate->isActive()) {
+         //if format was changed, restart the surface
+-        QVideoSurfaceFormat format = formatForCaps(intersection);
++        QVideoSurfaceFormat format = QGstUtils::formatForCaps(intersection);
+         QVideoSurfaceFormat surfaceFormat = sink->delegate->surfaceFormat();
+ 
+         if (format.pixelFormat() != surfaceFormat.pixelFormat() ||
+@@ -749,7 +552,7 @@ GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
+         QAbstractVideoBuffer::HandleType handleType =
+                 pool ? pool->handleType() : QAbstractVideoBuffer::NoHandle;
+ 
+-        QVideoSurfaceFormat format = formatForCaps(intersection, &bytesPerLine, handleType);
++        QVideoSurfaceFormat format = QGstUtils::formatForCaps(intersection, &bytesPerLine, handleType);
+ 
+         if (!sink->delegate->start(format, bytesPerLine)) {
+             qWarning() << "failed to start video surface";
+@@ -763,7 +566,7 @@ GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
+     QVideoSurfaceFormat surfaceFormat = sink->delegate->surfaceFormat();
+ 
+     if (!pool->isFormatSupported(surfaceFormat)) {
+-        //qDebug() << "sink doesn't support native pool format, skip custom buffers allocation";
++        qDebug() << "sink doesn't support native pool format, skip custom buffers allocation";
+         return GST_FLOW_OK;
+     }
+ 
+@@ -787,7 +590,6 @@ GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
+ gboolean QVideoSurfaceGstSink::start(GstBaseSink *base)
+ {
+     Q_UNUSED(base);
+-
+     return TRUE;
+ }
+ 
+diff --git a/src/multimedia/gsttools_headers/qgstappsrc_p.h b/src/multimedia/gsttools_headers/qgstappsrc_p.h
+index 4af9252..0e0fc0a 100644
+--- a/src/multimedia/gsttools_headers/qgstappsrc_p.h
++++ b/src/multimedia/gsttools_headers/qgstappsrc_p.h
+@@ -39,7 +39,10 @@
+ 
+ #include <gst/gst.h>
+ #include <gst/app/gstappsrc.h>
++
++#if GST_VERSION_MAJOR < 1
+ #include <gst/app/gstappbuffer.h>
++#endif
+ 
+ QT_BEGIN_NAMESPACE
+ 
+diff --git a/src/multimedia/gsttools_headers/qgstreameraudioprobecontrol_p.h b/src/multimedia/gsttools_headers/qgstreameraudioprobecontrol_p.h
+index 34669b8..571a7ce 100644
+--- a/src/multimedia/gsttools_headers/qgstreameraudioprobecontrol_p.h
++++ b/src/multimedia/gsttools_headers/qgstreameraudioprobecontrol_p.h
+@@ -38,23 +38,32 @@
+ #include <qmediaaudioprobecontrol.h>
+ #include <QtCore/qmutex.h>
+ #include <qaudiobuffer.h>
++#include <qshareddata.h>
++
++#include <private/qgstreamerbufferprobe_p.h>
+ 
+ QT_BEGIN_NAMESPACE
+ 
+-class QGstreamerAudioProbeControl : public QMediaAudioProbeControl
++class QGstreamerAudioProbeControl
++    : public QMediaAudioProbeControl
++    , public QGstreamerBufferProbe
++    , public QSharedData
+ {
+     Q_OBJECT
+ public:
+     explicit QGstreamerAudioProbeControl(QObject *parent);
+     virtual ~QGstreamerAudioProbeControl();
+ 
+-    void bufferProbed(GstBuffer* buffer);
++protected:
++    void probeCaps(GstCaps *caps);
++    bool probeBuffer(GstBuffer *buffer);
+ 
+ private slots:
+     void bufferProbed();
+ 
+ private:
+     QAudioBuffer m_pendingBuffer;
++    QAudioFormat m_format;
+     QMutex m_bufferMutex;
+ };
+ 
+diff --git a/src/multimedia/gsttools_headers/qgstreamerbufferprobe_p.h b/src/multimedia/gsttools_headers/qgstreamerbufferprobe_p.h
+new file mode 100644
+index 0000000..9240742
+--- /dev/null
++++ b/src/multimedia/gsttools_headers/qgstreamerbufferprobe_p.h
+@@ -0,0 +1,86 @@
++/****************************************************************************
++**
++** Copyright (C) 2014 Jolla Ltd.
++** Contact: http://www.qt-project.org/legal
++**
++** This file is part of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and Digia.  For licensing terms and
++** conditions see http://qt.digia.com/licensing.  For further information
++** use the contact form at http://qt.digia.com/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 2.1 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL included in the
++** packaging of this file.  Please review the following information to
++** ensure the GNU Lesser General Public License version 2.1 requirements
++** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
++**
++** In addition, as a special exception, Digia gives you certain additional
++** rights.  These rights are described in the Digia Qt LGPL Exception
++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 3.0 as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL included in the
++** packaging of this file.  Please review the following information to
++** ensure the GNU General Public License version 3.0 requirements will be
++** met: http://www.gnu.org/copyleft/gpl.html.
++**
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#ifndef QGSTREAMERBUFFERPROBE_H
++#define QGSTREAMERBUFFERPROBE_H
++
++#include <gst/gst.h>
++
++#include <QtCore/qglobal.h>
++
++QT_BEGIN_NAMESPACE
++
++class QGstreamerBufferProbe
++{
++public:
++    enum Flags
++    {
++        ProbeCaps       = 0x01,
++        ProbeBuffers    = 0x02,
++        ProbeAll    = ProbeCaps | ProbeBuffers
++    };
++
++    explicit QGstreamerBufferProbe(Flags flags = ProbeAll);
++    virtual ~QGstreamerBufferProbe();
++
++    void addProbeToPad(GstPad *pad, bool downstream = true);
++    void removeProbeFromPad(GstPad *pad);
++
++protected:
++    virtual void probeCaps(GstCaps *caps);
++    virtual bool probeBuffer(GstBuffer *buffer);
++
++private:
++#if GST_CHECK_VERSION(1,0,0)
++    static GstPadProbeReturn capsProbe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data);
++    static GstPadProbeReturn bufferProbe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data);
++    int m_capsProbeId;
++#else
++    static gboolean bufferProbe(GstElement *element, GstBuffer *buffer, gpointer user_data);
++    GstCaps *m_caps;
++#endif
++    int m_bufferProbeId;
++    const Flags m_flags;
++};
++
++QT_END_NAMESPACE
++
++#endif // QGSTREAMERAUDIOPROBECONTROL_H
+diff --git a/src/multimedia/gsttools_headers/qgstreamermirtexturerenderer_p.h b/src/multimedia/gsttools_headers/qgstreamermirtexturerenderer_p.h
+new file mode 100644
+index 0000000..25b8d60
+--- /dev/null
++++ b/src/multimedia/gsttools_headers/qgstreamermirtexturerenderer_p.h
+@@ -0,0 +1,102 @@
++/****************************************************************************
++**
++** Copyright (C) 2014 Canonical Ltd.
++** Contact: http://www.qt-project.org/legal
++**
++** This file is part of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL21$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and Digia. For licensing terms and
++** conditions see http://qt.digia.com/licensing. For further information
++** use the contact form at http://qt.digia.com/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 2.1 or version 3 as published by the Free
++** Software Foundation and appearing in the file LICENSE.LGPLv21 and
++** LICENSE.LGPLv3 included in the packaging of this file. Please review the
++** following information to ensure the GNU Lesser General Public License
++** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
++** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
++**
++** In addition, as a special exception, Digia gives you certain additional
++** rights. These rights are described in the Digia Qt LGPL Exception
++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#ifndef QGSTREAMERMIRTEXTURERENDERER_H
++#define QGSTREAMERMIRTEXTURERENDERER_H
++
++#include <qmediaplayer.h>
++#include <qvideorenderercontrol.h>
++#include <private/qvideosurfacegstsink_p.h>
++#include <qabstractvideosurface.h>
++
++#include "qgstreamervideorendererinterface_p.h"
++
++QT_BEGIN_NAMESPACE
++
++class QGstreamerMirTextureBuffer;
++class QGstreamerPlayerSession;
++class QGLContext;
++class QOpenGLContext;
++class QSurfaceFormat;
++
++class QGstreamerMirTextureRenderer : public QVideoRendererControl, public QGstreamerVideoRendererInterface
++{
++    Q_OBJECT
++    Q_INTERFACES(QGstreamerVideoRendererInterface)
++public:
++    QGstreamerMirTextureRenderer(QObject *parent = 0, const QGstreamerPlayerSession *playerSession = 0);
++    virtual ~QGstreamerMirTextureRenderer();
++
++    QAbstractVideoSurface *surface() const;
++    void setSurface(QAbstractVideoSurface *surface);
++
++    void setPlayerSession(const QGstreamerPlayerSession *playerSession);
++
++    GstElement *videoSink();
++
++    void stopRenderer();
++    bool isReady() const { return m_surface != 0; }
++
++signals:
++    void sinkChanged();
++    void readyChanged(bool);
++    void nativeSizeChanged();
++
++private slots:
++    void handleFormatChange();
++    void updateNativeVideoSize();
++    void handleFocusWindowChanged(QWindow *window);
++    void renderFrame();
++
++private:
++    QWindow *createOffscreenWindow(const QSurfaceFormat &format);
++    static void handleFrameReady(gpointer userData);
++    static GstPadProbeReturn padBufferProbe(GstPad *pad, GstPadProbeInfo *info, gpointer userData);
++
++    GstElement *m_videoSink;
++    QPointer<QAbstractVideoSurface> m_surface;
++    QPointer<QAbstractVideoSurface> m_glSurface;
++    QGLContext *m_context;
++    QOpenGLContext *m_glContext;
++    unsigned int m_textureId;
++    QWindow *m_offscreenSurface;
++    QGstreamerPlayerSession *m_playerSession;
++    QGstreamerMirTextureBuffer *m_textureBuffer;
++    QSize m_nativeSize;
++
++    QMutex m_mutex;
++};
++
++QT_END_NAMESPACE
++
++#endif // QGSTREAMERMIRTEXTURERENDRER_H
+diff --git a/src/multimedia/gsttools_headers/qgstreamervideoprobecontrol_p.h b/src/multimedia/gsttools_headers/qgstreamervideoprobecontrol_p.h
+index 49064f9..f035f65 100644
+--- a/src/multimedia/gsttools_headers/qgstreamervideoprobecontrol_p.h
++++ b/src/multimedia/gsttools_headers/qgstreamervideoprobecontrol_p.h
+@@ -35,20 +35,29 @@
+ #define QGSTREAMERVIDEOPROBECONTROL_H
+ 
+ #include <gst/gst.h>
++#include <gst/video/video.h>
+ #include <qmediavideoprobecontrol.h>
+ #include <QtCore/qmutex.h>
+ #include <qvideoframe.h>
++#include <qvideosurfaceformat.h>
++
++#include <private/qgstreamerbufferprobe_p.h>
+ 
+ QT_BEGIN_NAMESPACE
+ 
+-class QGstreamerVideoProbeControl : public QMediaVideoProbeControl
++class QGstreamerVideoProbeControl
++    : public QMediaVideoProbeControl
++    , public QGstreamerBufferProbe
++    , public QSharedData
+ {
+     Q_OBJECT
+ public:
+     explicit QGstreamerVideoProbeControl(QObject *parent);
+     virtual ~QGstreamerVideoProbeControl();
+ 
+-    void bufferProbed(GstBuffer* buffer);
++    void probeCaps(GstCaps *caps);
++    bool probeBuffer(GstBuffer *buffer);
++
+     void startFlushing();
+     void stopFlushing();
+ 
+@@ -56,10 +65,16 @@ private slots:
+     void frameProbed();
+ 
+ private:
+-    bool m_flushing;
+-    bool m_frameProbed; // true if at least one frame was probed
++    QVideoSurfaceFormat m_format;
+     QVideoFrame m_pendingFrame;
+     QMutex m_frameMutex;
++#if GST_CHECK_VERSION(1,0,0)
++    GstVideoInfo m_videoInfo;
++#else
++    int m_bytesPerLine;
++#endif
++    bool m_flushing;
++    bool m_frameProbed; // true if at least one frame was probed
+ };
+ 
+ QT_END_NAMESPACE
+diff --git a/src/multimedia/gsttools_headers/qgstreamervideowindow_p.h b/src/multimedia/gsttools_headers/qgstreamervideowindow_p.h
+index 81e5764..d38156c 100644
+--- a/src/multimedia/gsttools_headers/qgstreamervideowindow_p.h
++++ b/src/multimedia/gsttools_headers/qgstreamervideowindow_p.h
+@@ -38,6 +38,7 @@
+ 
+ #include "qgstreamervideorendererinterface_p.h"
+ #include <private/qgstreamerbushelper_p.h>
++#include <private/qgstreamerbufferprobe_p.h>
+ #include <QtGui/qcolor.h>
+ 
+ QT_BEGIN_NAMESPACE
+@@ -45,7 +46,8 @@ class QAbstractVideoSurface;
+ 
+ class QGstreamerVideoWindow : public QVideoWindowControl,
+         public QGstreamerVideoRendererInterface,
+-        public QGstreamerSyncMessageFilter
++        public QGstreamerSyncMessageFilter,
++        private QGstreamerBufferProbe
+ {
+     Q_OBJECT
+     Q_INTERFACES(QGstreamerVideoRendererInterface QGstreamerSyncMessageFilter)
+@@ -101,10 +103,10 @@ signals:
+     void readyChanged(bool);
+ 
+ private slots:
+-    void updateNativeVideoSize();
++    void updateNativeVideoSize(const QSize &size);
+ 
+ private:
+-    static void padBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data);
++    void probeCaps(GstCaps *caps);
+ 
+     GstElement *m_videoSink;
+     WId m_windowId;
+@@ -113,7 +115,6 @@ private:
+     bool m_fullScreen;
+     QSize m_nativeSize;
+     mutable QColor m_colorKey;
+-    int m_bufferProbeId;
+ };
+ 
+ QT_END_NAMESPACE
+diff --git a/src/multimedia/gsttools_headers/qgstutils_p.h b/src/multimedia/gsttools_headers/qgstutils_p.h
+index 65ff759..71a0a57 100644
+--- a/src/multimedia/gsttools_headers/qgstutils_p.h
++++ b/src/multimedia/gsttools_headers/qgstutils_p.h
+@@ -49,14 +49,32 @@
+ #include <QtCore/qset.h>
+ #include <QtCore/qvector.h>
+ #include <gst/gst.h>
++#include <gst/video/video.h>
+ #include <qaudioformat.h>
+ #include <qcamera.h>
++#include <qabstractvideobuffer.h>
++#include <qvideoframe.h>
++#include <QDebug>
++
++#if GST_CHECK_VERSION(1,0,0)
++# define QT_GSTREAMER_PLAYBIN_ELEMENT_NAME "playbin"
++# define QT_GSTREAMER_CAMERABIN_ELEMENT_NAME "camerabin"
++# define QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME "videoconvert"
++# define QT_GSTREAMER_RAW_AUDIO_MIME "audio/x-raw"
++#else
++# define QT_GSTREAMER_PLAYBIN_ELEMENT_NAME "playbin2"
++# define QT_GSTREAMER_CAMERABIN_ELEMENT_NAME "camerabin2"
++# define QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME "ffmpegcolorspace"
++# define QT_GSTREAMER_RAW_AUDIO_MIME "audio/x-raw-int"
++#endif
+ 
+ QT_BEGIN_NAMESPACE
+ 
+ class QSize;
+ class QVariant;
+ class QByteArray;
++class QImage;
++class QVideoSurfaceFormat;
+ 
+ namespace QGstUtils {
+     struct CameraInfo
+@@ -73,8 +91,12 @@ namespace QGstUtils {
+     QSize capsResolution(const GstCaps *caps);
+     QSize capsCorrectedResolution(const GstCaps *caps);
+     QAudioFormat audioFormatForCaps(const GstCaps *caps);
++#if GST_CHECK_VERSION(1,0,0)
++    QAudioFormat audioFormatForSample(GstSample *sample);
++#else
+     QAudioFormat audioFormatForBuffer(GstBuffer *buffer);
+-    GstCaps *capsForAudioFormat(QAudioFormat format);
++#endif
++    GstCaps *capsForAudioFormat(const QAudioFormat &format);
+     void initializeGst();
+     QMultimedia::SupportEstimate hasSupport(const QString &mimeType,
+                                              const QStringList &codecs,
+@@ -86,9 +108,40 @@ namespace QGstUtils {
+     QCamera::Position cameraPosition(const QString &device, GstElementFactory * factory = 0);
+     int cameraOrientation(const QString &device, GstElementFactory * factory = 0);
+     QByteArray cameraDriver(const QString &device, GstElementFactory * factory = 0);
++
++    QSet<QString> supportedMimeTypes(bool (*isValidFactory)(GstElementFactory *factory));
++
++#if GST_CHECK_VERSION(1,0,0)
++    QImage bufferToImage(GstBuffer *buffer, const GstVideoInfo &info);
++    QVideoSurfaceFormat formatForCaps(
++            GstCaps *caps,
++            GstVideoInfo *info,
++            QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle);
++#else
++    QImage bufferToImage(GstBuffer *buffer);
++    QVideoSurfaceFormat formatForCaps(
++            GstCaps *caps,
++            int *bytesPerLine = 0,
++            QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle);
++#endif
++
++    GstCaps *capsForFormats(const QList<QVideoFrame::PixelFormat> &formats);
++    void setFrameTimeStamps(QVideoFrame *frame, GstBuffer *buffer);
++
++    void setMetaData(GstElement *element, const QMap<QByteArray, QVariant> &data);
++    void setMetaData(GstBin *bin, const QMap<QByteArray, QVariant> &data);
++
++    GstCaps *videoFilterCaps();
++
+ }
+ 
+ void qt_gst_object_ref_sink(gpointer object);
++GstCaps *qt_gst_pad_get_current_caps(GstPad *pad);
++GstStructure *qt_gst_structure_new_empty(const char *name);
++gboolean qt_gst_element_query_position(GstElement *element, GstFormat format, gint64 *cur);
++gboolean qt_gst_element_query_duration(GstElement *element, GstFormat format, gint64 *cur);
++
++QDebug operator <<(QDebug debug, GstCaps *caps);
+ 
+ QT_END_NAMESPACE
+ 
+diff --git a/src/multimedia/gsttools_headers/qgstvideobuffer_p.h b/src/multimedia/gsttools_headers/qgstvideobuffer_p.h
+index 1e0fda8..00aca48 100644
+--- a/src/multimedia/gsttools_headers/qgstvideobuffer_p.h
++++ b/src/multimedia/gsttools_headers/qgstvideobuffer_p.h
+@@ -49,26 +49,47 @@
+ #include <QtCore/qvariant.h>
+ 
+ #include <gst/gst.h>
++#include <gst/video/video.h>
+ 
+ QT_BEGIN_NAMESPACE
+ 
++#if GST_CHECK_VERSION(1,0,0)
++class QGstVideoBuffer : public QAbstractPlanarVideoBuffer
++{
++public:
++    QGstVideoBuffer(GstBuffer *buffer, const GstVideoInfo &info);
++    QGstVideoBuffer(GstBuffer *buffer, const GstVideoInfo &info,
++                    HandleType handleType, const QVariant &handle);
++#else
+ class QGstVideoBuffer : public QAbstractVideoBuffer
+ {
+ public:
+     QGstVideoBuffer(GstBuffer *buffer, int bytesPerLine);
+     QGstVideoBuffer(GstBuffer *buffer, int bytesPerLine,
+                     HandleType handleType, const QVariant &handle);
++#endif
++
+     ~QGstVideoBuffer();
+ 
+     MapMode mapMode() const;
+ 
++#if GST_CHECK_VERSION(1,0,0)
++    int map(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4]);
++#else
+     uchar *map(MapMode mode, int *numBytes, int *bytesPerLine);
++#endif
++
+     void unmap();
+ 
+     QVariant handle() const { return m_handle; }
+ private:
+-    GstBuffer *m_buffer;
++#if GST_CHECK_VERSION(1,0,0)
++    GstVideoInfo m_videoInfo;
++    GstVideoFrame m_frame;
++#else
+     int m_bytesPerLine;
++#endif
++    GstBuffer *m_buffer;
+     MapMode m_mode;
+     QVariant m_handle;
+ };
+diff --git a/src/multimedia/gsttools_headers/qgstvideorendererplugin_p.h b/src/multimedia/gsttools_headers/qgstvideorendererplugin_p.h
+new file mode 100644
+index 0000000..616677a
+--- /dev/null
++++ b/src/multimedia/gsttools_headers/qgstvideorendererplugin_p.h
+@@ -0,0 +1,111 @@
++/****************************************************************************
++**
++** Copyright (C) 2014 Jolla Ltd.
++** Contact: http://www.qt-project.org/legal
++**
++** This file is part of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and Digia.  For licensing terms and
++** conditions see http://qt.digia.com/licensing.  For further information
++** use the contact form at http://qt.digia.com/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 2.1 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL included in the
++** packaging of this file.  Please review the following information to
++** ensure the GNU Lesser General Public License version 2.1 requirements
++** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
++**
++** In addition, as a special exception, Digia gives you certain additional
++** rights.  These rights are described in the Digia Qt LGPL Exception
++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 3.0 as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL included in the
++** packaging of this file.  Please review the following information to
++** ensure the GNU General Public License version 3.0 requirements will be
++** met: http://www.gnu.org/copyleft/gpl.html.
++**
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#ifndef QGSTVIDEORENDERERPLUGIN_P_H
++#define QGSTVIDEORENDERERPLUGIN_P_H
++
++//
++//  W A R N I N G
++//  -------------
++//
++// This file is not part of the Qt API. It exists purely as an
++// implementation detail. This header file may change from version to
++// version without notice, or even be removed.
++//
++// We mean it.
++//
++
++#include <qabstractvideobuffer.h>
++#include <qvideosurfaceformat.h>
++#include <QtCore/qobject.h>
++#include <QtCore/qplugin.h>
++
++#include <gst/gst.h>
++
++QT_BEGIN_NAMESPACE
++
++class QAbstractVideoSurface;
++
++const QLatin1String QGstVideoRendererPluginKey("gstvideorenderer");
++
++class QGstVideoRenderer
++{
++public:
++    virtual ~QGstVideoRenderer() {}
++
++    virtual GstCaps *getCaps(QAbstractVideoSurface *surface) = 0;
++    virtual bool start(QAbstractVideoSurface *surface, GstCaps *caps) = 0;
++    virtual void stop(QAbstractVideoSurface *surface) = 0;  // surface may be null if unexpectedly deleted.
++    virtual bool proposeAllocation(GstQuery *query) = 0;    // may be called from a thread.
++
++    virtual bool present(QAbstractVideoSurface *surface, GstBuffer *buffer) = 0;
++    virtual void flush(QAbstractVideoSurface *surface) = 0; // surface may be null if unexpectedly deleted.
++};
++
++/*
++    Abstract interface for video buffers allocation.
++*/
++class QGstVideoRendererInterface
++{
++public:
++    virtual ~QGstVideoRendererInterface() {}
++
++    virtual QGstVideoRenderer *createRenderer() = 0;
++};
++
++#define QGstVideoRendererInterface_iid "org.qt-project.qt.gstvideorenderer/5.4"
++Q_DECLARE_INTERFACE(QGstVideoRendererInterface, QGstVideoRendererInterface_iid)
++
++class QGstVideoRendererPlugin : public QObject, public QGstVideoRendererInterface
++{
++    Q_OBJECT
++    Q_INTERFACES(QGstVideoRendererInterface)
++public:
++    explicit QGstVideoRendererPlugin(QObject *parent = 0);
++    virtual ~QGstVideoRendererPlugin() {}
++
++    virtual QGstVideoRenderer *createRenderer() = 0;
++
++};
++
++QT_END_NAMESPACE
++
++#endif
+diff --git a/src/multimedia/gsttools_headers/qgstvideorenderersink_p.h b/src/multimedia/gsttools_headers/qgstvideorenderersink_p.h
+new file mode 100644
+index 0000000..6feb371
+--- /dev/null
++++ b/src/multimedia/gsttools_headers/qgstvideorenderersink_p.h
+@@ -0,0 +1,183 @@
++/****************************************************************************
++**
++** Copyright (C) 2014 Jolla Ltd.
++** Contact: http://www.qt-project.org/legal
++**
++** This file is part of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:LGPL$
++** Commercial License Usage
++** Licensees holding valid commercial Qt licenses may use this file in
++** accordance with the commercial license agreement provided with the
++** Software or, alternatively, in accordance with the terms contained in
++** a written agreement between you and Digia.  For licensing terms and
++** conditions see http://qt.digia.com/licensing.  For further information
++** use the contact form at http://qt.digia.com/contact-us.
++**
++** GNU Lesser General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU Lesser
++** General Public License version 2.1 as published by the Free Software
++** Foundation and appearing in the file LICENSE.LGPL included in the
++** packaging of this file.  Please review the following information to
++** ensure the GNU Lesser General Public License version 2.1 requirements
++** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
++**
++** In addition, as a special exception, Digia gives you certain additional
++** rights.  These rights are described in the Digia Qt LGPL Exception
++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
++**
++** GNU General Public License Usage
++** Alternatively, this file may be used under the terms of the GNU
++** General Public License version 3.0 as published by the Free Software
++** Foundation and appearing in the file LICENSE.GPL included in the
++** packaging of this file.  Please review the following information to
++** ensure the GNU General Public License version 3.0 requirements will be
++** met: http://www.gnu.org/copyleft/gpl.html.
++**
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#ifndef QGSTVIDEORENDERERSINK_P_H
++#define QGSTVIDEORENDERERSINK_P_H
++
++//
++//  W A R N I N G
++//  -------------
++//
++// This file is not part of the Qt API. It exists purely as an
++// implementation detail. This header file may change from version to
++// version without notice, or even be removed.
++//
++// We mean it.
++//
++
++#include <gst/video/gstvideosink.h>
++#include <gst/video/video.h>
++
++#include <QtCore/qlist.h>
++#include <QtCore/qmutex.h>
++#include <QtCore/qqueue.h>
++#include <QtCore/qpointer.h>
++#include <QtCore/qwaitcondition.h>
++#include <qvideosurfaceformat.h>
++#include <qvideoframe.h>
++#include <qabstractvideobuffer.h>
++
++#include "qgstvideorendererplugin_p.h"
++
++#include "qgstvideorendererplugin_p.h"
++
++QT_BEGIN_NAMESPACE
++class QAbstractVideoSurface;
++
++class QGstDefaultVideoRenderer : public QGstVideoRenderer
++{
++public:
++    QGstDefaultVideoRenderer();
++    ~QGstDefaultVideoRenderer();
++
++    GstCaps *getCaps(QAbstractVideoSurface *surface);
++    bool start(QAbstractVideoSurface *surface, GstCaps *caps);
++    void stop(QAbstractVideoSurface *surface);
++
++    bool proposeAllocation(GstQuery *query);
++
++    bool present(QAbstractVideoSurface *surface, GstBuffer *buffer);
++    void flush(QAbstractVideoSurface *surface);
++
++private:
++    QVideoSurfaceFormat m_format;
++    GstVideoInfo m_videoInfo;
++    bool m_flushed;
++};
++
++class QVideoSurfaceGstDelegate : public QObject
++{
++    Q_OBJECT
++public:
++    QVideoSurfaceGstDelegate(QAbstractVideoSurface *surface);
++    ~QVideoSurfaceGstDelegate();
++
++    GstCaps *caps();
++
++    bool start(GstCaps *caps);
++    void stop();
++    bool proposeAllocation(GstQuery *query);
++
++    void flush();
++
++    GstFlowReturn render(GstBuffer *buffer, bool show);
++
++    bool event(QEvent *event);
++
++    static void handleShowPrerollChange(GObject *o, GParamSpec *p, gpointer d);
++
++private slots:
++    bool handleEvent(QMutexLocker *locker);
++    void updateSupportedFormats();
++
++private:
++    void notify();
++    bool waitForAsyncEvent(QMutexLocker *locker, QWaitCondition *condition, unsigned long time);
++
++    QPointer<QAbstractVideoSurface> m_surface;
++
++    QMutex m_mutex;
++    QWaitCondition m_setupCondition;
++    QWaitCondition m_renderCondition;
++    GstFlowReturn m_renderReturn;
++    QList<QGstVideoRenderer *> m_renderers;
++    QGstVideoRenderer *m_renderer;
++    QGstVideoRenderer *m_activeRenderer;
++
++    GstCaps *m_surfaceCaps;
++    GstCaps *m_startCaps;
++    GstBuffer *m_lastBuffer;
++
++    bool m_notified;
++    bool m_stop;
++    bool m_render;
++    bool m_flush;
++};
++
++class QGstVideoRendererSink
++{
++public:
++    GstVideoSink parent;
++
++    static QGstVideoRendererSink *createSink(QAbstractVideoSurface *surface);
++
++private:
++    static GType get_type();
++    static void class_init(gpointer g_class, gpointer class_data);
++    static void base_init(gpointer g_class);
++    static void instance_init(GTypeInstance *instance, gpointer g_class);
++
++    static void finalize(GObject *object);
++
++    static GstStateChangeReturn change_state(GstElement *element, GstStateChange transition);
++
++    static GstCaps *get_caps(GstBaseSink *sink, GstCaps *filter);
++    static gboolean set_caps(GstBaseSink *sink, GstCaps *caps);
++
++    static gboolean propose_allocation(GstBaseSink *sink, GstQuery *query);
++
++    static GstFlowReturn preroll(GstBaseSink *sink, GstBuffer *buffer);
++    static GstFlowReturn render(GstBaseSink *sink, GstBuffer *buffer);
++
++private:
++    QVideoSurfaceGstDelegate *delegate;
++};
++
++
++class QGstVideoRendererSinkClass
++{
++public:
++    GstVideoSinkClass parent_class;
++};
++
++QT_END_NAMESPACE
++
++#endif
+diff --git a/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h b/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h
+index 11b305d..0ea18c0 100644
+--- a/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h
++++ b/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h
+@@ -45,6 +45,18 @@
+ // We mean it.
+ //
+ 
++#include <gst/gst.h>
++
++#if GST_CHECK_VERSION(1,0,0)
++
++#include "qgstvideorenderersink_p.h"
++
++QT_BEGIN_NAMESPACE
++typedef QGstVideoRendererSink QVideoSurfaceGstSink;
++QT_END_NAMESPACE
++
++#else
++
+ #include <gst/video/gstvideosink.h>
+ 
+ #include <QtCore/qlist.h>
+@@ -116,10 +128,6 @@ public:
+     GstVideoSink parent;
+ 
+     static QVideoSurfaceGstSink *createSink(QAbstractVideoSurface *surface);
+-    static QVideoSurfaceFormat formatForCaps(GstCaps *caps,
+-                                             int *bytesPerLine = 0,
+-                                             QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle);
+-    static void setFrameTimeStamps(QVideoFrame *frame, GstBuffer *buffer);
+ 
+ private:
+     static GType get_type();
+@@ -150,7 +158,6 @@ private:
+     QVideoSurfaceFormat *lastSurfaceFormat;
+ };
+ 
+-
+ class QVideoSurfaceGstSinkClass
+ {
+ public:
+@@ -160,3 +167,5 @@ public:
+ QT_END_NAMESPACE
+ 
+ #endif
++
++#endif
+diff --git a/src/multimedia/multimedia.pro b/src/multimedia/multimedia.pro
+index b3bdaa8..ff47768 100644
+--- a/src/multimedia/multimedia.pro
++++ b/src/multimedia/multimedia.pro
+@@ -4,6 +4,8 @@ QT = core-private network gui-private
+ MODULE_PLUGIN_TYPES = \
+     mediaservice \
+     audio \
++    video/bufferpool \
++    video/gstvideorenderer \
+     video/videonode \
+     playlistformats
+ 
+diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp
+index 3098aab..befbb9a 100644
+--- a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp
++++ b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp
+@@ -68,89 +68,16 @@ QMultimedia::SupportEstimate QGstreamerAudioDecoderServicePlugin::hasSupport(con
+     return QGstUtils::hasSupport(mimeType, codecs, m_supportedMimeTypeSet);
+ }
+ 
+-void QGstreamerAudioDecoderServicePlugin::updateSupportedMimeTypes() const
++static bool isDecoderOrDemuxer(GstElementFactory *factory)
+ {
+-    //enumerate supported mime types
+-    gst_init(NULL, NULL);
+-
+-    GList *plugins, *orig_plugins;
+-    orig_plugins = plugins = gst_default_registry_get_plugin_list ();
+-
+-    while (plugins) {
+-        GList *features, *orig_features;
+-
+-        GstPlugin *plugin = (GstPlugin *) (plugins->data);
+-        plugins = g_list_next (plugins);
+-
+-        if (plugin->flags & (1<<1)) //GST_PLUGIN_FLAG_BLACKLISTED
+-            continue;
+-
+-        orig_features = features = gst_registry_get_feature_list_by_plugin(gst_registry_get_default (),
+-                                                                        plugin->desc.name);
+-        while (features) {
+-            if (!G_UNLIKELY(features->data == NULL)) {
+-                GstPluginFeature *feature = GST_PLUGIN_FEATURE(features->data);
+-                if (GST_IS_ELEMENT_FACTORY (feature)) {
+-                    GstElementFactory *factory = GST_ELEMENT_FACTORY(gst_plugin_feature_load(feature));
+-                    if (factory
+-                       && factory->numpadtemplates > 0
+-                       && (qstrcmp(factory->details.klass, "Codec/Decoder/Audio") == 0
+-                          || qstrcmp(factory->details.klass, "Codec/Demux") == 0 )) {
+-                        const GList *pads = factory->staticpadtemplates;
+-                        while (pads) {
+-                            GstStaticPadTemplate *padtemplate = (GstStaticPadTemplate*)(pads->data);
+-                            pads = g_list_next (pads);
+-                            if (padtemplate->direction != GST_PAD_SINK)
+-                                continue;
+-                            if (padtemplate->static_caps.string) {
+-                                GstCaps *caps = gst_static_caps_get(&padtemplate->static_caps);
+-                                if (!gst_caps_is_any (caps) && ! gst_caps_is_empty (caps)) {
+-                                    for (guint i = 0; i < gst_caps_get_size(caps); i++) {
+-                                        GstStructure *structure = gst_caps_get_structure(caps, i);
+-                                        QString nameLowcase = QString(gst_structure_get_name (structure)).toLower();
+-
+-                                        m_supportedMimeTypeSet.insert(nameLowcase);
+-                                        if (nameLowcase.contains("mpeg")) {
+-                                            //Because mpeg version number is only included in the detail
+-                                            //description,  it is necessary to manually extract this information
+-                                            //in order to match the mime type of mpeg4.
+-                                            const GValue *value = gst_structure_get_value(structure, "mpegversion");
+-                                            if (value) {
+-                                                gchar *str = gst_value_serialize (value);
+-                                                QString versions(str);
+-                                                QStringList elements = versions.split(QRegExp("\\D+"), QString::SkipEmptyParts);
+-                                                foreach (const QString &e, elements)
+-                                                    m_supportedMimeTypeSet.insert(nameLowcase + e);
+-                                                g_free (str);
+-                                            }
+-                                        }
+-                                    }
+-                                }
+-                                gst_caps_unref(caps);
+-                            }
+-                        }
+-                        gst_object_unref (factory);
+-                    }
+-                } else if (GST_IS_TYPE_FIND_FACTORY(feature)) {
+-                    QString name(gst_plugin_feature_get_name(feature));
+-                    if (name.contains('/')) //filter out any string without '/' which is obviously not a mime type
+-                        m_supportedMimeTypeSet.insert(name.toLower());
+-                }
+-            }
+-            features = g_list_next (features);
+-        }
+-        gst_plugin_feature_list_free (orig_features);
+-    }
+-    gst_plugin_list_free (orig_plugins);
++    return gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_DEMUXER)
++                || gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_DECODER
++                            | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO);
++}
+ 
+-#if defined QT_SUPPORTEDMIMETYPES_DEBUG
+-    QStringList list = m_supportedMimeTypeSet.toList();
+-    list.sort();
+-    if (qgetenv("QT_DEBUG_PLUGINS").toInt() > 0) {
+-        foreach (const QString &type, list)
+-            qDebug() << type;
+-    }
+-#endif
++void QGstreamerAudioDecoderServicePlugin::updateSupportedMimeTypes() const
++{
++    m_supportedMimeTypeSet = QGstUtils::supportedMimeTypes(isDecoderOrDemuxer);
+ }
+ 
+ QStringList QGstreamerAudioDecoderServicePlugin::supportedMimeTypes() const
+diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp
+index f944a60..69876b9 100644
+--- a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp
++++ b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp
+@@ -85,7 +85,7 @@ QGstreamerAudioDecoderSession::QGstreamerAudioDecoderSession(QObject *parent)
+      m_durationQueries(0)
+ {
+     // Create pipeline here
+-    m_playbin = gst_element_factory_make("playbin2", NULL);
++    m_playbin = gst_element_factory_make(QT_GSTREAMER_PLAYBIN_ELEMENT_NAME, NULL);
+ 
+     if (m_playbin != 0) {
+         // Sort out messages
+@@ -446,21 +446,40 @@ QAudioBuffer QGstreamerAudioDecoderSession::read()
+         if (buffersAvailable == 1)
+             emit bufferAvailableChanged(false);
+ 
++        const char* bufferData = 0;
++        int bufferSize = 0;
++
++#if GST_CHECK_VERSION(1,0,0)
++        GstSample *sample = gst_app_sink_pull_sample(m_appSink);
++        GstBuffer *buffer = gst_sample_get_buffer(sample);
++        GstMapInfo mapInfo;
++        gst_buffer_map(buffer, &mapInfo, GST_MAP_READ);
++        bufferData = (const char*)mapInfo.data;
++        bufferSize = mapInfo.size;
++        QAudioFormat format = QGstUtils::audioFormatForSample(sample);
++#else
+         GstBuffer *buffer = gst_app_sink_pull_buffer(m_appSink);
+-
++        bufferData = (const char*)buffer->data;
++        bufferSize = buffer->size;
+         QAudioFormat format = QGstUtils::audioFormatForBuffer(buffer);
++#endif
++
+         if (format.isValid()) {
+             // XXX At the moment we have to copy data from GstBuffer into QAudioBuffer.
+             // We could improve performance by implementing QAbstractAudioBuffer for GstBuffer.
+             qint64 position = getPositionFromBuffer(buffer);
+-            audioBuffer = QAudioBuffer(QByteArray((const char*)buffer->data, buffer->size), format, position);
++            audioBuffer = QAudioBuffer(QByteArray((const char*)bufferData, bufferSize), format, position);
+             position /= 1000; // convert to milliseconds
+             if (position != m_position) {
+                 m_position = position;
+                 emit positionChanged(m_position);
+             }
+         }
++#if GST_CHECK_VERSION(1,0,0)
++        gst_sample_unref(sample);
++#else
+         gst_buffer_unref(buffer);
++#endif
+     }
+ 
+     return audioBuffer;
+@@ -488,7 +507,7 @@ void QGstreamerAudioDecoderSession::processInvalidMedia(QAudioDecoder::Error err
+     emit error(int(errorCode), errorString);
+ }
+ 
+-GstFlowReturn QGstreamerAudioDecoderSession::new_buffer(GstAppSink *, gpointer user_data)
++GstFlowReturn QGstreamerAudioDecoderSession::new_sample(GstAppSink *, gpointer user_data)
+ {
+     // "Note that the preroll buffer will also be returned as the first buffer when calling gst_app_sink_pull_buffer()."
+     QGstreamerAudioDecoderSession *session = reinterpret_cast<QGstreamerAudioDecoderSession*>(user_data);
+@@ -531,7 +550,11 @@ void QGstreamerAudioDecoderSession::addAppSink()
+ 
+     GstAppSinkCallbacks callbacks;
+     memset(&callbacks, 0, sizeof(callbacks));
+-    callbacks.new_buffer = &new_buffer;
++#if GST_CHECK_VERSION(1,0,0)
++    callbacks.new_sample = &new_sample;
++#else
++    callbacks.new_buffer = &new_sample;
++#endif
+     gst_app_sink_set_callbacks(m_appSink, &callbacks, this, NULL);
+     gst_app_sink_set_max_buffers(m_appSink, MAX_BUFFERS_IN_QUEUE);
+     gst_base_sink_set_sync(GST_BASE_SINK(m_appSink), FALSE);
+@@ -553,11 +576,10 @@ void QGstreamerAudioDecoderSession::removeAppSink()
+ 
+ void QGstreamerAudioDecoderSession::updateDuration()
+ {
+-    GstFormat format = GST_FORMAT_TIME;
+     gint64 gstDuration = 0;
+     int duration = -1;
+ 
+-    if (m_playbin && gst_element_query_duration(m_playbin, &format, &gstDuration))
++    if (m_playbin && qt_gst_element_query_duration(m_playbin, GST_FORMAT_TIME, &gstDuration))
+         duration = gstDuration / 1000000;
+ 
+     if (m_duration != duration) {
+diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.h b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.h
+index 0912196..068221c 100644
+--- a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.h
++++ b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.h
+@@ -92,7 +92,7 @@ public:
+     qint64 position() const;
+     qint64 duration() const;
+ 
+-    static GstFlowReturn new_buffer(GstAppSink *sink, gpointer user_data);
++    static GstFlowReturn new_sample(GstAppSink *sink, gpointer user_data);
+ 
+ signals:
+     void stateChanged(QAudioDecoder::State newState);
+diff --git a/src/plugins/gstreamer/camerabin/camerabin.pro b/src/plugins/gstreamer/camerabin/camerabin.pro
+index bba797f..64fee3e 100644
+--- a/src/plugins/gstreamer/camerabin/camerabin.pro
++++ b/src/plugins/gstreamer/camerabin/camerabin.pro
+@@ -79,7 +79,7 @@ config_gstreamer_photography {
+         $$PWD/camerabinlocks.cpp \
+         $$PWD/camerabinzoom.cpp
+ 
+-    LIBS += -lgstphotography-0.10
++    LIBS += -lgstphotography-$$GST_VERSION
+     DEFINES += GST_USE_UNSTABLE_API #prevents warnings because of unstable photography API
+ }
+ 
+diff --git a/src/plugins/gstreamer/camerabin/camerabincontainer.cpp b/src/plugins/gstreamer/camerabin/camerabincontainer.cpp
+index ebb914b..9531f01 100644
+--- a/src/plugins/gstreamer/camerabin/camerabincontainer.cpp
++++ b/src/plugins/gstreamer/camerabin/camerabincontainer.cpp
+@@ -96,7 +96,7 @@ GstEncodingContainerProfile *CameraBinContainer::createProfile()
+     GstCaps *caps;
+ 
+     if (m_actualFormat.isEmpty()) {
+-        caps = gst_caps_new_any();
++        return 0;
+     } else {
+         QString format = m_actualFormat;
+         QStringList supportedFormats = m_supportedContainers.supportedCodecs();
+diff --git a/src/plugins/gstreamer/camerabin/camerabincontrol.cpp b/src/plugins/gstreamer/camerabin/camerabincontrol.cpp
+index 3ec9927..8c6b8b0 100644
+--- a/src/plugins/gstreamer/camerabin/camerabincontrol.cpp
++++ b/src/plugins/gstreamer/camerabin/camerabincontrol.cpp
+@@ -95,11 +95,6 @@ void CameraBinControl::setCaptureMode(QCamera::CaptureModes mode)
+                         captureMode() == QCamera::CaptureStillImage ?
+                             CamerabinResourcePolicy::ImageCaptureResources :
+                             CamerabinResourcePolicy::VideoCaptureResources);
+-#if (GST_VERSION_MAJOR == 0) && ((GST_VERSION_MINOR < 10) || (GST_VERSION_MICRO < 23))
+-            //due to bug in v4l2src, it's necessary to reload camera on video caps changes
+-            //https://bugzilla.gnome.org/show_bug.cgi?id=649832
+-            reloadLater();
+-#endif
+         }
+         emit captureModeChanged(mode);
+     }
+@@ -299,6 +294,8 @@ bool CameraBinControl::canChangeProperty(PropertyChangeType changeType, QCamera:
+ 
+     switch (changeType) {
+     case QCameraControl::CaptureMode:
++        return status != QCamera::ActiveStatus;
++        break;
+     case QCameraControl::ImageEncodingSettings:
+     case QCameraControl::VideoEncodingSettings:
+     case QCameraControl::Viewfinder:
+diff --git a/src/plugins/gstreamer/camerabin/camerabinexposure.cpp b/src/plugins/gstreamer/camerabin/camerabinexposure.cpp
+index a235de2..795fd42 100644
+--- a/src/plugins/gstreamer/camerabin/camerabinexposure.cpp
++++ b/src/plugins/gstreamer/camerabin/camerabinexposure.cpp
+@@ -37,6 +37,10 @@
+ 
+ #include <QDebug>
+ 
++#if !GST_CHECK_VERSION(1,0,0)
++typedef GstSceneMode GstPhotographySceneMode;
++#endif
++
+ QT_BEGIN_NAMESPACE
+ 
+ CameraBinExposure::CameraBinExposure(CameraBinSession *session)
+@@ -119,7 +123,7 @@ QVariant CameraBinExposure::actualValue(ExposureParameter parameter) const
+     }
+     case QCameraExposureControl::ExposureMode:
+     {
+-        GstSceneMode sceneMode;
++        GstPhotographySceneMode sceneMode;
+         gst_photography_get_scene_mode(m_session->photography(), &sceneMode);
+ 
+         switch (sceneMode) {
+@@ -167,7 +171,7 @@ bool CameraBinExposure::setValue(ExposureParameter parameter, const QVariant& va
+     case QCameraExposureControl::ExposureMode:
+     {
+         QCameraExposure::ExposureMode mode = QCameraExposure::ExposureMode(value.toInt());
+-        GstSceneMode sceneMode;
++        GstPhotographySceneMode sceneMode;
+         gst_photography_get_scene_mode(m_session->photography(), &sceneMode);
+ 
+         switch (mode) {
+diff --git a/src/plugins/gstreamer/camerabin/camerabinflash.cpp b/src/plugins/gstreamer/camerabin/camerabinflash.cpp
+index 2140f66..51bb9a2 100644
+--- a/src/plugins/gstreamer/camerabin/camerabinflash.cpp
++++ b/src/plugins/gstreamer/camerabin/camerabinflash.cpp
+@@ -37,6 +37,10 @@
+ 
+ #include <QDebug>
+ 
++#if !GST_CHECK_VERSION(1,0,0)
++typedef GstFlashMode GstPhotographyFlashMode;
++#endif
++
+ QT_BEGIN_NAMESPACE
+ 
+ CameraBinFlash::CameraBinFlash(CameraBinSession *session)
+@@ -51,7 +55,7 @@ CameraBinFlash::~CameraBinFlash()
+ 
+ QCameraExposure::FlashModes CameraBinFlash::flashMode() const
+ {
+-    GstFlashMode flashMode;
++    GstPhotographyFlashMode flashMode;
+     gst_photography_get_flash_mode(m_session->photography(), &flashMode);
+ 
+     QCameraExposure::FlashModes modes;
+@@ -70,7 +74,7 @@ QCameraExposure::FlashModes CameraBinFlash::flashMode() const
+ 
+ void CameraBinFlash::setFlashMode(QCameraExposure::FlashModes mode)
+ {
+-    GstFlashMode flashMode;
++    GstPhotographyFlashMode flashMode;
+     gst_photography_get_flash_mode(m_session->photography(), &flashMode);
+ 
+     if (mode.testFlag(QCameraExposure::FlashAuto)) flashMode = GST_PHOTOGRAPHY_FLASH_MODE_AUTO;
+diff --git a/src/plugins/gstreamer/camerabin/camerabinfocus.cpp b/src/plugins/gstreamer/camerabin/camerabinfocus.cpp
+index 665e204..061c680 100644
+--- a/src/plugins/gstreamer/camerabin/camerabinfocus.cpp
++++ b/src/plugins/gstreamer/camerabin/camerabinfocus.cpp
+@@ -39,6 +39,12 @@
+ #include <QDebug>
+ #include <QtCore/qmetaobject.h>
+ 
++#include <private/qgstutils_p.h>
++
++#if !GST_CHECK_VERSION(1,0,0)
++typedef GstFocusMode GstPhotographyFocusMode;
++#endif
++
+ //#define CAMERABIN_DEBUG 1
+ 
+ QT_BEGIN_NAMESPACE
+@@ -73,7 +79,7 @@ QCameraFocus::FocusModes CameraBinFocus::focusMode() const
+ 
+ void CameraBinFocus::setFocusMode(QCameraFocus::FocusModes mode)
+ {
+-    GstFocusMode photographyMode;
++    GstPhotographyFocusMode photographyMode;
+ 
+     switch (mode) {
+     case QCameraFocus::AutoFocus:
+@@ -181,9 +187,10 @@ QCameraFocusZoneList CameraBinFocus::focusZones() const
+ void CameraBinFocus::handleFocusMessage(GstMessage *gm)
+ {
+     //it's a sync message, so it's called from non main thread
+-    if (gst_structure_has_name(gm->structure, GST_PHOTOGRAPHY_AUTOFOCUS_DONE)) {
++    const GstStructure *structure = gst_message_get_structure(gm);
++    if (gst_structure_has_name(structure, GST_PHOTOGRAPHY_AUTOFOCUS_DONE)) {
+         gint status = GST_PHOTOGRAPHY_FOCUS_STATUS_NONE;
+-        gst_structure_get_int (gm->structure, "status", &status);
++        gst_structure_get_int (structure, "status", &status);
+         QCamera::LockStatus focusStatus = m_focusStatus;
+         QCamera::LockChangeReason reason = QCamera::UserRequest;
+ 
+@@ -243,7 +250,7 @@ void CameraBinFocus::_q_handleCameraStateChange(QCamera::State state)
+     m_cameraState = state;
+     if (state == QCamera::ActiveState) {
+         if (GstPad *pad = gst_element_get_static_pad(m_session->cameraSource(), "vfsrc")) {
+-            if (GstCaps *caps = gst_pad_get_negotiated_caps(pad)) {
++            if (GstCaps *caps = qt_gst_pad_get_current_caps(pad)) {
+                 if (GstStructure *structure = gst_caps_get_structure(caps, 0)) {
+                     int width = 0;
+                     int height = 0;
+diff --git a/src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp b/src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp
+index 6952155..8b51306 100644
+--- a/src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp
++++ b/src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp
+@@ -53,11 +53,13 @@ QT_BEGIN_NAMESPACE
+ 
+ CameraBinImageCapture::CameraBinImageCapture(CameraBinSession *session)
+     :QCameraImageCaptureControl(session)
++    , m_encoderProbe(this)
++    , m_muxerProbe(this)
+     , m_session(session)
+-    , m_ready(false)
+-    , m_requestId(0)
+     , m_jpegEncoderElement(0)
+     , m_metadataMuxerElement(0)
++    , m_requestId(0)
++    , m_ready(false)
+ {
+     connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(updateState()));
+     connect(m_session, SIGNAL(imageExposed(int)), this, SIGNAL(imageExposed(int)));
+@@ -108,11 +110,18 @@ void CameraBinImageCapture::updateState()
+     }
+ }
+ 
+-gboolean CameraBinImageCapture::metadataEventProbe(GstPad *pad, GstEvent *event, CameraBinImageCapture *self)
++#if GST_CHECK_VERSION(1,0,0)
++GstPadProbeReturn CameraBinImageCapture::encoderEventProbe(
++        GstPad *, GstPadProbeInfo *info, gpointer user_data)
+ {
+-    Q_UNUSED(pad);
+-
+-    if (GST_EVENT_TYPE(event) == GST_EVENT_TAG) {
++    GstEvent * const event = gst_pad_probe_info_get_event(info);
++#else
++gboolean CameraBinImageCapture::encoderEventProbe(
++        GstElement *, GstEvent *event, gpointer user_data)
++{
++#endif
++    CameraBinImageCapture  * const self = static_cast<CameraBinImageCapture *>(user_data);
++    if (event && GST_EVENT_TYPE(event) == GST_EVENT_TAG) {
+         GstTagList *gstTags;
+         gst_event_parse_tag(event, &gstTags);
+         QMap<QByteArray, QVariant> extendedTags = QGstUtils::gstTagListToMap(gstTags);
+@@ -146,17 +155,31 @@ gboolean CameraBinImageCapture::metadataEventProbe(GstPad *pad, GstEvent *event,
+             }
+         }
+     }
++#if GST_CHECK_VERSION(1,0,0)
++    return GST_PAD_PROBE_OK;
++#else
++    return TRUE;
++#endif
++}
+ 
+-    return true;
++void CameraBinImageCapture::EncoderProbe::probeCaps(GstCaps *caps)
++{
++#if GST_CHECK_VERSION(1,0,0)
++    capture->m_bufferFormat = QGstUtils::formatForCaps(caps, &capture->m_videoInfo);
++#else
++    int bytesPerLine = 0;
++    QVideoSurfaceFormat format = QGstUtils::formatForCaps(caps, &bytesPerLine);
++    capture->m_bytesPerLine = bytesPerLine;
++    capture->m_bufferFormat = format;
++#endif
+ }
+ 
+-gboolean CameraBinImageCapture::uncompressedBufferProbe(GstPad *pad, GstBuffer *buffer, CameraBinImageCapture *self)
++bool CameraBinImageCapture::EncoderProbe::probeBuffer(GstBuffer *buffer)
+ {
+-    Q_UNUSED(pad);
+-    CameraBinSession *session = self->m_session;
++    CameraBinSession * const session = capture->m_session;
+ 
+ #ifdef DEBUG_CAPTURE
+-    qDebug() << "Uncompressed buffer probe" << gst_caps_to_string(GST_BUFFER_CAPS(buffer));
++    qDebug() << "Uncompressed buffer probe";
+ #endif
+ 
+     QCameraImageCapture::CaptureDestinations destination =
+@@ -165,21 +188,23 @@ gboolean CameraBinImageCapture::uncompressedBufferProbe(GstPad *pad, GstBuffer *
+ 
+     if (destination & QCameraImageCapture::CaptureToBuffer) {
+         if (format != QVideoFrame::Format_Jpeg) {
+-            GstCaps *caps = GST_BUFFER_CAPS(buffer);
+-            int bytesPerLine = -1;
+-            QVideoSurfaceFormat format = QVideoSurfaceGstSink::formatForCaps(caps, &bytesPerLine);
+ #ifdef DEBUG_CAPTURE
+             qDebug() << "imageAvailable(uncompressed):" << format;
+ #endif
+-            QGstVideoBuffer *videoBuffer = new QGstVideoBuffer(buffer, bytesPerLine);
++#if GST_CHECK_VERSION(1,0,0)
++            QGstVideoBuffer *videoBuffer = new QGstVideoBuffer(buffer, capture->m_videoInfo);
++#else
++            QGstVideoBuffer *videoBuffer = new QGstVideoBuffer(buffer, capture->m_bytesPerLine);
++#endif
+ 
+-            QVideoFrame frame(videoBuffer,
+-                              format.frameSize(),
+-                              format.pixelFormat());
++            QVideoFrame frame(
++                        videoBuffer,
++                        capture->m_bufferFormat.frameSize(),
++                        capture->m_bufferFormat.pixelFormat());
+ 
+-            QMetaObject::invokeMethod(self, "imageAvailable",
++            QMetaObject::invokeMethod(capture, "imageAvailable",
+                                       Qt::QueuedConnection,
+-                                      Q_ARG(int, self->m_requestId),
++                                      Q_ARG(int, capture->m_requestId),
+                                       Q_ARG(QVideoFrame, frame));
+         }
+     }
+@@ -192,25 +217,40 @@ gboolean CameraBinImageCapture::uncompressedBufferProbe(GstPad *pad, GstBuffer *
+     return keepBuffer;
+ }
+ 
+-gboolean CameraBinImageCapture::jpegBufferProbe(GstPad *pad, GstBuffer *buffer, CameraBinImageCapture *self)
++void CameraBinImageCapture::MuxerProbe::probeCaps(GstCaps *caps)
+ {
+-    Q_UNUSED(pad);
+-    CameraBinSession *session = self->m_session;
++    capture->m_jpegResolution = QGstUtils::capsCorrectedResolution(caps);
++}
+ 
+-#ifdef DEBUG_CAPTURE
+-    qDebug() << "Jpeg buffer probe" << gst_caps_to_string(GST_BUFFER_CAPS(buffer));
+-#endif
++bool CameraBinImageCapture::MuxerProbe::probeBuffer(GstBuffer *buffer)
++{
++    CameraBinSession * const session = capture->m_session;
+ 
+     QCameraImageCapture::CaptureDestinations destination =
+             session->captureDestinationControl()->captureDestination();
+ 
+     if ((destination & QCameraImageCapture::CaptureToBuffer) &&
+          session->captureBufferFormatControl()->bufferFormat() == QVideoFrame::Format_Jpeg) {
+-        QGstVideoBuffer *videoBuffer = new QGstVideoBuffer(buffer,
+-                                                           -1); //bytesPerLine is not available for jpegs
+ 
+-        QSize resolution = QGstUtils::capsCorrectedResolution(GST_BUFFER_CAPS(buffer));
++        QSize resolution = capture->m_jpegResolution;
+         //if resolution is not presented in caps, try to find it from encoded jpeg data:
++#if GST_CHECK_VERSION(1,0,0)
++        GstMapInfo mapInfo;
++        if (resolution.isEmpty() && gst_buffer_map(buffer, &mapInfo, GST_MAP_READ)) {
++            QBuffer data;
++            data.setData(reinterpret_cast<const char*>(mapInfo.data), mapInfo.size);
++
++            QImageReader reader(&data, "JPEG");
++            resolution = reader.size();
++
++            gst_buffer_unmap(buffer, &mapInfo);
++        }
++
++        GstVideoInfo info;
++        gst_video_info_set_format(
++                    &info, GST_VIDEO_FORMAT_ENCODED, resolution.width(), resolution.height());
++        QGstVideoBuffer *videoBuffer = new QGstVideoBuffer(buffer, info);
++#else
+         if (resolution.isEmpty()) {
+             QBuffer data;
+             data.setData(reinterpret_cast<const char*>(GST_BUFFER_DATA(buffer)), GST_BUFFER_SIZE(buffer));
+@@ -218,20 +258,28 @@ gboolean CameraBinImageCapture::jpegBufferProbe(GstPad *pad, GstBuffer *buffer,
+             resolution = reader.size();
+         }
+ 
++        QGstVideoBuffer *videoBuffer = new QGstVideoBuffer(buffer,
++                                                           -1); //bytesPerLine is not available for jpegs
++#endif
++
++
+         QVideoFrame frame(videoBuffer,
+                           resolution,
+                           QVideoFrame::Format_Jpeg);
+-
+-        QMetaObject::invokeMethod(self, "imageAvailable",
++        QMetaObject::invokeMethod(capture, "imageAvailable",
+                                   Qt::QueuedConnection,
+-                                  Q_ARG(int, self->m_requestId),
++                                  Q_ARG(int, capture->m_requestId),
+                                   Q_ARG(QVideoFrame, frame));
+     }
+ 
+-    //drop the buffer if capture to file was disabled
+-    return destination & QCameraImageCapture::CaptureToFile;
++
++    // Theoretically we could drop the buffer here when don't want to capture to file but that
++    // prevents camerabin from recognizing that capture has been completed and returning
++    // to its idle state.
++    return true;
+ }
+ 
++
+ bool CameraBinImageCapture::processBusMessage(const QGstreamerMessage &message)
+ {
+     //Install metadata event and buffer probes
+@@ -252,9 +300,10 @@ bool CameraBinImageCapture::processBusMessage(const QGstreamerMessage &message)
+                 return false;
+ 
+             QString elementName = QString::fromLatin1(gst_element_get_name(element));
++#if !GST_CHECK_VERSION(1,0,0)
+             GstElementClass *elementClass = GST_ELEMENT_GET_CLASS(element);
+             QString elementLongName = elementClass->details.longname;
+-
++#endif
+             if (elementName.contains("jpegenc") && element != m_jpegEncoderElement) {
+                 m_jpegEncoderElement = element;
+                 GstPad *sinkpad = gst_element_get_static_pad(element, "sink");
+@@ -264,21 +313,23 @@ bool CameraBinImageCapture::processBusMessage(const QGstreamerMessage &message)
+ #ifdef DEBUG_CAPTURE
+                 qDebug() << "install metadata probe";
+ #endif
+-                gst_pad_add_event_probe(sinkpad,
+-                                        G_CALLBACK(CameraBinImageCapture::metadataEventProbe),
+-                                        this);
+-
++#if GST_CHECK_VERSION(1,0,0)
++                gst_pad_add_probe(
++                            sinkpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, encoderEventProbe, this, NULL);
++#else
++                gst_pad_add_event_probe(sinkpad, G_CALLBACK(encoderEventProbe), this);
++#endif
+ #ifdef DEBUG_CAPTURE
+                 qDebug() << "install uncompressed buffer probe";
+ #endif
+-                gst_pad_add_buffer_probe(sinkpad,
+-                                         G_CALLBACK(CameraBinImageCapture::uncompressedBufferProbe),
+-                                         this);
++                m_encoderProbe.addProbeToPad(sinkpad, true);
+ 
+                 gst_object_unref(sinkpad);
+-            } else if ((elementName.contains("jifmux") ||
+-                        elementName.startsWith("metadatamux") ||
+-                        elementLongName == QLatin1String("JPEG stream muxer"))
++            } else if ((elementName.contains("jifmux")
++#if !GST_CHECK_VERSION(1,0,0)
++                        || elementLongName == QLatin1String("JPEG stream muxer")
++#endif
++                        || elementName.startsWith("metadatamux"))
+                        && element != m_metadataMuxerElement) {
+                 //Jpeg encoded buffer probe is added after jifmux/metadatamux
+                 //element to ensure the resulting jpeg buffer contains capture metadata
+@@ -288,9 +339,8 @@ bool CameraBinImageCapture::processBusMessage(const QGstreamerMessage &message)
+ #ifdef DEBUG_CAPTURE
+                 qDebug() << "install jpeg buffer probe";
+ #endif
+-                gst_pad_add_buffer_probe(srcpad,
+-                                         G_CALLBACK(CameraBinImageCapture::jpegBufferProbe),
+-                                         this);
++                m_muxerProbe.addProbeToPad(srcpad);
++
+                 gst_object_unref(srcpad);
+             }
+         }
+diff --git a/src/plugins/gstreamer/camerabin/camerabinimagecapture.h b/src/plugins/gstreamer/camerabin/camerabinimagecapture.h
+index c2e26f5..9a52dd9 100644
+--- a/src/plugins/gstreamer/camerabin/camerabinimagecapture.h
++++ b/src/plugins/gstreamer/camerabin/camerabinimagecapture.h
+@@ -38,6 +38,14 @@
+ #include <qcameraimagecapturecontrol.h>
+ #include "camerabinsession.h"
+ 
++#include <qvideosurfaceformat.h>
++
++#include <private/qgstreamerbufferprobe_p.h>
++
++#if GST_CHECK_VERSION(1,0,0)
++#include <gst/video/video.h>
++#endif
++
+ QT_BEGIN_NAMESPACE
+ 
+ class CameraBinImageCapture : public QCameraImageCaptureControl, public QGstreamerBusMessageFilter
+@@ -61,15 +69,47 @@ private slots:
+     void updateState();
+ 
+ private:
+-    static gboolean metadataEventProbe(GstPad *pad, GstEvent *event, CameraBinImageCapture *);
+-    static gboolean uncompressedBufferProbe(GstPad *pad, GstBuffer *buffer, CameraBinImageCapture *);
+-    static gboolean jpegBufferProbe(GstPad *pad, GstBuffer *buffer, CameraBinImageCapture *);
++#if GST_CHECK_VERSION(1,0,0)
++    static GstPadProbeReturn encoderEventProbe(GstPad *, GstPadProbeInfo *info, gpointer user_data);
++#else
++    static gboolean encoderEventProbe(GstElement *, GstEvent *event, gpointer user_data);
++#endif
++
++    class EncoderProbe : public QGstreamerBufferProbe
++    {
++    public:
++        EncoderProbe(CameraBinImageCapture *capture) : capture(capture) {}
++        void probeCaps(GstCaps *caps);
++        bool probeBuffer(GstBuffer *buffer);
++
++    private:
++        CameraBinImageCapture * const capture;
++    } m_encoderProbe;
++
++    class MuxerProbe : public QGstreamerBufferProbe
++    {
++    public:
++        MuxerProbe(CameraBinImageCapture *capture) : capture(capture) {}
++        void probeCaps(GstCaps *caps);
++        bool probeBuffer(GstBuffer *buffer);
+ 
++    private:
++        CameraBinImageCapture * const capture;
++
++    } m_muxerProbe;
++
++    QVideoSurfaceFormat m_bufferFormat;
++    QSize m_jpegResolution;
+     CameraBinSession *m_session;
+-    bool m_ready;
+-    int m_requestId;
+     GstElement *m_jpegEncoderElement;
+     GstElement *m_metadataMuxerElement;
++#if GST_CHECK_VERSION(1,0,0)
++    GstVideoInfo m_videoInfo;
++#else
++    int m_bytesPerLine;
++#endif
++    int m_requestId;
++    bool m_ready;
+ };
+ 
+ QT_END_NAMESPACE
+diff --git a/src/plugins/gstreamer/camerabin/camerabinimageencoder.cpp b/src/plugins/gstreamer/camerabin/camerabinimageencoder.cpp
+index 824f996..739364f 100644
+--- a/src/plugins/gstreamer/camerabin/camerabinimageencoder.cpp
++++ b/src/plugins/gstreamer/camerabin/camerabinimageencoder.cpp
+@@ -49,7 +49,6 @@ CameraBinImageEncoder::~CameraBinImageEncoder()
+ 
+ QList<QSize> CameraBinImageEncoder::supportedResolutions(const QImageEncoderSettings &, bool *continuous) const
+ {
+-    qDebug() << "CameraBinImageEncoder::supportedResolutions()";
+     if (continuous)
+         *continuous = false;
+ 
+diff --git a/src/plugins/gstreamer/camerabin/camerabinimageprocessing.cpp b/src/plugins/gstreamer/camerabin/camerabinimageprocessing.cpp
+index ebfb087..811225f 100644
+--- a/src/plugins/gstreamer/camerabin/camerabinimageprocessing.cpp
++++ b/src/plugins/gstreamer/camerabin/camerabinimageprocessing.cpp
+@@ -34,7 +34,11 @@
+ #include "camerabinimageprocessing.h"
+ #include "camerabinsession.h"
+ 
+-#include <gst/interfaces/colorbalance.h>
++#if GST_CHECK_VERSION(1,0,0)
++# include <gst/video/colorbalance.h>
++#else
++# include <gst/interfaces/colorbalance.h>
++#endif
+ 
+ QT_BEGIN_NAMESPACE
+ 
+@@ -126,7 +130,7 @@ bool CameraBinImageProcessing::setColorBalanceValue(const QString& channel, qrea
+ QCameraImageProcessing::WhiteBalanceMode CameraBinImageProcessing::whiteBalanceMode() const
+ {
+ #ifdef HAVE_GST_PHOTOGRAPHY
+-    GstWhiteBalanceMode wbMode;
++    GstPhotographyWhiteBalanceMode wbMode;
+     gst_photography_get_white_balance_mode(m_session->photography(), &wbMode);
+     return m_mappedWbValues[wbMode];
+ #else
+diff --git a/src/plugins/gstreamer/camerabin/camerabinimageprocessing.h b/src/plugins/gstreamer/camerabin/camerabinimageprocessing.h
+index dcefcd0..2c6347f 100644
+--- a/src/plugins/gstreamer/camerabin/camerabinimageprocessing.h
++++ b/src/plugins/gstreamer/camerabin/camerabinimageprocessing.h
+@@ -41,7 +41,10 @@
+ #include <glib.h>
+ 
+ #ifdef HAVE_GST_PHOTOGRAPHY
+-#include <gst/interfaces/photography.h>
++# include <gst/interfaces/photography.h>
++# if !GST_CHECK_VERSION(1,0,0)
++typedef GstWhiteBalanceMode GstPhotographyWhiteBalanceMode;
++# endif
+ #endif
+ 
+ QT_BEGIN_NAMESPACE
+@@ -73,7 +76,7 @@ private:
+     CameraBinSession *m_session;
+     QMap<QCameraImageProcessingControl::ProcessingParameter, int> m_values;
+ #ifdef HAVE_GST_PHOTOGRAPHY
+-    QMap<GstWhiteBalanceMode, QCameraImageProcessing::WhiteBalanceMode> m_mappedWbValues;
++    QMap<GstPhotographyWhiteBalanceMode, QCameraImageProcessing::WhiteBalanceMode> m_mappedWbValues;
+ #endif
+ };
+ 
+diff --git a/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp b/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp
+index 5148135..bc1b260 100644
+--- a/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp
++++ b/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp
+@@ -126,7 +126,7 @@ static const QGStreamerMetaDataKeys *qt_gstreamerMetaDataKeys()
+         metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::AlbumTitle, GST_TAG_ALBUM, QVariant::String));
+         metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::AlbumArtist,  GST_TAG_ARTIST, QVariant::String));
+         metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::ContributingArtist, GST_TAG_PERFORMER, QVariant::String));
+-#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 19)
++#if GST_CHECK_VERSION(0,10,19)
+         metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Composer, GST_TAG_COMPOSER, QVariant::String));
+ #endif
+         //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Conductor, 0, QVariant::String));
+@@ -153,8 +153,7 @@ static const QGStreamerMetaDataKeys *qt_gstreamerMetaDataKeys()
+         //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Director, 0, QVariant::String));
+         metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::LeadPerformer, GST_TAG_PERFORMER, QVariant::String));
+         //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Writer, 0, QVariant::String));
+-
+-#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 30)
++#if GST_CHECK_VERSION(0,10,30)
+         // Photos
+         metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::CameraManufacturer, GST_TAG_DEVICE_MANUFACTURER, QVariant::String));
+         metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::CameraModel, GST_TAG_DEVICE_MODEL, QVariant::String));
+diff --git a/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp b/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp
+index 3a04c2f..801c7ab 100644
+--- a/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp
++++ b/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp
+@@ -110,9 +110,10 @@ void CameraBinRecorder::updateStatus()
+             m_state = QMediaRecorder::StoppedState;
+             m_session->stopVideoRecording();
+         }
+-        m_status = m_session->pendingState() == QCamera::ActiveState ?
+-                    QMediaRecorder::LoadingStatus :
+-                    QMediaRecorder::UnloadedStatus;
++        m_status = m_session->pendingState() == QCamera::ActiveState
++                    && m_session->captureMode().testFlag(QCamera::CaptureVideo)
++                ? QMediaRecorder::LoadingStatus
++                : QMediaRecorder::UnloadedStatus;
+     }
+ 
+     if (m_state != oldState)
+@@ -161,8 +162,6 @@ void CameraBinRecorder::applySettings()
+ 
+                 QVideoEncoderSettings videoSettings = videoEncoderControl->videoSettings();
+                 videoSettings.setCodec(candidate[1]);
+-                if (videoSettings.resolution().isEmpty())
+-                    videoSettings.setResolution(640, 480);
+                 videoEncoderControl->setActualVideoSettings(videoSettings);
+ 
+                 QAudioEncoderSettings audioSettings = audioEncoderControl->audioSettings();
+diff --git a/src/plugins/gstreamer/camerabin/camerabinservice.cpp b/src/plugins/gstreamer/camerabin/camerabinservice.cpp
+index 969955f..388f2fd 100644
+--- a/src/plugins/gstreamer/camerabin/camerabinservice.cpp
++++ b/src/plugins/gstreamer/camerabin/camerabinservice.cpp
+@@ -56,11 +56,11 @@
+ #include "camerabincapturedestination.h"
+ #include "camerabinviewfindersettings.h"
+ #include <private/qgstreamerbushelper_p.h>
++#include <private/qgstutils_p.h>
+ 
+ #include <private/qgstreameraudioinputselector_p.h>
+ #include <private/qgstreamervideoinputdevicecontrol_p.h>
+ 
+-
+ #if defined(HAVE_WIDGETS)
+ #include <private/qgstreamervideowidget_p.h>
+ #endif
+@@ -121,7 +121,6 @@ CameraBinService::CameraBinService(GstElementFactory *sourceFactory, QObject *pa
+ #else
+     m_videoWindow = new QGstreamerVideoWindow(this);
+ #endif
+-
+ #if defined(HAVE_WIDGETS)
+     m_videoWidgetControl = new QGstreamerVideoWidgetControl(this);
+ #endif
+@@ -150,8 +149,6 @@ QMediaControl *CameraBinService::requestControl(const char *name)
+     if (!m_captureSession)
+         return 0;
+ 
+-    //qDebug() << "Request control" << name;
+-
+     if (!m_videoOutput) {
+         if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
+             m_videoOutput = m_videoRenderer;
+@@ -249,7 +246,7 @@ void CameraBinService::releaseControl(QMediaControl *control)
+ 
+ bool CameraBinService::isCameraBinAvailable()
+ {
+-    GstElementFactory *factory = gst_element_factory_find("camerabin2");
++    GstElementFactory *factory = gst_element_factory_find(QT_GSTREAMER_CAMERABIN_ELEMENT_NAME);
+     if (factory) {
+         gst_object_unref(GST_OBJECT(factory));
+         return true;
+diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp
+index a4038c5..f916b58 100644
+--- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp
++++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp
+@@ -140,8 +140,8 @@ CameraBinSession::CameraBinSession(GstElementFactory *sourceFactory, QObject *pa
+ {
+     if (m_sourceFactory)
+         gst_object_ref(GST_OBJECT(m_sourceFactory));
++    m_camerabin = gst_element_factory_make(QT_GSTREAMER_CAMERABIN_ELEMENT_NAME, "camerabin");
+ 
+-    m_camerabin = gst_element_factory_make("camerabin2", "camerabin2");
+     g_signal_connect(G_OBJECT(m_camerabin), "notify::idle", G_CALLBACK(updateBusyStatus), this);
+     g_signal_connect(G_OBJECT(m_camerabin), "element-added",  G_CALLBACK(elementAdded), this);
+     g_signal_connect(G_OBJECT(m_camerabin), "element-removed",  G_CALLBACK(elementRemoved), this);
+@@ -178,7 +178,15 @@ CameraBinSession::CameraBinSession(GstElementFactory *sourceFactory, QObject *pa
+     //post image preview in RGB format
+     g_object_set(G_OBJECT(m_camerabin), POST_PREVIEWS_PROPERTY, TRUE, NULL);
+ 
++#if GST_CHECK_VERSION(1,0,0)
++    GstCaps *previewCaps = gst_caps_new_simple(
++                "video/x-raw",
++                "format", G_TYPE_STRING, "RGBx",
++                NULL);
++#else
+     GstCaps *previewCaps = gst_caps_from_string("video/x-raw-rgb");
++#endif
++
+     g_object_set(G_OBJECT(m_camerabin), PREVIEW_CAPS_PROPERTY, previewCaps, NULL);
+     gst_caps_unref(previewCaps);
+ }
+@@ -243,6 +251,7 @@ bool CameraBinSession::setupCameraBin()
+             qWarning() << "Staring camera without viewfinder available";
+             m_viewfinderElement = gst_element_factory_make("fakesink", NULL);
+         }
++        g_object_set(G_OBJECT(m_viewfinderElement), "sync", FALSE, NULL);
+         qt_gst_object_ref_sink(GST_OBJECT(m_viewfinderElement));
+         gst_element_set_state(m_camerabin, GST_STATE_NULL);
+         g_object_set(G_OBJECT(m_camerabin), VIEWFINDER_SINK_PROPERTY, m_viewfinderElement, NULL);
+@@ -251,61 +260,27 @@ bool CameraBinSession::setupCameraBin()
+     return true;
+ }
+ 
+-static GstCaps *resolutionToCaps(const QSize &resolution, const QPair<int, int> &rate = qMakePair<int,int>(0,0))
++static GstCaps *resolutionToCaps(const QSize &resolution, qreal frameRate = 0.0)
+ {
+-    if (resolution.isEmpty())
+-        return gst_caps_new_any();
++    GstCaps *caps = QGstUtils::videoFilterCaps();
+ 
+-    GstCaps *caps = 0;
+-    if (rate.second > 0) {
+-        caps = gst_caps_new_full(gst_structure_new("video/x-raw-yuv",
+-                                                   "width", G_TYPE_INT, resolution.width(),
+-                                                   "height", G_TYPE_INT, resolution.height(),
+-                                                   "framerate", GST_TYPE_FRACTION, rate.first, rate.second,
+-                                                   NULL),
+-                                 gst_structure_new("video/x-raw-rgb",
+-                                                   "width", G_TYPE_INT, resolution.width(),
+-                                                   "height", G_TYPE_INT, resolution.height(),
+-                                                   "framerate", GST_TYPE_FRACTION, rate.first, rate.second,
+-                                                   NULL),
+-                                 gst_structure_new("video/x-raw-data",
+-                                                   "width", G_TYPE_INT, resolution.width(),
+-                                                   "height", G_TYPE_INT, resolution.height(),
+-                                                   "framerate", GST_TYPE_FRACTION, rate.first, rate.second,
+-                                                   NULL),
+-                                gst_structure_new("video/x-android-buffer",
+-                                                   "width", G_TYPE_INT, resolution.width(),
+-                                                                                    "height", G_TYPE_INT, resolution.height(),
+-                                                                                    "framerate", GST_TYPE_FRACTION, rate.first, rate.second,
+-                                                                                    NULL),
+-                                 gst_structure_new("image/jpeg",
+-                                                   "width", G_TYPE_INT, resolution.width(),
+-                                                   "height", G_TYPE_INT, resolution.height(),
+-                                                   "framerate", GST_TYPE_FRACTION, rate.first, rate.second,
+-                                                   NULL),
+-                                 NULL);
+-    } else {
+-        caps = gst_caps_new_full (gst_structure_new ("video/x-raw-yuv",
+-                                                     "width", G_TYPE_INT, resolution.width(),
+-                                                     "height", G_TYPE_INT, resolution.height(),
+-                                                     NULL),
+-                                  gst_structure_new ("video/x-raw-rgb",
+-                                                     "width", G_TYPE_INT, resolution.width(),
+-                                                     "height", G_TYPE_INT, resolution.height(),
+-                                                     NULL),
+-                                  gst_structure_new("video/x-raw-data",
+-                                                    "width", G_TYPE_INT, resolution.width(),
+-                                                    "height", G_TYPE_INT, resolution.height(),
+-                                                    NULL),
+-                                  gst_structure_new ("video/x-android-buffer",
+-                                                     "width", G_TYPE_INT, resolution.width(),
+-                                                     "height", G_TYPE_INT, resolution.height(),
+-                                                     NULL),
+-                                  gst_structure_new ("image/jpeg",
+-                                                     "width", G_TYPE_INT, resolution.width(),
+-                                                     "height", G_TYPE_INT, resolution.height(),
+-                                                     NULL),
+-                                  NULL);
++    if (!resolution.isEmpty()) {
++        gst_caps_set_simple(
++                    caps,
++                    "width", G_TYPE_INT, resolution.width(),
++                    "height", G_TYPE_INT, resolution.height(),
++                     NULL);
++    }
++
++    if (frameRate > 0.0) {
++        gint numerator;
++        gint denominator;
++        gst_util_double_to_fraction(frameRate, &numerator, &denominator);
++
++        gst_caps_set_simple(
++                    caps,
++                    "framerate", GST_TYPE_FRACTION, numerator, denominator,
++                    NULL);
+     }
+ 
+     return caps;
+@@ -314,40 +289,40 @@ static GstCaps *resolutionToCaps(const QSize &resolution, const QPair<int, int>
+ void CameraBinSession::setupCaptureResolution()
+ {
+     QSize resolution = m_imageEncodeControl->imageSettings().resolution();
+-    if (!resolution.isEmpty()) {
++    {
+         GstCaps *caps = resolutionToCaps(resolution);
+ #if CAMERABIN_DEBUG
+-        qDebug() << Q_FUNC_INFO << "set image resolution" << resolution << gst_caps_to_string(caps);
++        qDebug() << Q_FUNC_INFO << "set image resolution" << resolution << caps;
+ #endif
+         g_object_set(m_camerabin, IMAGE_CAPTURE_CAPS_PROPERTY, caps, NULL);
+-        gst_caps_unref(caps);
+-    } else {
+-        g_object_set(m_camerabin, IMAGE_CAPTURE_CAPS_PROPERTY, NULL, NULL);
++        if (caps)
++            gst_caps_unref(caps);
+     }
+ 
++    const QSize viewfinderResolution = m_viewfinderSettingsControl->resolution();
+     resolution = m_videoEncodeControl->actualVideoSettings().resolution();
+-    //qreal framerate = m_videoEncodeControl->videoSettings().frameRate();
+-    if (!resolution.isEmpty()) {
+-        GstCaps *caps = resolutionToCaps(resolution /*, framerate*/); //convert to rational
++    qreal framerate = m_videoEncodeControl->videoSettings().frameRate();
++    {
++        GstCaps *caps = resolutionToCaps(
++                    !resolution.isEmpty() ? resolution : viewfinderResolution, framerate);
+ #if CAMERABIN_DEBUG
+-        qDebug() << Q_FUNC_INFO << "set video resolution" << resolution << gst_caps_to_string(caps);
++        qDebug() << Q_FUNC_INFO << "set video resolution" << resolution << caps;
+ #endif
+         g_object_set(m_camerabin, VIDEO_CAPTURE_CAPS_PROPERTY, caps, NULL);
+-        gst_caps_unref(caps);
+-    } else {
+-        g_object_set(m_camerabin, VIDEO_CAPTURE_CAPS_PROPERTY, NULL, NULL);
++        if (caps)
++            gst_caps_unref(caps);
+     }
+ 
+-    resolution = m_viewfinderSettingsControl->resolution();
+-    if (!resolution.isEmpty()) {
++    if (!viewfinderResolution.isEmpty())
++        resolution = viewfinderResolution;
++    {
+         GstCaps *caps = resolutionToCaps(resolution);
+ #if CAMERABIN_DEBUG
+-        qDebug() << Q_FUNC_INFO << "set viewfinder resolution" << resolution << gst_caps_to_string(caps);
++        qDebug() << Q_FUNC_INFO << "set viewfinder resolution" << resolution << caps;
+ #endif
+         g_object_set(m_camerabin, VIEWFINDER_CAPS_PROPERTY, caps, NULL);
+-        gst_caps_unref(caps);
+-    } else {
+-        g_object_set(m_camerabin, VIEWFINDER_CAPS_PROPERTY, NULL, NULL);
++        if (caps)
++            gst_caps_unref(caps);
+     }
+ 
+     if (m_videoEncoder)
+@@ -363,13 +338,17 @@ void CameraBinSession::setAudioCaptureCaps()
+     if (sampleRate == -1 && channelCount == -1)
+         return;
+ 
++#if GST_CHECK_VERSION(1,0,0)
++    GstStructure *structure = gst_structure_new_empty(QT_GSTREAMER_RAW_AUDIO_MIME);
++#else
+     GstStructure *structure = gst_structure_new(
+-                "audio/x-raw-int",
++                QT_GSTREAMER_RAW_AUDIO_MIME,
+                 "endianness", G_TYPE_INT, 1234,
+                 "signed", G_TYPE_BOOLEAN, TRUE,
+                 "width", G_TYPE_INT, 16,
+                 "depth", G_TYPE_INT, 16,
+                 NULL);
++#endif
+     if (sampleRate != -1)
+         gst_structure_set(structure, "rate", G_TYPE_INT, sampleRate, NULL);
+     if (channelCount != -1)
+@@ -760,7 +739,7 @@ qint64 CameraBinSession::duration() const
+         if (fileSink) {
+             GstFormat format = GST_FORMAT_TIME;
+             gint64 duration = 0;
+-            bool ret = gst_element_query_position(fileSink, &format, &duration);
++            bool ret = qt_gst_element_query_position(fileSink, format, &duration);
+             gst_object_unref(GST_OBJECT(fileSink));
+             if (ret)
+                 return duration / 1000000;
+@@ -795,129 +774,57 @@ void CameraBinSession::setMetaData(const QMap<QByteArray, QVariant> &data)
+ {
+     m_metaData = data;
+ 
+-    if (m_camerabin) {
+-        GstIterator *elements = gst_bin_iterate_all_by_interface(GST_BIN(m_camerabin), GST_TYPE_TAG_SETTER);
+-        GstElement *element = 0;
+-        while (gst_iterator_next(elements, (void**)&element) == GST_ITERATOR_OK) {
+-            gst_tag_setter_reset_tags(GST_TAG_SETTER(element));
+-
+-            QMapIterator<QByteArray, QVariant> it(data);
+-            while (it.hasNext()) {
+-                it.next();
+-                const QString tagName = it.key();
+-                const QVariant tagValue = it.value();
+-
+-                switch(tagValue.type()) {
+-                    case QVariant::String:
+-                        gst_tag_setter_add_tags(GST_TAG_SETTER(element),
+-                            GST_TAG_MERGE_REPLACE,
+-                            tagName.toUtf8().constData(),
+-                            tagValue.toString().toUtf8().constData(),
+-                            NULL);
+-                        break;
+-                    case QVariant::Int:
+-                    case QVariant::LongLong:
+-                        gst_tag_setter_add_tags(GST_TAG_SETTER(element),
+-                            GST_TAG_MERGE_REPLACE,
+-                            tagName.toUtf8().constData(),
+-                            tagValue.toInt(),
+-                            NULL);
+-                        break;
+-                    case QVariant::Double:
+-                        gst_tag_setter_add_tags(GST_TAG_SETTER(element),
+-                            GST_TAG_MERGE_REPLACE,
+-                            tagName.toUtf8().constData(),
+-                            tagValue.toDouble(),
+-                            NULL);
+-                        break;
+-                    case QVariant::DateTime: {
+-                        QDateTime date = tagValue.toDateTime().toLocalTime();
+-                        gst_tag_setter_add_tags(GST_TAG_SETTER(element),
+-                            GST_TAG_MERGE_REPLACE,
+-                            tagName.toUtf8().constData(),
+-                            gst_date_time_new_local_time(
+-                                        date.date().year(), date.date().month(), date.date().day(),
+-                                        date.time().hour(), date.time().minute(), date.time().second()),
+-                            NULL);
+-                        break;
+-                    }
+-                    default:
+-                        break;
+-                }
+-            }
+-        }
+-        gst_iterator_free(elements);
+-    }
++    if (m_camerabin)
++        QGstUtils::setMetaData(m_camerabin, data);
+ }
+ 
+ bool CameraBinSession::processSyncMessage(const QGstreamerMessage &message)
+ {
+     GstMessage* gm = message.rawMessage();
+-    const GstStructure *st;
+-    const GValue *image;
+-    GstBuffer *buffer = NULL;
+ 
+     if (gm && GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) {
+-        if (m_captureMode == QCamera::CaptureStillImage &&
+-            gst_structure_has_name(gm->structure, "preview-image")) {
+-            st = gst_message_get_structure(gm);
+-
+-            if (gst_structure_has_field_typed(st, "buffer", GST_TYPE_BUFFER)) {
+-                image = gst_structure_get_value(st, "buffer");
+-                if (image) {
+-                    buffer = gst_value_get_buffer(image);
+-
+-                    QImage img;
+-
+-                    GstCaps *caps = gst_buffer_get_caps(buffer);
+-                    if (caps) {
+-                        GstStructure *structure = gst_caps_get_structure(caps, 0);
+-                        gint width = 0;
+-                        gint height = 0;
+-#if CAMERABIN_DEBUG
+-                        qDebug() << "Preview caps:" << gst_structure_to_string(structure);
++        const GstStructure *st = gst_message_get_structure(gm);
++        const GValue *sampleValue = 0;
++        if (m_captureMode == QCamera::CaptureStillImage
++                    && gst_structure_has_name(st, "preview-image")
++#if GST_CHECK_VERSION(1,0,0)
++                    && gst_structure_has_field_typed(st, "sample", GST_TYPE_SAMPLE)
++                    && (sampleValue = gst_structure_get_value(st, "sample"))) {
++            GstSample * const sample = gst_value_get_sample(sampleValue);
++            GstCaps * const previewCaps = gst_sample_get_caps(sample);
++            GstBuffer * const buffer = gst_sample_get_buffer(sample);
++#else
++                    && gst_structure_has_field_typed(st, "buffer", GST_TYPE_BUFFER)
++                    && (sampleValue = gst_structure_get_value(st, "buffer"))) {
++            GstBuffer * const buffer = gst_value_get_buffer(sampleValue);
+ #endif
+ 
+-                        if (structure &&
+-                            gst_structure_get_int(structure, "width", &width) &&
+-                            gst_structure_get_int(structure, "height", &height) &&
+-                            width > 0 && height > 0) {
+-                            if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-rgb") == 0) {
+-                                QImage::Format format = QImage::Format_Invalid;
+-                                int bpp = 0;
+-                                gst_structure_get_int(structure, "bpp", &bpp);
+-
+-                                if (bpp == 24)
+-                                    format = QImage::Format_RGB888;
+-                                else if (bpp == 32)
+-                                    format = QImage::Format_RGB32;
+-
+-                                if (format != QImage::Format_Invalid) {
+-                                    img = QImage((const uchar *)buffer->data, width, height, format);
+-                                    img.bits(); //detach
+-                                 }
+-                            }
+-                        }
+-                        gst_caps_unref(caps);
+-
+-                        static QMetaMethod exposedSignal = QMetaMethod::fromSignal(&CameraBinSession::imageExposed);
+-                        exposedSignal.invoke(this,
+-                                             Qt::QueuedConnection,
+-                                             Q_ARG(int,m_requestId));
+-
+-                        static QMetaMethod capturedSignal = QMetaMethod::fromSignal(&CameraBinSession::imageCaptured);
+-                        capturedSignal.invoke(this,
+-                                              Qt::QueuedConnection,
+-                                              Q_ARG(int,m_requestId),
+-                                              Q_ARG(QImage,img));
+-                    }
+-
+-                }
+-                return true;
++            QImage image;
++#if GST_CHECK_VERSION(1,0,0)
++            GstVideoInfo previewInfo;
++            if (gst_video_info_from_caps(&previewInfo, previewCaps))
++                image = QGstUtils::bufferToImage(buffer, previewInfo);
++            gst_sample_unref(sample);
++#else
++            image = QGstUtils::bufferToImage(buffer);
++            gst_buffer_unref(buffer);
++#endif
++            if (!image.isNull()) {
++                static QMetaMethod exposedSignal = QMetaMethod::fromSignal(&CameraBinSession::imageExposed);
++                exposedSignal.invoke(this,
++                                     Qt::QueuedConnection,
++                                     Q_ARG(int,m_requestId));
++
++                static QMetaMethod capturedSignal = QMetaMethod::fromSignal(&CameraBinSession::imageCaptured);
++                capturedSignal.invoke(this,
++                                      Qt::QueuedConnection,
++                                      Q_ARG(int,m_requestId),
++                                      Q_ARG(QImage,image));
+             }
++            return true;
+         }
+ #ifdef HAVE_GST_PHOTOGRAPHY
+-        if (gst_structure_has_name(gm->structure, GST_PHOTOGRAPHY_AUTOFOCUS_DONE))
++        if (gst_structure_has_name(st, GST_PHOTOGRAPHY_AUTOFOCUS_DONE))
+             m_cameraFocusControl->handleFocusMessage(gm);
+ #endif
+     }
+@@ -1109,20 +1016,12 @@ QList< QPair<int,int> > CameraBinSession::supportedFrameRates(const QSize &frame
+     if (frameSize.isEmpty()) {
+         caps = gst_caps_copy(supportedCaps);
+     } else {
+-        GstCaps *filter = gst_caps_new_full(
+-                gst_structure_new(
+-                        "video/x-raw-rgb",
+-                        "width"     , G_TYPE_INT , frameSize.width(),
+-                        "height"    , G_TYPE_INT, frameSize.height(), NULL),
+-                gst_structure_new(
+-                        "video/x-raw-yuv",
+-                        "width"     , G_TYPE_INT, frameSize.width(),
+-                        "height"    , G_TYPE_INT, frameSize.height(), NULL),
+-                gst_structure_new(
+-                        "image/jpeg",
+-                        "width"     , G_TYPE_INT, frameSize.width(),
+-                        "height"    , G_TYPE_INT, frameSize.height(), NULL),
+-                NULL);
++        GstCaps *filter = QGstUtils::videoFilterCaps();
++        gst_caps_set_simple(
++                    filter,
++                    "width", G_TYPE_INT, frameSize.width(),
++                    "height", G_TYPE_INT, frameSize.height(),
++                     NULL);
+ 
+         caps = gst_caps_intersect(supportedCaps, filter);
+         gst_caps_unref(filter);
+@@ -1133,7 +1032,7 @@ QList< QPair<int,int> > CameraBinSession::supportedFrameRates(const QSize &frame
+     caps = gst_caps_make_writable(caps);
+     for (uint i=0; i<gst_caps_get_size(caps); i++) {
+         GstStructure *structure = gst_caps_get_structure(caps, i);
+-        gst_structure_set_name(structure, "video/x-raw-yuv");
++        gst_structure_set_name(structure, "video/x-raw");
+         const GValue *oldRate = gst_structure_get_value(structure, "framerate");
+         GValue rate;
+         memset(&rate, 0, sizeof(rate));
+@@ -1142,8 +1041,11 @@ QList< QPair<int,int> > CameraBinSession::supportedFrameRates(const QSize &frame
+         gst_structure_remove_all_fields(structure);
+         gst_structure_set_value(structure, "framerate", &rate);
+     }
++#if GST_CHECK_VERSION(1,0,0)
++    caps = gst_caps_simplify(caps);
++#else
+     gst_caps_do_simplify(caps);
+-
++#endif
+ 
+     for (uint i=0; i<gst_caps_get_size(caps); i++) {
+         GstStructure *structure = gst_caps_get_structure(caps, i);
+@@ -1154,7 +1056,7 @@ QList< QPair<int,int> > CameraBinSession::supportedFrameRates(const QSize &frame
+     qSort(res.begin(), res.end(), rateLessThan);
+ 
+ #if CAMERABIN_DEBUG
+-    qDebug() << "Supported rates:" << gst_caps_to_string(caps);
++    qDebug() << "Supported rates:" << caps;
+     qDebug() << res;
+ #endif
+ 
+@@ -1213,31 +1115,24 @@ QList<QSize> CameraBinSession::supportedResolutions(QPair<int,int> rate,
+                      SUPPORTED_IMAGE_CAPTURE_CAPS_PROPERTY : SUPPORTED_VIDEO_CAPTURE_CAPS_PROPERTY,
+                  &supportedCaps, NULL);
+ 
+-    if (!supportedCaps)
+-        return res;
+-
+ #if CAMERABIN_DEBUG
+-    qDebug() << "Source caps:" << gst_caps_to_string(supportedCaps);
++    qDebug() << "Source caps:" << supportedCaps;
+ #endif
+ 
++    if (!supportedCaps)
++        return res;
++
+     GstCaps *caps = 0;
+     bool isContinuous = false;
+ 
+     if (rate.first <= 0 || rate.second <= 0) {
+         caps = gst_caps_copy(supportedCaps);
+     } else {
+-        GstCaps *filter = gst_caps_new_full(
+-                gst_structure_new(
+-                        "video/x-raw-rgb",
+-                        "framerate"     , GST_TYPE_FRACTION , rate.first, rate.second, NULL),
+-                gst_structure_new(
+-                        "video/x-raw-yuv",
+-                        "framerate"     , GST_TYPE_FRACTION , rate.first, rate.second, NULL),
+-                gst_structure_new(
+-                        "image/jpeg",
+-                        "framerate"     , GST_TYPE_FRACTION , rate.first, rate.second, NULL),
+-                NULL);
+-
++        GstCaps *filter = QGstUtils::videoFilterCaps();
++        gst_caps_set_simple(
++                    filter,
++                    "framerate"     , GST_TYPE_FRACTION , rate.first, rate.second,
++                     NULL);
+         caps = gst_caps_intersect(supportedCaps, filter);
+         gst_caps_unref(filter);
+     }
+@@ -1247,7 +1142,7 @@ QList<QSize> CameraBinSession::supportedResolutions(QPair<int,int> rate,
+     caps = gst_caps_make_writable(caps);
+     for (uint i=0; i<gst_caps_get_size(caps); i++) {
+         GstStructure *structure = gst_caps_get_structure(caps, i);
+-        gst_structure_set_name(structure, "video/x-raw-yuv");
++        gst_structure_set_name(structure, "video/x-raw");
+         const GValue *oldW = gst_structure_get_value(structure, "width");
+         const GValue *oldH = gst_structure_get_value(structure, "height");
+         GValue w;
+@@ -1262,7 +1157,13 @@ QList<QSize> CameraBinSession::supportedResolutions(QPair<int,int> rate,
+         gst_structure_set_value(structure, "width", &w);
+         gst_structure_set_value(structure, "height", &h);
+     }
++
++#if GST_CHECK_VERSION(1,0,0)
++    caps = gst_caps_simplify(caps);
++#else
+     gst_caps_do_simplify(caps);
++#endif
++
+ 
+     for (uint i=0; i<gst_caps_get_size(caps); i++) {
+         GstStructure *structure = gst_caps_get_structure(caps, i);
+diff --git a/src/plugins/gstreamer/common.pri b/src/plugins/gstreamer/common.pri
+index 8b421b8..eb6a299 100644
+--- a/src/plugins/gstreamer/common.pri
++++ b/src/plugins/gstreamer/common.pri
+@@ -12,14 +12,18 @@ LIBS += -lqgsttools_p
+ CONFIG += link_pkgconfig
+ 
+ PKGCONFIG += \
+-    gstreamer-0.10 \
+-    gstreamer-base-0.10 \
+-    gstreamer-interfaces-0.10 \
+-    gstreamer-audio-0.10 \
+-    gstreamer-video-0.10 \
+-    gstreamer-pbutils-0.10
++    gstreamer-$$GST_VERSION \
++    gstreamer-base-$$GST_VERSION \
++    gstreamer-audio-$$GST_VERSION \
++    gstreamer-video-$$GST_VERSION \
++    gstreamer-pbutils-$$GST_VERSION
++
++maemo*:PKGCONFIG +=gstreamer-plugins-bad-$$GST_VERSION
++
++mir: {
++    DEFINES += HAVE_MIR
++}
+ 
+-maemo*:PKGCONFIG +=gstreamer-plugins-bad-0.10
+ 
+ config_resourcepolicy {
+     DEFINES += HAVE_RESOURCE_POLICY
+@@ -27,8 +31,8 @@ config_resourcepolicy {
+ }
+ 
+ config_gstreamer_appsrc {
+-    PKGCONFIG += gstreamer-app-0.10
++    PKGCONFIG += gstreamer-app-$$GST_VERSION
+     DEFINES += HAVE_GST_APPSRC
+-    LIBS += -lgstapp-0.10
++    LIBS += -lgstapp-$$GST_VERSION
+ }
+ 
+diff --git a/src/plugins/gstreamer/gstreamer.pro b/src/plugins/gstreamer/gstreamer.pro
+index 7649010..0ff3510 100644
+--- a/src/plugins/gstreamer/gstreamer.pro
++++ b/src/plugins/gstreamer/gstreamer.pro
+@@ -2,8 +2,8 @@ TEMPLATE = subdirs
+ 
+ SUBDIRS += \
+     audiodecoder \
+-    mediacapture \
+-    mediaplayer
++    mediaplayer \
++    mediacapture
+ 
+ config_gstreamer_encodingprofiles {
+     SUBDIRS += camerabin
+diff --git a/src/plugins/gstreamer/mediacapture/mediacapturecamera.json b/src/plugins/gstreamer/mediacapture/mediacapturecamera.json
+index af9f357..f5fba17 100644
+--- a/src/plugins/gstreamer/mediacapture/mediacapturecamera.json
++++ b/src/plugins/gstreamer/mediacapture/mediacapturecamera.json
+@@ -1,4 +1,4 @@
+ {
+-    "Keys": ["gstreamermediacapture"]
++    "Keys": ["gstreamermediacapture"],
+     "Services": ["org.qt-project.qt.audiosource", "org.qt-project.qt.camera"]
+ }
+diff --git a/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp b/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp
+index d05df49..8881445 100644
+--- a/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp
++++ b/src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp
+@@ -34,6 +34,7 @@
+ #include "qgstreameraudioencode.h"
+ #include "qgstreamercapturesession.h"
+ #include "qgstreamermediacontainercontrol.h"
++#include <private/qgstutils_p.h>
+ 
+ #include <QtCore/qdebug.h>
+ 
+@@ -175,7 +176,7 @@ GstElement *QGstreamerAudioEncode::createEncoder()
+ 
+     if (m_audioSettings.sampleRate() > 0 || m_audioSettings.channelCount() > 0) {
+         GstCaps *caps = gst_caps_new_empty();
+-        GstStructure *structure = gst_structure_new("audio/x-raw-int", NULL);
++        GstStructure *structure = qt_gst_structure_new_empty(QT_GSTREAMER_RAW_AUDIO_MIME);
+ 
+         if (m_audioSettings.sampleRate() > 0)
+             gst_structure_set(structure, "rate", G_TYPE_INT, m_audioSettings.sampleRate(), NULL );
+diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
+index 97a165d..1ab98cd 100644
+--- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
++++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.cpp
+@@ -62,27 +62,25 @@
+ 
+ QT_BEGIN_NAMESPACE
+ 
+-QGstreamerCaptureService::QGstreamerCaptureService(const QString &service, QObject *parent):
+-    QMediaService(parent)
+-{
+-    m_captureSession = 0;
+-    m_cameraControl = 0;
+-    m_metaDataControl = 0;
+-
++QGstreamerCaptureService::QGstreamerCaptureService(const QString &service, QObject *parent)
++    : QMediaService(parent)
++    , m_captureSession(0)
++    , m_cameraControl(0)
+ #if defined(USE_GSTREAMER_CAMERA)
+-    m_videoInput = 0;
++    , m_videoInput(0)
+ #endif
+-    m_audioInputSelector = 0;
+-    m_videoInputDevice = 0;
+-
+-    m_videoOutput = 0;
+-    m_videoRenderer = 0;
+-    m_videoWindow = 0;
++    , m_metaDataControl(0)
++    , m_audioInputSelector(0)
++    , m_videoInputDevice(0)
++    , m_videoOutput(0)
++    , m_videoRenderer(0)
++    , m_videoWindow(0)
+ #if defined(HAVE_WIDGETS)
+-    m_videoWidgetControl = 0;
++    , m_videoWidgetControl(0)
+ #endif
+-    m_imageCaptureControl = 0;
+-
++    , m_imageCaptureControl(0)
++    , m_audioProbeControl(0)
++{
+     if (service == Q_MEDIASERVICE_AUDIOSOURCE) {
+         m_captureSession = new QGstreamerCaptureSession(QGstreamerCaptureSession::Audio, this);
+     }
+@@ -163,12 +161,12 @@ QMediaControl *QGstreamerCaptureService::requestControl(const char *name)
+         return m_imageCaptureControl;
+ 
+     if (qstrcmp(name,QMediaAudioProbeControl_iid) == 0) {
+-        if (m_captureSession) {
+-            QGstreamerAudioProbeControl *probe = new QGstreamerAudioProbeControl(this);
+-            m_captureSession->addProbe(probe);
+-            return probe;
++        if (!m_audioProbeControl) {
++            m_audioProbeControl = new QGstreamerAudioProbeControl(this);
++            m_captureSession->addProbe(m_audioProbeControl);
+         }
+-        return 0;
++        m_audioProbeControl->ref.ref();
++        return m_audioProbeControl;
+     }
+ 
+     if (!m_videoOutput) {
+@@ -194,17 +192,15 @@ QMediaControl *QGstreamerCaptureService::requestControl(const char *name)
+ 
+ void QGstreamerCaptureService::releaseControl(QMediaControl *control)
+ {
+-    if (control && control == m_videoOutput) {
++    if (!control) {
++        return;
++    } else if (control == m_videoOutput) {
+         m_videoOutput = 0;
+         m_captureSession->setVideoPreview(0);
+-    }
+-
+-    QGstreamerAudioProbeControl* audioProbe = qobject_cast<QGstreamerAudioProbeControl*>(control);
+-    if (audioProbe) {
+-        if (m_captureSession)
+-            m_captureSession->removeProbe(audioProbe);
+-        delete audioProbe;
+-        return;
++    } else if (control == m_audioProbeControl && !m_audioProbeControl->ref.deref()) {
++        m_captureSession->removeProbe(m_audioProbeControl);
++        delete m_audioProbeControl;
++        m_audioProbeControl = 0;
+     }
+ }
+ 
+diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h
+index 7ff8ce2..e0cf4ee 100644
+--- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h
++++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureservice.h
+@@ -43,6 +43,7 @@ QT_BEGIN_NAMESPACE
+ class QAudioInputSelectorControl;
+ class QVideoDeviceSelectorControl;
+ 
++class QGstreamerAudioProbeControl;
+ class QGstreamerCaptureSession;
+ class QGstreamerCameraControl;
+ class QGstreamerMessage;
+@@ -86,6 +87,8 @@ private:
+     QMediaControl *m_videoWidgetControl;
+ #endif
+     QGstreamerImageCaptureControl *m_imageCaptureControl;
++
++    QGstreamerAudioProbeControl *m_audioProbeControl;
+ };
+ 
+ QT_END_NAMESPACE
+diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp
+index 0ac34ee..85ed687 100644
+--- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp
++++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp
+@@ -110,90 +110,16 @@ QMultimedia::SupportEstimate QGstreamerCaptureServicePlugin::hasSupport(const QS
+     return QGstUtils::hasSupport(mimeType, codecs, m_supportedMimeTypeSet);
+ }
+ 
++
++static bool isEncoderOrMuxer(GstElementFactory *factory)
++{
++    return gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_MUXER)
++                || gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_ENCODER);
++}
++
+ void QGstreamerCaptureServicePlugin::updateSupportedMimeTypes() const
+ {
+-    //enumerate supported mime types
+-    gst_init(NULL, NULL);
+-
+-    GList *plugins, *orig_plugins;
+-    orig_plugins = plugins = gst_default_registry_get_plugin_list ();
+-
+-    while (plugins) {
+-        GList *features, *orig_features;
+-
+-        GstPlugin *plugin = (GstPlugin *) (plugins->data);
+-        plugins = g_list_next (plugins);
+-
+-        if (plugin->flags & (1<<1)) //GST_PLUGIN_FLAG_BLACKLISTED
+-            continue;
+-
+-        orig_features = features = gst_registry_get_feature_list_by_plugin(gst_registry_get_default (),
+-                                                                        plugin->desc.name);
+-        while (features) {
+-            if (!G_UNLIKELY(features->data == NULL)) {
+-                GstPluginFeature *feature = GST_PLUGIN_FEATURE(features->data);
+-                if (GST_IS_ELEMENT_FACTORY (feature)) {
+-                    GstElementFactory *factory = GST_ELEMENT_FACTORY(gst_plugin_feature_load(feature));
+-                    if (factory
+-                       && factory->numpadtemplates > 0
+-                       && (qstrcmp(factory->details.klass, "Codec/Decoder/Audio") == 0
+-                          || qstrcmp(factory->details.klass, "Codec/Decoder/Video") == 0
+-                          || qstrcmp(factory->details.klass, "Codec/Demux") == 0 )) {
+-                        const GList *pads = factory->staticpadtemplates;
+-                        while (pads) {
+-                            GstStaticPadTemplate *padtemplate = (GstStaticPadTemplate*)(pads->data);
+-                            pads = g_list_next (pads);
+-                            if (padtemplate->direction != GST_PAD_SINK)
+-                                continue;
+-                            if (padtemplate->static_caps.string) {
+-                                GstCaps *caps = gst_static_caps_get(&padtemplate->static_caps);
+-                                if (!gst_caps_is_any (caps) && ! gst_caps_is_empty (caps)) {
+-                                    for (guint i = 0; i < gst_caps_get_size(caps); i++) {
+-                                        GstStructure *structure = gst_caps_get_structure(caps, i);
+-                                        QString nameLowcase = QString(gst_structure_get_name (structure)).toLower();
+-
+-                                        m_supportedMimeTypeSet.insert(nameLowcase);
+-                                        if (nameLowcase.contains("mpeg")) {
+-                                            //Because mpeg version number is only included in the detail
+-                                            //description,  it is necessary to manually extract this information
+-                                            //in order to match the mime type of mpeg4.
+-                                            const GValue *value = gst_structure_get_value(structure, "mpegversion");
+-                                            if (value) {
+-                                                gchar *str = gst_value_serialize (value);
+-                                                QString versions(str);
+-                                                QStringList elements = versions.split(QRegExp("\\D+"), QString::SkipEmptyParts);
+-                                                foreach (const QString &e, elements)
+-                                                    m_supportedMimeTypeSet.insert(nameLowcase + e);
+-                                                g_free (str);
+-                                            }
+-                                        }
+-                                    }
+-                                }
+-                                gst_caps_unref(caps);
+-                            }
+-                        }
+-                        gst_object_unref (factory);
+-                    }
+-                } else if (GST_IS_TYPE_FIND_FACTORY(feature)) {
+-                    QString name(gst_plugin_feature_get_name(feature));
+-                    if (name.contains('/')) //filter out any string without '/' which is obviously not a mime type
+-                        m_supportedMimeTypeSet.insert(name.toLower());
+-                }
+-            }
+-            features = g_list_next (features);
+-        }
+-        gst_plugin_feature_list_free (orig_features);
+-    }
+-    gst_plugin_list_free (orig_plugins);
+-
+-#if defined QT_SUPPORTEDMIMETYPES_DEBUG
+-    QStringList list = m_supportedMimeTypeSet.toList();
+-    list.sort();
+-    if (qgetenv("QT_DEBUG_PLUGINS").toInt() > 0) {
+-        foreach (const QString &type, list)
+-            qDebug() << type;
+-    }
+-#endif
++    m_supportedMimeTypeSet = QGstUtils::supportedMimeTypes(isEncoderOrMuxer);
+ }
+ 
+ QStringList QGstreamerCaptureServicePlugin::supportedMimeTypes() const
+diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
+index a2bd80d..af5b339 100644
+--- a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
++++ b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
+@@ -45,6 +45,7 @@
+ 
+ #include <gst/gsttagsetter.h>
+ #include <gst/gstversion.h>
++#include <gst/video/video.h>
+ 
+ #include <QtCore/qdebug.h>
+ #include <QtCore/qurl.h>
+@@ -52,7 +53,6 @@
+ #include <QCoreApplication>
+ #include <QtCore/qmetaobject.h>
+ #include <QtCore/qfile.h>
+-
+ #include <QtGui/qimage.h>
+ 
+ QT_BEGIN_NAMESPACE
+@@ -64,7 +64,7 @@ QGstreamerCaptureSession::QGstreamerCaptureSession(QGstreamerCaptureSession::Cap
+      m_waitingForEos(false),
+      m_pipelineMode(EmptyPipeline),
+      m_captureMode(captureMode),
+-     m_audioBufferProbeId(-1),
++     m_audioProbe(0),
+      m_audioInputFactory(0),
+      m_audioPreviewFactory(0),
+      m_videoInputFactory(0),
+@@ -169,7 +169,7 @@ GstElement *QGstreamerCaptureSession::buildEncodeBin()
+ 
+     if (m_captureMode & Video) {
+         GstElement *videoQueue = gst_element_factory_make("queue", "video-encode-queue");
+-        GstElement *colorspace = gst_element_factory_make("ffmpegcolorspace", "ffmpegcolorspace-encoder");
++        GstElement *colorspace = gst_element_factory_make(QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME, "videoconvert-encoder");
+         GstElement *videoscale = gst_element_factory_make("videoscale","videoscale-encoder");
+         gst_bin_add_many(GST_BIN(encodeBin), videoQueue, colorspace, videoscale, NULL);
+ 
+@@ -280,7 +280,7 @@ GstElement *QGstreamerCaptureSession::buildVideoPreview()
+ 
+     if (m_viewfinderInterface) {
+         GstElement *bin = gst_bin_new("video-preview-bin");
+-        GstElement *colorspace = gst_element_factory_make("ffmpegcolorspace", "ffmpegcolorspace-preview");
++        GstElement *colorspace = gst_element_factory_make(QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME, "videoconvert-preview");
+         GstElement *capsFilter = gst_element_factory_make("capsfilter", "capsfilter-video-preview");
+         GstElement *preview = m_viewfinderInterface->videoSink();
+ 
+@@ -299,36 +299,25 @@ GstElement *QGstreamerCaptureSession::buildVideoPreview()
+             resolution = m_imageEncodeControl->imageSettings().resolution();
+         }
+ 
+-        if (!resolution.isEmpty() || frameRate > 0.001) {
+-            GstCaps *caps = gst_caps_new_empty();
+-            QStringList structureTypes;
+-            structureTypes << "video/x-raw-yuv" << "video/x-raw-rgb";
+-
+-            foreach(const QString &structureType, structureTypes) {
+-                GstStructure *structure = gst_structure_new(structureType.toLatin1().constData(), NULL);
+-
+-                if (!resolution.isEmpty()) {
+-                    gst_structure_set(structure, "width", G_TYPE_INT, resolution.width(), NULL);
+-                    gst_structure_set(structure, "height", G_TYPE_INT, resolution.height(), NULL);
+-                }
+-
+-                if (frameRate > 0.001) {
+-                    QPair<int,int> rate = m_videoEncodeControl->rateAsRational();
++        GstCaps *caps = QGstUtils::videoFilterCaps();
+ 
+-                    //qDebug() << "frame rate:" << num << denum;
++        if (!resolution.isEmpty()) {
++            gst_caps_set_simple(caps, "width", G_TYPE_INT, resolution.width(), NULL);
++            gst_caps_set_simple(caps, "height", G_TYPE_INT, resolution.height(), NULL);
++        }
++        if (frameRate > 0.001) {
++            QPair<int,int> rate = m_videoEncodeControl->rateAsRational();
+ 
+-                    gst_structure_set(structure, "framerate", GST_TYPE_FRACTION, rate.first, rate.second, NULL);
+-                }
++            //qDebug() << "frame rate:" << num << denum;
+ 
+-                gst_caps_append_structure(caps,structure);
+-            }
++            gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, rate.first, rate.second, NULL);
++        }
+ 
+-            //qDebug() << "set video preview caps filter:" << gst_caps_to_string(caps);
++        //qDebug() << "set video preview caps filter:" << gst_caps_to_string(caps);
+ 
+-            g_object_set(G_OBJECT(capsFilter), "caps", caps, NULL);
++        g_object_set(G_OBJECT(capsFilter), "caps", caps, NULL);
+ 
+-            gst_caps_unref(caps);
+-        }
++        gst_caps_unref(caps);
+ 
+         // add ghostpads
+         GstPad *pad = gst_element_get_static_pad(colorspace, "sink");
+@@ -342,7 +331,7 @@ GstElement *QGstreamerCaptureSession::buildVideoPreview()
+         previewElement = gst_element_factory_make("fakesink", "video-preview");
+ #else
+         GstElement *bin = gst_bin_new("video-preview-bin");
+-        GstElement *colorspace = gst_element_factory_make("ffmpegcolorspace", "ffmpegcolorspace-preview");
++        GstElement *colorspace = gst_element_factory_make(QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME, "videoconvert-preview");
+         GstElement *preview = gst_element_factory_make("ximagesink", "video-preview");
+         gst_bin_add_many(GST_BIN(bin), colorspace, preview,  NULL);
+         gst_element_link(colorspace,preview);
+@@ -360,101 +349,49 @@ GstElement *QGstreamerCaptureSession::buildVideoPreview()
+     return previewElement;
+ }
+ 
+-
+-static gboolean passImageFilter(GstElement *element,
+-                                GstBuffer *buffer,
+-                                void *appdata)
++void QGstreamerCaptureSession::probeCaps(GstCaps *caps)
+ {
+-    Q_UNUSED(element);
+-    Q_UNUSED(buffer);
+-
+-    QGstreamerCaptureSession *session = (QGstreamerCaptureSession *)appdata;
+-    if (session->m_passImage || session->m_passPrerollImage) {
+-        session->m_passImage = false;
+-
+-        if (session->m_passPrerollImage) {
+-            session->m_passPrerollImage = false;
+-            return TRUE;
+-        }
+-        session->m_passPrerollImage = false;
+-
+-        QImage img;
+-
+-        GstCaps *caps = gst_buffer_get_caps(buffer);
+-        if (caps) {
+-            GstStructure *structure = gst_caps_get_structure (caps, 0);
+-            gint width = 0;
+-            gint height = 0;
+-
+-            if (structure &&
+-                gst_structure_get_int(structure, "width", &width) &&
+-                gst_structure_get_int(structure, "height", &height) &&
+-                width > 0 && height > 0) {
+-                    if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-yuv") == 0) {
+-                        guint32 fourcc = 0;
+-                        gst_structure_get_fourcc(structure, "format", &fourcc);
+-
+-                        if (fourcc == GST_MAKE_FOURCC('I','4','2','0')) {
+-                            img = QImage(width/2, height/2, QImage::Format_RGB32);
+-
+-                            const uchar *data = (const uchar *)buffer->data;
++#if GST_CHECK_VERSION(1,0,0)
++    gst_video_info_from_caps(&m_previewInfo, caps);
++#else
++    Q_UNUSED(caps);
++#endif
++}
+ 
+-                            for (int y=0; y<height; y+=2) {
+-                                const uchar *yLine = data + y*width;
+-                                const uchar *uLine = data + width*height + y*width/4;
+-                                const uchar *vLine = data + width*height*5/4 + y*width/4;
++bool QGstreamerCaptureSession::probeBuffer(GstBuffer *buffer)
++{
++    if (m_passPrerollImage) {
++        m_passImage = false;
++        m_passPrerollImage = false;
+ 
+-                                for (int x=0; x<width; x+=2) {
+-                                    const qreal Y = 1.164*(yLine[x]-16);
+-                                    const int U = uLine[x/2]-128;
+-                                    const int V = vLine[x/2]-128;
++        return true;
++    } else  if (!m_passImage) {
++        return false;
++    }
+ 
+-                                    int b = qBound(0, int(Y + 2.018*U), 255);
+-                                    int g = qBound(0, int(Y - 0.813*V - 0.391*U), 255);
+-                                    int r = qBound(0, int(Y + 1.596*V), 255);
++    m_passImage = false;
+ 
+-                                    img.setPixel(x/2,y/2,qRgb(r,g,b));
+-                                }
+-                            }
+-                        }
++#if GST_CHECK_VERSION(1,0,0)
++    QImage img = QGstUtils::bufferToImage(buffer, m_previewInfo);
++#else
++    QImage img = QGstUtils::bufferToImage(buffer);
++#endif
+ 
+-                    } else if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-rgb") == 0) {
+-                        QImage::Format format = QImage::Format_Invalid;
+-                        int bpp = 0;
+-                        gst_structure_get_int(structure, "bpp", &bpp);
+-
+-                        if (bpp == 24)
+-                            format = QImage::Format_RGB888;
+-                        else if (bpp == 32)
+-                            format = QImage::Format_RGB32;
+-
+-                        if (format != QImage::Format_Invalid) {
+-                            img = QImage((const uchar *)buffer->data,
+-                                         width,
+-                                         height,
+-                                         format);
+-                            img.bits(); //detach
+-                        }
+-                    }
+-            }
+-            gst_caps_unref(caps);
+-        }
++    if (img.isNull())
++        return true;
+ 
+-        static QMetaMethod exposedSignal = QMetaMethod::fromSignal(&QGstreamerCaptureSession::imageExposed);
+-        exposedSignal.invoke(session,
+-                             Qt::QueuedConnection,
+-                             Q_ARG(int,session->m_imageRequestId));
++    static QMetaMethod exposedSignal = QMetaMethod::fromSignal(&QGstreamerCaptureSession::imageExposed);
++    exposedSignal.invoke(this,
++                         Qt::QueuedConnection,
++                         Q_ARG(int,m_imageRequestId));
+ 
+-        static QMetaMethod capturedSignal = QMetaMethod::fromSignal(&QGstreamerCaptureSession::imageCaptured);
+-        capturedSignal.invoke(session,
+-                              Qt::QueuedConnection,
+-                              Q_ARG(int,session->m_imageRequestId),
+-                              Q_ARG(QImage,img));
++    static QMetaMethod capturedSignal = QMetaMethod::fromSignal(&QGstreamerCaptureSession::imageCaptured);
++    capturedSignal.invoke(this,
++                          Qt::QueuedConnection,
++                          Q_ARG(int,m_imageRequestId),
++                          Q_ARG(QImage,img));
+ 
+-        return TRUE;
+-    } else {
+-        return FALSE;
+-    }
++    return true;
+ }
+ 
+ static gboolean saveImageFilter(GstElement *element,
+@@ -471,7 +408,15 @@ static gboolean saveImageFilter(GstElement *element,
+     if (!fileName.isEmpty()) {
+         QFile f(fileName);
+         if (f.open(QFile::WriteOnly)) {
+-            f.write((const char *)buffer->data, buffer->size);
++#if GST_CHECK_VERSION(1,0,0)
++            GstMapInfo info;
++            if (gst_buffer_map(buffer, &info, GST_MAP_READ)) {
++                f.write(reinterpret_cast<const char *>(info.data), info.size);
++                gst_buffer_unmap(buffer, &info);
++            }
++#else
++            f.write(reinterpret_cast<const char *>(buffer->data), buffer->size);
++#endif
+             f.close();
+ 
+             static QMetaMethod savedSignal = QMetaMethod::fromSignal(&QGstreamerCaptureSession::imageSaved);
+@@ -489,18 +434,19 @@ GstElement *QGstreamerCaptureSession::buildImageCapture()
+ {
+     GstElement *bin = gst_bin_new("image-capture-bin");
+     GstElement *queue = gst_element_factory_make("queue", "queue-image-capture");
+-    GstElement *colorspace = gst_element_factory_make("ffmpegcolorspace", "ffmpegcolorspace-image-capture");
++    GstElement *colorspace = gst_element_factory_make(QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME, "videoconvert-image-capture");
+     GstElement *encoder = gst_element_factory_make("jpegenc", "image-encoder");
+     GstElement *sink = gst_element_factory_make("fakesink","sink-image-capture");
+ 
+     GstPad *pad = gst_element_get_static_pad(queue, "src");
+     Q_ASSERT(pad);
+-    gst_pad_add_buffer_probe(pad, G_CALLBACK(passImageFilter), this);
++
++    addProbeToPad(pad, false);
++
+     gst_object_unref(GST_OBJECT(pad));
+ 
+     g_object_set(G_OBJECT(sink), "signal-handoffs", TRUE, NULL);
+-    g_signal_connect(G_OBJECT(sink), "handoff",
+-                     G_CALLBACK(saveImageFilter), this);
++    g_signal_connect(G_OBJECT(sink), "handoff", G_CALLBACK(saveImageFilter), this);
+ 
+     gst_bin_add_many(GST_BIN(bin), queue, colorspace, encoder, sink,  NULL);
+     gst_element_link_many(queue, colorspace, encoder, sink, NULL);
+@@ -715,6 +661,8 @@ void QGstreamerCaptureSession::dumpGraph(const QString &fileName)
+     _gst_debug_bin_to_dot_file(GST_BIN(m_pipeline),
+                                GstDebugGraphDetails(/*GST_DEBUG_GRAPH_SHOW_ALL |*/ GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES),
+                                fileName.toLatin1());
++#else
++    Q_UNUSED(fileName);
+ #endif
+ }
+ 
+@@ -877,10 +825,8 @@ void QGstreamerCaptureSession::setState(QGstreamerCaptureSession::State newState
+ 
+ qint64 QGstreamerCaptureSession::duration() const
+ {
+-    GstFormat   format = GST_FORMAT_TIME;
+-    gint64      duration = 0;
+-
+-    if ( m_encodeBin && gst_element_query_position(m_encodeBin, &format, &duration))
++    gint64 duration = 0;
++    if (m_encodeBin && qt_gst_element_query_position(m_encodeBin, GST_FORMAT_TIME, &duration))
+         return duration / 1000000;
+     else
+         return 0;
+@@ -896,50 +842,8 @@ void QGstreamerCaptureSession::setMetaData(const QMap<QByteArray, QVariant> &dat
+     //qDebug() << "QGstreamerCaptureSession::setMetaData" << data;
+     m_metaData = data;
+ 
+-    if (m_encodeBin) {
+-        GstIterator *elements = gst_bin_iterate_all_by_interface(GST_BIN(m_encodeBin), GST_TYPE_TAG_SETTER);
+-        GstElement *element = 0;
+-        while (gst_iterator_next(elements, (void**)&element) == GST_ITERATOR_OK) {
+-            //qDebug() << "found element with tag setter interface:" << gst_element_get_name(element);
+-            QMapIterator<QByteArray, QVariant> it(data);
+-            while (it.hasNext()) {
+-                it.next();
+-                const QString tagName = it.key();
+-                const QVariant tagValue = it.value();
+-
+-
+-                switch(tagValue.type()) {
+-                    case QVariant::String:
+-                        gst_tag_setter_add_tags(GST_TAG_SETTER(element),
+-                            GST_TAG_MERGE_REPLACE_ALL,
+-                            tagName.toUtf8().constData(),
+-                            tagValue.toString().toUtf8().constData(),
+-                            NULL);
+-                        break;
+-                    case QVariant::Int:
+-                    case QVariant::LongLong:
+-                        gst_tag_setter_add_tags(GST_TAG_SETTER(element),
+-                            GST_TAG_MERGE_REPLACE_ALL,
+-                            tagName.toUtf8().constData(),
+-                            tagValue.toInt(),
+-                            NULL);
+-                        break;
+-                    case QVariant::Double:
+-                        gst_tag_setter_add_tags(GST_TAG_SETTER(element),
+-                            GST_TAG_MERGE_REPLACE_ALL,
+-                            tagName.toUtf8().constData(),
+-                            tagValue.toDouble(),
+-                            NULL);
+-                        break;
+-                    default:
+-                        break;
+-                }
+-
+-            }
+-
+-        }
+-        gst_iterator_free(elements);
+-    }
++    if (m_encodeBin)
++        QGstUtils::setMetaData(GST_BIN(m_encodeBin), data);
+ }
+ 
+ bool QGstreamerCaptureSession::processBusMessage(const QGstreamerMessage &message)
+@@ -1058,34 +962,16 @@ void QGstreamerCaptureSession::setVolume(qreal volume)
+ 
+ void QGstreamerCaptureSession::addProbe(QGstreamerAudioProbeControl* probe)
+ {
+-    QMutexLocker locker(&m_audioProbeMutex);
+-
+-    if (m_audioProbes.contains(probe))
+-        return;
+-
+-    m_audioProbes.append(probe);
++    Q_ASSERT(!m_audioProbe);
++    m_audioProbe = probe;
++    addAudioBufferProbe();
+ }
+ 
+ void QGstreamerCaptureSession::removeProbe(QGstreamerAudioProbeControl* probe)
+ {
+-    QMutexLocker locker(&m_audioProbeMutex);
+-    m_audioProbes.removeOne(probe);
+-}
+-
+-gboolean QGstreamerCaptureSession::padAudioBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data)
+-{
+-    Q_UNUSED(pad);
+-
+-    QGstreamerCaptureSession *session = reinterpret_cast<QGstreamerCaptureSession*>(user_data);
+-    QMutexLocker locker(&session->m_audioProbeMutex);
+-
+-    if (session->m_audioProbes.isEmpty())
+-        return TRUE;
+-
+-    foreach (QGstreamerAudioProbeControl* probe, session->m_audioProbes)
+-        probe->bufferProbed(buffer);
+-
+-    return TRUE;
++    Q_ASSERT(m_audioProbe == probe);
++    removeAudioBufferProbe();
++    m_audioProbe = 0;
+ }
+ 
+ GstPad *QGstreamerCaptureSession::getAudioProbePad()
+@@ -1114,26 +1000,25 @@ GstPad *QGstreamerCaptureSession::getAudioProbePad()
+ 
+ void QGstreamerCaptureSession::removeAudioBufferProbe()
+ {
+-    if (m_audioBufferProbeId == -1)
++    if (!m_audioProbe)
+         return;
+ 
+     GstPad *pad = getAudioProbePad();
+     if (pad) {
+-        gst_pad_remove_buffer_probe(pad, m_audioBufferProbeId);
+-        gst_object_unref(G_OBJECT(pad));
++        m_audioProbe->removeProbeFromPad(pad);
++        gst_object_unref(GST_OBJECT(pad));
+     }
+-
+-    m_audioBufferProbeId = -1;
+ }
+ 
+ void QGstreamerCaptureSession::addAudioBufferProbe()
+ {
+-    Q_ASSERT(m_audioBufferProbeId == -1);
++    if (!m_audioProbe)
++        return;
+ 
+     GstPad *pad = getAudioProbePad();
+     if (pad) {
+-        m_audioBufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padAudioBufferProbe), this);
+-        gst_object_unref(G_OBJECT(pad));
++        m_audioProbe->addProbeToPad(pad);
++        gst_object_unref(GST_OBJECT(pad));
+     }
+ }
+ 
+diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h
+index a759f22..ad26327 100644
+--- a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h
++++ b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.h
+@@ -41,8 +41,10 @@
+ #include <QtCore/qurl.h>
+ 
+ #include <gst/gst.h>
++#include <gst/video/video.h>
+ 
+ #include <private/qgstreamerbushelper_p.h>
++#include <private/qgstreamerbufferprobe_p.h>
+ 
+ QT_BEGIN_NAMESPACE
+ 
+@@ -70,7 +72,10 @@ public:
+     virtual QList<QSize> supportedResolutions(qreal frameRate = -1) const = 0;
+ };
+ 
+-class QGstreamerCaptureSession : public QObject, public QGstreamerBusMessageFilter
++class QGstreamerCaptureSession
++        : public QObject
++        , public QGstreamerBusMessageFilter
++        , private QGstreamerBufferProbe
+ {
+     Q_OBJECT
+     Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged)
+@@ -131,7 +136,6 @@ public:
+ 
+     void addProbe(QGstreamerAudioProbeControl* probe);
+     void removeProbe(QGstreamerAudioProbeControl* probe);
+-    static gboolean padAudioBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data);
+ 
+ signals:
+     void stateChanged(QGstreamerCaptureSession::State state);
+@@ -156,6 +160,9 @@ public slots:
+     void setVolume(qreal volume);
+ 
+ private:
++    void probeCaps(GstCaps *caps);
++    bool probeBuffer(GstBuffer *buffer);
++
+     enum PipelineMode { EmptyPipeline, PreviewPipeline, RecordingPipeline, PreviewAndRecordingPipeline };
+ 
+     GstElement *buildEncodeBin();
+@@ -180,9 +187,7 @@ private:
+     QGstreamerCaptureSession::CaptureMode m_captureMode;
+     QMap<QByteArray, QVariant> m_metaData;
+ 
+-    QList<QGstreamerAudioProbeControl*> m_audioProbes;
+-    QMutex m_audioProbeMutex;
+-    int m_audioBufferProbeId;
++    QGstreamerAudioProbeControl *m_audioProbe;
+ 
+     QGstreamerElementFactory *m_audioInputFactory;
+     QGstreamerElementFactory *m_audioPreviewFactory;
+@@ -217,6 +222,10 @@ private:
+ 
+     GstElement *m_encodeBin;
+ 
++#if GST_CHECK_VERSION(1,0,0)
++    GstVideoInfo m_previewInfo;
++#endif
++
+ public:
+     bool m_passImage;
+     bool m_passPrerollImage;
+diff --git a/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp b/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp
+index 2f0d0ee..81b85d7 100644
+--- a/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp
++++ b/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp
+@@ -34,7 +34,7 @@
+ #include "qgstreamervideoencode.h"
+ #include "qgstreamercapturesession.h"
+ #include "qgstreamermediacontainercontrol.h"
+-
++#include <private/qgstutils_p.h>
+ #include <QtCore/qdebug.h>
+ 
+ #include <math.h>
+@@ -147,7 +147,7 @@ GstElement *QGstreamerVideoEncode::createEncoder()
+     GstElement *capsFilter = gst_element_factory_make("capsfilter", "capsfilter-video");
+     gst_bin_add(encoderBin, capsFilter);
+ 
+-    GstElement *colorspace = gst_element_factory_make("ffmpegcolorspace", NULL);
++    GstElement *colorspace = gst_element_factory_make(QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME, NULL);
+     gst_bin_add(encoderBin, colorspace);
+     gst_bin_add(encoderBin, encoderElement);
+ 
+@@ -252,27 +252,22 @@ GstElement *QGstreamerVideoEncode::createEncoder()
+     }
+ 
+     if (!m_videoSettings.resolution().isEmpty() || m_videoSettings.frameRate() > 0.001) {
+-        GstCaps *caps = gst_caps_new_empty();
+-        QStringList structureTypes;
+-        structureTypes << "video/x-raw-yuv" << "video/x-raw-rgb";
+-
+-        foreach(const QString &structureType, structureTypes) {
+-            GstStructure *structure = gst_structure_new(structureType.toLatin1().constData(), NULL);
+-
+-            if (!m_videoSettings.resolution().isEmpty()) {
+-                gst_structure_set(structure, "width", G_TYPE_INT, m_videoSettings.resolution().width(), NULL);
+-                gst_structure_set(structure, "height", G_TYPE_INT, m_videoSettings.resolution().height(), NULL);
+-            }
+-
+-            if (m_videoSettings.frameRate() > 0.001) {
+-                QPair<int,int> rate = rateAsRational();
+-
+-                //qDebug() << "frame rate:" << num << denum;
+-
+-                gst_structure_set(structure, "framerate", GST_TYPE_FRACTION, rate.first, rate.second, NULL);
+-            }
++        GstCaps *caps = QGstUtils::videoFilterCaps();
++
++        if (!m_videoSettings.resolution().isEmpty()) {
++            gst_caps_set_simple(
++                        caps,
++                        "width", G_TYPE_INT, m_videoSettings.resolution().width(),
++                        "height", G_TYPE_INT, m_videoSettings.resolution().height(),
++                        NULL);
++        }
+ 
+-            gst_caps_append_structure(caps,structure);
++        if (m_videoSettings.frameRate() > 0.001) {
++            QPair<int,int> rate = rateAsRational();
++            gst_caps_set_simple(
++                        caps,
++                        "framerate", GST_TYPE_FRACTION, rate.first, rate.second,
++                        NULL);
+         }
+ 
+         //qDebug() << "set video caps filter:" << gst_caps_to_string(caps);
+diff --git a/src/plugins/gstreamer/mediaplayer/mediaplayer.pro b/src/plugins/gstreamer/mediaplayer/mediaplayer.pro
+index 2ca9377..b986fc7 100644
+--- a/src/plugins/gstreamer/mediaplayer/mediaplayer.pro
++++ b/src/plugins/gstreamer/mediaplayer/mediaplayer.pro
+@@ -28,4 +28,3 @@ SOURCES += \
+ 
+ OTHER_FILES += \
+     mediaplayer.json
+-
+diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp
+index fed756a..c1fb64a 100644
+--- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp
++++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp
+@@ -425,7 +425,6 @@ void QGstreamerPlayerControl::setMedia(const QMediaContent &content, QIODevice *
+         m_session->loadFromUri(request);
+ #endif
+ 
+-
+ #if defined(HAVE_GST_APPSRC)
+     if (!request.url().isEmpty() || userStreamValid) {
+ #else
+diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp
+index ce267d7..84805b6 100644
+--- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp
++++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp
+@@ -51,7 +51,11 @@
+ #include <private/qgstreamervideorenderer_p.h>
+ 
+ #if defined(Q_WS_MAEMO_6) && defined(__arm__)
+-#include "qgstreamergltexturerenderer.h"
++#include "private/qgstreamergltexturerenderer.h"
++#endif
++
++#if defined(HAVE_MIR) && defined (__arm__)
++#include "private/qgstreamermirtexturerenderer_p.h"
+ #endif
+ 
+ #include "qgstreamerstreamscontrol.h"
+@@ -66,6 +70,8 @@ QT_BEGIN_NAMESPACE
+ 
+ QGstreamerPlayerService::QGstreamerPlayerService(QObject *parent):
+      QMediaService(parent)
++     , m_audioProbeControl(0)
++     , m_videoProbeControl(0)
+      , m_videoOutput(0)
+      , m_videoRenderer(0)
+      , m_videoWindow(0)
+@@ -82,6 +88,8 @@ QGstreamerPlayerService::QGstreamerPlayerService(QObject *parent):
+ 
+ #if defined(Q_WS_MAEMO_6) && defined(__arm__)
+     m_videoRenderer = new QGstreamerGLTextureRenderer(this);
++#elif defined(HAVE_MIR) && defined (__arm__)
++    m_videoRenderer = new QGstreamerMirTextureRenderer(this, m_session);
+ #else
+     m_videoRenderer = new QGstreamerVideoRenderer(this);
+ #endif
+@@ -115,23 +123,23 @@ QMediaControl *QGstreamerPlayerService::requestControl(const char *name)
+     if (qstrcmp(name, QMediaAvailabilityControl_iid) == 0)
+         return m_availabilityControl;
+ 
+-    if (qstrcmp(name,QMediaVideoProbeControl_iid) == 0) {
+-        if (m_session) {
+-            QGstreamerVideoProbeControl *probe = new QGstreamerVideoProbeControl(this);
++    if (qstrcmp(name, QMediaVideoProbeControl_iid) == 0) {
++        if (!m_videoProbeControl) {
+             increaseVideoRef();
+-            m_session->addProbe(probe);
+-            return probe;
++            m_videoProbeControl = new QGstreamerVideoProbeControl(this);
++            m_session->addProbe(m_videoProbeControl);
+         }
+-        return 0;
++        m_videoProbeControl->ref.ref();
++        return m_videoProbeControl;
+     }
+ 
+-    if (qstrcmp(name,QMediaAudioProbeControl_iid) == 0) {
+-        if (m_session) {
+-            QGstreamerAudioProbeControl *probe = new QGstreamerAudioProbeControl(this);
+-            m_session->addProbe(probe);
+-            return probe;
++    if (qstrcmp(name, QMediaAudioProbeControl_iid) == 0) {
++        if (!m_audioProbeControl) {
++            m_audioProbeControl = new QGstreamerAudioProbeControl(this);
++            m_session->addProbe(m_audioProbeControl);
+         }
+-        return 0;
++        m_audioProbeControl->ref.ref();
++        return m_audioProbeControl;
+     }
+ 
+     if (!m_videoOutput) {
+@@ -156,28 +164,21 @@ QMediaControl *QGstreamerPlayerService::requestControl(const char *name)
+ 
+ void QGstreamerPlayerService::releaseControl(QMediaControl *control)
+ {
+-    if (control == m_videoOutput) {
++    if (!control) {
++        return;
++    } else if (control == m_videoOutput) {
+         m_videoOutput = 0;
+         m_control->setVideoOutput(0);
+         decreaseVideoRef();
+-    }
+-
+-    QGstreamerVideoProbeControl* videoProbe = qobject_cast<QGstreamerVideoProbeControl*>(control);
+-    if (videoProbe) {
+-        if (m_session) {
+-            m_session->removeProbe(videoProbe);
+-            decreaseVideoRef();
+-        }
+-        delete videoProbe;
+-        return;
+-    }
+-
+-    QGstreamerAudioProbeControl* audioProbe = qobject_cast<QGstreamerAudioProbeControl*>(control);
+-    if (audioProbe) {
+-        if (m_session)
+-            m_session->removeProbe(audioProbe);
+-        delete audioProbe;
+-        return;
++    } else if (control == m_videoProbeControl && !m_videoProbeControl->ref.deref()) {
++        m_session->removeProbe(m_videoProbeControl);
++        delete m_videoProbeControl;
++        m_videoProbeControl = 0;
++        decreaseVideoRef();
++    } else if (control == m_audioProbeControl && !m_audioProbeControl->ref.deref()) {
++        m_session->removeProbe(m_audioProbeControl);
++        delete m_audioProbeControl;
++        m_audioProbeControl = 0;
+     }
+ }
+ 
+diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.h
+index f3081e9..22be262 100644
+--- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.h
++++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.h
+@@ -52,6 +52,8 @@ class QGstreamerStreamsControl;
+ class QGstreamerVideoRenderer;
+ class QGstreamerVideoWidgetControl;
+ class QGStreamerAvailabilityControl;
++class QGstreamerAudioProbeControl;
++class QGstreamerVideoProbeControl;
+ 
+ class QGstreamerPlayerService : public QMediaService
+ {
+@@ -70,6 +72,9 @@ private:
+     QGstreamerStreamsControl *m_streamsControl;
+     QGStreamerAvailabilityControl *m_availabilityControl;
+ 
++    QGstreamerAudioProbeControl *m_audioProbeControl;
++    QGstreamerVideoProbeControl *m_videoProbeControl;
++
+     QMediaControl *m_videoOutput;
+     QMediaControl *m_videoRenderer;
+     QMediaControl *m_videoWindow;
+diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp
+index 7d20b6d..f1fd421 100644
+--- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp
++++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp
+@@ -81,89 +81,15 @@ QMultimedia::SupportEstimate QGstreamerPlayerServicePlugin::hasSupport(const QSt
+     return QGstUtils::hasSupport(mimeType, codecs, m_supportedMimeTypeSet);
+ }
+ 
+-void QGstreamerPlayerServicePlugin::updateSupportedMimeTypes() const
++static bool isDecoderOrDemuxer(GstElementFactory *factory)
+ {
+-    //enumerate supported mime types
+-    gst_init(NULL, NULL);
+-
+-    GList *plugins, *orig_plugins;
+-    orig_plugins = plugins = gst_default_registry_get_plugin_list ();
+-
+-    while (plugins) {
+-        GList *features, *orig_features;
+-
+-        GstPlugin *plugin = (GstPlugin *) (plugins->data);
+-        plugins = g_list_next (plugins);
+-
+-        if (plugin->flags & (1<<1)) //GST_PLUGIN_FLAG_BLACKLISTED
+-            continue;
+-
+-        orig_features = features = gst_registry_get_feature_list_by_plugin(gst_registry_get_default (),
+-                                                                        plugin->desc.name);
+-        while (features) {
+-            if (!G_UNLIKELY(features->data == NULL)) {
+-                GstPluginFeature *feature = GST_PLUGIN_FEATURE(features->data);
+-                if (GST_IS_ELEMENT_FACTORY (feature)) {
+-                    GstElementFactory *factory = GST_ELEMENT_FACTORY(gst_plugin_feature_load(feature));
+-                    if (factory
+-                       && factory->numpadtemplates > 0
+-                       && (qstrcmp(factory->details.klass, "Codec/Decoder/Audio") == 0
+-                          || qstrcmp(factory->details.klass, "Codec/Decoder/Video") == 0
+-                          || qstrcmp(factory->details.klass, "Codec/Demux") == 0 )) {
+-                        const GList *pads = factory->staticpadtemplates;
+-                        while (pads) {
+-                            GstStaticPadTemplate *padtemplate = (GstStaticPadTemplate*)(pads->data);
+-                            pads = g_list_next (pads);
+-                            if (padtemplate->direction != GST_PAD_SINK)
+-                                continue;
+-                            if (padtemplate->static_caps.string) {
+-                                GstCaps *caps = gst_static_caps_get(&padtemplate->static_caps);
+-                                if (!gst_caps_is_any (caps) && ! gst_caps_is_empty (caps)) {
+-                                    for (guint i = 0; i < gst_caps_get_size(caps); i++) {
+-                                        GstStructure *structure = gst_caps_get_structure(caps, i);
+-                                        QString nameLowcase = QString(gst_structure_get_name (structure)).toLower();
+-
+-                                        m_supportedMimeTypeSet.insert(nameLowcase);
+-                                        if (nameLowcase.contains("mpeg")) {
+-                                            //Because mpeg version number is only included in the detail
+-                                            //description,  it is necessary to manually extract this information
+-                                            //in order to match the mime type of mpeg4.
+-                                            const GValue *value = gst_structure_get_value(structure, "mpegversion");
+-                                            if (value) {
+-                                                gchar *str = gst_value_serialize (value);
+-                                                QString versions(str);
+-                                                QStringList elements = versions.split(QRegExp("\\D+"), QString::SkipEmptyParts);
+-                                                foreach (const QString &e, elements)
+-                                                    m_supportedMimeTypeSet.insert(nameLowcase + e);
+-                                                g_free (str);
+-                                            }
+-                                        }
+-                                    }
+-                                }
+-                            }
+-                        }
+-                        gst_object_unref (factory);
+-                    }
+-                } else if (GST_IS_TYPE_FIND_FACTORY(feature)) {
+-                    QString name(gst_plugin_feature_get_name(feature));
+-                    if (name.contains('/')) //filter out any string without '/' which is obviously not a mime type
+-                        m_supportedMimeTypeSet.insert(name.toLower());
+-                }
+-            }
+-            features = g_list_next (features);
+-        }
+-        gst_plugin_feature_list_free (orig_features);
+-    }
+-    gst_plugin_list_free (orig_plugins);
++    return gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_DEMUXER)
++                || gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_DECODER);
++}
+ 
+-#if defined QT_SUPPORTEDMIMETYPES_DEBUG
+-    QStringList list = m_supportedMimeTypeSet.toList();
+-    list.sort();
+-    if (qgetenv("QT_DEBUG_PLUGINS").toInt() > 0) {
+-        foreach (const QString &type, list)
+-            qDebug() << type;
+-    }
+-#endif
++void QGstreamerPlayerServicePlugin::updateSupportedMimeTypes() const
++{
++     m_supportedMimeTypeSet = QGstUtils::supportedMimeTypes(isDecoderOrDemuxer);
+ }
+ 
+ QStringList QGstreamerPlayerServicePlugin::supportedMimeTypes() const
+diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
+index 15924a6..b5c354d 100644
+--- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
++++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
+@@ -37,7 +37,9 @@
+ #include <private/qgstreameraudioprobecontrol_p.h>
+ #include <private/qgstreamervideoprobecontrol_p.h>
+ #include <private/qgstreamervideorendererinterface_p.h>
++#if !GST_CHECK_VERSION(1,0,0)
+ #include <private/gstvideoconnector_p.h>
++#endif
+ #include <private/qgstutils_p.h>
+ #include <private/playlistfileparser_p.h>
+ #include <private/qgstutils_p.h>
+@@ -85,6 +87,7 @@ typedef enum {
+     GST_PLAY_FLAG_BUFFERING     = 0x000000100
+ } GstPlayFlags;
+ 
++#if !GST_CHECK_VERSION(1,0,0)
+ #define DEFAULT_RAW_CAPS \
+     "video/x-raw-yuv; " \
+     "video/x-raw-rgb; " \
+@@ -97,7 +100,9 @@ typedef enum {
+     "text/x-pango-markup; " \
+     "video/x-dvd-subpicture; " \
+     "subpicture/x-pgs"
++
+ static GstStaticCaps static_RawCaps = GST_STATIC_CAPS(DEFAULT_RAW_CAPS);
++#endif
+ 
+ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
+     :QObject(parent),
+@@ -105,7 +110,9 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
+      m_pendingState(QMediaPlayer::StoppedState),
+      m_busHelper(0),
+      m_playbin(0),
++#if !GST_CHECK_VERSION(1,0,0)
+      m_usingColorspaceElement(false),
++#endif
+      m_videoSink(0),
+      m_pendingVideoSink(0),
+      m_nullVideoSink(0),
+@@ -117,8 +124,8 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
+ #if defined(HAVE_GST_APPSRC)
+      m_appSrc(0),
+ #endif
+-     m_videoBufferProbeId(-1),
+-     m_audioBufferProbeId(-1),
++     m_videoProbe(0),
++     m_audioProbe(0),
+      m_volume(100),
+      m_playbackRate(1.0),
+      m_muted(false),
+@@ -138,8 +145,7 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
+     Q_ASSERT(result == TRUE);
+     Q_UNUSED(result);
+ 
+-    m_playbin = gst_element_factory_make("playbin2", NULL);
+-
++    m_playbin = gst_element_factory_make(QT_GSTREAMER_PLAYBIN_ELEMENT_NAME, NULL);
+     if (m_playbin) {
+         //GST_PLAY_FLAG_NATIVE_VIDEO omits configuration of ffmpegcolorspace and videoscale,
+         //since those elements are included in the video output bin when necessary.
+@@ -147,13 +153,14 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
+         int flags = GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_AUDIO |
+                     GST_PLAY_FLAG_NATIVE_VIDEO | GST_PLAY_FLAG_NATIVE_AUDIO;
+ #else
+-        int flags = 0;
+-        g_object_get(G_OBJECT(m_playbin), "flags", &flags, NULL);
++        int flags = GST_PLAY_FLAG_VIDEO | GST_PLAY_FLAG_AUDIO;
+         QByteArray envFlags = qgetenv("QT_GSTREAMER_PLAYBIN_FLAGS");
+         if (!envFlags.isEmpty()) {
+             flags |= envFlags.toInt();
++#if !GST_CHECK_VERSION(1,0,0)
+         } else {
+             flags |= GST_PLAY_FLAG_NATIVE_VIDEO;
++#endif
+         }
+ #endif
+         g_object_set(G_OBJECT(m_playbin), "flags", flags, NULL);
+@@ -185,12 +192,16 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
+         }
+     }
+ 
++#if GST_CHECK_VERSION(1,0,0)
++    m_videoIdentity = gst_element_factory_make("identity", NULL); // floating ref
++#else
+     m_videoIdentity = GST_ELEMENT(g_object_new(gst_video_connector_get_type(), 0)); // floating ref
+     g_signal_connect(G_OBJECT(m_videoIdentity), "connection-failed", G_CALLBACK(insertColorSpaceElement), (gpointer)this);
++    m_colorSpace = gst_element_factory_make(QT_GSTREAMER_COLORCONVERSION_ELEMENT_NAME, "ffmpegcolorspace-vo");
+ 
+-    m_colorSpace = gst_element_factory_make("ffmpegcolorspace", "ffmpegcolorspace-vo");
+     // might not get a parent, take ownership to avoid leak
+     qt_gst_object_ref_sink(GST_OBJECT(m_colorSpace));
++#endif
+ 
+     m_nullVideoSink = gst_element_factory_make("fakesink", NULL);
+     g_object_set(G_OBJECT(m_nullVideoSink), "sync", true, NULL);
+@@ -206,7 +217,7 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
+ 
+     // add ghostpads
+     GstPad *pad = gst_element_get_static_pad(m_videoIdentity,"sink");
+-    gst_element_add_pad(GST_ELEMENT(m_videoOutputBin), gst_ghost_pad_new("videosink", pad));
++    gst_element_add_pad(GST_ELEMENT(m_videoOutputBin), gst_ghost_pad_new("sink", pad));
+     gst_object_unref(GST_OBJECT(pad));
+ 
+     if (m_playbin != 0) {
+@@ -244,7 +255,9 @@ QGstreamerPlayerSession::~QGstreamerPlayerSession()
+         delete m_busHelper;
+         gst_object_unref(GST_OBJECT(m_bus));
+         gst_object_unref(GST_OBJECT(m_playbin));
++#if !GST_CHECK_VERSION(1,0,0)
+         gst_object_unref(GST_OBJECT(m_colorSpace));
++#endif
+         gst_object_unref(GST_OBJECT(m_nullVideoSink));
+         gst_object_unref(GST_OBJECT(m_videoOutputBin));
+     }
+@@ -339,12 +352,10 @@ qint64 QGstreamerPlayerSession::duration() const
+ 
+ qint64 QGstreamerPlayerSession::position() const
+ {
+-    GstFormat   format = GST_FORMAT_TIME;
+     gint64      position = 0;
+ 
+-    if ( m_playbin && gst_element_query_position(m_playbin, &format, &position))
++    if (m_playbin && qt_gst_element_query_position(m_playbin, GST_FORMAT_TIME, &position))
+         m_lastPosition = position / 1000000;
+-
+     return m_lastPosition;
+ }
+ 
+@@ -474,17 +485,26 @@ bool QGstreamerPlayerSession::isAudioAvailable() const
+     return m_audioAvailable;
+ }
+ 
++#if GST_CHECK_VERSION(1,0,0)
++static GstPadProbeReturn block_pad_cb(GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
++#else
+ static void block_pad_cb(GstPad *pad, gboolean blocked, gpointer user_data)
++#endif
+ {
+     Q_UNUSED(pad);
++#if GST_CHECK_VERSION(1,0,0)
++    Q_UNUSED(info);
++    Q_UNUSED(user_data);
++    return GST_PAD_PROBE_OK;
++#else
+ #ifdef DEBUG_PLAYBIN
+     qDebug() << "block_pad_cb, blocked:" << blocked;
+ #endif
+-
+     if (blocked && user_data) {
+         QGstreamerPlayerSession *session = reinterpret_cast<QGstreamerPlayerSession*>(user_data);
+         QMetaObject::invokeMethod(session, "finishVideoOutputChange", Qt::QueuedConnection);
+     }
++#endif
+ }
+ 
+ void QGstreamerPlayerSession::updateVideoRenderer()
+@@ -529,7 +549,7 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
+     m_renderer = renderer;
+ 
+ #ifdef DEBUG_VO_BIN_DUMP
+-    _gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_playbin),
++    gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_playbin),
+                                   GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL /* GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES*/),
+                                   "playbin_set");
+ #endif
+@@ -570,12 +590,14 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
+         gst_element_set_state(m_videoSink, GST_STATE_NULL);
+         gst_element_set_state(m_playbin, GST_STATE_NULL);
+ 
++#if !GST_CHECK_VERSION(1,0,0)
+         if (m_usingColorspaceElement) {
+             gst_element_unlink(m_colorSpace, m_videoSink);
+             gst_bin_remove(GST_BIN(m_videoOutputBin), m_colorSpace);
+         } else {
+             gst_element_unlink(m_videoIdentity, m_videoSink);
+         }
++#endif
+ 
+         removeVideoBufferProbe();
+ 
+@@ -585,8 +607,9 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
+ 
+         gst_bin_add(GST_BIN(m_videoOutputBin), m_videoSink);
+ 
+-        m_usingColorspaceElement = false;
+         bool linked = gst_element_link(m_videoIdentity, m_videoSink);
++#if !GST_CHECK_VERSION(1,0,0)
++        m_usingColorspaceElement = false;
+         if (!linked) {
+             m_usingColorspaceElement = true;
+ #ifdef DEBUG_PLAYBIN
+@@ -595,6 +618,10 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
+             gst_bin_add(GST_BIN(m_videoOutputBin), m_colorSpace);
+             linked = gst_element_link_many(m_videoIdentity, m_colorSpace, m_videoSink, NULL);
+         }
++#endif
++
++        if (!linked)
++            qWarning() << "Linking video output element failed";
+ 
+         if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "show-preroll-frame") != 0) {
+             gboolean value = m_displayPrerolledFrame;
+@@ -633,7 +660,11 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
+ 
+         //block pads, async to avoid locking in paused state
+         GstPad *srcPad = gst_element_get_static_pad(m_videoIdentity, "src");
++#if GST_CHECK_VERSION(1,0,0)
++        this->pad_probe_id = gst_pad_add_probe(srcPad, (GstPadProbeType)(GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BLOCKING), block_pad_cb, this, NULL);
++#else
+         gst_pad_set_blocked_async(srcPad, true, &block_pad_cb, this);
++#endif
+         gst_object_unref(GST_OBJECT(srcPad));
+ 
+         //Unpause the sink to avoid waiting until the buffer is processed
+@@ -671,16 +702,22 @@ void QGstreamerPlayerSession::finishVideoOutputChange()
+     }
+ 
+     if (m_pendingVideoSink == m_videoSink) {
++        qDebug() << "Abort, no change";
+         //video output was change back to the current one,
+         //no need to torment the pipeline, just unblock the pad
+         if (gst_pad_is_blocked(srcPad))
++#if GST_CHECK_VERSION(1,0,0)
++            gst_pad_remove_probe(srcPad, this->pad_probe_id);
++#else
+             gst_pad_set_blocked_async(srcPad, false, &block_pad_cb, 0);
++#endif
+ 
+         m_pendingVideoSink = 0;
+         gst_object_unref(GST_OBJECT(srcPad));
+         return;
+     }
+ 
++#if !GST_CHECK_VERSION(1,0,0)
+     if (m_usingColorspaceElement) {
+         gst_element_set_state(m_colorSpace, GST_STATE_NULL);
+         gst_element_set_state(m_videoSink, GST_STATE_NULL);
+@@ -688,6 +725,9 @@ void QGstreamerPlayerSession::finishVideoOutputChange()
+         gst_element_unlink(m_colorSpace, m_videoSink);
+         gst_bin_remove(GST_BIN(m_videoOutputBin), m_colorSpace);
+     } else {
++#else
++    {
++#endif
+         gst_element_set_state(m_videoSink, GST_STATE_NULL);
+         gst_element_unlink(m_videoIdentity, m_videoSink);
+     }
+@@ -703,8 +743,9 @@ void QGstreamerPlayerSession::finishVideoOutputChange()
+ 
+     addVideoBufferProbe();
+ 
+-    m_usingColorspaceElement = false;
+     bool linked = gst_element_link(m_videoIdentity, m_videoSink);
++#if !GST_CHECK_VERSION(1,0,0)
++    m_usingColorspaceElement = false;
+     if (!linked) {
+         m_usingColorspaceElement = true;
+ #ifdef DEBUG_PLAYBIN
+@@ -713,6 +754,7 @@ void QGstreamerPlayerSession::finishVideoOutputChange()
+         gst_bin_add(GST_BIN(m_videoOutputBin), m_colorSpace);
+         linked = gst_element_link_many(m_videoIdentity, m_colorSpace, m_videoSink, NULL);
+     }
++#endif
+ 
+     if (!linked)
+         qWarning() << "Linking video output element failed";
+@@ -720,6 +762,8 @@ void QGstreamerPlayerSession::finishVideoOutputChange()
+ #ifdef DEBUG_PLAYBIN
+     qDebug() << "notify the video connector it has to emit a new segment message...";
+ #endif
++
++#if !GST_CHECK_VERSION(1,0,0)
+     //it's necessary to send a new segment event just before
+     //the first buffer pushed to the new sink
+     g_signal_emit_by_name(m_videoIdentity,
+@@ -727,7 +771,7 @@ void QGstreamerPlayerSession::finishVideoOutputChange()
+                           true //emit connection-failed signal
+                                //to have a chance to insert colorspace element
+                           );
+-
++#endif
+ 
+     GstState state = GST_STATE_VOID_PENDING;
+ 
+@@ -743,8 +787,10 @@ void QGstreamerPlayerSession::finishVideoOutputChange()
+         break;
+     }
+ 
++#if !GST_CHECK_VERSION(1,0,0)
+     if (m_usingColorspaceElement)
+         gst_element_set_state(m_colorSpace, state);
++#endif
+ 
+     gst_element_set_state(m_videoSink, state);
+ 
+@@ -760,16 +806,23 @@ void QGstreamerPlayerSession::finishVideoOutputChange()
+ 
+     //don't have to wait here, it will unblock eventually
+     if (gst_pad_is_blocked(srcPad))
+-        gst_pad_set_blocked_async(srcPad, false, &block_pad_cb, 0);
++#if GST_CHECK_VERSION(1,0,0)
++            gst_pad_remove_probe(srcPad, this->pad_probe_id);
++#else
++            gst_pad_set_blocked_async(srcPad, false, &block_pad_cb, 0);
++#endif
++
+     gst_object_unref(GST_OBJECT(srcPad));
+ 
+ #ifdef DEBUG_VO_BIN_DUMP
+-    _gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_playbin),
+-                                  GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL /* GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES*/),
++    gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_playbin),
++                                  GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL /* | GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES */),
+                                   "playbin_finish");
+ #endif
+ }
+ 
++#if !GST_CHECK_VERSION(1,0,0)
++
+ void QGstreamerPlayerSession::insertColorSpaceElement(GstElement *element, gpointer data)
+ {
+ #ifdef DEBUG_PLAYBIN
+@@ -814,6 +867,7 @@ void QGstreamerPlayerSession::insertColorSpaceElement(GstElement *element, gpoin
+     gst_element_set_state(session->m_colorSpace, state);
+ }
+ 
++#endif
+ 
+ bool QGstreamerPlayerSession::isVideoAvailable() const
+ {
+@@ -830,6 +884,7 @@ bool QGstreamerPlayerSession::play()
+ #ifdef DEBUG_PLAYBIN
+     qDebug() << Q_FUNC_INFO;
+ #endif
++
+     m_everPlayed = false;
+     if (m_playbin) {
+         m_pendingState = QMediaPlayer::PlayingState;
+@@ -1161,21 +1216,20 @@ bool QGstreamerPlayerSession::processBusMessage(const QGstreamerMessage &message
+             case GST_MESSAGE_SEGMENT_DONE:
+                 break;
+             case GST_MESSAGE_LATENCY:
+-#if (GST_VERSION_MAJOR >= 0) &&  (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 13)
++#if GST_CHECK_VERSION(0,10,13)
+             case GST_MESSAGE_ASYNC_START:
+                 break;
+             case GST_MESSAGE_ASYNC_DONE:
+             {
+-                GstFormat   format = GST_FORMAT_TIME;
+                 gint64      position = 0;
+-                if (gst_element_query_position(m_playbin, &format, &position)) {
++                if (qt_gst_element_query_position(m_playbin, GST_FORMAT_TIME, &position)) {
+                     position /= 1000000;
+                     m_lastPosition = position;
+                     emit positionChanged(position);
+                 }
+                 break;
+             }
+-#if GST_VERSION_MICRO >= 23
++#if GST_CHECK_VERSION(0,10,23)
+             case GST_MESSAGE_REQUEST_STATE:
+ #endif
+ #endif
+@@ -1327,8 +1381,11 @@ void QGstreamerPlayerSession::getStreamsInfo()
+         default:
+             break;
+         }
+-
++#if GST_CHECK_VERSION(1,0,0)
++        if (tags && GST_IS_TAG_LIST(tags)) {
++#else
+         if (tags && gst_is_tag_list(tags)) {
++#endif
+             gchar *languageCode = 0;
+             if (gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &languageCode))
+                 streamProperties[QMediaMetaData::Language] = QString::fromUtf8(languageCode);
+@@ -1365,9 +1422,8 @@ void QGstreamerPlayerSession::updateVideoResolutionTag()
+ #endif
+     QSize size;
+     QSize aspectRatio;
+-
+     GstPad *pad = gst_element_get_static_pad(m_videoIdentity, "src");
+-    GstCaps *caps = gst_pad_get_negotiated_caps(pad);
++    GstCaps *caps = qt_gst_pad_get_current_caps(pad);
+ 
+     if (caps) {
+         const GstStructure *structure = gst_caps_get_structure(caps, 0);
+@@ -1407,11 +1463,10 @@ void QGstreamerPlayerSession::updateVideoResolutionTag()
+ 
+ void QGstreamerPlayerSession::updateDuration()
+ {
+-    GstFormat format = GST_FORMAT_TIME;
+     gint64 gstDuration = 0;
+     int duration = -1;
+ 
+-    if (m_playbin && gst_element_query_duration(m_playbin, &format, &gstDuration))
++    if (m_playbin && qt_gst_element_query_duration(m_playbin, GST_FORMAT_TIME, &gstDuration))
+         duration = gstDuration / 1000000;
+ 
+     if (m_duration != duration) {
+@@ -1467,7 +1522,7 @@ void QGstreamerPlayerSession::playbinNotifySource(GObject *o, GParamSpec *p, gpo
+ 
+     // The rest
+     if (g_object_class_find_property(G_OBJECT_GET_CLASS(source), "extra-headers") != 0) {
+-        GstStructure *extras = gst_structure_empty_new("extras");
++        GstStructure *extras = qt_gst_structure_new_empty("extras");
+ 
+         foreach (const QByteArray &rawHeader, self->m_request.rawHeaderList()) {
+             if (rawHeader == userAgentString) // Filter User-Agent
+@@ -1528,7 +1583,8 @@ void QGstreamerPlayerSession::playbinNotifySource(GObject *o, GParamSpec *p, gpo
+         qDebug() << "Current source is a non-live source";
+ #endif
+ 
+-    g_object_set(G_OBJECT(self->m_videoSink), "sync", !self->m_isLiveSource, NULL);
++    if (self->m_videoSink)
++        g_object_set(G_OBJECT(self->m_videoSink), "sync", !self->m_isLiveSource, NULL);
+ 
+     gst_object_unref(source);
+ }
+@@ -1623,7 +1679,11 @@ GstAutoplugSelectResult QGstreamerPlayerSession::handleAutoplugSelect(GstBin *bi
+     const gchar *factoryName = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
+     if (g_str_has_prefix(factoryName, "vaapi")) {
+         GstPad *sinkPad = gst_element_get_static_pad(session->m_videoSink, "sink");
++#if GST_CHECK_VERSION(1,0,0)
++        GstCaps *sinkCaps = gst_pad_query_caps(sinkPad, NULL);
++#else
+         GstCaps *sinkCaps = gst_pad_get_caps(sinkPad);
++#endif
+ 
+ #if (GST_VERSION_MAJOR == 0) && ((GST_VERSION_MINOR < 10) || (GST_VERSION_MICRO < 33))
+         if (!factory_can_src_any_caps(factory, sinkCaps))
+@@ -1652,8 +1712,10 @@ void QGstreamerPlayerSession::handleElementAdded(GstBin *bin, GstElement *elemen
+         // Disable on-disk buffering.
+         g_object_set(G_OBJECT(element), "temp-template", NULL, NULL);
+     } else if (g_str_has_prefix(elementName, "uridecodebin") ||
+-               g_str_has_prefix(elementName, "decodebin2")) {
+-
++#if GST_CHECK_VERSION(1,0,0)
++        g_str_has_prefix(elementName, "decodebin")) {
++#else
++        g_str_has_prefix(elementName, "decodebin2")) {
+         if (g_str_has_prefix(elementName, "uridecodebin")) {
+             // Add video/x-surface (VAAPI) to default raw formats
+             g_object_set(G_OBJECT(element), "caps", gst_static_caps_get(&static_RawCaps), NULL);
+@@ -1661,7 +1723,7 @@ void QGstreamerPlayerSession::handleElementAdded(GstBin *bin, GstElement *elemen
+             // video sink doesn't support it
+             g_signal_connect(element, "autoplug-select", G_CALLBACK(handleAutoplugSelect), session);
+         }
+-
++#endif
+         //listen for queue2 element added to uridecodebin/decodebin2 as well.
+         //Don't touch other bins since they may have unrelated queues
+         g_signal_connect(element, "element-added",
+@@ -1711,68 +1773,30 @@ void QGstreamerPlayerSession::showPrerollFrames(bool enabled)
+ 
+ void QGstreamerPlayerSession::addProbe(QGstreamerVideoProbeControl* probe)
+ {
+-    QMutexLocker locker(&m_videoProbeMutex);
+-
+-    if (m_videoProbes.contains(probe))
+-        return;
+-
+-    m_videoProbes.append(probe);
++    Q_ASSERT(!m_videoProbe);
++    m_videoProbe = probe;
++    addVideoBufferProbe();
+ }
+ 
+ void QGstreamerPlayerSession::removeProbe(QGstreamerVideoProbeControl* probe)
+ {
+-    QMutexLocker locker(&m_videoProbeMutex);
+-    m_videoProbes.removeOne(probe);
+-    // Do not emit flush signal in this case.
+-    // Assume user releases any outstanding references to video frames.
+-}
+-
+-gboolean QGstreamerPlayerSession::padVideoBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data)
+-{
+-    Q_UNUSED(pad);
+-
+-    QGstreamerPlayerSession *session = reinterpret_cast<QGstreamerPlayerSession*>(user_data);
+-    QMutexLocker locker(&session->m_videoProbeMutex);
+-
+-    if (session->m_videoProbes.isEmpty())
+-        return TRUE;
+-
+-    foreach (QGstreamerVideoProbeControl* probe, session->m_videoProbes)
+-        probe->bufferProbed(buffer);
+-
+-    return TRUE;
++    Q_ASSERT(m_videoProbe == probe);
++    removeVideoBufferProbe();
++    m_videoProbe = 0;
+ }
+ 
+ void QGstreamerPlayerSession::addProbe(QGstreamerAudioProbeControl* probe)
+ {
+-    QMutexLocker locker(&m_audioProbeMutex);
+-
+-    if (m_audioProbes.contains(probe))
+-        return;
+-
+-    m_audioProbes.append(probe);
++    Q_ASSERT(!m_audioProbe);
++    m_audioProbe = probe;
++    addAudioBufferProbe();
+ }
+ 
+ void QGstreamerPlayerSession::removeProbe(QGstreamerAudioProbeControl* probe)
+ {
+-    QMutexLocker locker(&m_audioProbeMutex);
+-    m_audioProbes.removeOne(probe);
+-}
+-
+-gboolean QGstreamerPlayerSession::padAudioBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data)
+-{
+-    Q_UNUSED(pad);
+-
+-    QGstreamerPlayerSession *session = reinterpret_cast<QGstreamerPlayerSession*>(user_data);
+-    QMutexLocker locker(&session->m_audioProbeMutex);
+-
+-    if (session->m_audioProbes.isEmpty())
+-        return TRUE;
+-
+-    foreach (QGstreamerAudioProbeControl* probe, session->m_audioProbes)
+-        probe->bufferProbed(buffer);
+-
+-    return TRUE;
++    Q_ASSERT(m_audioProbe == probe);
++    removeAudioBufferProbe();
++    m_audioProbe = 0;
+ }
+ 
+ // This function is similar to stop(),
+@@ -1797,80 +1821,62 @@ void QGstreamerPlayerSession::endOfMediaReset()
+ 
+ void QGstreamerPlayerSession::removeVideoBufferProbe()
+ {
+-    if (m_videoBufferProbeId == -1)
++    if (!m_videoProbe)
+         return;
+ 
+-    if (!m_videoSink) {
+-        m_videoBufferProbeId = -1;
+-        return;
+-    }
+-
+     GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink");
+     if (pad) {
+-        gst_pad_remove_buffer_probe(pad, m_videoBufferProbeId);
++        m_videoProbe->removeProbeFromPad(pad);
+         gst_object_unref(GST_OBJECT(pad));
+     }
+-
+-    m_videoBufferProbeId = -1;
+ }
+ 
+ void QGstreamerPlayerSession::addVideoBufferProbe()
+ {
+-    Q_ASSERT(m_videoBufferProbeId == -1);
+-    if (!m_videoSink)
++    if (!m_videoProbe)
+         return;
+ 
+     GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink");
+     if (pad) {
+-        m_videoBufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padVideoBufferProbe), this);
++        m_videoProbe->addProbeToPad(pad);
+         gst_object_unref(GST_OBJECT(pad));
+     }
+ }
+ 
+ void QGstreamerPlayerSession::removeAudioBufferProbe()
+ {
+-    if (m_audioBufferProbeId == -1)
+-        return;
+-
+-    if (!m_audioSink) {
+-        m_audioBufferProbeId = -1;
++    if (!m_audioProbe)
+         return;
+-    }
+ 
+     GstPad *pad = gst_element_get_static_pad(m_audioSink, "sink");
+     if (pad) {
+-        gst_pad_remove_buffer_probe(pad, m_audioBufferProbeId);
++        m_audioProbe->removeProbeFromPad(pad);
+         gst_object_unref(GST_OBJECT(pad));
+     }
+-
+-    m_audioBufferProbeId = -1;
+ }
+ 
+ void QGstreamerPlayerSession::addAudioBufferProbe()
+ {
+-    Q_ASSERT(m_audioBufferProbeId == -1);
+-    if (!m_audioSink)
++    if (!m_audioProbe)
+         return;
+ 
+     GstPad *pad = gst_element_get_static_pad(m_audioSink, "sink");
+     if (pad) {
+-        m_audioBufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padAudioBufferProbe), this);
++        m_audioProbe->addProbeToPad(pad);
+         gst_object_unref(GST_OBJECT(pad));
+     }
+ }
+ 
+ void QGstreamerPlayerSession::flushVideoProbes()
+ {
+-    QMutexLocker locker(&m_videoProbeMutex);
+-    foreach (QGstreamerVideoProbeControl* probe, m_videoProbes)
+-        probe->startFlushing();
++    if (m_videoProbe)
++        m_videoProbe->startFlushing();
+ }
+ 
+ void QGstreamerPlayerSession::resumeVideoProbes()
+ {
+-    QMutexLocker locker(&m_videoProbeMutex);
+-    foreach (QGstreamerVideoProbeControl* probe, m_videoProbes)
+-        probe->stopFlushing();
++    if (m_videoProbe)
++        m_videoProbe->stopFlushing();
+ }
+ 
+ void QGstreamerPlayerSession::playlistTypeFindFunction(GstTypeFind *find, gpointer userData)
+@@ -1878,7 +1884,11 @@ void QGstreamerPlayerSession::playlistTypeFindFunction(GstTypeFind *find, gpoint
+     QGstreamerPlayerSession* session = (QGstreamerPlayerSession*)userData;
+ 
+     const gchar *uri = 0;
++#if GST_CHECK_VERSION(1,0,0)
++    g_object_get(G_OBJECT(session->m_playbin), "current-uri", &uri, NULL);
++#else
+     g_object_get(G_OBJECT(session->m_playbin), "uri", &uri, NULL);
++#endif
+ 
+     guint64 length = gst_type_find_get_length(find);
+     if (!length)
+@@ -1887,7 +1897,7 @@ void QGstreamerPlayerSession::playlistTypeFindFunction(GstTypeFind *find, gpoint
+         length = qMin(length, guint64(1024));
+ 
+     while (length > 0) {
+-        guint8 *data = gst_type_find_peek(find, 0, length);
++        const guint8 *data = gst_type_find_peek(find, 0, length);
+         if (data) {
+             session->m_isPlaylist = (QPlaylistFileParser::findPlaylistType(QString::fromUtf8(uri), 0, data, length) != QPlaylistFileParser::UNKNOWN);
+             return;
+diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h
+index f2e760a..92b4a0c 100644
+--- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h
++++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h
+@@ -119,11 +119,9 @@ public:
+ 
+     void addProbe(QGstreamerVideoProbeControl* probe);
+     void removeProbe(QGstreamerVideoProbeControl* probe);
+-    static gboolean padVideoBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data);
+ 
+     void addProbe(QGstreamerAudioProbeControl* probe);
+     void removeProbe(QGstreamerAudioProbeControl* probe);
+-    static gboolean padAudioBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data);
+ 
+     void endOfMediaReset();
+ 
+@@ -172,7 +170,9 @@ private:
+     static void playbinNotifySource(GObject *o, GParamSpec *p, gpointer d);
+     static void handleVolumeChange(GObject *o, GParamSpec *p, gpointer d);
+     static void handleMutedChange(GObject *o, GParamSpec *p, gpointer d);
++#if !GST_CHECK_VERSION(1,0,0)
+     static void insertColorSpaceElement(GstElement *element, gpointer data);
++#endif
+     static void handleElementAdded(GstBin *bin, GstElement *element, QGstreamerPlayerSession *session);
+     static void handleStreamsChange(GstBin *bin, gpointer user_data);
+     static GstAutoplugSelectResult handleAutoplugSelect(GstBin *bin, GstPad *pad, GstCaps *caps, GstElementFactory *factory, QGstreamerPlayerSession *session);
+@@ -194,11 +194,14 @@ private:
+     QGstreamerBusHelper* m_busHelper;
+     GstElement* m_playbin;
+ 
++    GstElement* m_videoSink;
++
+     GstElement* m_videoOutputBin;
+     GstElement* m_videoIdentity;
++#if !GST_CHECK_VERSION(1,0,0)
+     GstElement* m_colorSpace;
+     bool m_usingColorspaceElement;
+-    GstElement* m_videoSink;
++#endif
+     GstElement* m_pendingVideoSink;
+     GstElement* m_nullVideoSink;
+ 
+@@ -218,13 +221,8 @@ private:
+     QList<QMediaStreamsControl::StreamType> m_streamTypes;
+     QMap<QMediaStreamsControl::StreamType, int> m_playbin2StreamOffset;
+ 
+-    QList<QGstreamerVideoProbeControl*> m_videoProbes;
+-    QMutex m_videoProbeMutex;
+-    int m_videoBufferProbeId;
+-
+-    QList<QGstreamerAudioProbeControl*> m_audioProbes;
+-    QMutex m_audioProbeMutex;
+-    int m_audioBufferProbeId;
++    QGstreamerVideoProbeControl *m_videoProbe;
++    QGstreamerAudioProbeControl *m_audioProbe;
+ 
+     int m_volume;
+     qreal m_playbackRate;
+@@ -252,6 +250,7 @@ private:
+     bool m_isLiveSource;
+ 
+     bool m_isPlaylist;
++    gulong pad_probe_id;
+ };
+ 
+ QT_END_NAMESPACE
+diff --git a/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp b/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp
+index 344f1f5..2711ae0 100644
+--- a/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp
++++ b/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp
+@@ -495,6 +495,8 @@ void tst_QCameraBackend::testCaptureToBuffer()
+         QCOMPARE(imageCapture.bufferFormat(), QVideoFrame::Format_Jpeg);
+     }
+ 
++    QTRY_VERIFY(imageCapture.isReadyForCapture());
++
+     //Try to capture to both buffer and file
+ #ifdef Q_WS_MAEMO_6
+     QVERIFY(imageCapture.isCaptureDestinationSupported(QCameraImageCapture::CaptureToBuffer | QCameraImageCapture::CaptureToFile));
+@@ -651,11 +653,11 @@ void tst_QCameraBackend::testVideoRecording()
+ {
+     QFETCH(QByteArray, device);
+ 
+-    QCamera *camera = device.isEmpty() ? new QCamera : new QCamera(device);
++    QScopedPointer<QCamera> camera(device.isEmpty() ? new QCamera : new QCamera(device));
+ 
+-    QMediaRecorder recorder(camera);
++    QMediaRecorder recorder(camera.data());
+ 
+-    QSignalSpy errorSignal(camera, SIGNAL(error(QCamera::Error)));
++    QSignalSpy errorSignal(camera.data(), SIGNAL(error(QCamera::Error)));
+     QSignalSpy recorderErrorSignal(&recorder, SIGNAL(error(QMediaRecorder::Error)));
+     QSignalSpy recorderStatusSignal(&recorder, SIGNAL(statusChanged(QMediaRecorder::Status)));
+ 
+@@ -702,8 +704,6 @@ void tst_QCameraBackend::testVideoRecording()
+     camera->setCaptureMode(QCamera::CaptureStillImage);
+     QTRY_COMPARE(recorder.status(), QMediaRecorder::UnloadedStatus);
+     QCOMPARE(recorderStatusSignal.last().first().value<QMediaRecorder::Status>(), recorder.status());
+-
+-    delete camera;
+ }
+ 
+ QTEST_MAIN(tst_QCameraBackend)
+diff --git a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
+index 0a1441c..ddf438b 100644
+--- a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
++++ b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp
+@@ -724,7 +724,7 @@ void tst_QMediaPlayerBackend::seekPauseSeek()
+ 
+     {
+         QVideoFrame frame = surface->m_frameList.back();
+-        const qint64 elapsed = frame.startTime() - position;
++        const qint64 elapsed = (frame.startTime() / 1000) - position; // frame.startTime() is microsecond, position is milliseconds.
+         QVERIFY2(qAbs(elapsed) < (qint64)500, QByteArray::number(elapsed).constData());
+         QCOMPARE(frame.width(), 160);
+         QCOMPARE(frame.height(), 120);
+@@ -748,7 +748,7 @@ void tst_QMediaPlayerBackend::seekPauseSeek()
+ 
+     {
+         QVideoFrame frame = surface->m_frameList.back();
+-        const qint64 elapsed = frame.startTime() - position;
++        const qint64 elapsed = (frame.startTime() / 1000) - position;
+         QVERIFY2(qAbs(elapsed) < (qint64)500, QByteArray::number(elapsed).constData());
+         QCOMPARE(frame.width(), 160);
+         QCOMPARE(frame.height(), 120);
+-- 
+2.1.4
+
diff --git a/recipes-qt/qt5/qtmultimedia/0001-Initial-porting-effort-to-GStreamer-1.0.patch b/recipes-qt/qt5/qtmultimedia/0001-Initial-porting-effort-to-GStreamer-1.0.patch
deleted file mode 100644
index 8c6c4fa..0000000
--- a/recipes-qt/qt5/qtmultimedia/0001-Initial-porting-effort-to-GStreamer-1.0.patch
+++ /dev/null
@@ -1,2369 +0,0 @@
-From 4af76880d63e8d392eb8add8b8999e3f5031675a Mon Sep 17 00:00:00 2001
-From: Yoann Lopes <yoann.lopes@digia.com>
-Date: Thu, 31 Oct 2013 15:06:30 +0100
-Subject: [PATCH 1/2] Initial porting effort to GStreamer 1.0.
-
-Imported from git@github.com:jhodapp/qtmultimedia.git
-
-Contributions from:
-Ilya Smelykh <ilya@videoexpertsgroup.com>
-Jim Hodapp <jim.hodapp@canonical.com>
-Sergio Schvezov <sergio.schvezov@canonical.com>
-
-Change-Id: I10fa5e5078efa4564ce833befd417008e26a90a9
-Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
-(cherry picked from commit d91dac090d92fdbc3a3425e8d969c62e5c79eff9)
-
-Conflicts:
-	src/gsttools/qgstreamervideorenderer.cpp
-	src/gsttools/qgstreamervideowidget.cpp
-	src/gsttools/qgstreamervideowindow.cpp
-	src/plugins/gstreamer/camerabin/camerabinsession.cpp
-	src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
-	src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
----
- config.tests/gstreamer/gstreamer.pro               |  11 +-
- config.tests/gstreamer_appsrc/gstreamer_appsrc.pro |  13 +-
- .../gstreamer_encodingprofiles.pro                 |  13 +-
- .../gstreamer_photography.pro                      |  15 +-
- qtmultimedia.pro                                   |  25 ++-
- src/gsttools/gsttools.pro                          |  22 +--
- src/gsttools/gstvideoconnector.c                   | 199 +++++++++++++++++++--
- src/gsttools/qgstappsrc.cpp                        |  29 ++-
- src/gsttools/qgstreameraudioprobecontrol.cpp       |  19 +-
- src/gsttools/qgstreamerbushelper.cpp               |   8 +
- src/gsttools/qgstreamervideoprobecontrol.cpp       |   9 +
- src/gsttools/qgstreamervideorenderer.cpp           |   3 +-
- src/gsttools/qgstreamervideowidget.cpp             |  29 ++-
- src/gsttools/qgstreamervideowindow.cpp             |  79 +++++++-
- src/gsttools/qgstutils.cpp                         |  27 ++-
- src/gsttools/qgstvideobuffer.cpp                   |  18 +-
- src/gsttools/qvideosurfacegstsink.cpp              | 138 +++++++++++++-
- src/multimedia/gsttools_headers/qgstappsrc_p.h     |   3 +
- .../qgstreameraudioprobecontrol_p.h                |   5 +-
- .../qgstreamervideoprobecontrol_p.h                |   4 +
- .../gsttools_headers/qgstreamervideowindow_p.h     |   4 +
- src/multimedia/gsttools_headers/qgstutils_p.h      |   4 +
- .../gsttools_headers/qgstvideobuffer_p.h           |   3 +
- .../gsttools_headers/qvideosurfacegstsink_p.h      |   6 +-
- .../qgstreameraudiodecoderserviceplugin.cpp        |  27 ++-
- .../audiodecoder/qgstreameraudiodecodersession.cpp |  33 +++-
- .../gstreamer/camerabin/camerabinsession.cpp       |  25 +++
- src/plugins/gstreamer/common.pri                   |  21 ++-
- src/plugins/gstreamer/gstreamer.pro                |   3 +-
- .../mediacapture/qgstreamercapturesession.cpp      |   5 +
- src/plugins/gstreamer/mediaplayer/mediaplayer.pro  |   1 -
- .../mediaplayer/qgstreamerplayercontrol.cpp        |   2 +
- .../mediaplayer/qgstreamerplayerservice.cpp        |   9 +-
- .../mediaplayer/qgstreamerplayerserviceplugin.cpp  |  27 ++-
- .../mediaplayer/qgstreamerplayersession.cpp        | 154 ++++++++++++++--
- .../mediaplayer/qgstreamerplayersession.h          |   9 +
- 36 files changed, 872 insertions(+), 130 deletions(-)
-
-diff --git a/config.tests/gstreamer/gstreamer.pro b/config.tests/gstreamer/gstreamer.pro
-index 02a7e34..6b9843a 100644
---- a/config.tests/gstreamer/gstreamer.pro
-+++ b/config.tests/gstreamer/gstreamer.pro
-@@ -3,11 +3,10 @@ SOURCES += main.cpp
- CONFIG += link_pkgconfig
- 
- PKGCONFIG += \
--    gstreamer-0.10 \
--    gstreamer-base-0.10 \
--    gstreamer-interfaces-0.10 \
--    gstreamer-audio-0.10 \
--    gstreamer-video-0.10 \
--    gstreamer-pbutils-0.10
-+    gstreamer-$$GST_VERSION \
-+    gstreamer-base-$$GST_VERSION \
-+    gstreamer-audio-$$GST_VERSION \
-+    gstreamer-video-$$GST_VERSION \
-+    gstreamer-pbutils-$$GST_VERSION
- 
- 
-diff --git a/config.tests/gstreamer_appsrc/gstreamer_appsrc.pro b/config.tests/gstreamer_appsrc/gstreamer_appsrc.pro
-index 9f61703..0f3ca2b 100644
---- a/config.tests/gstreamer_appsrc/gstreamer_appsrc.pro
-+++ b/config.tests/gstreamer_appsrc/gstreamer_appsrc.pro
-@@ -3,11 +3,8 @@ SOURCES += main.cpp
- CONFIG += link_pkgconfig
- 
- PKGCONFIG += \
--    gstreamer-0.10 \
--    gstreamer-base-0.10 \
--    gstreamer-interfaces-0.10 \
--    gstreamer-audio-0.10 \
--    gstreamer-video-0.10 \
--    gstreamer-app-0.10
--
--
-+    gstreamer-$$GST_VERSION \
-+    gstreamer-base-$$GST_VERSION \
-+    gstreamer-audio-$$GST_VERSION \
-+    gstreamer-video-$$GST_VERSION \
-+    gstreamer-pbutils-$$GST_VERSION
-diff --git a/config.tests/gstreamer_encodingprofiles/gstreamer_encodingprofiles.pro b/config.tests/gstreamer_encodingprofiles/gstreamer_encodingprofiles.pro
-index 7e8a9e7..fad40b0 100644
---- a/config.tests/gstreamer_encodingprofiles/gstreamer_encodingprofiles.pro
-+++ b/config.tests/gstreamer_encodingprofiles/gstreamer_encodingprofiles.pro
-@@ -2,11 +2,10 @@ SOURCES += main.cpp
- 
- CONFIG += link_pkgconfig
- 
--PKGCONFIG += \
--    gstreamer-0.10 \
--    gstreamer-base-0.10 \
--    gstreamer-interfaces-0.10 \
--    gstreamer-audio-0.10 \
--    gstreamer-video-0.10 \
--    gstreamer-pbutils-0.10
- 
-+PKGCONFIG += \
-+    gstreamer-$$GST_VERSION \
-+    gstreamer-base-$$GST_VERSION \
-+    gstreamer-audio-$$GST_VERSION \
-+    gstreamer-video-$$GST_VERSION \
-+    gstreamer-pbutils-$$GST_VERSION
-diff --git a/config.tests/gstreamer_photography/gstreamer_photography.pro b/config.tests/gstreamer_photography/gstreamer_photography.pro
-index 6b530cb..975991f 100644
---- a/config.tests/gstreamer_photography/gstreamer_photography.pro
-+++ b/config.tests/gstreamer_photography/gstreamer_photography.pro
-@@ -3,12 +3,11 @@ SOURCES += main.cpp
- CONFIG += link_pkgconfig
- 
- PKGCONFIG += \
--    gstreamer-0.10 \
--    gstreamer-base-0.10 \
--    gstreamer-interfaces-0.10 \
--    gstreamer-audio-0.10 \
--    gstreamer-video-0.10 \
--    gstreamer-pbutils-0.10
--
--LIBS += -lgstphotography-0.10
-+    gstreamer-$$GST_VERSION \
-+    gstreamer-base-$$GST_VERSION \
-+    gstreamer-audio-$$GST_VERSION \
-+    gstreamer-video-$$GST_VERSION \
-+    gstreamer-pbutils-$$GST_VERSION
-+
-+LIBS += -lgstphotography-$$GST_VERSION
- 
-diff --git a/qtmultimedia.pro b/qtmultimedia.pro
-index 3cec526..109dd81 100644
---- a/qtmultimedia.pro
-+++ b/qtmultimedia.pro
-@@ -17,11 +17,26 @@ win32 {
- } else {
-     qtCompileTest(alsa)
-     qtCompileTest(pulseaudio)
--    qtCompileTest(gstreamer) {
--        qtCompileTest(gstreamer_photography)
--        qtCompileTest(gstreamer_encodingprofiles)
--        qtCompileTest(gstreamer_appsrc)
--        qtCompileTest(linux_v4l)
-+    !done_config_gstreamer {
-+        gstver=1.0
-+        cache(GST_VERSION, set, gstver);
-+        qtCompileTest(gstreamer) {
-+            qtCompileTest(gstreamer_photography)
-+            qtCompileTest(gstreamer_encodingprofiles)
-+            qtCompileTest(gstreamer_appsrc)
-+            qtCompileTest(linux_v4l)
-+        } else {
-+            gstver=0.10
-+            cache(GST_VERSION, set, gstver);
-+            # Force a re-run of the test
-+            CONFIG -= done_config_gstreamer
-+            qtCompileTest(gstreamer) {
-+                qtCompileTest(gstreamer_photography)
-+                qtCompileTest(gstreamer_encodingprofiles)
-+                qtCompileTest(gstreamer_appsrc)
-+                qtCompileTest(linux_v4l)
-+            }
-+        }
-     }
-     qtCompileTest(resourcepolicy)
-     qtCompileTest(gpu_vivante)
-diff --git a/src/gsttools/gsttools.pro b/src/gsttools/gsttools.pro
-index 7c809a7..6b9bf5d 100644
---- a/src/gsttools/gsttools.pro
-+++ b/src/gsttools/gsttools.pro
-@@ -2,7 +2,7 @@ TEMPLATE = lib
- 
- TARGET = qgsttools_p
- QPRO_PWD = $$PWD
--QT = core-private multimedia-private gui-private
-+QT = core-private multimedia-private gui-private opengl
- 
- !static:DEFINES += QT_MAKEDLL
- DEFINES += GLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_26
-@@ -15,13 +15,14 @@ LIBS_PRIVATE += \
- 
- CONFIG += link_pkgconfig
- 
--PKGCONFIG_PRIVATE += \
--    gstreamer-0.10 \
--    gstreamer-base-0.10 \
--    gstreamer-interfaces-0.10 \
--    gstreamer-audio-0.10 \
--    gstreamer-video-0.10 \
--    gstreamer-pbutils-0.10
-+PKGCONFIG += \
-+    gstreamer-$$GST_VERSION \
-+    gstreamer-base-$$GST_VERSION \
-+    gstreamer-audio-$$GST_VERSION \
-+    gstreamer-video-$$GST_VERSION \
-+    gstreamer-pbutils-$$GST_VERSION
-+
-+equals(GST_VERSION,"0.10"): PKGCONFIG_PRIVATE += gstreamer-interfaces-$$GST_VERSION
- 
- maemo*: PKGCONFIG_PRIVATE +=gstreamer-plugins-bad-0.10
- 
-@@ -33,6 +34,7 @@ config_resourcepolicy {
- # Header files must go inside source directory of a module
- # to be installed by syncqt.
- INCLUDEPATH += ../multimedia/gsttools_headers/
-+INCLUDEPATH += ../plugins/gstreamer/mediaplayer/
- VPATH += ../multimedia/gsttools_headers/
- 
- PRIVATE_HEADERS += \
-@@ -91,13 +93,13 @@ maemo6 {
- }
- 
- config_gstreamer_appsrc {
--    PKGCONFIG_PRIVATE += gstreamer-app-0.10
-+    PKGCONFIG_PRIVATE += gstreamer-app-$$GST_VERSION
-     PRIVATE_HEADERS += qgstappsrc_p.h
-     SOURCES += qgstappsrc.cpp
- 
-     DEFINES += HAVE_GST_APPSRC
- 
--    LIBS_PRIVATE += -lgstapp-0.10
-+    LIBS_PRIVATE += -lgstapp-$$GST_VERSION
- }
- 
- config_linux_v4l: DEFINES += USE_V4L
-diff --git a/src/gsttools/gstvideoconnector.c b/src/gsttools/gstvideoconnector.c
-index 3ed539e..ed0ed3c 100644
---- a/src/gsttools/gstvideoconnector.c
-+++ b/src/gsttools/gstvideoconnector.c
-@@ -59,26 +59,93 @@ GST_STATIC_PAD_TEMPLATE ("src",
-                          GST_PAD_ALWAYS,
-                          GST_STATIC_CAPS_ANY);
- 
-+
-+#if GST_CHECK_VERSION(1,0,0)
-+
-+G_DEFINE_TYPE(GstVideoConnector, gst_video_connector, GST_TYPE_ELEMENT);
-+#else
- #define _do_init(bla) \
-     GST_DEBUG_CATEGORY_INIT (video_connector_debug, \
-     "video-connector", 0, "An identity like element for reconnecting video stream");
- 
- GST_BOILERPLATE_FULL (GstVideoConnector, gst_video_connector, GstElement,
-                       GST_TYPE_ELEMENT, _do_init);
-+#endif
- 
- static void gst_video_connector_dispose (GObject * object);
-+
-+#if GST_CHECK_VERSION(1,0,0)
-+static GstFlowReturn gst_video_connector_chain (GstPad * pad, GstObject* parent, GstBuffer * buf);
-+#else
- static GstFlowReturn gst_video_connector_chain (GstPad * pad, GstBuffer * buf);
- static GstFlowReturn gst_video_connector_buffer_alloc (GstPad * pad,
-                                                        guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
-+#endif
-+
- static GstStateChangeReturn gst_video_connector_change_state (GstElement *
-                                                               element, GstStateChange transition);
-+
-+#if GST_CHECK_VERSION(1,0,0)
-+static gboolean gst_video_connector_handle_sink_event (GstPad * pad, GstObject* parent,
-+                                                       GstEvent * event);
-+#else
- static gboolean gst_video_connector_handle_sink_event (GstPad * pad,
-                                                        GstEvent * event);
-+#endif
-+
-+#if GST_CHECK_VERSION(1,0,0)
-+static GstPadProbeReturn gst_video_connector_new_buffer_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object);
-+static GstPadProbeReturn gst_video_connector_new_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object);
-+static GstPadProbeReturn gst_video_connector_new_query_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object);
-+#else
- static gboolean gst_video_connector_new_buffer_probe(GstObject *pad, GstBuffer *buffer, guint * object);
--static void gst_video_connector_resend_new_segment(GstElement * element, gboolean emitFailedSignal);
- static gboolean gst_video_connector_setcaps (GstPad  *pad, GstCaps *caps);
- static GstCaps *gst_video_connector_getcaps (GstPad * pad);
- static gboolean gst_video_connector_acceptcaps (GstPad * pad, GstCaps * caps);
-+#endif
-+
-+static void gst_video_connector_resend_new_segment(GstElement * element, gboolean emitFailedSignal);
-+
-+#if GST_CHECK_VERSION(1,0,0)
-+static void
-+gst_video_connector_class_init (GstVideoConnectorClass * klass)
-+{
-+    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-+    GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
-+
-+    gst_element_class_set_details_simple (gstelement_class, "Video Connector",
-+                                          "Generic",
-+                                          "An identity like element used for reconnecting video stream",
-+                                          "Dmytro Poplavskiy <dmytro.poplavskiy@nokia.com>");
-+    gst_element_class_add_pad_template (gstelement_class,
-+                                        gst_static_pad_template_get (&gst_video_connector_sink_factory));
-+    gst_element_class_add_pad_template (gstelement_class,
-+                                        gst_static_pad_template_get (&gst_video_connector_src_factory));
-+
-+    gst_video_connector_parent_class = g_type_class_peek_parent (klass);
-+
-+    gobject_class->dispose = gst_video_connector_dispose;
-+    gstelement_class->change_state = gst_video_connector_change_state;
-+    klass->resend_new_segment = gst_video_connector_resend_new_segment;
-+
-+    gst_video_connector_signals[SIGNAL_RESEND_NEW_SEGMENT] =
-+            g_signal_new ("resend-new-segment", G_TYPE_FROM_CLASS (klass),
-+                          G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-+                          G_STRUCT_OFFSET (GstVideoConnectorClass, resend_new_segment), NULL, NULL,
-+                          g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
-+
-+    gst_video_connector_signals[SIGNAL_CONNECTION_FAILED] =
-+            g_signal_new ("connection-failed", G_TYPE_FROM_CLASS (klass),
-+                          G_SIGNAL_RUN_LAST,
-+                          0, NULL, NULL,
-+                          g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-+
-+    GST_DEBUG_CATEGORY_INIT(video_connector_debug, "video-connector", 0,
-+                            "An identity like element for reconnecting video stream");
-+
-+}
-+
-+#else
- 
- static void
- gst_video_connector_base_init (gpointer g_class)
-@@ -120,18 +187,33 @@ gst_video_connector_class_init (GstVideoConnectorClass * klass)
-                           g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
- }
- 
-+#endif
-+
- static void
--gst_video_connector_init (GstVideoConnector *element,
--                          GstVideoConnectorClass *g_class)
-+gst_video_connector_init (GstVideoConnector *element
-+#if GST_CHECK_VERSION(1,0,0)
-+#else
-+                          ,GstVideoConnectorClass *g_class
-+#endif
-+                          )
- {
-+#if GST_CHECK_VERSION(1,0,0)
-+#else
-     (void) g_class;
-+#endif
-     element->sinkpad =
-             gst_pad_new_from_static_template (&gst_video_connector_sink_factory,
-                                               "sink");
-     gst_pad_set_chain_function(element->sinkpad,
-                                GST_DEBUG_FUNCPTR (gst_video_connector_chain));
-+#if GST_CHECK_VERSION(1,0,0)
-+    /* gstreamer 1.x uses QUERIES and EVENTS for allocation and caps handiling purposes */
-+    GST_OBJECT_FLAG_SET (element->sinkpad, GST_PAD_FLAG_PROXY_CAPS);
-+    GST_OBJECT_FLAG_SET (element->sinkpad, GST_PAD_FLAG_PROXY_ALLOCATION);
-+#else
-     gst_pad_set_event_function(element->sinkpad,
-                                GST_DEBUG_FUNCPTR (gst_video_connector_handle_sink_event));
-+
-     gst_pad_set_bufferalloc_function(element->sinkpad,
-                                      GST_DEBUG_FUNCPTR (gst_video_connector_buffer_alloc));
-     gst_pad_set_setcaps_function(element->sinkpad,
-@@ -140,14 +222,23 @@ gst_video_connector_init (GstVideoConnector *element,
-                                GST_DEBUG_FUNCPTR(gst_video_connector_getcaps));
-     gst_pad_set_acceptcaps_function(element->sinkpad,
-                                GST_DEBUG_FUNCPTR(gst_video_connector_acceptcaps));
--
-+#endif
-     gst_element_add_pad (GST_ELEMENT (element), element->sinkpad);
- 
-     element->srcpad =
-             gst_pad_new_from_static_template (&gst_video_connector_src_factory,
-                                               "src");
-+#if GST_CHECK_VERSION(1,0,0)
-+    gst_pad_add_probe(element->srcpad, GST_PAD_PROBE_TYPE_BUFFER,
-+                             gst_video_connector_new_buffer_probe, element, NULL);
-+    gst_pad_add_probe(element->srcpad, GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM,
-+                             gst_video_connector_new_query_probe, element, NULL);
-+    gst_pad_add_probe(element->sinkpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
-+                             gst_video_connector_new_event_probe, element, NULL);
-+#else
-     gst_pad_add_buffer_probe(element->srcpad,
-                              G_CALLBACK(gst_video_connector_new_buffer_probe), element);
-+#endif
-     gst_element_add_pad (GST_ELEMENT (element), element->srcpad);
- 
-     element->relinked = FALSE;
-@@ -175,9 +266,16 @@ gst_video_connector_dispose (GObject * object)
- 
-     gst_video_connector_reset (element);
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+    G_OBJECT_CLASS (gst_video_connector_parent_class)->dispose (object);
-+#else
-     G_OBJECT_CLASS (parent_class)->dispose (object);
-+#endif
- }
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+/* For gstreamer 1.x we handle it in ALLOCATION Query */
-+#else
- // "When this function returns anything else than GST_FLOW_OK,
- // the buffer allocation failed and buf does not contain valid data."
- static GstFlowReturn
-@@ -221,6 +319,7 @@ gst_video_connector_buffer_alloc (GstPad * pad, guint64 offset, guint size,
-                 if (state == GST_STATE_NULL) {
-                     GST_DEBUG_OBJECT (element, "Downstream element is in NULL state");
-                     // Downstream filter seems to be in the wrong state
-+
-                     return GST_FLOW_UNEXPECTED;
-                 }
-             }
-@@ -293,6 +392,7 @@ static GstCaps *gst_video_connector_getcaps (GstPad * pad)
-     return caps;
- }
- 
-+
- static gboolean gst_video_connector_acceptcaps (GstPad * pad, GstCaps * caps)
- {
-     GstVideoConnector *element;
-@@ -300,6 +400,7 @@ static gboolean gst_video_connector_acceptcaps (GstPad * pad, GstCaps * caps)
- 
-     return gst_pad_peer_accept_caps(element->srcpad, caps);
- }
-+#endif
- 
- static void
- gst_video_connector_resend_new_segment(GstElement * element, gboolean emitFailedSignal)
-@@ -311,11 +412,39 @@ gst_video_connector_resend_new_segment(GstElement * element, gboolean emitFailed
-         connector->failedSignalEmited = FALSE;
- }
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+static GstPadProbeReturn gst_video_connector_new_event_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object)
-+{
-+    GstVideoConnector *connector = GST_VIDEO_CONNECTOR (object);
-+    GstEvent *event = gst_pad_probe_info_get_event(info);
-+
-+    GST_DEBUG_OBJECT(connector, "Event %"GST_PTR_FORMAT" received\n", event);
-+
-+    return GST_PAD_PROBE_OK;
-+}
-+
-+static GstPadProbeReturn gst_video_connector_new_query_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object)
-+{
-+    GstVideoConnector *connector = GST_VIDEO_CONNECTOR (object);
-+    GstQuery *query = gst_pad_probe_info_get_query(info);
-+
-+    GST_DEBUG_OBJECT(connector, "Query %"GST_PTR_FORMAT" received\n", query);
-+
-+    return GST_PAD_PROBE_OK;
-+}
-+#endif
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+static GstPadProbeReturn gst_video_connector_new_buffer_probe(GstPad *pad, GstPadProbeInfo *info, gpointer object)
-+{
-+    (void) info;
-+#else
- static gboolean gst_video_connector_new_buffer_probe(GstObject *pad, GstBuffer *buffer, guint * object)
- {
--    (void) pad;
-     (void) buffer;
-+#endif
-+    (void) pad;
-+
- 
-     GstVideoConnector *element = GST_VIDEO_CONNECTOR (object);
- 
-@@ -327,16 +456,23 @@ static gboolean gst_video_connector_new_buffer_probe(GstObject *pad, GstBuffer *
-     if (element->relinked)
-         GST_LOG_OBJECT(element, "rejected buffer because of new segment request");
- 
--    return !element->relinked;
-+    return element->relinked ? GST_PAD_PROBE_DROP : GST_PAD_PROBE_OK;
- }
- 
--
- static GstFlowReturn
-+#if GST_CHECK_VERSION(1,0,0)
-+gst_video_connector_chain (GstPad * pad, GstObject* parent, GstBuffer * buf)
-+#else
- gst_video_connector_chain (GstPad * pad, GstBuffer * buf)
-+#endif
- {
-     GstFlowReturn res;
-     GstVideoConnector *element;
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+    (void)parent;
-+#endif
-+
-     element = GST_VIDEO_CONNECTOR (gst_pad_get_parent (pad));
- 
-     do {
-@@ -348,20 +484,29 @@ gst_video_connector_chain (GstPad * pad, GstBuffer * buf)
-         */
-         while (element->relinked) {
-             element->relinked = FALSE;
--
-+#if GST_CHECK_VERSION(1,0,0)
-+            if (element->latest_buffer && GST_BUFFER_TIMESTAMP_IS_VALID(element->latest_buffer)) {
-+                element->segment.position = GST_BUFFER_TIMESTAMP (element->latest_buffer);
-+            }
-+#else
-             gint64 pos = element->segment.last_stop;
--
-             if (element->latest_buffer && GST_BUFFER_TIMESTAMP_IS_VALID(element->latest_buffer)) {
-                 pos = GST_BUFFER_TIMESTAMP (element->latest_buffer);
-             }
-+#endif
- 
-             //push a new segment and last buffer
-+#if GST_CHECK_VERSION(1,0,0)
-+            GstEvent *ev = gst_event_new_segment (&element->segment);
-+
-+#else
-             GstEvent *ev = gst_event_new_new_segment (TRUE,
-                                                       element->segment.rate,
-                                                       element->segment.format,
-                                                       pos, //start
-                                                       element->segment.stop,
-                                                       pos);
-+#endif
- 
-             GST_DEBUG_OBJECT (element, "Pushing new segment event");
-             if (!gst_pad_push_event (element->srcpad, ev)) {
-@@ -424,8 +569,11 @@ gst_video_connector_change_state (GstElement * element,
-     GstStateChangeReturn result;
- 
-     connector = GST_VIDEO_CONNECTOR(element);
-+#if GST_CHECK_VERSION(1,0,0)
-+    result = GST_ELEMENT_CLASS (gst_video_connector_parent_class)->change_state(element, transition);
-+#else
-     result = GST_ELEMENT_CLASS (parent_class)->change_state(element, transition);
--
-+#endif
-     switch (transition) {
-     case GST_STATE_CHANGE_PAUSED_TO_READY:
-         gst_video_connector_reset (connector);
-@@ -440,9 +588,32 @@ gst_video_connector_change_state (GstElement * element,
-     return result;
- }
- 
--static gboolean
--gst_video_connector_handle_sink_event (GstPad * pad, GstEvent * event)
-+#if GST_CHECK_VERSION(1,0,0)
-+static gboolean gst_video_connector_handle_sink_event (GstPad * pad, GstObject* parent,
-+                                                       GstEvent * event)
-+{
-+    GstVideoConnector *element = GST_VIDEO_CONNECTOR (gst_pad_get_parent (pad));
-+
-+    switch (GST_EVENT_TYPE (event)) {
-+      case GST_EVENT_SEGMENT:
-+      break;
-+      case GST_EVENT_CAPS:
-+      break;
-+    default:
-+      break;
-+    }
-+
-+    gst_object_unref (element);
-+    return gst_pad_event_default (pad, parent, event);
-+}
-+
-+#else
-+
-+static gboolean gst_video_connector_handle_sink_event (GstPad * pad,
-+                                                       GstEvent * event)
- {
-+    (void)parent;
-+
-     if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
-         GstVideoConnector *element = GST_VIDEO_CONNECTOR (gst_pad_get_parent (pad));
- 
-@@ -453,7 +624,6 @@ gst_video_connector_handle_sink_event (GstPad * pad, GstEvent * event)
- 
-         gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
-                                           &start, &stop, &time);
--
-         GST_LOG_OBJECT (element,
-                           "NEWSEGMENT update %d, rate %lf, applied rate %lf, "
-                           "format %d, " "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
-@@ -461,9 +631,10 @@ gst_video_connector_handle_sink_event (GstPad * pad, GstEvent * event)
- 
-         gst_segment_set_newsegment_full (&element->segment, update,
-                                          rate, arate, format, start, stop, time);
--
-         gst_object_unref (element);
-     }
- 
-     return gst_pad_event_default (pad, event);
- }
-+
-+#endif
-diff --git a/src/gsttools/qgstappsrc.cpp b/src/gsttools/qgstappsrc.cpp
-index 561a96f..d5e106f 100644
---- a/src/gsttools/qgstappsrc.cpp
-+++ b/src/gsttools/qgstappsrc.cpp
-@@ -147,23 +147,44 @@ void QGstAppSrc::pushDataToAppSrc()
-             size = qMin(m_stream->bytesAvailable(), (qint64)m_dataRequestSize);
- 
-         if (size) {
--            void *data = g_malloc(size);
--            GstBuffer* buffer = gst_app_buffer_new(data, size, g_free, data);
-+            GstBuffer* buffer = gst_buffer_new_and_alloc(size);
-+
-+#if GST_CHECK_VERSION(1,0,0)
-+            GstMapInfo mapInfo;
-+            gst_buffer_map(buffer, &mapInfo, GST_MAP_WRITE);
-+            void* bufferData = mapInfo.data;
-+#else
-+            void* bufferData = GST_BUFFER_DATA(buffer);
-+#endif
-+            
-             buffer->offset = m_stream->pos();
--            qint64 bytesRead = m_stream->read((char*)GST_BUFFER_DATA(buffer), size);
-+            qint64 bytesRead = m_stream->read((char*)bufferData, size);
-             buffer->offset_end =  buffer->offset + bytesRead - 1;
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+            gst_buffer_unmap(buffer, &mapInfo);
-+#endif
-+            
-             if (bytesRead > 0) {
-                 m_dataRequested = false;
-                 m_enoughData = false;
-                 GstFlowReturn ret = gst_app_src_push_buffer (GST_APP_SRC (element()), buffer);
-                 if (ret == GST_FLOW_ERROR) {
-                     qWarning()<<"appsrc: push buffer error";
-+#if GST_CHECK_VERSION(1,0,0)
-+                } else if (ret == GST_FLOW_FLUSHING) {
-+                    qWarning()<<"appsrc: push buffer wrong state";
-+                }
-+#else
-                 } else if (ret == GST_FLOW_WRONG_STATE) {
-                     qWarning()<<"appsrc: push buffer wrong state";
--                } else if (ret == GST_FLOW_RESEND) {
-+                }
-+#endif
-+#if GST_VERSION_MAJOR < 1
-+                else if (ret == GST_FLOW_RESEND) {
-                     qWarning()<<"appsrc: push buffer resend";
-                 }
-+#endif
-             }
-         } else {
-             sendEOS();
-diff --git a/src/gsttools/qgstreameraudioprobecontrol.cpp b/src/gsttools/qgstreameraudioprobecontrol.cpp
-index 3baca53..be3de3f 100644
---- a/src/gsttools/qgstreameraudioprobecontrol.cpp
-+++ b/src/gsttools/qgstreameraudioprobecontrol.cpp
-@@ -45,9 +45,14 @@ QGstreamerAudioProbeControl::~QGstreamerAudioProbeControl()
- 
- }
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+void QGstreamerAudioProbeControl::bufferProbed(GstBuffer* buffer, GstCaps* caps)
-+{
-+#else
- void QGstreamerAudioProbeControl::bufferProbed(GstBuffer* buffer)
- {
--    GstCaps* caps = gst_buffer_get_caps(buffer);
-+    gst_buffer_get_caps(buffer);
-+#endif
-     if (!caps)
-         return;
- 
-@@ -56,8 +61,20 @@ void QGstreamerAudioProbeControl::bufferProbed(GstBuffer* buffer)
-     if (!format.isValid())
-         return;
- 
-+    #if GST_CHECK_VERSION(1,0,0)
-+
-+    GstMapInfo info;
-+
-+    gst_buffer_map (buffer, &info, GST_MAP_READ);
-+    QAudioBuffer audioBuffer = QAudioBuffer(QByteArray((const char*)info.data, info.size), format);
-+    gst_buffer_unmap(buffer, &info);
-+
-+    #else
-+
-     QAudioBuffer audioBuffer = QAudioBuffer(QByteArray((const char*)buffer->data, buffer->size), format);
- 
-+    #endif
-+
-     {
-         QMutexLocker locker(&m_bufferMutex);
-         m_pendingBuffer = audioBuffer;
-diff --git a/src/gsttools/qgstreamerbushelper.cpp b/src/gsttools/qgstreamerbushelper.cpp
-index 84eda46..eb1fc36 100644
---- a/src/gsttools/qgstreamerbushelper.cpp
-+++ b/src/gsttools/qgstreamerbushelper.cpp
-@@ -154,13 +154,21 @@ QGstreamerBusHelper::QGstreamerBusHelper(GstBus* bus, QObject* parent):
-     QObject(parent)
- {
-     d = new QGstreamerBusHelperPrivate(this, bus);
-+#if GST_CHECK_VERSION(1,0,0)
-+    gst_bus_set_sync_handler(bus, (GstBusSyncHandler)syncGstBusFilter, d, 0);
-+#else
-     gst_bus_set_sync_handler(bus, (GstBusSyncHandler)syncGstBusFilter, d);
-+#endif
-     gst_object_ref(GST_OBJECT(bus));
- }
- 
- QGstreamerBusHelper::~QGstreamerBusHelper()
- {
-+#if GST_CHECK_VERSION(1,0,0)
-+    gst_bus_set_sync_handler(d->bus(), 0, 0, 0);
-+#else
-     gst_bus_set_sync_handler(d->bus(),0,0);
-+#endif
-     gst_object_unref(GST_OBJECT(d->bus()));
- }
- 
-diff --git a/src/gsttools/qgstreamervideoprobecontrol.cpp b/src/gsttools/qgstreamervideoprobecontrol.cpp
-index a78a9da..9c31140 100644
---- a/src/gsttools/qgstreamervideoprobecontrol.cpp
-+++ b/src/gsttools/qgstreamervideoprobecontrol.cpp
-@@ -67,12 +67,21 @@ void QGstreamerVideoProbeControl::stopFlushing()
-     m_flushing = false;
- }
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+void QGstreamerVideoProbeControl::bufferProbed(GstBuffer* buffer, GstCaps* caps)
-+#else
- void QGstreamerVideoProbeControl::bufferProbed(GstBuffer* buffer)
-+#endif
- {
-     if (m_flushing)
-         return;
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+    // FIXME:
-+   // GstCaps* caps = NULL;//gst_buffer_get_caps(buffer);
-+#else
-     GstCaps* caps = gst_buffer_get_caps(buffer);
-+#endif
-     if (!caps)
-         return;
- 
-diff --git a/src/gsttools/qgstreamervideorenderer.cpp b/src/gsttools/qgstreamervideorenderer.cpp
-index 2b66f76..804dce9 100644
---- a/src/gsttools/qgstreamervideorenderer.cpp
-+++ b/src/gsttools/qgstreamervideorenderer.cpp
-@@ -35,8 +35,7 @@
- #include <private/qvideosurfacegstsink_p.h>
- #include <private/qgstutils_p.h>
- #include <qabstractvideosurface.h>
--
--#include <QDebug>
-+#include <QtCore/qdebug.h>
- 
- #include <gst/gst.h>
- 
-diff --git a/src/gsttools/qgstreamervideowidget.cpp b/src/gsttools/qgstreamervideowidget.cpp
-index aa2e2a3..14c1f04 100644
---- a/src/gsttools/qgstreamervideowidget.cpp
-+++ b/src/gsttools/qgstreamervideowidget.cpp
-@@ -40,8 +40,13 @@
- #include <QtGui/qpainter.h>
- 
- #include <gst/gst.h>
-+
-+#if !GST_CHECK_VERSION(1,0,0)
- #include <gst/interfaces/xoverlay.h>
- #include <gst/interfaces/propertyprobe.h>
-+#else
-+#include <gst/video/videooverlay.h>
-+#endif
- 
- QT_BEGIN_NAMESPACE
- 
-@@ -169,9 +174,13 @@ bool QGstreamerVideoWidgetControl::processSyncMessage(const QGstreamerMessage &m
- {
-     GstMessage* gm = message.rawMessage();
- 
-+#if !GST_CHECK_VERSION(1,0,0)
-     if (gm && (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) &&
-             gst_structure_has_name(gm->structure, "prepare-xwindow-id")) {
--
-+#else
-+      if (gm && (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) &&
-+              gst_structure_has_name(gst_message_get_structure(gm), "prepare-window-handle")) {
-+#endif
-         setOverlay();
-         QMetaObject::invokeMethod(this, "updateNativeVideoSize", Qt::QueuedConnection);
-         return true;
-@@ -199,18 +208,29 @@ bool QGstreamerVideoWidgetControl::processBusMessage(const QGstreamerMessage &me
- 
- void QGstreamerVideoWidgetControl::setOverlay()
- {
-+#if !GST_CHECK_VERSION(1,0,0)
-     if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
-         gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_windowId);
-     }
-+#else
-+    if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) {
-+        gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(m_videoSink), m_windowId);
-+    }
-+#endif
- }
- 
- void QGstreamerVideoWidgetControl::updateNativeVideoSize()
- {
-     if (m_videoSink) {
-         //find video native size to update video widget size hint
--        GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
-+        GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink");
-+#if !GST_CHECK_VERSION(1,0,0)
-         GstCaps *caps = gst_pad_get_negotiated_caps(pad);
-         gst_object_unref(GST_OBJECT(pad));
-+#else
-+        GstCaps *caps = gst_pad_get_current_caps(pad);
-+        gst_object_unref(GST_OBJECT(pad));
-+#endif
- 
-         if (caps) {
-             m_widget->setNativeSize(QGstUtils::capsCorrectedResolution(caps));
-@@ -225,8 +245,13 @@ void QGstreamerVideoWidgetControl::updateNativeVideoSize()
- 
- void QGstreamerVideoWidgetControl::windowExposed()
- {
-+#if !GST_CHECK_VERSION(1,0,0)
-     if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink))
-         gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink));
-+#else
-+    if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink))
-+        gst_video_overlay_expose(GST_VIDEO_OVERLAY(m_videoSink));
-+#endif
- }
- 
- QWidget *QGstreamerVideoWidgetControl::videoWidget()
-diff --git a/src/gsttools/qgstreamervideowindow.cpp b/src/gsttools/qgstreamervideowindow.cpp
-index a373dcc..587b010 100644
---- a/src/gsttools/qgstreamervideowindow.cpp
-+++ b/src/gsttools/qgstreamervideowindow.cpp
-@@ -37,8 +37,12 @@
- #include <QtCore/qdebug.h>
- 
- #include <gst/gst.h>
-+#include <gst/video/videooverlay.h>
-+
-+#if !GST_CHECK_VERSION(1,0,0)
- #include <gst/interfaces/xoverlay.h>
- #include <gst/interfaces/propertyprobe.h>
-+#endif
- 
- 
- QGstreamerVideoWindow::QGstreamerVideoWindow(QObject *parent, const char *elementName)
-@@ -49,18 +53,25 @@ QGstreamerVideoWindow::QGstreamerVideoWindow(QObject *parent, const char *elemen
-     , m_fullScreen(false)
-     , m_colorKey(QColor::Invalid)
- {
--    if (elementName)
-+    if (elementName) {
-         m_videoSink = gst_element_factory_make(elementName, NULL);
--    else
-+    } else {
-         m_videoSink = gst_element_factory_make("xvimagesink", NULL);
-+    }
- 
-     if (m_videoSink) {
-         qt_gst_object_ref_sink(GST_OBJECT(m_videoSink)); //Take ownership
- 
-         GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
-+#if GST_CHECK_VERSION(1,0,0)
-+        m_bufferProbeId = gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, padBufferProbe, this, NULL);
-+#else
-         m_bufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padBufferProbe), this);
-+#endif
-         gst_object_unref(GST_OBJECT(pad));
-     }
-+    else
-+        qDebug() << "No m_videoSink available!";
- }
- 
- QGstreamerVideoWindow::~QGstreamerVideoWindow()
-@@ -82,11 +93,15 @@ void QGstreamerVideoWindow::setWinId(WId id)
-     WId oldId = m_windowId;
- 
-     m_windowId = id;
--
-+#if GST_CHECK_VERSION(1,0,0)
-+    if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) {
-+        gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(m_videoSink), m_windowId);
-+    }
-+#else
-     if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
-         gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(m_videoSink), m_windowId);
-     }
--
-+#endif
-     if (!oldId)
-         emit readyChanged(true);
- 
-@@ -97,7 +112,20 @@ void QGstreamerVideoWindow::setWinId(WId id)
- bool QGstreamerVideoWindow::processSyncMessage(const QGstreamerMessage &message)
- {
-     GstMessage* gm = message.rawMessage();
-+#if GST_CHECK_VERSION(1,0,0)
-+    const GstStructure *s = gst_message_get_structure(gm);
-+    if ((GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) &&
-+            gst_structure_has_name(s, "prepare-window-handle") &&
-+            m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) {
-+
-+        gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(m_videoSink), m_windowId);
- 
-+        GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
-+        m_bufferProbeId = gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, padBufferProbe, this, NULL);
-+
-+        return true;
-+    }
-+#else
-     if ((GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) &&
-             gst_structure_has_name(gm->structure, "prepare-xwindow-id") &&
-             m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
-@@ -110,7 +138,7 @@ bool QGstreamerVideoWindow::processSyncMessage(const QGstreamerMessage &message)
- 
-         return true;
-     }
--
-+#endif
-     return false;
- }
- 
-@@ -122,7 +150,19 @@ QRect QGstreamerVideoWindow::displayRect() const
- void QGstreamerVideoWindow::setDisplayRect(const QRect &rect)
- {
-     m_displayRect = rect;
--
-+#if GST_CHECK_VERSION(1,0,0)
-+    if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) {
-+        if (m_displayRect.isEmpty())
-+            gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(m_videoSink), -1, -1, -1, -1);
-+        else
-+            gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(m_videoSink),
-+                                               m_displayRect.x(),
-+                                               m_displayRect.y(),
-+                                               m_displayRect.width(),
-+                                               m_displayRect.height());
-+        repaint();
-+    }
-+#else
-     if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
- #if GST_VERSION_MICRO >= 29
-         if (m_displayRect.isEmpty())
-@@ -136,6 +176,7 @@ void QGstreamerVideoWindow::setDisplayRect(const QRect &rect)
-         repaint();
- #endif
-     }
-+#endif
- }
- 
- Qt::AspectRatioMode QGstreamerVideoWindow::aspectRatioMode() const
-@@ -157,6 +198,16 @@ void QGstreamerVideoWindow::setAspectRatioMode(Qt::AspectRatioMode mode)
- 
- void QGstreamerVideoWindow::repaint()
- {
-+#if GST_CHECK_VERSION(1,0,0)
-+    if (m_videoSink && GST_IS_VIDEO_OVERLAY(m_videoSink)) {
-+        //don't call gst_x_overlay_expose if the sink is in null state
-+        GstState state = GST_STATE_NULL;
-+        GstStateChangeReturn res = gst_element_get_state(m_videoSink, &state, NULL, 1000000);
-+        if (res != GST_STATE_CHANGE_FAILURE && state != GST_STATE_NULL) {
-+            gst_video_overlay_expose(GST_VIDEO_OVERLAY(m_videoSink));
-+        }
-+    }
-+#else
-     if (m_videoSink && GST_IS_X_OVERLAY(m_videoSink)) {
-         //don't call gst_x_overlay_expose if the sink is in null state
-         GstState state = GST_STATE_NULL;
-@@ -165,6 +216,7 @@ void QGstreamerVideoWindow::repaint()
-             gst_x_overlay_expose(GST_X_OVERLAY(m_videoSink));
-         }
-     }
-+#endif
- }
- 
- QColor QGstreamerVideoWindow::colorKey() const
-@@ -296,11 +348,22 @@ QSize QGstreamerVideoWindow::nativeSize() const
-     return m_nativeSize;
- }
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+GstPadProbeReturn QGstreamerVideoWindow::padBufferProbe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
-+#else
- void QGstreamerVideoWindow::padBufferProbe(GstPad *pad, GstBuffer * /* buffer */, gpointer user_data)
-+#endif
- {
-     QGstreamerVideoWindow *control = reinterpret_cast<QGstreamerVideoWindow*>(user_data);
-     QMetaObject::invokeMethod(control, "updateNativeVideoSize", Qt::QueuedConnection);
-+
-+#if GST_CHECK_VERSION(1,0,0)
-+    Q_UNUSED(pad);
-+    Q_UNUSED(info);
-+    return GST_PAD_PROBE_REMOVE;
-+#else
-     gst_pad_remove_buffer_probe(pad, control->m_bufferProbeId);
-+#endif
- }
- 
- void QGstreamerVideoWindow::updateNativeVideoSize()
-@@ -311,7 +374,11 @@ void QGstreamerVideoWindow::updateNativeVideoSize()
-     if (m_videoSink) {
-         //find video native size to update video widget size hint
-         GstPad *pad = gst_element_get_static_pad(m_videoSink,"sink");
-+#if GST_CHECK_VERSION(1,0,0)
-+        GstCaps *caps = gst_pad_get_current_caps(pad);
-+#else
-         GstCaps *caps = gst_pad_get_negotiated_caps(pad);
-+#endif
-         gst_object_unref(GST_OBJECT(pad));
- 
-         if (caps) {
-diff --git a/src/gsttools/qgstutils.cpp b/src/gsttools/qgstutils.cpp
-index 556fc03..5ea2c59 100644
---- a/src/gsttools/qgstutils.cpp
-+++ b/src/gsttools/qgstutils.cpp
-@@ -89,8 +89,13 @@ static void addTagToMap(const GstTagList *list,
-             break;
-         default:
-             // GST_TYPE_DATE is a function, not a constant, so pull it out of the switch
-+#if GST_CHECK_VERSION(1,0,0)
-+            if (G_VALUE_TYPE(&val) == G_TYPE_DATE) {
-+                const GDate *date = (const GDate *)g_value_get_boxed(&val);
-+#else
-             if (G_VALUE_TYPE(&val) == GST_TYPE_DATE) {
-                 const GDate *date = gst_value_get_date(&val);
-+#endif
-                 if (g_date_valid(date)) {
-                     int year = g_date_get_year(date);
-                     int month = g_date_get_month(date);
-@@ -254,6 +259,24 @@ QAudioFormat QGstUtils::audioFormatForCaps(const GstCaps *caps)
- }
- 
- 
-+
-+#if GST_CHECK_VERSION(1,0,0)
-+/*!
-+  Returns audio format for a buffer.
-+  If the buffer doesn't have a valid audio format, an empty QAudioFormat is returned.
-+*/
-+
-+QAudioFormat QGstUtils::audioFormatForSample(GstSample *sample)
-+{
-+    GstCaps* caps = gst_sample_get_caps(sample);
-+    if (!caps)
-+        return QAudioFormat();
-+
-+    QAudioFormat format = QGstUtils::audioFormatForCaps(caps);
-+    gst_caps_unref(caps);
-+    return format;
-+}
-+#else
- /*!
-   Returns audio format for a buffer.
-   If the buffer doesn't have a valid audio format, an empty QAudioFormat is returned.
-@@ -269,7 +292,7 @@ QAudioFormat QGstUtils::audioFormatForBuffer(GstBuffer *buffer)
-     gst_caps_unref(caps);
-     return format;
- }
--
-+#endif
- 
- /*!
-   Builds GstCaps for an audio format.
-@@ -579,7 +602,7 @@ QByteArray QGstUtils::cameraDriver(const QString &device, GstElementFactory *fac
- 
- void qt_gst_object_ref_sink(gpointer object)
- {
--#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 24)
-+#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 24) || GST_CHECK_VERSION(1,0,0)
-     gst_object_ref_sink(object);
- #else
-     g_return_if_fail (GST_IS_OBJECT(object));
-diff --git a/src/gsttools/qgstvideobuffer.cpp b/src/gsttools/qgstvideobuffer.cpp
-index 18702ec..93f22f5 100644
---- a/src/gsttools/qgstvideobuffer.cpp
-+++ b/src/gsttools/qgstvideobuffer.cpp
-@@ -70,21 +70,33 @@ QAbstractVideoBuffer::MapMode QGstVideoBuffer::mapMode() const
- uchar *QGstVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
- {
-     if (mode != NotMapped && m_mode == NotMapped) {
--        if (numBytes)
--            *numBytes = m_buffer->size;
-+        m_mode = mode;
- 
-         if (bytesPerLine)
-             *bytesPerLine = m_bytesPerLine;
- 
--        m_mode = mode;
-+#if GST_CHECK_VERSION(1,0,0)
-+        gst_buffer_map(m_buffer, &m_mapInfo, GST_MAP_READ);
-+        if (numBytes)
-+            *numBytes = m_mapInfo.size;
-+
-+        return m_mapInfo.data;
-+#else
-+        if (numBytes)
-+            *numBytes = m_buffer->size;
- 
-         return m_buffer->data;
-+#endif
-     } else {
-         return 0;
-     }
- }
- void QGstVideoBuffer::unmap()
- {
-+#if GST_CHECK_VERSION(1,0,0)
-+    if (m_mode != NotMapped)
-+        gst_buffer_unmap(m_buffer, &m_mapInfo);
-+#endif
-     m_mode = NotMapped;
- }
- 
-diff --git a/src/gsttools/qvideosurfacegstsink.cpp b/src/gsttools/qvideosurfacegstsink.cpp
-index f3e2d88..a964e82 100644
---- a/src/gsttools/qvideosurfacegstsink.cpp
-+++ b/src/gsttools/qvideosurfacegstsink.cpp
-@@ -43,7 +43,11 @@
- 
- #include "qvideosurfacegstsink_p.h"
- 
--//#define DEBUG_VIDEO_SURFACE_SINK
-+#if GST_VERSION_MAJOR >=1
-+#include <gst/video/video.h>
-+#endif
-+
-+#define DEBUG_VIDEO_SURFACE_SINK
- 
- QT_BEGIN_NAMESPACE
- 
-@@ -62,10 +66,12 @@ QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(
-     if (m_surface) {
-         foreach (QObject *instance, bufferPoolLoader()->instances(QGstBufferPoolPluginKey)) {
-             QGstBufferPoolInterface* plugin = qobject_cast<QGstBufferPoolInterface*>(instance);
-+
-             if (plugin) {
-                 m_pools.append(plugin);
-             }
-         }
-+
-         updateSupportedFormats();
-         connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(updateSupportedFormats()));
-     }
-@@ -198,6 +204,8 @@ GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer)
-     if (QThread::currentThread() == thread()) {
-         if (!m_surface.isNull())
-             m_surface->present(m_frame);
-+        else
-+            qWarning() << "m_surface.isNull().";
-     } else {
-         QMetaObject::invokeMethod(this, "queuedRender", Qt::QueuedConnection);
-         m_renderCondition.wait(&m_mutex, 300);
-@@ -283,6 +291,27 @@ void QVideoSurfaceGstDelegate::updateSupportedFormats()
-     }
- }
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+struct YuvFormat
-+{
-+    QVideoFrame::PixelFormat pixelFormat;
-+    GstVideoFormat vfmt;
-+    guint32 fourcc;
-+    int bitsPerPixel;
-+};
-+
-+static const YuvFormat qt_yuvColorLookup[] =
-+{
-+    { QVideoFrame::Format_YUV420P, GST_VIDEO_FORMAT_I420, GST_MAKE_FOURCC('I','4','2','0'), 8  },
-+    { QVideoFrame::Format_YV12,    GST_VIDEO_FORMAT_YV12, GST_MAKE_FOURCC('Y','V','1','2'), 8  },
-+    { QVideoFrame::Format_UYVY,    GST_VIDEO_FORMAT_UYVY, GST_MAKE_FOURCC('U','Y','V','Y'), 16 },
-+    { QVideoFrame::Format_YUYV,    GST_VIDEO_FORMAT_YUY2, GST_MAKE_FOURCC('Y','U','Y','2'), 16 },
-+    { QVideoFrame::Format_NV12,    GST_VIDEO_FORMAT_NV12, GST_MAKE_FOURCC('N','V','1','2'), 8 },
-+    { QVideoFrame::Format_NV21,    GST_VIDEO_FORMAT_NV21, GST_MAKE_FOURCC('N','V','2','1'), 8 },
-+    { QVideoFrame::Format_AYUV444, GST_VIDEO_FORMAT_AYUV, GST_MAKE_FOURCC('A','Y','U','V'), 32 },
-+};
-+
-+#else
- struct YuvFormat
- {
-     QVideoFrame::PixelFormat pixelFormat;
-@@ -300,6 +329,7 @@ static const YuvFormat qt_yuvColorLookup[] =
-     { QVideoFrame::Format_NV21,    GST_MAKE_FOURCC('N','V','2','1'), 8 },
-     { QVideoFrame::Format_AYUV444, GST_MAKE_FOURCC('A','Y','U','V'), 32 }
- };
-+#endif
- 
- static int indexOfYuvColor(QVideoFrame::PixelFormat format)
- {
-@@ -312,12 +342,20 @@ static int indexOfYuvColor(QVideoFrame::PixelFormat format)
-     return -1;
- }
- 
-+#if GST_VERSION_MAJOR >=1
-+static int indexOfYuvColor(GstVideoFormat vfmt)
-+#else
- static int indexOfYuvColor(guint32 fourcc)
-+#endif
- {
-     const int count = sizeof(qt_yuvColorLookup) / sizeof(YuvFormat);
- 
-     for (int i = 0; i < count; ++i)
-+#if GST_VERSION_MAJOR >=1
-+        if (qt_yuvColorLookup[i].vfmt == vfmt)
-+#else
-         if (qt_yuvColorLookup[i].fourcc == fourcc)
-+#endif
-             return i;
- 
-     return -1;
-@@ -388,13 +426,13 @@ GType QVideoSurfaceGstSink::get_type()
-     if (type == 0) {
-         static const GTypeInfo info =
-         {
--            sizeof(QVideoSurfaceGstSinkClass),                    // class_size
-+            sizeof(QVideoSurfaceGstSinkClass),                 // class_size
-             base_init,                                         // base_init
-             NULL,                                              // base_finalize
-             class_init,                                        // class_init
-             NULL,                                              // class_finalize
-             NULL,                                              // class_data
--            sizeof(QVideoSurfaceGstSink),                         // instance_size
-+            sizeof(QVideoSurfaceGstSink),                      // instance_size
-             0,                                                 // n_preallocs
-             instance_init,                                     // instance_init
-             0                                                  // value_table
-@@ -419,7 +457,11 @@ void QVideoSurfaceGstSink::class_init(gpointer g_class, gpointer class_data)
-     GstBaseSinkClass *base_sink_class = reinterpret_cast<GstBaseSinkClass *>(g_class);
-     base_sink_class->get_caps = QVideoSurfaceGstSink::get_caps;
-     base_sink_class->set_caps = QVideoSurfaceGstSink::set_caps;
-+// FIXME:
-+#if GST_CHECK_VERSION(1,0,0)
-+#else
-     base_sink_class->buffer_alloc = QVideoSurfaceGstSink::buffer_alloc;
-+#endif
-     base_sink_class->start = QVideoSurfaceGstSink::start;
-     base_sink_class->stop = QVideoSurfaceGstSink::stop;
- 
-@@ -434,6 +476,18 @@ void QVideoSurfaceGstSink::base_init(gpointer g_class)
- {
-     static GstStaticPadTemplate sink_pad_template = GST_STATIC_PAD_TEMPLATE(
-             "sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS(
-+#if GST_CHECK_VERSION(1,0,0)
-+                    "video/x-raw, "
-+                    "format = (string) RGBA,"
-+                    "framerate = (fraction) [ 0, MAX ], "
-+                    "width = (int) [ 1, MAX ], "
-+                    "height = (int) [ 1, MAX ]; "
-+                    "video/x-raw, "
-+                    "format = (string) I420,"
-+                    "framerate = (fraction) [ 0, MAX ], "
-+                    "width = (int) [ 1, MAX ], "
-+                    "height = (int) [ 1, MAX ]"));
-+#else
-                     "video/x-raw-rgb, "
-                     "framerate = (fraction) [ 0, MAX ], "
-                     "width = (int) [ 1, MAX ], "
-@@ -442,6 +496,7 @@ void QVideoSurfaceGstSink::base_init(gpointer g_class)
-                     "framerate = (fraction) [ 0, MAX ], "
-                     "width = (int) [ 1, MAX ], "
-                     "height = (int) [ 1, MAX ]"));
-+#endif
- 
-     gst_element_class_add_pad_template(
-             GST_ELEMENT_CLASS(g_class), gst_static_pad_template_get(&sink_pad_template));
-@@ -490,7 +545,11 @@ GstStateChangeReturn QVideoSurfaceGstSink::change_state(
-             element, transition);
- }
- 
--GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base)
-+GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base
-+#if GST_CHECK_VERSION(1,0,0)
-+                                        , GstCaps* /*filterCaps*/
-+#endif
-+)
- {
-     VO_SINK(base);
- 
-@@ -503,6 +562,7 @@ GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base)
-     QList<QVideoFrame::PixelFormat> poolHandleFormats;
-     sink->delegate->poolMutex()->lock();
-     QGstBufferPoolInterface *pool = sink->delegate->pool();
-+
-     if (pool)
-         poolHandleFormats = sink->delegate->supportedPixelFormats(pool->handleType());
-     sink->delegate->poolMutex()->unlock();
-@@ -518,11 +578,19 @@ GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base)
- 
-         if (index != -1) {
-             gst_caps_append_structure(caps, gst_structure_new(
-+#if GST_CHECK_VERSION(1,0,0)
-+                    "video/x-raw",
-+#else
-                     "video/x-raw-yuv",
-+#endif
-                     "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, INT_MAX, 1,
-                     "width"    , GST_TYPE_INT_RANGE, 1, INT_MAX,
-                     "height"   , GST_TYPE_INT_RANGE, 1, INT_MAX,
--                    "format"   , GST_TYPE_FOURCC, qt_yuvColorLookup[index].fourcc,
-+#if GST_CHECK_VERSION(1,0,0)
-+                    "format"   , G_TYPE_STRING, gst_video_format_to_string(qt_yuvColorLookup[index].vfmt),
-+#else
-+                    "format"   , GST_TYPE_FOURCC, qt_yuvColorLookup[index].fourcc,
-+#endif
-                     NULL));
-             continue;
-         }
-@@ -532,7 +600,18 @@ GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base)
-         for (int i = 0; i < count; ++i) {
-             if (qt_rgbColorLookup[i].pixelFormat == format) {
-                 GstStructure *structure = gst_structure_new(
-+#if GST_CHECK_VERSION(1,0,0)
-+                        "video/x-raw",
-+                        "format"    , G_TYPE_STRING, gst_video_format_to_string(gst_video_format_from_masks(qt_rgbColorLookup[i].depth,
-+                                                                                 qt_rgbColorLookup[i].bitsPerPixel,
-+                                                                                 qt_rgbColorLookup[i].endianness,
-+                                                                                 qt_rgbColorLookup[i].red,
-+                                                                                 qt_rgbColorLookup[i].green,
-+                                                                                 qt_rgbColorLookup[i].blue,
-+                                                                                 qt_rgbColorLookup[i].alpha)),
-+#else
-                         "video/x-raw-rgb",
-+#endif
-                         "framerate" , GST_TYPE_FRACTION_RANGE, 0, 1, INT_MAX, 1,
-                         "width"     , GST_TYPE_INT_RANGE, 1, INT_MAX,
-                         "height"    , GST_TYPE_INT_RANGE, 1, INT_MAX,
-@@ -553,6 +632,7 @@ GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base)
-         }
-     }
- 
-+//    printf("get Caps %"GST_PTR_FORMAT"\n", caps);
-     return caps;
- }
- 
-@@ -592,7 +672,7 @@ gboolean QVideoSurfaceGstSink::set_caps(GstBaseSink *base, GstCaps *caps)
-         sink->lastRequestedCaps = 0;
- 
- #ifdef DEBUG_VIDEO_SURFACE_SINK
--        qDebug() << "Staring video surface, format:";
-+        qDebug() << "Starting video surface, format:";
-         qDebug() << format;
-         qDebug() << "bytesPerLine:" << bytesPerLine;
- #endif
-@@ -617,11 +697,49 @@ QVideoSurfaceFormat QVideoSurfaceGstSink::formatForCaps(GstCaps *caps, int *byte
-     gst_structure_get_int(structure, "width", &size.rwidth());
-     gst_structure_get_int(structure, "height", &size.rheight());
- 
-+#if GST_CHECK_VERSION(1, 0, 0)
-+    GstVideoInfo info;
-+    gst_video_info_from_caps(&info, caps);
-+
-+    if (info.finfo->format == GST_VIDEO_FORMAT_I420) {
-+        int index = indexOfYuvColor(GST_VIDEO_FORMAT_I420);
-+
-+        if (index != -1) {
-+            pixelFormat = qt_yuvColorLookup[index].pixelFormat;
-+            bitsPerPixel = qt_yuvColorLookup[index].bitsPerPixel;
-+        }
-+    } else if (info.finfo->format == GST_VIDEO_FORMAT_RGBx) {
-+        int depth = 0;
-+        int endianness = 0;
-+        int red = 0;
-+        int green = 0;
-+        int blue = 0;
-+        int alpha = 0;
-+
-+        gst_structure_get_int(structure, "bpp", &bitsPerPixel);
-+        gst_structure_get_int(structure, "depth", &depth);
-+        gst_structure_get_int(structure, "endianness", &endianness);
-+        gst_structure_get_int(structure, "red_mask", &red);
-+        gst_structure_get_int(structure, "green_mask", &green);
-+        gst_structure_get_int(structure, "blue_mask", &blue);
-+        gst_structure_get_int(structure, "alpha_mask", &alpha);
-+
-+        int index = indexOfRgbColor(bitsPerPixel, depth, endianness, red, green, blue, alpha);
-+        printf("INDEX %x\n", index);
-+        if (index != -1)
-+            pixelFormat = qt_rgbColorLookup[index].pixelFormat;
-+    }
-+#else
-+
-     if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-yuv") == 0) {
-         guint32 fourcc = 0;
-+#if GST_CHECK_VERSION(1, 0, 0)
-+        int index = indexOfYuvColor(gst_video_format_from_string(gst_structure_get_string(structure, "format")));
-+#else
-         gst_structure_get_fourcc(structure, "format", &fourcc);
- 
-         int index = indexOfYuvColor(fourcc);
-+#endif
-         if (index != -1) {
-             pixelFormat = qt_yuvColorLookup[index].pixelFormat;
-             bitsPerPixel = qt_yuvColorLookup[index].bitsPerPixel;
-@@ -647,6 +765,7 @@ QVideoSurfaceFormat QVideoSurfaceGstSink::formatForCaps(GstCaps *caps, int *byte
-         if (index != -1)
-             pixelFormat = qt_rgbColorLookup[index].pixelFormat;
-     }
-+#endif
- 
-     if (pixelFormat != QVideoFrame::Format_Invalid) {
-         QVideoSurfaceFormat format(size, pixelFormat, handleType);
-@@ -722,7 +841,11 @@ GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
- 
-     poolLock.unlock();
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+    GstCaps *intersection = gst_caps_intersect(get_caps(GST_BASE_SINK(sink), NULL), caps);
-+#else
-     GstCaps *intersection = gst_caps_intersect(get_caps(GST_BASE_SINK(sink)), caps);
-+#endif
- 
-     if (gst_caps_is_empty (intersection)) {
-         gst_caps_unref(intersection);
-@@ -763,7 +886,7 @@ GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
-     QVideoSurfaceFormat surfaceFormat = sink->delegate->surfaceFormat();
- 
-     if (!pool->isFormatSupported(surfaceFormat)) {
--        //qDebug() << "sink doesn't support native pool format, skip custom buffers allocation";
-+        qDebug() << "sink doesn't support native pool format, skip custom buffers allocation";
-         return GST_FLOW_OK;
-     }
- 
-@@ -787,7 +910,6 @@ GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
- gboolean QVideoSurfaceGstSink::start(GstBaseSink *base)
- {
-     Q_UNUSED(base);
--
-     return TRUE;
- }
- 
-diff --git a/src/multimedia/gsttools_headers/qgstappsrc_p.h b/src/multimedia/gsttools_headers/qgstappsrc_p.h
-index 4af9252..0e0fc0a 100644
---- a/src/multimedia/gsttools_headers/qgstappsrc_p.h
-+++ b/src/multimedia/gsttools_headers/qgstappsrc_p.h
-@@ -39,7 +39,10 @@
- 
- #include <gst/gst.h>
- #include <gst/app/gstappsrc.h>
-+
-+#if GST_VERSION_MAJOR < 1
- #include <gst/app/gstappbuffer.h>
-+#endif
- 
- QT_BEGIN_NAMESPACE
- 
-diff --git a/src/multimedia/gsttools_headers/qgstreameraudioprobecontrol_p.h b/src/multimedia/gsttools_headers/qgstreameraudioprobecontrol_p.h
-index 34669b8..0f3b165 100644
---- a/src/multimedia/gsttools_headers/qgstreameraudioprobecontrol_p.h
-+++ b/src/multimedia/gsttools_headers/qgstreameraudioprobecontrol_p.h
-@@ -47,8 +47,11 @@ class QGstreamerAudioProbeControl : public QMediaAudioProbeControl
- public:
-     explicit QGstreamerAudioProbeControl(QObject *parent);
-     virtual ~QGstreamerAudioProbeControl();
--
-+#if GST_CHECK_VERSION(1,0,0)
-+    void bufferProbed(GstBuffer* buffer, GstCaps* caps);
-+#else
-     void bufferProbed(GstBuffer* buffer);
-+#endif
- 
- private slots:
-     void bufferProbed();
-diff --git a/src/multimedia/gsttools_headers/qgstreamervideoprobecontrol_p.h b/src/multimedia/gsttools_headers/qgstreamervideoprobecontrol_p.h
-index 49064f9..fce6309 100644
---- a/src/multimedia/gsttools_headers/qgstreamervideoprobecontrol_p.h
-+++ b/src/multimedia/gsttools_headers/qgstreamervideoprobecontrol_p.h
-@@ -48,7 +48,11 @@ public:
-     explicit QGstreamerVideoProbeControl(QObject *parent);
-     virtual ~QGstreamerVideoProbeControl();
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+    void bufferProbed(GstBuffer* buffer, GstCaps*);
-+#else
-     void bufferProbed(GstBuffer* buffer);
-+#endif
-     void startFlushing();
-     void stopFlushing();
- 
-diff --git a/src/multimedia/gsttools_headers/qgstreamervideowindow_p.h b/src/multimedia/gsttools_headers/qgstreamervideowindow_p.h
-index 81e5764..c9fdb5c 100644
---- a/src/multimedia/gsttools_headers/qgstreamervideowindow_p.h
-+++ b/src/multimedia/gsttools_headers/qgstreamervideowindow_p.h
-@@ -104,7 +104,11 @@ private slots:
-     void updateNativeVideoSize();
- 
- private:
-+#if GST_CHECK_VERSION(1,0,0)
-+    static GstPadProbeReturn padBufferProbe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data);
-+#else
-     static void padBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data);
-+#endif
- 
-     GstElement *m_videoSink;
-     WId m_windowId;
-diff --git a/src/multimedia/gsttools_headers/qgstutils_p.h b/src/multimedia/gsttools_headers/qgstutils_p.h
-index 65ff759..6015980 100644
---- a/src/multimedia/gsttools_headers/qgstutils_p.h
-+++ b/src/multimedia/gsttools_headers/qgstutils_p.h
-@@ -73,7 +73,11 @@ namespace QGstUtils {
-     QSize capsResolution(const GstCaps *caps);
-     QSize capsCorrectedResolution(const GstCaps *caps);
-     QAudioFormat audioFormatForCaps(const GstCaps *caps);
-+#if GST_CHECK_VERSION(1,0,0)
-+    QAudioFormat audioFormatForSample(GstSample *sample);
-+#else
-     QAudioFormat audioFormatForBuffer(GstBuffer *buffer);
-+#endif
-     GstCaps *capsForAudioFormat(QAudioFormat format);
-     void initializeGst();
-     QMultimedia::SupportEstimate hasSupport(const QString &mimeType,
-diff --git a/src/multimedia/gsttools_headers/qgstvideobuffer_p.h b/src/multimedia/gsttools_headers/qgstvideobuffer_p.h
-index 1e0fda8..be48820 100644
---- a/src/multimedia/gsttools_headers/qgstvideobuffer_p.h
-+++ b/src/multimedia/gsttools_headers/qgstvideobuffer_p.h
-@@ -71,6 +71,9 @@ private:
-     int m_bytesPerLine;
-     MapMode m_mode;
-     QVariant m_handle;
-+#if GST_CHECK_VERSION(1,0,0)
-+    GstMapInfo m_mapInfo;
-+#endif
- };
- 
- QT_END_NAMESPACE
-diff --git a/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h b/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h
-index 11b305d..01935f7 100644
---- a/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h
-+++ b/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h
-@@ -131,7 +131,11 @@ private:
- 
-     static GstStateChangeReturn change_state(GstElement *element, GstStateChange transition);
- 
--    static GstCaps *get_caps(GstBaseSink *sink);
-+    static GstCaps *get_caps(GstBaseSink *sink
-+#if GST_CHECK_VERSION(1,0,0)
-+                             , GstCaps* /*filterCaps*/
-+#endif
-+                            );
-     static gboolean set_caps(GstBaseSink *sink, GstCaps *caps);
- 
-     static GstFlowReturn buffer_alloc(
-diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp
-index 3098aab..9c54663 100644
---- a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp
-+++ b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecoderserviceplugin.cpp
-@@ -74,29 +74,42 @@ void QGstreamerAudioDecoderServicePlugin::updateSupportedMimeTypes() const
-     gst_init(NULL, NULL);
- 
-     GList *plugins, *orig_plugins;
-+#if GST_CHECK_VERSION(1,0,0)
-+    orig_plugins = plugins = gst_registry_get_plugin_list (gst_registry_get());
-+#else
-     orig_plugins = plugins = gst_default_registry_get_plugin_list ();
--
-+#endif
-     while (plugins) {
-         GList *features, *orig_features;
- 
-         GstPlugin *plugin = (GstPlugin *) (plugins->data);
-         plugins = g_list_next (plugins);
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+        if (GST_OBJECT_FLAG_IS_SET(plugin, GST_PLUGIN_FLAG_BLACKLISTED))
-+            continue;
-+#else
-         if (plugin->flags & (1<<1)) //GST_PLUGIN_FLAG_BLACKLISTED
-             continue;
--
--        orig_features = features = gst_registry_get_feature_list_by_plugin(gst_registry_get_default (),
--                                                                        plugin->desc.name);
-+#endif
-+        orig_features = features = gst_registry_get_feature_list_by_plugin(gst_registry_get (),
-+                                                                         gst_plugin_get_name(plugin));
-         while (features) {
-             if (!G_UNLIKELY(features->data == NULL)) {
-                 GstPluginFeature *feature = GST_PLUGIN_FEATURE(features->data);
-                 if (GST_IS_ELEMENT_FACTORY (feature)) {
-                     GstElementFactory *factory = GST_ELEMENT_FACTORY(gst_plugin_feature_load(feature));
-                     if (factory
--                       && factory->numpadtemplates > 0
-+                       && gst_element_factory_get_num_pad_templates(factory) > 0
-+#if GST_CHECK_VERSION(1,0,0)
-+                       && (qstrcmp(gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS), "Codec/Decoder/Audio") == 0
-+                          || qstrcmp(gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS), "Codec/Demux") == 0 )
-+#else
-                        && (qstrcmp(factory->details.klass, "Codec/Decoder/Audio") == 0
--                          || qstrcmp(factory->details.klass, "Codec/Demux") == 0 )) {
--                        const GList *pads = factory->staticpadtemplates;
-+                           || qstrcmp(factory->details.klass, "Codec/Demux") == 0 )
-+#endif
-+                        ) {
-+                        const GList *pads = gst_element_factory_get_static_pad_templates(factory);
-                         while (pads) {
-                             GstStaticPadTemplate *padtemplate = (GstStaticPadTemplate*)(pads->data);
-                             pads = g_list_next (pads);
-diff --git a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp
-index f944a60..72d1cf1 100644
---- a/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp
-+++ b/src/plugins/gstreamer/audiodecoder/qgstreameraudiodecodersession.cpp
-@@ -446,21 +446,40 @@ QAudioBuffer QGstreamerAudioDecoderSession::read()
-         if (buffersAvailable == 1)
-             emit bufferAvailableChanged(false);
- 
-+        const char* bufferData = 0;
-+        int bufferSize = 0;
-+
-+#if GST_CHECK_VERSION(1,0,0)
-+        GstSample *sample = gst_app_sink_pull_sample(m_appSink);
-+        GstBuffer *buffer = gst_sample_get_buffer(sample);
-+        GstMapInfo mapInfo;
-+        gst_buffer_map(buffer, &mapInfo, GST_MAP_READ);
-+        bufferData = (const char*)mapInfo.data;
-+        bufferSize = mapInfo.size;
-+        QAudioFormat format = QGstUtils::audioFormatForSample(sample);
-+#else
-         GstBuffer *buffer = gst_app_sink_pull_buffer(m_appSink);
--
-+        bufferData = (const char*)buffer->data;
-+        bufferSize = buffer->size;
-         QAudioFormat format = QGstUtils::audioFormatForBuffer(buffer);
-+#endif
-+
-         if (format.isValid()) {
-             // XXX At the moment we have to copy data from GstBuffer into QAudioBuffer.
-             // We could improve performance by implementing QAbstractAudioBuffer for GstBuffer.
-             qint64 position = getPositionFromBuffer(buffer);
--            audioBuffer = QAudioBuffer(QByteArray((const char*)buffer->data, buffer->size), format, position);
-+            audioBuffer = QAudioBuffer(QByteArray((const char*)bufferData, bufferSize), format, position);
-             position /= 1000; // convert to milliseconds
-             if (position != m_position) {
-                 m_position = position;
-                 emit positionChanged(m_position);
-             }
-         }
-+#if GST_CHECK_VERSION(1,0,0)
-+        gst_sample_unref(sample);
-+#else
-         gst_buffer_unref(buffer);
-+#endif
-     }
- 
-     return audioBuffer;
-@@ -531,7 +550,12 @@ void QGstreamerAudioDecoderSession::addAppSink()
- 
-     GstAppSinkCallbacks callbacks;
-     memset(&callbacks, 0, sizeof(callbacks));
-+#if GST_CHECK_VERSION(1,0,0)
-+    // ### Should perhaps also rename new_buffer to new_sample.
-+    callbacks.new_sample = &new_buffer;
-+#else
-     callbacks.new_buffer = &new_buffer;
-+#endif
-     gst_app_sink_set_callbacks(m_appSink, &callbacks, this, NULL);
-     gst_app_sink_set_max_buffers(m_appSink, MAX_BUFFERS_IN_QUEUE);
-     gst_base_sink_set_sync(GST_BASE_SINK(m_appSink), FALSE);
-@@ -557,8 +581,13 @@ void QGstreamerAudioDecoderSession::updateDuration()
-     gint64 gstDuration = 0;
-     int duration = -1;
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+    if (m_playbin && gst_element_query_duration(m_playbin, format, &gstDuration))
-+        duration = gstDuration / 1000000;
-+#else
-     if (m_playbin && gst_element_query_duration(m_playbin, &format, &gstDuration))
-         duration = gstDuration / 1000000;
-+#endif
- 
-     if (m_duration != duration) {
-         m_duration = duration;
-diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp
-index a4038c5..9d1fdfa 100644
---- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp
-+++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp
-@@ -760,7 +760,11 @@ qint64 CameraBinSession::duration() const
-         if (fileSink) {
-             GstFormat format = GST_FORMAT_TIME;
-             gint64 duration = 0;
-+#if GST_CHECK_VERSION(1,0,0)
-+            bool ret = gst_element_query_duration(fileSink, format, &duration);
-+#else
-             bool ret = gst_element_query_position(fileSink, &format, &duration);
-+#endif
-             gst_object_unref(GST_OBJECT(fileSink));
-             if (ret)
-                 return duration / 1000000;
-@@ -797,8 +801,13 @@ void CameraBinSession::setMetaData(const QMap<QByteArray, QVariant> &data)
- 
-     if (m_camerabin) {
-         GstIterator *elements = gst_bin_iterate_all_by_interface(GST_BIN(m_camerabin), GST_TYPE_TAG_SETTER);
-+#if GST_CHECK_VERSION(1,0,0)
-+        GValue *element = 0;
-+        while (gst_iterator_next(elements, element) == GST_ITERATOR_OK) {
-+#else
-         GstElement *element = 0;
-         while (gst_iterator_next(elements, (void**)&element) == GST_ITERATOR_OK) {
-+#endif
-             gst_tag_setter_reset_tags(GST_TAG_SETTER(element));
- 
-             QMapIterator<QByteArray, QVariant> it(data);
-@@ -859,7 +868,11 @@ bool CameraBinSession::processSyncMessage(const QGstreamerMessage &message)
- 
-     if (gm && GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) {
-         if (m_captureMode == QCamera::CaptureStillImage &&
-+#if GST_CHECK_VERSION(1,0,0)
-+            gst_message_has_name (gm, "preview-image")) {
-+#else
-             gst_structure_has_name(gm->structure, "preview-image")) {
-+#endif
-             st = gst_message_get_structure(gm);
- 
-             if (gst_structure_has_field_typed(st, "buffer", GST_TYPE_BUFFER)) {
-@@ -869,7 +882,11 @@ bool CameraBinSession::processSyncMessage(const QGstreamerMessage &message)
- 
-                     QImage img;
- 
-+#if GST_CHECK_VERSION(1,0,0)
-                     GstCaps *caps = gst_buffer_get_caps(buffer);
-+#else
-+                    GstCaps *caps = gst_buffer_get_caps(buffer);
-+#endif
-                     if (caps) {
-                         GstStructure *structure = gst_caps_get_structure(caps, 0);
-                         gint width = 0;
-@@ -1142,7 +1159,11 @@ QList< QPair<int,int> > CameraBinSession::supportedFrameRates(const QSize &frame
-         gst_structure_remove_all_fields(structure);
-         gst_structure_set_value(structure, "framerate", &rate);
-     }
-+#if GST_CHECK_VERSION(1,0,0)
-+    caps = gst_caps_simplify(caps);
-+#else
-     gst_caps_do_simplify(caps);
-+#endif
- 
- 
-     for (uint i=0; i<gst_caps_get_size(caps); i++) {
-@@ -1262,7 +1283,11 @@ QList<QSize> CameraBinSession::supportedResolutions(QPair<int,int> rate,
-         gst_structure_set_value(structure, "width", &w);
-         gst_structure_set_value(structure, "height", &h);
-     }
-+#if GST_CHECK_VERSION(1,0,0)
-+    caps = gst_caps_simplify(caps);
-+#else
-     gst_caps_do_simplify(caps);
-+#endif
- 
-     for (uint i=0; i<gst_caps_get_size(caps); i++) {
-         GstStructure *structure = gst_caps_get_structure(caps, i);
-diff --git a/src/plugins/gstreamer/common.pri b/src/plugins/gstreamer/common.pri
-index 8b421b8..2e7f746 100644
---- a/src/plugins/gstreamer/common.pri
-+++ b/src/plugins/gstreamer/common.pri
-@@ -12,14 +12,17 @@ LIBS += -lqgsttools_p
- CONFIG += link_pkgconfig
- 
- PKGCONFIG += \
--    gstreamer-0.10 \
--    gstreamer-base-0.10 \
--    gstreamer-interfaces-0.10 \
--    gstreamer-audio-0.10 \
--    gstreamer-video-0.10 \
--    gstreamer-pbutils-0.10
-+    gstreamer-$$GST_VERSION \
-+    gstreamer-base-$$GST_VERSION \
-+    gstreamer-audio-$$GST_VERSION \
-+    gstreamer-video-$$GST_VERSION \
-+    gstreamer-pbutils-$$GST_VERSION
- 
--maemo*:PKGCONFIG +=gstreamer-plugins-bad-0.10
-+maemo*:PKGCONFIG +=gstreamer-plugins-bad-$$GST_VERSION
-+
-+mir: {
-+    DEFINES += HAVE_MIR
-+}
- 
- config_resourcepolicy {
-     DEFINES += HAVE_RESOURCE_POLICY
-@@ -27,8 +30,8 @@ config_resourcepolicy {
- }
- 
- config_gstreamer_appsrc {
--    PKGCONFIG += gstreamer-app-0.10
-+    PKGCONFIG += gstreamer-app-$$GST_VERSION
-     DEFINES += HAVE_GST_APPSRC
--    LIBS += -lgstapp-0.10
-+    LIBS += -lgstapp-$$GST_VERSION
- }
- 
-diff --git a/src/plugins/gstreamer/gstreamer.pro b/src/plugins/gstreamer/gstreamer.pro
-index 7649010..fce55ac 100644
---- a/src/plugins/gstreamer/gstreamer.pro
-+++ b/src/plugins/gstreamer/gstreamer.pro
-@@ -2,11 +2,10 @@ TEMPLATE = subdirs
- 
- SUBDIRS += \
-     audiodecoder \
--    mediacapture \
-     mediaplayer
- 
- config_gstreamer_encodingprofiles {
--    SUBDIRS += camerabin
-+#    SUBDIRS += camerabin
- }
- 
- OTHER_FILES += \
-diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
-index a2bd80d..d12e9a5 100644
---- a/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
-+++ b/src/plugins/gstreamer/mediacapture/qgstreamercapturesession.cpp
-@@ -498,6 +498,11 @@ GstElement *QGstreamerCaptureSession::buildImageCapture()
-     gst_pad_add_buffer_probe(pad, G_CALLBACK(passImageFilter), this);
-     gst_object_unref(GST_OBJECT(pad));
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+    gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, passImageFilter, this);
-+#else
-+    gst_pad_add_buffer_probe(pad, G_CALLBACK(passImageFilter), this);
-+#endif
-     g_object_set(G_OBJECT(sink), "signal-handoffs", TRUE, NULL);
-     g_signal_connect(G_OBJECT(sink), "handoff",
-                      G_CALLBACK(saveImageFilter), this);
-diff --git a/src/plugins/gstreamer/mediaplayer/mediaplayer.pro b/src/plugins/gstreamer/mediaplayer/mediaplayer.pro
-index 2ca9377..b986fc7 100644
---- a/src/plugins/gstreamer/mediaplayer/mediaplayer.pro
-+++ b/src/plugins/gstreamer/mediaplayer/mediaplayer.pro
-@@ -28,4 +28,3 @@ SOURCES += \
- 
- OTHER_FILES += \
-     mediaplayer.json
--
-diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp
-index fed756a..8239710 100644
---- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp
-+++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp
-@@ -537,6 +537,8 @@ void QGstreamerPlayerControl::processEOS()
-         m_session->showPrerollFrames(false); // stop showing prerolled frames in stop state
-     }
- 
-+    qWarning() << "Processing EOS!";
-+
-     popAndNotifyState();
- }
- 
-diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp
-index ce267d7..062de07 100644
---- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp
-+++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerservice.cpp
-@@ -51,7 +51,11 @@
- #include <private/qgstreamervideorenderer_p.h>
- 
- #if defined(Q_WS_MAEMO_6) && defined(__arm__)
--#include "qgstreamergltexturerenderer.h"
-+#include "private/qgstreamergltexturerenderer.h"
-+#endif
-+
-+#if defined(HAVE_MIR) && defined (__arm__)
-+#include "private/qgstreamermirtexturerenderer_p.h"
- #endif
- 
- #include "qgstreamerstreamscontrol.h"
-@@ -82,6 +86,9 @@ QGstreamerPlayerService::QGstreamerPlayerService(QObject *parent):
- 
- #if defined(Q_WS_MAEMO_6) && defined(__arm__)
-     m_videoRenderer = new QGstreamerGLTextureRenderer(this);
-+#elif defined(HAVE_MIR) && defined (__arm__)
-+    //m_videoRenderer = new QGstreamerVideoRenderer(this);
-+    m_videoRenderer = new QGstreamerMirTextureRenderer(this, m_session);
- #else
-     m_videoRenderer = new QGstreamerVideoRenderer(this);
- #endif
-diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp
-index 7d20b6d..bf2f9f8 100644
---- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp
-+++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayerserviceplugin.cpp
-@@ -87,7 +87,11 @@ void QGstreamerPlayerServicePlugin::updateSupportedMimeTypes() const
-     gst_init(NULL, NULL);
- 
-     GList *plugins, *orig_plugins;
-+#if GST_CHECK_VERSION(1,0,0)
-+    orig_plugins = plugins = gst_registry_get_plugin_list (gst_registry_get());
-+#else
-     orig_plugins = plugins = gst_default_registry_get_plugin_list ();
-+#endif
- 
-     while (plugins) {
-         GList *features, *orig_features;
-@@ -95,22 +99,33 @@ void QGstreamerPlayerServicePlugin::updateSupportedMimeTypes() const
-         GstPlugin *plugin = (GstPlugin *) (plugins->data);
-         plugins = g_list_next (plugins);
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+        if (GST_OBJECT_FLAG_IS_SET(plugin, GST_PLUGIN_FLAG_BLACKLISTED))
-+            continue;
-+#else
-         if (plugin->flags & (1<<1)) //GST_PLUGIN_FLAG_BLACKLISTED
-             continue;
-+#endif
- 
--        orig_features = features = gst_registry_get_feature_list_by_plugin(gst_registry_get_default (),
--                                                                        plugin->desc.name);
-+        orig_features = features = gst_registry_get_feature_list_by_plugin(gst_registry_get(),
-+                                                                           gst_plugin_get_name(plugin));
-         while (features) {
-             if (!G_UNLIKELY(features->data == NULL)) {
-                 GstPluginFeature *feature = GST_PLUGIN_FEATURE(features->data);
-                 if (GST_IS_ELEMENT_FACTORY (feature)) {
-                     GstElementFactory *factory = GST_ELEMENT_FACTORY(gst_plugin_feature_load(feature));
-                     if (factory
--                       && factory->numpadtemplates > 0
--                       && (qstrcmp(factory->details.klass, "Codec/Decoder/Audio") == 0
-+#if GST_CHECK_VERSION(1,0,0)
-+                        && (qstrcmp(gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS), "Codec/Decoder/Audio") == 0
-+                          || qstrcmp(gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS),"Codec/Decoder/Video") == 0
-+                          || qstrcmp(gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS), "Codec/Demux") == 0 )
-+#else
-+                        && (qstrcmp(factory->details.klass, "Codec/Decoder/Audio") == 0
-                           || qstrcmp(factory->details.klass, "Codec/Decoder/Video") == 0
--                          || qstrcmp(factory->details.klass, "Codec/Demux") == 0 )) {
--                        const GList *pads = factory->staticpadtemplates;
-+                          || qstrcmp(factory->details.klass, "Codec/Demux") == 0 )
-+#endif
-+                        ) {
-+                        const GList *pads = gst_element_factory_get_static_pad_templates(factory);
-                         while (pads) {
-                             GstStaticPadTemplate *padtemplate = (GstStaticPadTemplate*)(pads->data);
-                             pads = g_list_next (pads);
-diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
-index 15924a6..8013d0d 100644
---- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
-+++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp
-@@ -85,6 +85,16 @@ typedef enum {
-     GST_PLAY_FLAG_BUFFERING     = 0x000000100
- } GstPlayFlags;
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+#define DEFAULT_RAW_CAPS \
-+    "video/x-surface; " \
-+    "text/plain; " \
-+    "text/x-pango-markup; " \
-+    "video/x-dvd-subpicture; " \
-+    "subpicture/x-pgs" \
-+    "video/x-raw" \
-+    "audio/x-raw"
-+#else
- #define DEFAULT_RAW_CAPS \
-     "video/x-raw-yuv; " \
-     "video/x-raw-rgb; " \
-@@ -97,6 +107,8 @@ typedef enum {
-     "text/x-pango-markup; " \
-     "video/x-dvd-subpicture; " \
-     "subpicture/x-pgs"
-+#endif
-+
- static GstStaticCaps static_RawCaps = GST_STATIC_CAPS(DEFAULT_RAW_CAPS);
- 
- QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
-@@ -137,8 +149,11 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
-     gboolean result = gst_type_find_register(0, "playlist", GST_RANK_MARGINAL, playlistTypeFindFunction, 0, 0, this, 0);
-     Q_ASSERT(result == TRUE);
-     Q_UNUSED(result);
--
-+#if GST_CHECK_VERSION(1,0,0)
-+    m_playbin = gst_element_factory_make("playbin", NULL);
-+#else
-     m_playbin = gst_element_factory_make("playbin2", NULL);
-+#endif
- 
-     if (m_playbin) {
-         //GST_PLAY_FLAG_NATIVE_VIDEO omits configuration of ffmpegcolorspace and videoscale,
-@@ -188,7 +203,11 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
-     m_videoIdentity = GST_ELEMENT(g_object_new(gst_video_connector_get_type(), 0)); // floating ref
-     g_signal_connect(G_OBJECT(m_videoIdentity), "connection-failed", G_CALLBACK(insertColorSpaceElement), (gpointer)this);
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+    m_colorSpace = gst_element_factory_make("videoconvert", "ffmpegcolorspace-vo");
-+#else
-     m_colorSpace = gst_element_factory_make("ffmpegcolorspace", "ffmpegcolorspace-vo");
-+#endif
-     // might not get a parent, take ownership to avoid leak
-     qt_gst_object_ref_sink(GST_OBJECT(m_colorSpace));
- 
-@@ -206,7 +225,7 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
- 
-     // add ghostpads
-     GstPad *pad = gst_element_get_static_pad(m_videoIdentity,"sink");
--    gst_element_add_pad(GST_ELEMENT(m_videoOutputBin), gst_ghost_pad_new("videosink", pad));
-+    gst_element_add_pad(GST_ELEMENT(m_videoOutputBin), gst_ghost_pad_new("sink", pad));
-     gst_object_unref(GST_OBJECT(pad));
- 
-     if (m_playbin != 0) {
-@@ -218,7 +237,7 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
-         g_object_set(G_OBJECT(m_playbin), "video-sink", m_videoOutputBin, NULL);
- 
-         g_signal_connect(G_OBJECT(m_playbin), "notify::source", G_CALLBACK(playbinNotifySource), this);
--        g_signal_connect(G_OBJECT(m_playbin), "element-added",  G_CALLBACK(handleElementAdded), this);
-+        //g_signal_connect(G_OBJECT(m_playbin), "element-added",  G_CALLBACK(handleElementAdded), this);
- 
-         if (usePlaybinVolume()) {
-             updateVolume();
-@@ -342,9 +361,13 @@ qint64 QGstreamerPlayerSession::position() const
-     GstFormat   format = GST_FORMAT_TIME;
-     gint64      position = 0;
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+    if ( m_playbin && gst_element_query_position(m_playbin, format, &position))
-+        m_lastPosition = position / 1000000;
-+#else
-     if ( m_playbin && gst_element_query_position(m_playbin, &format, &position))
-         m_lastPosition = position / 1000000;
--
-+#endif
-     return m_lastPosition;
- }
- 
-@@ -474,9 +497,18 @@ bool QGstreamerPlayerSession::isAudioAvailable() const
-     return m_audioAvailable;
- }
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+static GstPadProbeReturn block_pad_cb(GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
-+#else
- static void block_pad_cb(GstPad *pad, gboolean blocked, gpointer user_data)
-+#endif
- {
-     Q_UNUSED(pad);
-+#if GST_CHECK_VERSION(1,0,0)
-+    Q_UNUSED(info);
-+    Q_UNUSED(user_data);
-+    return GST_PAD_PROBE_OK;
-+#else
- #ifdef DEBUG_PLAYBIN
-     qDebug() << "block_pad_cb, blocked:" << blocked;
- #endif
-@@ -485,6 +517,7 @@ static void block_pad_cb(GstPad *pad, gboolean blocked, gpointer user_data)
-         QGstreamerPlayerSession *session = reinterpret_cast<QGstreamerPlayerSession*>(user_data);
-         QMetaObject::invokeMethod(session, "finishVideoOutputChange", Qt::QueuedConnection);
-     }
-+#endif
- }
- 
- void QGstreamerPlayerSession::updateVideoRenderer()
-@@ -529,7 +562,7 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
-     m_renderer = renderer;
- 
- #ifdef DEBUG_VO_BIN_DUMP
--    _gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_playbin),
-+    gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_playbin),
-                                   GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL /* GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES*/),
-                                   "playbin_set");
- #endif
-@@ -633,7 +666,11 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
- 
-         //block pads, async to avoid locking in paused state
-         GstPad *srcPad = gst_element_get_static_pad(m_videoIdentity, "src");
-+#if GST_CHECK_VERSION(1,0,0)
-+        this->pad_probe_id = gst_pad_add_probe(srcPad, (GstPadProbeType)(GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BLOCK), block_pad_cb, this, NULL);
-+#else
-         gst_pad_set_blocked_async(srcPad, true, &block_pad_cb, this);
-+#endif
-         gst_object_unref(GST_OBJECT(srcPad));
- 
-         //Unpause the sink to avoid waiting until the buffer is processed
-@@ -674,7 +711,11 @@ void QGstreamerPlayerSession::finishVideoOutputChange()
-         //video output was change back to the current one,
-         //no need to torment the pipeline, just unblock the pad
-         if (gst_pad_is_blocked(srcPad))
-+#if GST_CHECK_VERSION(1,0,0)
-+            gst_pad_remove_probe(srcPad, this->pad_probe_id);
-+#else
-             gst_pad_set_blocked_async(srcPad, false, &block_pad_cb, 0);
-+#endif
- 
-         m_pendingVideoSink = 0;
-         gst_object_unref(GST_OBJECT(srcPad));
-@@ -760,12 +801,17 @@ void QGstreamerPlayerSession::finishVideoOutputChange()
- 
-     //don't have to wait here, it will unblock eventually
-     if (gst_pad_is_blocked(srcPad))
--        gst_pad_set_blocked_async(srcPad, false, &block_pad_cb, 0);
-+#if GST_CHECK_VERSION(1,0,0)
-+            gst_pad_remove_probe(srcPad, this->pad_probe_id);
-+#else
-+            gst_pad_set_blocked_async(srcPad, false, &block_pad_cb, 0);
-+#endif
-+
-     gst_object_unref(GST_OBJECT(srcPad));
- 
- #ifdef DEBUG_VO_BIN_DUMP
--    _gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_playbin),
--                                  GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL /* GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES*/),
-+    gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_playbin),
-+                                  GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL /* | GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES */),
-                                   "playbin_finish");
- #endif
- }
-@@ -830,6 +876,7 @@ bool QGstreamerPlayerSession::play()
- #ifdef DEBUG_PLAYBIN
-     qDebug() << Q_FUNC_INFO;
- #endif
-+
-     m_everPlayed = false;
-     if (m_playbin) {
-         m_pendingState = QMediaPlayer::PlayingState;
-@@ -1327,8 +1374,11 @@ void QGstreamerPlayerSession::getStreamsInfo()
-         default:
-             break;
-         }
--
-+#if GST_CHECK_VERSION(1,0,0)
-+        if (tags && GST_IS_TAG_LIST(tags)) {
-+#else
-         if (tags && gst_is_tag_list(tags)) {
-+#endif
-             gchar *languageCode = 0;
-             if (gst_tag_list_get_string(tags, GST_TAG_LANGUAGE_CODE, &languageCode))
-                 streamProperties[QMediaMetaData::Language] = QString::fromUtf8(languageCode);
-@@ -1367,7 +1417,11 @@ void QGstreamerPlayerSession::updateVideoResolutionTag()
-     QSize aspectRatio;
- 
-     GstPad *pad = gst_element_get_static_pad(m_videoIdentity, "src");
-+#if GST_CHECK_VERSION(1,0,0)
-+    GstCaps *caps = gst_pad_get_current_caps(pad);
-+#else
-     GstCaps *caps = gst_pad_get_negotiated_caps(pad);
-+#endif
- 
-     if (caps) {
-         const GstStructure *structure = gst_caps_get_structure(caps, 0);
-@@ -1411,7 +1465,11 @@ void QGstreamerPlayerSession::updateDuration()
-     gint64 gstDuration = 0;
-     int duration = -1;
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+    if (m_playbin && gst_element_query_duration(m_playbin, format, &gstDuration))
-+#else
-     if (m_playbin && gst_element_query_duration(m_playbin, &format, &gstDuration))
-+#endif
-         duration = gstDuration / 1000000;
- 
-     if (m_duration != duration) {
-@@ -1467,7 +1525,11 @@ void QGstreamerPlayerSession::playbinNotifySource(GObject *o, GParamSpec *p, gpo
- 
-     // The rest
-     if (g_object_class_find_property(G_OBJECT_GET_CLASS(source), "extra-headers") != 0) {
-+#if GST_CHECK_VERSION(1,0,0)
-+        GstStructure *extras = gst_structure_new_empty("extras");
-+#else
-         GstStructure *extras = gst_structure_empty_new("extras");
-+#endif
- 
-         foreach (const QByteArray &rawHeader, self->m_request.rawHeaderList()) {
-             if (rawHeader == userAgentString) // Filter User-Agent
-@@ -1623,7 +1685,11 @@ GstAutoplugSelectResult QGstreamerPlayerSession::handleAutoplugSelect(GstBin *bi
-     const gchar *factoryName = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
-     if (g_str_has_prefix(factoryName, "vaapi")) {
-         GstPad *sinkPad = gst_element_get_static_pad(session->m_videoSink, "sink");
-+#if GST_CHECK_VERSION(1,0,0)
-+        GstCaps *sinkCaps = gst_pad_query_caps(sinkPad, NULL);
-+#else
-         GstCaps *sinkCaps = gst_pad_get_caps(sinkPad);
-+#endif
- 
- #if (GST_VERSION_MAJOR == 0) && ((GST_VERSION_MINOR < 10) || (GST_VERSION_MICRO < 33))
-         if (!factory_can_src_any_caps(factory, sinkCaps))
-@@ -1652,14 +1718,19 @@ void QGstreamerPlayerSession::handleElementAdded(GstBin *bin, GstElement *elemen
-         // Disable on-disk buffering.
-         g_object_set(G_OBJECT(element), "temp-template", NULL, NULL);
-     } else if (g_str_has_prefix(elementName, "uridecodebin") ||
--               g_str_has_prefix(elementName, "decodebin2")) {
--
-+#if GST_CHECK_VERSION(1,0,0)
-+        g_str_has_prefix(elementName, "decodebin")) {
-+#else
-+        g_str_has_prefix(elementName, "decodebin2")) {
-+#endif
-         if (g_str_has_prefix(elementName, "uridecodebin")) {
-             // Add video/x-surface (VAAPI) to default raw formats
-             g_object_set(G_OBJECT(element), "caps", gst_static_caps_get(&static_RawCaps), NULL);
-             // listen for uridecodebin autoplug-select to skip VAAPI usage when the current
-             // video sink doesn't support it
-+#if !(GST_CHECK_VERSION(1,0,0))
-             g_signal_connect(element, "autoplug-select", G_CALLBACK(handleAutoplugSelect), session);
-+#endif
-         }
- 
-         //listen for queue2 element added to uridecodebin/decodebin2 as well.
-@@ -1727,7 +1798,27 @@ void QGstreamerPlayerSession::removeProbe(QGstreamerVideoProbeControl* probe)
-     // Assume user releases any outstanding references to video frames.
- }
- 
--gboolean QGstreamerPlayerSession::padVideoBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data)
-+#if GST_CHECK_VERSION(1,0,0)
-+GstPadProbeReturn QGstreamerPlayerSession::padVideoBufferProbe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
-+{
-+    Q_UNUSED(pad);
-+    GstBuffer* buffer = GST_PAD_PROBE_INFO_BUFFER(info);
-+
-+    QGstreamerPlayerSession *session = reinterpret_cast<QGstreamerPlayerSession*>(user_data);
-+    QMutexLocker locker(&session->m_videoProbeMutex);
-+
-+    if (session->m_videoProbes.isEmpty())
-+        return GST_PAD_PROBE_OK;
-+
-+    foreach (QGstreamerVideoProbeControl* probe, session->m_videoProbes)
-+        probe->bufferProbed(buffer, gst_pad_get_current_caps(pad));
-+
-+    return GST_PAD_PROBE_OK;
-+}
-+
-+#else
-+
-+static gboolean QGstreamerPlayerSession::padVideoBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data)
- {
-     Q_UNUSED(pad);
- 
-@@ -1742,6 +1833,7 @@ gboolean QGstreamerPlayerSession::padVideoBufferProbe(GstPad *pad, GstBuffer *bu
- 
-     return TRUE;
- }
-+#endif
- 
- void QGstreamerPlayerSession::addProbe(QGstreamerAudioProbeControl* probe)
- {
-@@ -1759,6 +1851,24 @@ void QGstreamerPlayerSession::removeProbe(QGstreamerAudioProbeControl* probe)
-     m_audioProbes.removeOne(probe);
- }
- 
-+#if GST_CHECK_VERSION(1,0,0)
-+GstPadProbeReturn  QGstreamerPlayerSession::padAudioBufferProbe(GstPad *pad, GstPadProbeInfo* info, gpointer user_data)
-+{
-+    Q_UNUSED(pad);
-+    GstBuffer* buffer = GST_PAD_PROBE_INFO_BUFFER(info);
-+
-+    QGstreamerPlayerSession *session = reinterpret_cast<QGstreamerPlayerSession*>(user_data);
-+    QMutexLocker locker(&session->m_audioProbeMutex);
-+
-+    if (session->m_audioProbes.isEmpty())
-+        return GST_PAD_PROBE_OK;
-+
-+    foreach (QGstreamerAudioProbeControl* probe, session->m_audioProbes)
-+        probe->bufferProbed(buffer, gst_pad_get_current_caps(pad));
-+
-+    return GST_PAD_PROBE_OK;
-+}
-+#else
- gboolean QGstreamerPlayerSession::padAudioBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data)
- {
-     Q_UNUSED(pad);
-@@ -1774,7 +1884,7 @@ gboolean QGstreamerPlayerSession::padAudioBufferProbe(GstPad *pad, GstBuffer *bu
- 
-     return TRUE;
- }
--
-+#endif
- // This function is similar to stop(),
- // but does not set m_everPlayed, m_lastPosition,
- // and setSeekable() values.
-@@ -1807,7 +1917,11 @@ void QGstreamerPlayerSession::removeVideoBufferProbe()
- 
-     GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink");
-     if (pad) {
-+#if GST_CHECK_VERSION(1,0,0)
-+        gst_pad_remove_probe(pad, m_videoBufferProbeId);
-+#else
-         gst_pad_remove_buffer_probe(pad, m_videoBufferProbeId);
-+#endif
-         gst_object_unref(GST_OBJECT(pad));
-     }
- 
-@@ -1822,7 +1936,11 @@ void QGstreamerPlayerSession::addVideoBufferProbe()
- 
-     GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink");
-     if (pad) {
-+#if GST_CHECK_VERSION(1,0,0)
-+        m_videoBufferProbeId = gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, padVideoBufferProbe, this, NULL);
-+#else
-         m_videoBufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padVideoBufferProbe), this);
-+#endif
-         gst_object_unref(GST_OBJECT(pad));
-     }
- }
-@@ -1839,7 +1957,11 @@ void QGstreamerPlayerSession::removeAudioBufferProbe()
- 
-     GstPad *pad = gst_element_get_static_pad(m_audioSink, "sink");
-     if (pad) {
-+#if GST_CHECK_VERSION(1,0,0)
-+        gst_pad_remove_probe(pad, m_audioBufferProbeId);
-+#else
-         gst_pad_remove_buffer_probe(pad, m_audioBufferProbeId);
-+#endif
-         gst_object_unref(GST_OBJECT(pad));
-     }
- 
-@@ -1854,7 +1976,11 @@ void QGstreamerPlayerSession::addAudioBufferProbe()
- 
-     GstPad *pad = gst_element_get_static_pad(m_audioSink, "sink");
-     if (pad) {
-+#if GST_CHECK_VERSION(1,0,0)
-+        m_audioBufferProbeId = gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, padAudioBufferProbe, this, NULL);
-+#else
-         m_audioBufferProbeId = gst_pad_add_buffer_probe(pad, G_CALLBACK(padAudioBufferProbe), this);
-+#endif
-         gst_object_unref(GST_OBJECT(pad));
-     }
- }
-@@ -1887,7 +2013,7 @@ void QGstreamerPlayerSession::playlistTypeFindFunction(GstTypeFind *find, gpoint
-         length = qMin(length, guint64(1024));
- 
-     while (length > 0) {
--        guint8 *data = gst_type_find_peek(find, 0, length);
-+        const guint8 *data = gst_type_find_peek(find, 0, length);
-         if (data) {
-             session->m_isPlaylist = (QPlaylistFileParser::findPlaylistType(QString::fromUtf8(uri), 0, data, length) != QPlaylistFileParser::UNKNOWN);
-             return;
-diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h
-index f2e760a..50bda3d 100644
---- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h
-+++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h
-@@ -119,11 +119,19 @@ public:
- 
-     void addProbe(QGstreamerVideoProbeControl* probe);
-     void removeProbe(QGstreamerVideoProbeControl* probe);
-+#if GST_CHECK_VERSION(1,0,0)
-+    static GstPadProbeReturn padVideoBufferProbe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data);
-+#else
-     static gboolean padVideoBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data);
-+#endif
- 
-     void addProbe(QGstreamerAudioProbeControl* probe);
-     void removeProbe(QGstreamerAudioProbeControl* probe);
-+#if GST_CHECK_VERSION(1,0,0)
-+    static GstPadProbeReturn padAudioBufferProbe(GstPad *pad, GstPadProbeInfo* info, gpointer user_data);
-+#else
-     static gboolean padAudioBufferProbe(GstPad *pad, GstBuffer *buffer, gpointer user_data);
-+#endif
- 
-     void endOfMediaReset();
- 
-@@ -252,6 +260,7 @@ private:
-     bool m_isLiveSource;
- 
-     bool m_isPlaylist;
-+    gulong pad_probe_id;
- };
- 
- QT_END_NAMESPACE
--- 
-2.1.3
-
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [meta-qt5][PATCH v2 7/8] qtwebengine: Add missing runtime dependencies for examples
  2015-02-11  1:43 [meta-qt5][PATCH v2 1/8] qtwebengine: Add a missing build dependency on libcap Otavio Salvador
                   ` (4 preceding siblings ...)
  2015-02-11  1:43 ` [meta-qt5][PATCH v2 6/8] qtmultimedia: Update the GStreamer 1.0 support patch Otavio Salvador
@ 2015-02-11  1:43 ` Otavio Salvador
  2015-02-11  1:43 ` [meta-qt5][PATCH v2 8/8] qt5.inc: Fix packaging of architecture independent data Otavio Salvador
  6 siblings, 0 replies; 9+ messages in thread
From: Otavio Salvador @ 2015-02-11  1:43 UTC (permalink / raw)
  To: Meta-OpenEmbedded Mailing listing; +Cc: Otavio Salvador

The qtdeclarative-qmlplugins and qtquickcontrols-qmlplugins are
required for the examples to run. Add them as rdepends.

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
---
 recipes-qt/qt5/qtwebengine.inc | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/recipes-qt/qt5/qtwebengine.inc b/recipes-qt/qt5/qtwebengine.inc
index f6b1304..46060c0 100644
--- a/recipes-qt/qt5/qtwebengine.inc
+++ b/recipes-qt/qt5/qtwebengine.inc
@@ -59,4 +59,9 @@ PACKAGE_DEBUG_SPLIT_STYLE = "debug-without-src"
 
 # for /usr/share/qt5/qtwebengine_resources.pak
 FILES_${PN} += "${OE_QMAKE_PATH_QT_TRANSLATIONS} ${OE_QMAKE_PATH_QT_DATA}"
-RDEPENDS_${PN}-examples += "${PN}-qmlplugins"
+
+RDEPENDS_${PN}-examples += " \
+    ${PN}-qmlplugins \
+    qtquickcontrols-qmlplugins \
+    qtdeclarative-qmlplugins \
+"
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [meta-qt5][PATCH v2 8/8] qt5.inc: Fix packaging of architecture independent data
  2015-02-11  1:43 [meta-qt5][PATCH v2 1/8] qtwebengine: Add a missing build dependency on libcap Otavio Salvador
                   ` (5 preceding siblings ...)
  2015-02-11  1:43 ` [meta-qt5][PATCH v2 7/8] qtwebengine: Add missing runtime dependencies for examples Otavio Salvador
@ 2015-02-11  1:43 ` Otavio Salvador
  6 siblings, 0 replies; 9+ messages in thread
From: Otavio Salvador @ 2015-02-11  1:43 UTC (permalink / raw)
  To: Meta-OpenEmbedded Mailing listing; +Cc: Otavio Salvador

The architecture independent data were being added to the '-dev'
package however it shouldn't be. For example the QtWebEngine had the
translation and the resources package were not being installed with
the main package, as it should be.

This commit changes the qttools and qttranslations recipes as well so
those keep its contents in the respective packages:

 qttools: add the phrasebooks in the qttools-tools package
 qttranslations: add a new subpackage for qtquickcontrols

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
---
 recipes-qt/qt5/qt5.inc            | 2 +-
 recipes-qt/qt5/qttools.inc        | 1 +
 recipes-qt/qt5/qttranslations.inc | 5 +++++
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/recipes-qt/qt5/qt5.inc b/recipes-qt/qt5/qt5.inc
index bb0bcdc..af0a906 100644
--- a/recipes-qt/qt5/qt5.inc
+++ b/recipes-qt/qt5/qt5.inc
@@ -118,7 +118,6 @@ FILES_${PN}-dev += " \
     ${OE_QMAKE_PATH_LIBS}/cmake/* \
     ${OE_QMAKE_PATH_LIBS}/*.prl \
     ${OE_QMAKE_PATH_LIBS}/*.la \
-    ${OE_QMAKE_PATH_DATA}/* \
     ${OE_QMAKE_PATH_HEADERS}/* \
 "
 FILES_${PN}-dbg += " \
@@ -129,6 +128,7 @@ FILES_${PN}-staticdev += " \
     ${OE_QMAKE_PATH_LIBS}/*.a \
 "
 FILES_${PN}-examples = " \
+    ${OE_QMAKE_PATH_EXAMPLES}/README \
     ${OE_QMAKE_PATH_EXAMPLES}/*/* \
 "
 FILES_${PN}-examples-dev = " \
diff --git a/recipes-qt/qt5/qttools.inc b/recipes-qt/qt5/qttools.inc
index 8c97e24..97717ae 100644
--- a/recipes-qt/qt5/qttools.inc
+++ b/recipes-qt/qt5/qttools.inc
@@ -7,6 +7,7 @@ SRC_URI += " \
     file://0003-add-noqtwebkit-configuration.patch \
 "
 
+FILES_${PN}-tools += "${datadir}/${QT_DIR_NAME}/phrasebooks"
 FILES_${PN}-examples = "${datadir}/${QT_DIR_NAME}/examples"
 
 PACKAGECONFIG ??= ""
diff --git a/recipes-qt/qt5/qttranslations.inc b/recipes-qt/qt5/qttranslations.inc
index c04aee6..c522694 100644
--- a/recipes-qt/qt5/qttranslations.inc
+++ b/recipes-qt/qt5/qttranslations.inc
@@ -16,6 +16,7 @@ PACKAGES =. " \
     ${PN}-qtmultimedia \
     ${PN}-qtlocation \
     ${PN}-qtdeclarative \
+    ${PN}-qtquickcontrols \
     ${PN}-qtxmlpatterns \
     ${PN}-qtconfig \
     ${PN}-qtquick1 \
@@ -57,6 +58,10 @@ FILES_${PN}-qtdeclarative = " \
     ${OE_QMAKE_PATH_TRANSLATIONS}/qtdeclarative_*.qm \
 "
 
+FILES_${PN}-qtquickcontrols = " \
+    ${OE_QMAKE_PATH_TRANSLATIONS}/qtquickcontrols_*.qm \
+"
+
 FILES_${PN}-qtxmlpatterns = " \
     ${OE_QMAKE_PATH_TRANSLATIONS}/qtxmlpatterns_*.qm \
 "
-- 
2.1.4



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [meta-qt5][PATCH v2 6/8] qtmultimedia: Update the GStreamer 1.0 support patch
  2015-02-11  1:43 ` [meta-qt5][PATCH v2 6/8] qtmultimedia: Update the GStreamer 1.0 support patch Otavio Salvador
@ 2015-02-13 12:02   ` Otavio Salvador
  0 siblings, 0 replies; 9+ messages in thread
From: Otavio Salvador @ 2015-02-13 12:02 UTC (permalink / raw)
  To: Meta-OpenEmbedded Mailing listing; +Cc: Otavio Salvador

On Tue, Feb 10, 2015 at 11:43 PM, Otavio Salvador
<otavio@ossystems.com.br> wrote:
> This updates the patch which adds support for GStreamer 1.0 to the one
> merged in the 5.5 development branch. For instance it fixes a color
> mismatch in one of our devices.
>
> Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>


Please hold on merging this one. I will prepare a v3.



-- 
Otavio Salvador                             O.S. Systems
http://www.ossystems.com.br        http://code.ossystems.com.br
Mobile: +55 (53) 9981-7854            Mobile: +1 (347) 903-9750


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-02-13 12:02 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-11  1:43 [meta-qt5][PATCH v2 1/8] qtwebengine: Add a missing build dependency on libcap Otavio Salvador
2015-02-11  1:43 ` [meta-qt5][PATCH v2 2/8] qtmultimedia: Fix floating dependency gst-plugins-bad Otavio Salvador
2015-02-11  1:43 ` [meta-qt5][PATCH v2 3/8] qtmultimedia: Use 'qtCompileTest' mechanism for GStreamer Otavio Salvador
2015-02-11  1:43 ` [meta-qt5][PATCH v2 4/8] qtmultimedia: Use 'bb.utils.contains' function Otavio Salvador
2015-02-11  1:43 ` [meta-qt5][PATCH v2 5/8] qtmultimedia: Easy use of GStreamer 1.0 support Otavio Salvador
2015-02-11  1:43 ` [meta-qt5][PATCH v2 6/8] qtmultimedia: Update the GStreamer 1.0 support patch Otavio Salvador
2015-02-13 12:02   ` Otavio Salvador
2015-02-11  1:43 ` [meta-qt5][PATCH v2 7/8] qtwebengine: Add missing runtime dependencies for examples Otavio Salvador
2015-02-11  1:43 ` [meta-qt5][PATCH v2 8/8] qt5.inc: Fix packaging of architecture independent data Otavio Salvador

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.