diff -Naur qt-gstreamer-orig/src/QGst/CMakeLists.txt qt-gstreamer/src/QGst/CMakeLists.txt
--- qt-gstreamer-orig/src/QGst/CMakeLists.txt	2013-06-28 11:29:15.844975780 +0200
+++ qt-gstreamer/src/QGst/CMakeLists.txt	2013-06-28 18:27:27.200851664 +0200
@@ -40,6 +40,19 @@
     Ui/graphicsvideowidget.cpp
 )
 
+if (USE_QT5)
+    set(QtGStreamerUi_SRCS
+    ${QtGStreamerUi_SRCS}
+    Ui/quickviewvideosurface.cpp
+    Ui/videonode.cpp
+    Ui/videonode_i420.cpp
+    Ui/videonode_rgb.cpp
+    Ui/videonode_generic.cpp
+    Ui/abstractmediaplayer.cpp
+    Ui/abstractvideosurface.h
+)
+endif()
+
 set(QtGStreamerUtils_SRCS
     Utils/applicationsink.cpp
     Utils/applicationsource.cpp
@@ -95,6 +108,15 @@
     Utils/applicationsource.h   Utils/ApplicationSource
 )
 
+if (USE_QT5)
+    set(QtGStreamer_INSTALLED_HEADERS
+    ${QtGStreamer_INSTALLED_HEADERS}
+    Ui/quickviewvideosurface.h  Ui/QuickViewVideoSurface
+    Ui/abstractmediaplayer.h    Ui/AbstractMediaPlayer
+    Ui/abstractvideosurface.h   Ui/AbstractVideoSurface
+)
+endif()
+
 file(GLOB QtGStreamer_CODEGEN_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h")
 list(REMOVE_ITEM QtGStreamer_CODEGEN_HEADERS "global.h")
 
@@ -158,7 +180,11 @@
                                                  SOVERSION ${QTGSTREAMER_UI_SOVERSION}
                                                    VERSION ${QTGSTREAMER_VERSION})
 target_link_libraries(${QTGSTREAMER_UI_LIBRARY} LINK_PUBLIC ${QTGSTREAMER_LIBRARY})
-qt4or5_use_modules(${QTGSTREAMER_UI_LIBRARY} LINK_PUBLIC Widgets Gui)
+if (USE_QT5)
+    qt4or5_use_modules(${QTGSTREAMER_UI_LIBRARY} LINK_PUBLIC Widgets Gui Quick2)
+else()
+    qt4or5_use_modules(${QTGSTREAMER_UI_LIBRARY} LINK_PUBLIC Widgets Gui)
+endif()
 qt4or5_use_modules(${QTGSTREAMER_UI_LIBRARY} LINK_PRIVATE Core)
 if (Qt4or5_OpenGL_FOUND AND (OPENGL_FOUND OR OPENGLES2_FOUND))
     qt4or5_use_modules(${QTGSTREAMER_UI_LIBRARY} LINK_PRIVATE OpenGL)
diff -Naur qt-gstreamer-orig/src/QGst/Ui/AbstractMediaPlayer qt-gstreamer/src/QGst/Ui/AbstractMediaPlayer
--- qt-gstreamer-orig/src/QGst/Ui/AbstractMediaPlayer	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/AbstractMediaPlayer	2013-06-13 18:28:48.000000000 +0200
@@ -0,0 +1 @@
+#include "abstractmediaplayer.h"
diff -Naur qt-gstreamer-orig/src/QGst/Ui/abstractmediaplayer.cpp qt-gstreamer/src/QGst/Ui/abstractmediaplayer.cpp
--- qt-gstreamer-orig/src/QGst/Ui/abstractmediaplayer.cpp	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/abstractmediaplayer.cpp	2013-07-02 12:01:06.407699630 +0200
@@ -0,0 +1,45 @@
+/*
+    Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+      @author Benjamin Federau <benjamin.federau@basyskom.com>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "abstractmediaplayer.h"
+
+namespace QGst {
+namespace Ui {
+
+AbstractMediaPlayer::AbstractMediaPlayer(QObject *parent) :
+    QObject(parent)
+{
+}
+
+AbstractMediaPlayer::~AbstractMediaPlayer()
+{
+}
+
+QGst::Ui::AbstractVideoSurface* AbstractMediaPlayer::videoSurface()
+{
+    return m_videoSurface;
+}
+
+void AbstractMediaPlayer::setVideoSurface(QGst::Ui::AbstractVideoSurface *videoSurface)
+{
+    m_videoSurface = videoSurface;
+
+    Q_EMIT videoSurfaceChanged();
+}
+
+}
+}
diff -Naur qt-gstreamer-orig/src/QGst/Ui/abstractmediaplayer.h qt-gstreamer/src/QGst/Ui/abstractmediaplayer.h
--- qt-gstreamer-orig/src/QGst/Ui/abstractmediaplayer.h	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/abstractmediaplayer.h	2013-07-02 12:01:13.111775481 +0200
@@ -0,0 +1,53 @@
+/*
+    Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+      @author Benjamin Federau <benjamin.federau@basyskom.com>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef ABSTRACTMEDIAPLAYER_H
+#define ABSTRACTMEDIAPLAYER_H
+
+#include <QtCore/QObject>
+#include <QGst/element.h>
+
+#include <QGst/Ui/AbstractVideoSurface>
+
+namespace QGst {
+namespace Ui {
+
+class QTGSTREAMERUI_EXPORT AbstractMediaPlayer : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(QGst::Ui::AbstractVideoSurface* videoSurface READ videoSurface WRITE setVideoSurface NOTIFY videoSurfaceChanged)
+public:
+    AbstractMediaPlayer(QObject *parent = 0);
+    virtual ~AbstractMediaPlayer();
+
+    virtual void setVideoSink(const QGst::ElementPtr & videoSink) = 0;
+
+    virtual QGst::Ui::AbstractVideoSurface* videoSurface();
+    virtual void setVideoSurface(QGst::Ui::AbstractVideoSurface *videoSurface);
+
+Q_SIGNALS:
+    void videoSurfaceChanged();
+
+protected:
+    QGst::Ui::AbstractVideoSurface *m_videoSurface;
+
+};
+
+}
+}
+
+#endif // ABSTRACTMEDIAPLAYER_H
diff -Naur qt-gstreamer-orig/src/QGst/Ui/AbstractVideoSurface qt-gstreamer/src/QGst/Ui/AbstractVideoSurface
--- qt-gstreamer-orig/src/QGst/Ui/AbstractVideoSurface	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/AbstractVideoSurface	2013-06-13 18:28:48.000000000 +0200
@@ -0,0 +1 @@
+#include "abstractvideosurface.h"
diff -Naur qt-gstreamer-orig/src/QGst/Ui/abstractvideosurface.h qt-gstreamer/src/QGst/Ui/abstractvideosurface.h
--- qt-gstreamer-orig/src/QGst/Ui/abstractvideosurface.h	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/abstractvideosurface.h	2013-07-02 12:02:00.760314287 +0200
@@ -0,0 +1,44 @@
+/*
+    Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+      @author Benjamin Federau <benjamin.federau@basyskom.com>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef ABSTRACTVIDEOSURFACE_H
+#define ABSTRACTVIDEOSURFACE_H
+
+#include "global.h"
+#include <QtCore/QObject>
+#include <QGst/Element>
+
+namespace QGst {
+namespace Ui {
+
+class QTGSTREAMERUI_EXPORT AbstractVideoSurface : public QObject
+{
+    Q_OBJECT
+public:
+    AbstractVideoSurface(QObject *parent) : QObject(parent) {}
+    virtual ~AbstractVideoSurface() {}
+
+    virtual ElementPtr videoSink() const = 0;
+
+protected:
+    virtual void onUpdate() = 0;
+};
+
+}
+}
+
+#endif // ABSTRACTVIDEOSURFACE_H
diff -Naur qt-gstreamer-orig/src/QGst/Ui/QuickViewVideoSurface qt-gstreamer/src/QGst/Ui/QuickViewVideoSurface
--- qt-gstreamer-orig/src/QGst/Ui/QuickViewVideoSurface	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/QuickViewVideoSurface	2013-06-13 18:28:48.000000000 +0200
@@ -0,0 +1 @@
+#include "quickviewvideosurface.h"
diff -Naur qt-gstreamer-orig/src/QGst/Ui/quickviewvideosurface.cpp qt-gstreamer/src/QGst/Ui/quickviewvideosurface.cpp
--- qt-gstreamer-orig/src/QGst/Ui/quickviewvideosurface.cpp	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/quickviewvideosurface.cpp	2013-07-02 12:02:44.880812741 +0200
@@ -0,0 +1,224 @@
+/*
+    Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+    Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+      @author Benjamin Federau <benjamin.federau@basyskom.com>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "quickviewvideosurface_p.h"
+#include "../elementfactory.h"
+#include "../../QGlib/connect.h"
+
+#include <QtCore/QDebug>
+#include <QtGui/QOpenGLContext>
+
+#include <QtQuick/QSGNode>
+
+#include <QGst/global.h>
+#include <QGst/Element>
+#include <QGlib/Signal>
+
+
+namespace QGst {
+namespace Ui {
+
+QuickViewVideoSurface::QuickViewVideoSurface(QQuickItem *paintedItem, QQuickWindow *parent)
+    : AbstractVideoSurface(parent), d(new QuickViewVideoSurfacePrivate)
+{
+    d->view = parent;
+    d->outputItem = paintedItem;
+    d->openglContext = 0;
+    d->frameChanged = false;
+    d->currentVideoFormat = GST_VIDEO_FORMAT_UNKNOWN;
+
+    d->videoNodeFactories.append(&(d->genericFactory));
+    d->videoNodeFactories.append(&(d->i420Factory));
+    d->videoNodeFactories.append(&(d->rgbFactory));
+}
+
+QuickViewVideoSurface::~QuickViewVideoSurface()
+{
+    if (!d->videoSink.isNull()) {
+        d->videoSink->setState(QGst::StateNull);
+    }
+
+    delete d;
+}
+
+// TODO: Still needed?
+void QuickViewVideoSurface::setRepaintItem(QQuickItem *item)
+{
+    d->items.remove(item);
+
+    d->items.insert(item);
+}
+
+QOpenGLContext* QuickViewVideoSurface::getOpenGLContext()
+{
+    return d->openglContext;
+}
+
+void QuickViewVideoSurface::setOpenGLContext(QOpenGLContext *context)
+{
+    d->openglContext = context;
+}
+
+QSize QuickViewVideoSurface::nativeSize()
+{
+    return d->nativeSize;
+}
+
+ElementPtr QuickViewVideoSurface::videoSink() const
+{
+    if (d->videoSink.isNull()) {
+
+#ifndef QTGSTREAMER_UI_NO_OPENGL
+
+        // TODO: Still needed with Qt5 and scene graph?
+        if (d->openglContext) {
+            d->videoSink = QGst::ElementFactory::make(QTGLVIDEOSINK_NAME);
+
+            if (!d->videoSink.isNull()) {
+
+                d->videoSink->setProperty("glcontext", (void*) d->openglContext);
+
+                if (d->videoSink->setState(QGst::StateReady) != QGst::StateChangeSuccess) {
+                    d->videoSink.clear();
+                }
+            }
+        } else {
+            qDebug() << "No OpenGL context available. Trying to create qtvideosink ...";
+        }
+
+#endif
+
+        if (d->videoSink.isNull()) {
+            d->videoSink = QGst::ElementFactory::make(QTVIDEOSINK_NAME);
+
+            if (d->videoSink.isNull()) {
+                qCritical("Failed to create qtvideosink. Make sure it is installed correctly");
+                return ElementPtr();
+            }
+        }
+
+        QGlib::connect(d->videoSink, "update",
+                       const_cast<QuickViewVideoSurface*>(this),
+                       &QuickViewVideoSurface::onUpdate);
+
+    }
+
+    return d->videoSink;
+}
+
+void QuickViewVideoSurface::updateGeometry(qreal width, qreal height, int orientation, QRectF contentRect, Qt::AspectRatioMode aspectRatio)
+{
+    const QRectF rect(0, 0, width, height);
+    if (d->nativeSize.isEmpty()) {
+        d->renderedRect = rect;
+        d->sourceTextureRect = QRectF(0, 0, 1, 1);
+    } else if (aspectRatio == Qt::IgnoreAspectRatio) {
+        d->renderedRect = rect;
+        d->sourceTextureRect = QRectF(0, 0, 1, 1);
+    } else if (aspectRatio == Qt::KeepAspectRatio) {
+        d->sourceTextureRect = QRectF(0, 0, 1, 1);
+        d->renderedRect = contentRect;
+    } else if (aspectRatio == Qt::KeepAspectRatio) {
+        d->renderedRect = rect;
+        const qreal contentHeight = contentRect.height();
+        const qreal contentWidth = contentRect.width();
+        if (isDefaultAspect(orientation)) {
+            d->sourceTextureRect = QRectF(-contentRect.left() / contentWidth,
+                                         -contentRect.top() / contentHeight,
+                                         rect.width() / contentWidth,
+                                         rect.height() / contentHeight);
+        } else {
+            d->sourceTextureRect = QRectF(-contentRect.top() / contentHeight,
+                                         -contentRect.left() / contentWidth,
+                                         rect.height() / contentHeight,
+                                         rect.width() / contentWidth);
+        }
+    }
+}
+
+QSGNode* QuickViewVideoSurface::updatePaintNode(QSGNode *oldNode, QRectF boundingRect)
+{
+    VideoNode *videoNode = static_cast<VideoNode *>(oldNode);
+
+    QRectF bounds = boundingRect;
+
+    if (!videoNode) {
+
+        Q_FOREACH (VideoNodeFactoryInterface* factory, d->videoNodeFactories) {
+            videoNode = factory->createEmptyNode(d->currentVideoFormat);
+            if (videoNode)
+                break;
+        }
+    }
+
+    if (videoNode && d->frameChanged) {
+
+        if (d->nativeSize != videoNode->nativeSize()) {
+            d->nativeSize = videoNode->nativeSize();
+            Q_EMIT nativeSizeChanged();
+        }
+
+        if (d->currentVideoFormat != videoNode->pixelFormat()) {
+
+            d->currentVideoFormat = videoNode->pixelFormat();
+
+            delete videoNode;
+            videoNode = 0;
+
+
+            Q_FOREACH (VideoNodeFactoryInterface* factory, d->videoNodeFactories) {
+                videoNode = factory->createEmptyNode(d->currentVideoFormat);
+                if (videoNode)
+                    break;
+            }
+
+        }
+    }
+
+    if (!videoNode) {
+        d->frameChanged = false;
+        return 0;
+    }
+
+    videoNode->setTexturedRectGeometry(d->renderedRect, d->sourceTextureRect, 0);
+
+    if (d->frameChanged) {
+
+        QGlib::emit<void>(d->videoSink, "updatePaintNode",
+                          (void*)videoNode, bounds.x(), bounds.y(), bounds.width(), bounds.height());
+
+        d->frameChanged = false;
+    }
+
+    return videoNode;
+}
+
+void QuickViewVideoSurface::onUpdate()
+{
+//    TODO: Still needed? see QuickViewVideoSurface::setRepaintItem()
+//    Q_FOREACH(QQuickItem *item, d->items) {
+//        item->update();
+//    }
+
+    d->outputItem->update();
+
+    d->frameChanged = true;
+}
+
+} // namespace Ui
+} // namespace QGst
diff -Naur qt-gstreamer-orig/src/QGst/Ui/quickviewvideosurface.h qt-gstreamer/src/QGst/Ui/quickviewvideosurface.h
--- qt-gstreamer-orig/src/QGst/Ui/quickviewvideosurface.h	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/quickviewvideosurface.h	2013-07-02 12:02:58.840970367 +0200
@@ -0,0 +1,87 @@
+/*
+    Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+    Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+      @author Benjamin Federau <benjamin.federau@basyskom.com>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef QGST_UI_QUICKVIEWVIDEOSURFACE_H
+#define QGST_UI_QUICKVIEWVIDEOSURFACE_H
+
+#include "global.h"
+#include "../element.h"
+#include "abstractvideosurface.h"
+#include <QtQuick/QQuickView>
+#include <QtQuick/QQuickItem>
+
+class QSGNode;
+
+namespace QGst {
+namespace Ui {
+
+class QuickViewVideoSurfacePrivate;
+
+class QTGSTREAMERUI_EXPORT QuickViewVideoSurface : public AbstractVideoSurface
+{
+    Q_OBJECT
+    Q_DISABLE_COPY(QuickViewVideoSurface)
+public:
+    explicit QuickViewVideoSurface(QQuickItem *paintedItem, QQuickWindow *parent);
+    virtual ~QuickViewVideoSurface();
+
+    void setRepaintItem(QQuickItem* item);
+
+    QOpenGLContext* getOpenGLContext();
+    void setOpenGLContext(QOpenGLContext *context);
+
+    QSize nativeSize();
+    virtual ElementPtr videoSink() const;
+
+    void updateGeometry(qreal width, qreal height, int orientation, QRectF contentRect, Qt::AspectRatioMode aspectRatio);
+    QSGNode* updatePaintNode(QSGNode *oldNode, QRectF boundingRect);
+
+Q_SIGNALS:
+    void nativeSizeChanged();
+
+protected:
+    virtual QTGSTREAMERUI_NO_EXPORT void onUpdate();
+
+private:
+    /*
+     * Helper - returns true if the given orientation has the same aspect as the default (e.g. 180*n)
+     */
+    inline bool isDefaultAspect(int o) {
+        return (o % 180) == 0;
+    }
+    /*
+     * Return the orientation normalized to 0-359
+     */
+    inline int normalizedOrientation(int o) {
+        // Negative orientations give negative results
+        int o2 = o % 360;
+        if (o2 < 0)
+            o2 += 360;
+        return o2;
+    }
+
+private:
+    QuickViewVideoSurfacePrivate * const d;
+};
+
+} // namespace Ui
+} // namespace QGst
+
+Q_DECLARE_METATYPE(QGst::Ui::QuickViewVideoSurface*)
+
+#endif // QGST_UI_QUICKVIEWVIDEOSURFACE_H
diff -Naur qt-gstreamer-orig/src/QGst/Ui/quickviewvideosurface_p.h qt-gstreamer/src/QGst/Ui/quickviewvideosurface_p.h
--- qt-gstreamer-orig/src/QGst/Ui/quickviewvideosurface_p.h	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/quickviewvideosurface_p.h	2013-06-13 18:28:48.000000000 +0200
@@ -0,0 +1,51 @@
+/*
+    Copyright (C) 2012 Collabora Ltd. <info@collabora.com>
+      @author George Kiagiadakis <george.kiagiadakis@collabora.com>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef QGST_UI_QUICKVIEWVIDEOSURFACE_P_H
+#define QGST_UI_QUICKVIEWVIDEOSURFACE_P_H
+
+#include "quickviewvideosurface.h"
+#include "videonode_i420.h"
+#include "videonode_generic.h"
+#include "videonode_rgb.h"
+
+namespace QGst {
+namespace Ui {
+
+class QTGSTREAMERUI_NO_EXPORT QuickViewVideoSurfacePrivate
+{
+public:
+    QQuickWindow *view;
+    QQuickItem *outputItem;
+    QSet<QQuickItem*> items;
+    ElementPtr videoSink;
+    QOpenGLContext *openglContext;
+    bool frameChanged;
+    QList<VideoNodeFactoryInterface*> videoNodeFactories;
+    VideoNodeFactory_I420 i420Factory;
+    VideoNodeFactory_Generic genericFactory;
+    VideoNodeFactory_RGB rgbFactory;
+    GstVideoFormat currentVideoFormat;
+    QSize nativeSize;
+    QRectF renderedRect;         // Destination pixel coordinates, clipped
+    QRectF sourceTextureRect;    // Source texture coordinates
+};
+
+} // namespace Ui
+} // namespace QGst
+
+#endif // QGST_UI_QUICKVIEWVIDEOSURFACE_P_H
diff -Naur qt-gstreamer-orig/src/QGst/Ui/videonode.cpp qt-gstreamer/src/QGst/Ui/videonode.cpp
--- qt-gstreamer-orig/src/QGst/Ui/videonode.cpp	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/videonode.cpp	2013-07-02 12:06:40.667469310 +0200
@@ -0,0 +1,102 @@
+/*
+    Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+    Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "videonode.h"
+
+VideoNode::VideoNode()
+    : m_orientation(-1)
+{
+}
+
+/* Helpers */
+static inline void qSetGeom(QSGGeometry::TexturedPoint2D *v, const QPointF &p)
+{
+    v->x = p.x();
+    v->y = p.y();
+}
+
+static inline void qSetTex(QSGGeometry::TexturedPoint2D *v, const QPointF &p)
+{
+    v->tx = p.x();
+    v->ty = p.y();
+}
+
+/* Update the vertices and texture coordinates.  Orientation must be in {0,90,180,270} */
+void VideoNode::setTexturedRectGeometry(const QRectF &rect, const QRectF &textureRect, int orientation)
+{
+    if (rect == m_rect && textureRect == m_textureRect && orientation == m_orientation)
+        return;
+
+    m_rect = rect;
+    m_textureRect = textureRect;
+    m_orientation = orientation;
+
+    QSGGeometry *g = geometry();
+
+    if (g == 0)
+        g = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4);
+
+    QSGGeometry::TexturedPoint2D *v = g->vertexDataAsTexturedPoint2D();
+
+    // Set geometry first
+    qSetGeom(v + 0, rect.topLeft());
+    qSetGeom(v + 1, rect.bottomLeft());
+    qSetGeom(v + 2, rect.topRight());
+    qSetGeom(v + 3, rect.bottomRight());
+
+    // and then texture coordinates
+    switch (orientation) {
+        default:
+            // tl, bl, tr, br
+            qSetTex(v + 0, textureRect.topLeft());
+            qSetTex(v + 1, textureRect.bottomLeft());
+            qSetTex(v + 2, textureRect.topRight());
+            qSetTex(v + 3, textureRect.bottomRight());
+            break;
+
+        case 90:
+            // tr, tl, br, bl
+            qSetTex(v + 0, textureRect.topRight());
+            qSetTex(v + 1, textureRect.topLeft());
+            qSetTex(v + 2, textureRect.bottomRight());
+            qSetTex(v + 3, textureRect.bottomLeft());
+            break;
+
+        case 180:
+            // br, tr, bl, tl
+            qSetTex(v + 0, textureRect.bottomRight());
+            qSetTex(v + 1, textureRect.topRight());
+            qSetTex(v + 2, textureRect.bottomLeft());
+            qSetTex(v + 3, textureRect.topLeft());
+            break;
+
+        case 270:
+            // bl, br, tl, tr
+            qSetTex(v + 0, textureRect.bottomLeft());
+            qSetTex(v + 1, textureRect.bottomRight());
+            qSetTex(v + 2, textureRect.topLeft());
+            qSetTex(v + 3, textureRect.topRight());
+            break;
+    }
+
+    if (!geometry())
+        setGeometry(g);
+
+    markDirty(DirtyGeometry);
+}
+
diff -Naur qt-gstreamer-orig/src/QGst/Ui/videonode_generic.cpp qt-gstreamer/src/QGst/Ui/videonode_generic.cpp
--- qt-gstreamer-orig/src/QGst/Ui/videonode_generic.cpp	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/videonode_generic.cpp	2013-07-02 12:08:19.324577350 +0200
@@ -0,0 +1,79 @@
+/*
+    Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+      @author Benjamin Federau <benjamin.federau@basyskom.com>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "videonode_generic.h"
+
+#include <QtQuick/QSGFlatColorMaterial>
+
+
+QSet<GstVideoFormat> VideoNodeFactory_Generic::supportedPixelFormats() const
+{
+    return QSet<GstVideoFormat>()
+        << GST_VIDEO_FORMAT_UNKNOWN
+        ;
+}
+
+VideoNode *VideoNodeFactory_Generic::createEmptyNode(GstVideoFormat format)
+{
+    if (supportedPixelFormats().contains(format))
+        return new VideoNode_Generic();
+
+    return 0;
+}
+
+VideoNode *VideoNodeFactory_Generic::createNode(const BufferFormat &format)
+{
+    if (supportedPixelFormats().contains(format.videoFormat()))
+        return new VideoNode_Generic(format);
+
+    return 0;
+}
+
+
+VideoNode_Generic::VideoNode_Generic()
+{
+    qDebug() << "generic";
+    setFlag(QSGNode::OwnsMaterial);
+
+    m_material = new QSGFlatColorMaterial();
+    m_material->setColor(QColor(Qt::black));
+
+    setMaterial(m_material);
+}
+
+VideoNode_Generic::VideoNode_Generic(const BufferFormat &format)
+{
+    setFlag(QSGNode::OwnsMaterial);
+}
+
+VideoNode_Generic::~VideoNode_Generic()
+{
+}
+
+
+void VideoNode_Generic::setCurrentFrame(quint8 *data)
+{
+    Q_UNUSED(data)
+
+    markDirty(DirtyMaterial);
+}
+
+void VideoNode_Generic::setBufferFormat(const BufferFormat &format)
+{
+    m_bufferFormat = format;
+}
diff -Naur qt-gstreamer-orig/src/QGst/Ui/videonode_generic.h qt-gstreamer/src/QGst/Ui/videonode_generic.h
--- qt-gstreamer-orig/src/QGst/Ui/videonode_generic.h	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/videonode_generic.h	2013-07-02 12:08:54.196968530 +0200
@@ -0,0 +1,58 @@
+/*
+    Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+      @author Benjamin Federau <benjamin.federau@basyskom.com>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef VIDEONODE_GENERIC_H
+#define VIDEONODE_GENERIC_H
+
+#include "videonode.h"
+
+class QSGFlatColorMaterial;
+class VideoNode_Generic : public VideoNode
+{
+public:
+    VideoNode_Generic();
+    VideoNode_Generic(const BufferFormat &format);
+    ~VideoNode_Generic();
+
+    virtual GstVideoFormat pixelFormat() const {
+        return m_bufferFormat.videoFormat();
+    }
+    virtual QSize nativeSize() const {
+        return m_bufferFormat.frameSize();
+    }
+    virtual void setBufferFormat(const BufferFormat &format);
+
+    void setCurrentFrame(quint8 *data);
+
+private:
+    BufferFormat m_bufferFormat;
+    QSGFlatColorMaterial *m_material;
+
+};
+
+class VideoNodeFactory_Generic : public VideoNodeFactoryInterface {
+public:
+    // new:
+    QSet<GstVideoFormat> supportedPixelFormats() const;
+    VideoNode *createEmptyNode(GstVideoFormat format);
+    VideoNode *createNode(const BufferFormat &format);
+};
+
+
+
+#endif // VIDEONODE_GENERIC_H
diff -Naur qt-gstreamer-orig/src/QGst/Ui/videonode.h qt-gstreamer/src/QGst/Ui/videonode.h
--- qt-gstreamer-orig/src/QGst/Ui/videonode.h	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/videonode.h	2013-07-02 12:06:55.523636295 +0200
@@ -0,0 +1,67 @@
+/*
+    Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+    Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef VIDEONODE_H
+#define VIDEONODE_H
+
+#include "../../elements/gstqtvideosink/bufferformat.h"
+
+#include <QtQuick/QSGNode>
+#include <QtGui/qopenglfunctions.h>
+
+
+class VideoNode : public QSGGeometryNode
+{
+public:
+    VideoNode();
+
+    virtual void setCurrentFrame(quint8 *data) = 0;
+    virtual void setBufferFormat(const BufferFormat &format) = 0;
+    virtual GstVideoFormat pixelFormat() const = 0;
+    virtual QSize nativeSize() const = 0;
+
+    void setTexturedRectGeometry(const QRectF &boundingRect, const QRectF &textureRect, int orientation);
+
+private:
+    QRectF m_rect;
+    QRectF m_textureRect;
+    int m_orientation;
+};
+
+class VideoNodeFactoryInterface
+{
+public:
+    virtual QSet<GstVideoFormat> supportedPixelFormats() const = 0;
+    virtual VideoNode *createEmptyNode(GstVideoFormat format) = 0;
+    virtual VideoNode *createNode(const BufferFormat &format) = 0;
+};
+
+#define VideoNodeFactoryInterface_iid "org.qt-project.qt.videonodefactory/1.0"
+Q_DECLARE_INTERFACE(VideoNodeFactoryInterface, VideoNodeFactoryInterface_iid)
+
+class VideoNodeFactoryPlugin : public QObject, public VideoNodeFactoryInterface
+{
+    Q_OBJECT
+    Q_INTERFACES(VideoNodeFactoryInterface)
+public:
+    virtual QSet<GstVideoFormat> supportedPixelFormats() const = 0;
+    virtual VideoNode *createEmptyNode(GstVideoFormat format) = 0;
+    virtual VideoNode *createNode(const BufferFormat &format) = 0;
+};
+
+#endif // VIDEONODE_H
diff -Naur qt-gstreamer-orig/src/QGst/Ui/videonode_i420.cpp qt-gstreamer/src/QGst/Ui/videonode_i420.cpp
--- qt-gstreamer-orig/src/QGst/Ui/videonode_i420.cpp	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/videonode_i420.cpp	2013-07-02 12:09:20.117259128 +0200
@@ -0,0 +1,506 @@
+/*
+    Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+    Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "videonode_i420.h"
+
+#include <QtCore/QMutex>
+#include <QtQuick/QSGTextureMaterial>
+#include <QtQuick/QSGMaterial>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QOpenGLShaderProgram>
+#include <QtCore/QDebug>
+
+QSet<GstVideoFormat> VideoNodeFactory_I420::supportedPixelFormats() const
+{
+    return QSet<GstVideoFormat>()
+        //also handled by the generic painter on LE
+//        << GST_VIDEO_FORMAT_BGRA
+//        << GST_VIDEO_FORMAT_BGRx
+
+//        //also handled by the generic painter on BE
+//        << GST_VIDEO_FORMAT_ARGB
+//        << GST_VIDEO_FORMAT_xRGB
+
+//        //also handled by the generic painter everywhere
+//        << GST_VIDEO_FORMAT_RGB
+//        << GST_VIDEO_FORMAT_RGB16
+
+//        //not handled by the generic painter
+//        << GST_VIDEO_FORMAT_BGR
+//        << GST_VIDEO_FORMAT_v308
+//        << GST_VIDEO_FORMAT_AYUV
+        << GST_VIDEO_FORMAT_YV12
+        << GST_VIDEO_FORMAT_I420
+        ;
+}
+
+VideoNode *VideoNodeFactory_I420::createEmptyNode(GstVideoFormat format)
+{
+    if (supportedPixelFormats().contains(format))
+        return new VideoNode_I420();
+
+    return 0;
+}
+
+VideoNode *VideoNodeFactory_I420::createNode(const BufferFormat &format)
+{
+    if (supportedPixelFormats().contains(format.videoFormat()))
+        return new VideoNode_I420(format);
+
+    return 0;
+}
+
+
+class VideoMaterialShader_YUV420 : public QSGMaterialShader
+{
+public:
+    void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial);
+
+    virtual char const *const *attributeNames() const {
+        static const char *names[] = {
+            "qt_VertexPosition",
+            "qt_VertexTexCoord",
+            0
+        };
+        return names;
+    }
+
+protected:
+
+    virtual const char *vertexShader() const {
+        const char *shader =
+        "uniform highp mat4 qt_Matrix;                      \n"
+        "attribute highp vec4 qt_VertexPosition;            \n"
+        "attribute highp vec2 qt_VertexTexCoord;            \n"
+        "varying highp vec2 qt_TexCoord;                    \n"
+        "void main() {                                      \n"
+        "    qt_TexCoord = qt_VertexTexCoord;               \n"
+        "    gl_Position = qt_Matrix * qt_VertexPosition;   \n"
+        "}";
+        return shader;
+    }
+
+    virtual const char *fragmentShader() const {
+        static const char *shader =
+        "uniform sampler2D yTexture;"
+        "uniform sampler2D uTexture;"
+        "uniform sampler2D vTexture;"
+        "uniform mediump mat4 colorMatrix;"
+        "uniform lowp float opacity;"
+        ""
+        "varying highp vec2 qt_TexCoord;"
+        ""
+        "void main()"
+        "{"
+        "    mediump float Y = texture2D(yTexture, qt_TexCoord).r;"
+        "    mediump float U = texture2D(uTexture, qt_TexCoord).r;"
+        "    mediump float V = texture2D(vTexture, qt_TexCoord).r;"
+        "    mediump vec4 color = vec4(Y, U, V, 1.);"
+        "    gl_FragColor = colorMatrix * color * opacity;"
+        "}";
+        return shader;
+    }
+
+    virtual void initialize() {
+        m_id_matrix = program()->uniformLocation("qt_Matrix");
+        m_id_yTexture = program()->uniformLocation("yTexture");
+        m_id_uTexture = program()->uniformLocation("uTexture");
+        m_id_vTexture = program()->uniformLocation("vTexture");
+        m_id_colorMatrix = program()->uniformLocation("colorMatrix");
+        m_id_opacity = program()->uniformLocation("opacity");
+    }
+
+    int m_id_matrix;
+    int m_id_yTexture;
+    int m_id_uTexture;
+    int m_id_vTexture;
+    int m_id_colorMatrix;
+    int m_id_opacity;
+};
+
+
+class VideoMaterial_YUV420 : public QSGMaterial
+{
+public:
+    VideoMaterial_YUV420();
+    VideoMaterial_YUV420(GstVideoColorMatrix format);
+    ~VideoMaterial_YUV420();
+
+    virtual QSGMaterialType *type() const {
+        static QSGMaterialType theType;
+        return &theType;
+    }
+
+    virtual QSGMaterialShader *createShader() const {
+        return new VideoMaterialShader_YUV420;
+    }
+
+    virtual int compare(const QSGMaterial *other) const {
+        const VideoMaterial_YUV420 *m = static_cast<const VideoMaterial_YUV420 *>(other);
+        int d = m_textureIds[0] - m->m_textureIds[0];
+        if (d)
+            return d;
+        else if ((d = m_textureIds[1] - m->m_textureIds[1]) != 0)
+            return d;
+        else
+            return m_textureIds[2] - m->m_textureIds[2];
+    }
+
+    void updateBlending() {
+        setFlag(Blending, qFuzzyCompare(m_opacity, qreal(1.0)) ? false : true);
+    }
+
+    void setCurrentFrame(quint8 *data) {
+        QMutexLocker lock(&m_frameMutex);
+        m_frame = data;
+    }
+
+    void setTextureSize(QSize size) {
+        if (m_textureSize != size) {
+            m_textureSize = size;
+            m_textureSizeChanged = true;
+        }
+    }
+
+    void setFormat(GstVideoFormat format) {
+        m_format = format;
+
+        qDebug() << "setFormat: " << format;
+
+        switch (m_format) {
+
+        case GST_VIDEO_FORMAT_I420:
+        {
+            QSize size = m_textureSize;
+
+            int bytesPerLine = (size.width() + 3) & ~3;
+            int bytesPerLine2 = (size.width() / 2 + 3) & ~3;
+
+            m_textureInternalFormat = GL_LUMINANCE;
+            m_textureFormat = GL_LUMINANCE;
+            m_textureType = GL_UNSIGNED_BYTE;
+            m_textureCount = 3;
+            m_textureWidths[0] = bytesPerLine;
+            m_textureHeights[0] = size.height();
+            m_textureOffsets[0] = 0;
+            m_textureWidths[1] = bytesPerLine2;
+            m_textureHeights[1] = size.height() / 2;
+            m_textureOffsets[1] = bytesPerLine * size.height();
+            m_textureWidths[2] = bytesPerLine2;
+            m_textureHeights[2] = size.height() / 2;
+            m_textureOffsets[2] = bytesPerLine * size.height() + bytesPerLine2 * size.height()/2;
+        }
+            break;
+        case GST_VIDEO_FORMAT_YV12:
+        {
+            QSize size = m_textureSize;
+
+            int bytesPerLine = (size.width() + 3) & ~3;
+            int bytesPerLine2 = (size.width() / 2 + 3) & ~3;
+
+            m_textureInternalFormat = GL_LUMINANCE;
+            m_textureFormat = GL_LUMINANCE;
+            m_textureType = GL_UNSIGNED_BYTE;
+            m_textureCount = 3;
+            m_textureWidths[0] = bytesPerLine;
+            m_textureHeights[0] = size.height();
+            m_textureOffsets[0] = 0;
+            m_textureWidths[1] = bytesPerLine2;
+            m_textureHeights[1] = size.height() / 2;
+            m_textureOffsets[1] = bytesPerLine * size.height() + bytesPerLine2 * size.height()/2;
+            m_textureWidths[2] = bytesPerLine2;
+            m_textureHeights[2] = size.height() / 2;
+            m_textureOffsets[2] = bytesPerLine * size.height();
+        }
+            break;
+        default:
+            Q_ASSERT_X(false, "VideoMaterial_YUV420::setFormat", "Unknown video format for I420 node.");
+            break;
+        }
+    }
+
+    void setColorMatrix(GstVideoColorMatrix format) {
+
+        switch (format) {
+    #if 0
+        //I have no idea what this is - it's not needed currently in this code
+        case BufferFormat::YCbCr_JPEG:
+            m_colorMatrix = QMatrix4x4(
+                        1.0,  0.000,  1.402, -0.701,
+                        1.0, -0.344, -0.714,  0.529,
+                        1.0,  1.772,  0.000, -0.886,
+                        0.0,  0.000,  0.000,  1.0000);
+            break;
+    #endif
+        case GST_VIDEO_COLOR_MATRIX_BT709:
+            m_colorMatrix = QMatrix4x4(
+                        1.164,  0.000,  1.793, -0.5727,
+                        1.164, -0.534, -0.213,  0.3007,
+                        1.164,  2.115,  0.000, -1.1302,
+                        0.0,    0.000,  0.000,  1.0000);
+            break;
+        case GST_VIDEO_COLOR_MATRIX_BT601:
+        default: //BT 601:
+            m_colorMatrix = QMatrix4x4(
+                        1.164,  0.000,  1.596, -0.8708,
+                        1.164, -0.392, -0.813,  0.5296,
+                        1.164,  2.017,  0.000, -1.081,
+                        0.0,    0.000,  0.000,  1.0000);
+        }
+
+    }
+
+    void bind();
+    void bindTexture(int id, int w, int h, const quint8 *bits);
+
+    GstVideoFormat m_format;
+    QSize m_textureSize;
+    bool m_textureSizeChanged;
+
+    static const uint Num_Texture_IDs = 3;
+    GLuint m_textureIds[Num_Texture_IDs];
+
+    qreal m_opacity;
+    QMatrix4x4 m_colorMatrix;
+
+    //QVideoFrame m_frame;
+    quint8 *m_frame;
+    QMutex m_frameMutex;
+
+    // from TextureProvider class
+    GLenum m_textureFormat;
+    GLuint m_textureInternalFormat;
+    GLenum m_textureType;
+    int m_textureCount;
+    int m_textureWidths[3];
+    int m_textureHeights[3];
+    int m_textureOffsets[3];
+};
+
+VideoMaterial_YUV420::VideoMaterial_YUV420() :
+    m_opacity(1.0)
+{
+    qDebug() << "VideoMaterial";
+    memset(m_textureIds, 0, sizeof(m_textureIds));
+
+    m_textureSizeChanged = true;
+
+    m_frame = 0;
+
+    setFlag(Blending, false);
+}
+
+
+VideoMaterial_YUV420::VideoMaterial_YUV420(GstVideoColorMatrix format) :
+    m_opacity(1.0)
+{
+    memset(m_textureIds, 0, sizeof(m_textureIds));
+
+    m_textureSizeChanged = true;
+
+    m_frame = 0;
+
+    switch (format) {
+#if 0
+    //I have no idea what this is - it's not needed currently in this code
+    case BufferFormat::YCbCr_JPEG:
+        m_colorMatrix = QMatrix4x4(
+                    1.0,  0.000,  1.402, -0.701,
+                    1.0, -0.344, -0.714,  0.529,
+                    1.0,  1.772,  0.000, -0.886,
+                    0.0,  0.000,  0.000,  1.0000);
+        break;
+#endif
+    case GST_VIDEO_COLOR_MATRIX_BT709:
+        m_colorMatrix = QMatrix4x4(
+                    1.164,  0.000,  1.793, -0.5727,
+                    1.164, -0.534, -0.213,  0.3007,
+                    1.164,  2.115,  0.000, -1.1302,
+                    0.0,    0.000,  0.000,  1.0000);
+        break;
+    case GST_VIDEO_COLOR_MATRIX_BT601:
+    default: //BT 601:
+        m_colorMatrix = QMatrix4x4(
+                    1.164,  0.000,  1.596, -0.8708,
+                    1.164, -0.392, -0.813,  0.5296,
+                    1.164,  2.017,  0.000, -1.081,
+                    0.0,    0.000,  0.000,  1.0000);
+    }
+
+    setFlag(Blending, false);
+}
+
+VideoMaterial_YUV420::~VideoMaterial_YUV420()
+{
+    if (!m_textureSize.isEmpty())
+        glDeleteTextures(Num_Texture_IDs, m_textureIds);
+}
+
+void VideoMaterial_YUV420::bind()
+{
+    QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions();
+
+    QMutexLocker lock(&m_frameMutex);
+
+    if (m_frame) {
+
+        if (m_textureSizeChanged) {
+            if (!m_textureSize.isEmpty())
+                glDeleteTextures(Num_Texture_IDs, m_textureIds);
+            glGenTextures(Num_Texture_IDs, m_textureIds);
+            m_textureSizeChanged = false;
+        }
+
+        if (m_format == GST_VIDEO_FORMAT_YV12)
+            qSwap(m_textureOffsets[1], m_textureOffsets[2]);
+
+
+        functions->glActiveTexture(GL_TEXTURE1);
+        bindTexture(m_textureIds[1], m_textureWidths[1], m_textureHeights[1], m_frame + m_textureOffsets[1]);
+        functions->glActiveTexture(GL_TEXTURE2);
+        bindTexture(m_textureIds[2], m_textureWidths[2], m_textureHeights[2], m_frame + m_textureOffsets[2]);
+        functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit
+        bindTexture(m_textureIds[0], m_textureWidths[0], m_textureHeights[0], m_frame + m_textureOffsets[0]);
+
+        m_frame = 0;
+
+    } else {
+        functions->glActiveTexture(GL_TEXTURE1);
+        glBindTexture(GL_TEXTURE_2D, m_textureIds[1]);
+        functions->glActiveTexture(GL_TEXTURE2);
+        glBindTexture(GL_TEXTURE_2D, m_textureIds[2]);
+        functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit
+        glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);
+    }
+
+
+
+
+//    if (m_frame) {
+//            int fw = m_frame.width();
+//            int fh = m_frame.height();
+
+//            // Frame has changed size, recreate textures...
+//            if (m_textureSize != m_frame.size()) {
+//                if (!m_textureSize.isEmpty())
+//                    glDeleteTextures(Num_Texture_IDs, m_textureIds);
+//                glGenTextures(Num_Texture_IDs, m_textureIds);
+//                m_textureSize = m_frame.size();
+//            }
+
+//            const uchar *bits = (uchar*)m_frame;
+//            int bpl = //m_frame.bytesPerLine();
+//            int bpl2 =  m_textureWidths[1]; //(bpl / 2 + 3) & ~3;
+//            int offsetU = bpl * fh;
+//            int offsetV = bpl * fh + bpl2 * fh / 2;
+
+//            if (m_frame.pixelFormat() == QVideoFrame::Format_YV12)
+////                qSwap(offsetU, offsetV);
+
+
+//            functions->glActiveTexture(GL_TEXTURE1);
+//            bindTexture(m_textureIds[1], fw/2, fh / 2, bits + offsetU);
+//            functions->glActiveTexture(GL_TEXTURE2);
+//            bindTexture(m_textureIds[2], fw/2, fh / 2, bits + offsetV);
+//            functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit
+//            bindTexture(m_textureIds[0], fw, fh, bits);
+
+
+//        m_frame = 0; //QVideoFrame();
+//    } else {
+//        functions->glActiveTexture(GL_TEXTURE1);
+//        glBindTexture(GL_TEXTURE_2D, m_textureIds[1]);
+//        functions->glActiveTexture(GL_TEXTURE2);
+//        glBindTexture(GL_TEXTURE_2D, m_textureIds[2]);
+//        functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit
+//        glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);
+//    }
+}
+
+void VideoMaterial_YUV420::bindTexture(int id, int w, int h, const quint8 *bits)
+{
+    glBindTexture(GL_TEXTURE_2D, id);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, bits);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+}
+
+
+VideoNode_I420::VideoNode_I420()
+{
+    qDebug() << "i420";
+    setFlag(QSGNode::OwnsMaterial);
+    m_material = new VideoMaterial_YUV420();
+    setMaterial(m_material);
+}
+
+VideoNode_I420::VideoNode_I420(const BufferFormat &format)
+{
+    setFlag(QSGNode::OwnsMaterial);
+    m_material = new VideoMaterial_YUV420(format.colorMatrix());
+    setMaterial(m_material);
+}
+
+VideoNode_I420::~VideoNode_I420()
+{
+}
+
+void VideoNode_I420::setCurrentFrame(quint8 *data)
+{
+    m_material->setCurrentFrame(data);
+    markDirty(DirtyMaterial);
+}
+
+void VideoNode_I420::setBufferFormat(const BufferFormat &format)
+{
+    m_bufferFormat = format;
+
+    m_material->setTextureSize(m_bufferFormat.frameSize());
+
+    m_material->setFormat(m_bufferFormat.videoFormat());
+
+    m_material->setColorMatrix(m_bufferFormat.colorMatrix());
+
+}
+
+
+void VideoMaterialShader_YUV420::updateState(const RenderState &state,
+                                                QSGMaterial *newMaterial,
+                                                QSGMaterial *oldMaterial)
+{
+    Q_UNUSED(oldMaterial);
+
+    VideoMaterial_YUV420 *mat = static_cast<VideoMaterial_YUV420 *>(newMaterial);
+    program()->setUniformValue(m_id_yTexture, 0);
+    program()->setUniformValue(m_id_uTexture, 1);
+    program()->setUniformValue(m_id_vTexture, 2);
+
+    mat->bind();
+
+    program()->setUniformValue(m_id_colorMatrix, mat->m_colorMatrix);
+    if (state.isOpacityDirty()) {
+        mat->m_opacity = state.opacity();
+        program()->setUniformValue(m_id_opacity, GLfloat(mat->m_opacity));
+    }
+
+    if (state.isMatrixDirty())
+        program()->setUniformValue(m_id_matrix, state.combinedMatrix());
+}
diff -Naur qt-gstreamer-orig/src/QGst/Ui/videonode_i420.h qt-gstreamer/src/QGst/Ui/videonode_i420.h
--- qt-gstreamer-orig/src/QGst/Ui/videonode_i420.h	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/videonode_i420.h	2013-07-02 12:09:29.077359550 +0200
@@ -0,0 +1,59 @@
+/*
+    Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+    Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef VIDEONODE_I420_H
+#define VIDEONODE_I420_H
+
+#include "videonode.h"
+
+class VideoMaterial_YUV420;
+
+class VideoNode_I420 : public VideoNode
+{
+public:
+    VideoNode_I420();
+    VideoNode_I420(const BufferFormat &format);
+    ~VideoNode_I420();
+
+    virtual GstVideoFormat pixelFormat() const {
+        return m_bufferFormat.videoFormat();
+    }
+    virtual QSize nativeSize() const {
+        return m_bufferFormat.frameSize();
+    }
+    virtual void setBufferFormat(const BufferFormat &format);
+
+    void setCurrentFrame(quint8 *data);
+
+private:
+    void bindTexture(int id, int unit, int w, int h, const uchar *bits);
+
+    BufferFormat m_bufferFormat;
+    VideoMaterial_YUV420 *m_material;
+};
+
+class VideoNodeFactory_I420 : public VideoNodeFactoryInterface
+{
+public:
+    QSet<GstVideoFormat> supportedPixelFormats() const;
+    VideoNode *createEmptyNode(GstVideoFormat format);
+    VideoNode *createNode(const BufferFormat &format);
+};
+
+
+#endif // QSGVIDEONODE_I420_H
diff -Naur qt-gstreamer-orig/src/QGst/Ui/videonode_rgb.cpp qt-gstreamer/src/QGst/Ui/videonode_rgb.cpp
--- qt-gstreamer-orig/src/QGst/Ui/videonode_rgb.cpp	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/videonode_rgb.cpp	2013-07-02 12:09:51.749613581 +0200
@@ -0,0 +1,471 @@
+/*
+    Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+    Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "videonode_rgb.h"
+
+#include <QtCore/QMutex>
+#include <QtQuick/QSGTextureMaterial>
+#include <QtQuick/QSGMaterial>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QOpenGLShaderProgram>
+#include <QtCore/QDebug>
+
+QSet<GstVideoFormat> VideoNodeFactory_RGB::supportedPixelFormats() const
+{
+    return QSet<GstVideoFormat>()
+        //also handled by the generic painter on LE
+        << GST_VIDEO_FORMAT_BGRA
+        << GST_VIDEO_FORMAT_BGRx
+
+        //also handled by the generic painter on BE
+        << GST_VIDEO_FORMAT_ARGB
+        << GST_VIDEO_FORMAT_xRGB
+
+        //also handled by the generic painter everywhere
+        << GST_VIDEO_FORMAT_RGB
+        << GST_VIDEO_FORMAT_RGB16
+
+        //not handled by the generic painter
+        << GST_VIDEO_FORMAT_BGR
+        << GST_VIDEO_FORMAT_v308
+        << GST_VIDEO_FORMAT_AYUV
+//        << GST_VIDEO_FORMAT_YV12
+//        << GST_VIDEO_FORMAT_I420
+        ;
+}
+
+VideoNode *VideoNodeFactory_RGB::createEmptyNode(GstVideoFormat format)
+{
+    if (supportedPixelFormats().contains(format))
+        return new VideoNode_RGB();
+
+    return 0;
+}
+
+VideoNode *VideoNodeFactory_RGB::createNode(const BufferFormat &format)
+{
+    if (supportedPixelFormats().contains(format.videoFormat()))
+        return new VideoNode_RGB(format);
+
+    return 0;
+}
+
+class VideoMaterialShader_RGB : public QSGMaterialShader
+{
+public:
+    VideoMaterialShader_RGB(GstVideoFormat format)
+        : QSGMaterialShader(),
+          m_id_matrix(-1),
+          m_id_rgbTexture(-1),
+          m_id_opacity(-1),
+          m_format(format)
+    {
+    }
+
+    void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial);
+
+    virtual char const *const *attributeNames() const {
+        static const char *names[] = {
+            "qt_VertexPosition",
+            "qt_VertexTexCoord",
+            0
+        };
+        return names;
+    }
+
+protected:
+
+    virtual const char *vertexShader() const {
+        const char *shader =
+        "uniform highp mat4 qt_Matrix;                      \n"
+        "attribute highp vec4 qt_VertexPosition;            \n"
+        "attribute highp vec2 qt_VertexTexCoord;            \n"
+        "varying highp vec2 qt_TexCoord;                    \n"
+        "void main() {                                      \n"
+        "    qt_TexCoord = qt_VertexTexCoord;               \n"
+        "    gl_Position = qt_Matrix * qt_VertexPosition;   \n"
+        "}";
+        return shader;
+    }
+
+    virtual const char *fragmentShader() const {
+        static const char *shader =
+        "uniform sampler2D rgbTexture;"
+        "uniform lowp float opacity;"
+        ""
+        "varying highp vec2 qt_TexCoord;"
+        ""
+        "void main()"
+        "{"
+        "    gl_FragColor = texture2D(rgbTexture, qt_TexCoord) * opacity;"
+        "}";
+
+        static const char *colorsSwapShader =
+        "uniform sampler2D rgbTexture;"
+        "uniform lowp float opacity;"
+        ""
+        "varying highp vec2 qt_TexCoord;"
+        ""
+        "void main()"
+        "{"
+        "    gl_FragColor =  vec4(texture2D(rgbTexture, qt_TexCoord).bgr, 1.0) * opacity;"
+        "}";
+
+
+        switch (m_format) {
+//            case GST_VIDEO_FORMAT_RGB: //QVideoFrame::Format_RGB32
+//            case GST_VIDEO_FORMAT_ARGB: //QVideoFrame::Format_ARGB32
+//                return colorsSwapShader;
+            default:
+                return shader;
+        }
+    }
+
+    virtual void initialize() {
+        m_id_matrix = program()->uniformLocation("qt_Matrix");
+        m_id_rgbTexture = program()->uniformLocation("rgbTexture");
+        m_id_opacity = program()->uniformLocation("opacity");
+    }
+
+    int m_id_matrix;
+    int m_id_rgbTexture;
+    int m_id_opacity;
+    GstVideoFormat m_format;
+};
+
+
+class VideoMaterial_RGB : public QSGMaterial
+{
+public:
+    VideoMaterial_RGB() :
+        m_textureId(0),
+        m_opacity(1.0)
+    {
+        m_textureSizeChanged = true;
+
+        m_frame = 0;
+
+        setFlag(Blending, false);
+    }
+
+    VideoMaterial_RGB(GstVideoColorMatrix format) :
+        m_textureId(0),
+        m_opacity(1.0)
+    {
+        setFlag(Blending, false);
+    }
+
+    ~VideoMaterial_RGB()
+    {
+        if (m_textureId)
+            glDeleteTextures(1, &m_textureId);
+    }
+
+    virtual QSGMaterialType *type() const {
+        static QSGMaterialType theType;
+        return &theType;
+    }
+
+    virtual QSGMaterialShader *createShader() const {
+        return new VideoMaterialShader_RGB(m_format);
+    }
+
+    virtual int compare(const QSGMaterial *other) const {
+        const VideoMaterial_RGB *m = static_cast<const VideoMaterial_RGB *>(other);
+        return m_textureId - m->m_textureId;
+    }
+
+    void updateBlending() {
+        setFlag(Blending, qFuzzyCompare(m_opacity, qreal(1.0)) ? false : true);
+    }
+
+    void setCurrentFrame(quint8 *data) {
+        QMutexLocker lock(&m_frameMutex);
+        m_frame = data;
+    }
+
+    void setTextureSize(QSize size) {
+        if (m_textureSize != size) {
+            m_textureSize = size;
+            m_textureSizeChanged = true;
+        }
+    }
+
+    void setFormat(GstVideoFormat format) {
+        m_format = format;
+
+//        qDebug() << "setFormat: " << format;
+
+        QSize size = m_textureSize;
+
+
+        switch (format) {
+        case GST_VIDEO_FORMAT_BGRx:
+            setTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, size);
+            break;
+        case GST_VIDEO_FORMAT_xRGB:
+            setTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, size);
+            break;
+        case GST_VIDEO_FORMAT_BGRA:
+            setTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, size);
+            break;
+        case GST_VIDEO_FORMAT_ARGB:
+            setTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, size);
+            break;
+        case GST_VIDEO_FORMAT_RGB:
+            setTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, size);
+            break;
+        case GST_VIDEO_FORMAT_BGR:
+            setTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, size);
+            break;
+        //NOTE: unlike the other formats, this is endianness-dependent,
+        //but using GL_UNSIGNED_SHORT_5_6_5 ensures that it's handled correctly
+        case GST_VIDEO_FORMAT_RGB16:
+            setTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, size);
+            break;
+        case GST_VIDEO_FORMAT_v308:
+            setTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, size);
+            break;
+        case GST_VIDEO_FORMAT_AYUV:
+            setTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, size);
+            break;
+        default:
+            Q_ASSERT(false);
+            break;
+        }
+
+
+
+    }
+
+    void setTextureInfo(GLenum internalFormat, GLuint format, GLenum type, const QSize &size) {
+
+
+//#ifndef QT_OPENGL_ES
+//        //make sure we get 8 bits per component, at least on the desktop GL where we can
+//        switch(internalFormat) {
+//        case GL_RGBA:
+//            internalFormat = GL_RGBA8;
+//            break;
+//        case GL_RGB:
+//            internalFormat = GL_RGB8;
+//            break;
+//        default:
+//            break;
+//        }
+//#endif
+
+        m_textureFormat = internalFormat;
+        m_textureInternalFormat = format;
+        m_textureType = type;
+
+        m_textureCount = 1;
+        m_textureWidth = size.width();
+        m_textureHeight = size.height();
+        m_textureOffsets = 0;
+    }
+
+    void setColorMatrix(GstVideoColorMatrix format) {
+
+    }
+
+    void bind()
+    {
+        QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions();
+
+        QMutexLocker lock(&m_frameMutex);
+
+
+        if (m_frame) {
+
+            if (m_textureSizeChanged) {
+                if (!m_textureSize.isEmpty())
+                    glDeleteTextures(1, &m_textureId);
+                glGenTextures(1, &m_textureId);
+                m_textureSizeChanged = false;
+            }
+
+
+            GLint dataType = GL_UNSIGNED_BYTE;
+            GLint dataFormat = GL_RGBA;
+
+            if (m_format == GST_VIDEO_FORMAT_RGB16) {
+                dataType = GL_UNSIGNED_SHORT_5_6_5;
+                dataFormat = GL_RGB;
+            }
+
+//            m_textureInternalFormat = dataFormat;
+//            m_textureFormat = dataFormat;
+//            m_textureType = dataType;
+
+
+//            qDebug() << "datatype: " << dataType;
+//            qDebug() << "dataformat: " << dataFormat;
+//            qDebug() << "texturesize: " << m_textureSize.width() << "x" << m_textureSize.height();
+
+//            qDebug() << "textinternal: " << m_textureInternalFormat;
+//            qDebug() << "texture: " << m_textureFormat;
+//            qDebug() << "type: " << m_textureType;
+//            qDebug() << "texturesize: " << m_textureWidth << "x" << m_textureHeight;
+
+            functions->glActiveTexture(GL_TEXTURE0);
+            glBindTexture(GL_TEXTURE_2D, m_textureId);
+
+            glTexImage2D(
+                        GL_TEXTURE_2D,
+                        0,
+                        m_textureInternalFormat,
+                        m_textureWidth,
+                        m_textureHeight,
+                        0,
+                        m_textureFormat,
+                        m_textureType,
+                        m_frame);
+
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+
+            m_frame = 0;
+
+        } else {
+            functions->glActiveTexture(GL_TEXTURE0);
+            glBindTexture(GL_TEXTURE_2D, m_textureId);
+        }
+
+
+
+//        if (m_frame.isValid()) {
+//            if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) {
+//                if (m_textureSize != m_frame.size()) {
+//                    if (!m_textureSize.isEmpty())
+//                        glDeleteTextures(1, &m_textureId);
+//                    glGenTextures(1, &m_textureId);
+//                    m_textureSize = m_frame.size();
+//                }
+
+//                GLint dataType = GL_UNSIGNED_BYTE;
+//                GLint dataFormat = GL_RGBA;
+
+//                if (m_frame.pixelFormat() == QVideoFrame::Format_RGB565) {
+//                    dataType = GL_UNSIGNED_SHORT_5_6_5;
+//                    dataFormat = GL_RGB;
+//                }
+
+//                functions->glActiveTexture(GL_TEXTURE0);
+//                glBindTexture(GL_TEXTURE_2D, m_textureId);
+//                glTexImage2D(GL_TEXTURE_2D, 0, dataFormat,
+//                             m_textureSize.width(), m_textureSize.height(),
+//                             0, dataFormat, dataType, m_frame.bits());
+
+//                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+//                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+//                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+//                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+//                m_frame.unmap();
+//            }
+//            m_frame = QVideoFrame();
+//        } else {
+//            functions->glActiveTexture(GL_TEXTURE0);
+//            glBindTexture(GL_TEXTURE_2D, m_textureId);
+//        }
+    }
+
+    //QVideoFrame m_frame;
+    quint8 *m_frame;
+    QMutex m_frameMutex;
+
+    QSize m_textureSize;
+    bool m_textureSizeChanged;
+    GstVideoFormat m_format;
+
+    GLuint m_textureId;
+    qreal m_opacity;
+
+    GLenum m_textureFormat;
+    GLuint m_textureInternalFormat;
+    GLenum m_textureType;
+
+    int m_textureCount;
+
+    int m_textureWidth;
+    int m_textureHeight;
+    int m_textureOffsets;
+};
+
+
+VideoNode_RGB::VideoNode_RGB()
+{
+    qDebug() << "RGB";
+    setFlag(QSGNode::OwnsMaterial);
+    m_material = new VideoMaterial_RGB();
+    setMaterial(m_material);
+}
+
+VideoNode_RGB::VideoNode_RGB(const BufferFormat &format)
+{
+    setFlag(QSGNode::OwnsMaterial);
+    m_material = new VideoMaterial_RGB(format.colorMatrix());
+    setMaterial(m_material);
+}
+
+VideoNode_RGB::~VideoNode_RGB()
+{
+}
+
+void VideoNode_RGB::setCurrentFrame(quint8 *data)
+{
+    m_material->setCurrentFrame(data);
+    markDirty(DirtyMaterial);
+}
+
+void VideoNode_RGB::setBufferFormat(const BufferFormat &format)
+{
+    m_bufferFormat = format;
+
+    m_material->setTextureSize(m_bufferFormat.frameSize());
+
+    m_material->setFormat(m_bufferFormat.videoFormat());
+
+    m_material->setColorMatrix(m_bufferFormat.colorMatrix());
+
+}
+
+void VideoMaterialShader_RGB::updateState(const RenderState &state,
+                                                QSGMaterial *newMaterial,
+                                                QSGMaterial *oldMaterial)
+{
+    Q_UNUSED(oldMaterial);
+    VideoMaterial_RGB *mat = static_cast<VideoMaterial_RGB *>(newMaterial);
+    program()->setUniformValue(m_id_rgbTexture, 0);
+
+    mat->bind();
+
+    if (state.isOpacityDirty()) {
+        mat->m_opacity = state.opacity();
+        mat->updateBlending();
+        program()->setUniformValue(m_id_opacity, GLfloat(mat->m_opacity));
+    }
+
+    if (state.isMatrixDirty())
+        program()->setUniformValue(m_id_matrix, state.combinedMatrix());
+}
diff -Naur qt-gstreamer-orig/src/QGst/Ui/videonode_rgb.h qt-gstreamer/src/QGst/Ui/videonode_rgb.h
--- qt-gstreamer-orig/src/QGst/Ui/videonode_rgb.h	1970-01-01 01:00:00.000000000 +0100
+++ qt-gstreamer/src/QGst/Ui/videonode_rgb.h	2013-07-02 12:09:57.893682405 +0200
@@ -0,0 +1,58 @@
+/*
+    Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+    Copyright (C) 2013 basysKom GmbH <info@basyskom.com>
+
+    This library is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published
+    by the Free Software Foundation; either version 2.1 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef VIDEONODE_RGB_H
+#define VIDEONODE_RGB_H
+
+#include "videonode.h"
+
+class VideoMaterial_RGB;
+
+class VideoNode_RGB : public VideoNode
+{
+public:
+    VideoNode_RGB();
+    VideoNode_RGB(const BufferFormat &format);
+    ~VideoNode_RGB();
+
+    virtual GstVideoFormat pixelFormat() const {
+        return m_bufferFormat.videoFormat();
+    }
+    virtual QSize nativeSize() const {
+        return m_bufferFormat.frameSize();
+    }
+    virtual void setBufferFormat(const BufferFormat &format);
+
+    void setCurrentFrame(quint8 *data);
+
+private:
+    BufferFormat m_bufferFormat;
+    VideoMaterial_RGB *m_material;
+
+};
+
+class VideoNodeFactory_RGB : public VideoNodeFactoryInterface
+{
+public:
+    QSet<GstVideoFormat> supportedPixelFormats() const;
+    VideoNode *createEmptyNode(GstVideoFormat format);
+    VideoNode *createNode(const BufferFormat &format);
+
+};
+
+#endif // VIDEONODE_RGB_H
