[oe] [meta-qt5][PATCH] QtGstreamer recipe with patches for IMX6 support.

Ilya Smelykh ilya.smelykh at gmail.com
Thu Jul 31 16:37:47 UTC 2014


---
 recipes-qt/qt5/qtgstreamer.inc                     |  12 +
 ...-i.MX6-zero-copy-rendering-implementation.patch | 249 +++++++++++++++++++++
 ...-s-flags-as-native-video-audio-in-case-of.patch |  60 +++++
 recipes-qt/qt5/qtgstreamer_git.bb                  |  44 ++++
 4 files changed, 365 insertions(+)
 create mode 100644 recipes-qt/qt5/qtgstreamer.inc
 create mode 100644 recipes-qt/qt5/qtgstreamer/0001-Added-i.MX6-zero-copy-rendering-implementation.patch
 create mode 100644 recipes-qt/qt5/qtgstreamer/0002-Set-playbin-s-flags-as-native-video-audio-in-case-of.patch
 create mode 100644 recipes-qt/qt5/qtgstreamer_git.bb

diff --git a/recipes-qt/qt5/qtgstreamer.inc b/recipes-qt/qt5/qtgstreamer.inc
new file mode 100644
index 0000000..6a8bd57
--- /dev/null
+++ b/recipes-qt/qt5/qtgstreamer.inc
@@ -0,0 +1,12 @@
+require qt5.inc
+
+LICENSE = "GPLv2 & LGPLv2 & LGPLv2.1"
+SECTION = "multimedia"
+LIC_FILES_CHKSUM = "file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 \
+                    file://COPYING-LGPL-2;md5=5f30f0716dfdd0d91eb439ebec522ec2 \
+                    file://COPYING-LGPL-2.1;md5=fbc093901857fcd118f065f900982c24"
+
+DEPENDS += "qtbase qtdeclarative boost"
+
+PACKAGECONFIG ??= "examples"
+PACKAGECONFIG[examples] = "-DQTGSTREAMER_EXAMPLES=ON, -DQTGSTREAMER_EXAMPLES=OFF"
diff --git a/recipes-qt/qt5/qtgstreamer/0001-Added-i.MX6-zero-copy-rendering-implementation.patch b/recipes-qt/qt5/qtgstreamer/0001-Added-i.MX6-zero-copy-rendering-implementation.patch
new file mode 100644
index 0000000..dd5658a
--- /dev/null
+++ b/recipes-qt/qt5/qtgstreamer/0001-Added-i.MX6-zero-copy-rendering-implementation.patch
@@ -0,0 +1,249 @@
+From c36ea48f3f4f0ad1b07a18c3717bd049ac24e32c Mon Sep 17 00:00:00 2001
+From: Benjamin Federau <benjamin.federau at basyskom.com>
+Date: Mon, 12 May 2014 17:31:12 +0200
+Subject: [PATCH] Added i.MX6 zero-copy rendering implementation
+
+---
+ CMakeLists.txt                                     |   11 +++
+ elements/gstqtvideosink/CMakeLists.txt             |    4 +
+ elements/gstqtvideosink/painters/videomaterial.cpp |   84 ++++++++++++++++++++
+ elements/gstqtvideosink/painters/videomaterial.h   |    8 ++
+ 4 files changed, 107 insertions(+)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 9304fc3..86dbd46 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -19,6 +19,8 @@ option(USE_QT_PLUGIN_DIR "Install qt plugins at the system location" ON)
+ include(GNUInstallDirs)
+ include(MacroLogFeature)
+ 
++set(HW_PLATFORM "none" CACHE STRING "Specific hardware platform used for the build")
++
+ set(Qt4_MIN_VERSION 4.7)
+ set(Qt5_MIN_VERSION 5.0.0)
+ find_package(Qt4or5 COMPONENTS Core Gui Widgets OPTIONAL_COMPONENTS OpenGL Quick1 Quick2 Qml Test)
+@@ -173,6 +175,15 @@ else()
+     endif()
+ endif()
+ 
++# Enable hardware specific functionality
++if (${HW_PLATFORM} STREQUAL "imx6")
++    message(STATUS "Enabled hardware platform: Freescale i.MX6")
++    set(USE_HW_PLATFORM TRUE)
++    set(QTGSTREAMER_HW_PLATFORM "-DHW_PLATFORM_IMX6")
++else()
++    set(USE_HW_PLATFORM FALSE)
++endif()
++
+ 
+ if (QTGSTREAMER_CODEGEN AND FLEX_FOUND AND BISON_FOUND)
+     add_subdirectory(codegen)
+diff --git a/elements/gstqtvideosink/CMakeLists.txt b/elements/gstqtvideosink/CMakeLists.txt
+index ddb3da9..307c434 100644
+--- a/elements/gstqtvideosink/CMakeLists.txt
++++ b/elements/gstqtvideosink/CMakeLists.txt
+@@ -57,6 +57,10 @@ add_definitions(
+     -DQWIDGETVIDEOSINK_NAME="${QWIDGETVIDEOSINK_NAME}"
+ )
+ 
++if (USE_HW_PLATFORM)
++    add_definitions(${QTGSTREAMER_HW_PLATFORM})
++endif()
++
+ if (GstQtVideoSink_LINK_OPENGL)
+     if (OPENGLES2_FOUND)
+         set(GstQtVideoSink_GL_LIBS ${OPENGLES2_LIBRARY})
+diff --git a/elements/gstqtvideosink/painters/videomaterial.cpp b/elements/gstqtvideosink/painters/videomaterial.cpp
+index 7711415..b9a83f7 100644
+--- a/elements/gstqtvideosink/painters/videomaterial.cpp
++++ b/elements/gstqtvideosink/painters/videomaterial.cpp
+@@ -95,6 +95,18 @@ inline const char * const qtvideosink_glsl_yuvPlanarFragmentShader()
+     "}\n";
+ }
+ 
++inline const char * const qtvideosink_glsl_vivanteFragmentShader()
++{
++    return
++    "uniform sampler2D texture;\n"
++    "uniform lowp float opacity;\n"
++    "varying highp vec2 qt_TexCoord;\n"
++    "void main(void)\n"
++    "{\n"
++    "    gl_FragColor = texture2D( texture, qt_TexCoord ) * opacity;\n"
++    "}\n";
++}
++
+ class VideoMaterialShader : public QSGMaterialShader
+ {
+ public:
+@@ -104,6 +116,10 @@ public:
+         Q_UNUSED(oldMaterial);
+ 
+         VideoMaterial *material = static_cast<VideoMaterial *>(newMaterial);
++
++#ifdef HW_PLATFORM_IMX6
++        program()->setUniformValue(m_id_texture, 0);
++#else
+         if (m_id_rgbTexture > 0) {
+             program()->setUniformValue(m_id_rgbTexture, 0);
+         } else {
+@@ -111,6 +127,7 @@ public:
+             program()->setUniformValue(m_id_uTexture, 1);
+             program()->setUniformValue(m_id_vTexture, 2);
+         }
++#endif
+ 
+         if (state.isOpacityDirty()) {
+             material->setFlag(QSGMaterial::Blending,
+@@ -144,6 +161,9 @@ protected:
+         m_id_vTexture = program()->uniformLocation("vTexture");
+         m_id_colorMatrix = program()->uniformLocation("colorMatrix");
+         m_id_opacity = program()->uniformLocation("opacity");
++#ifdef HW_PLATFORM_IMX6
++        m_id_texture = program()->uniformLocation("texture");
++#endif
+     }
+ 
+     virtual const char *vertexShader() const {
+@@ -157,6 +177,9 @@ protected:
+     int m_id_vTexture;
+     int m_id_colorMatrix;
+     int m_id_opacity;
++#ifdef HW_PLATFORM_IMX6
++    int m_id_texture;
++#endif
+ };
+ 
+ template <const char * const (*FragmentShader)()>
+@@ -220,10 +243,19 @@ VideoMaterial *VideoMaterial::create(const BufferFormat & format)
+     // YUV 420 planar
+     case GST_VIDEO_FORMAT_I420:
+     case GST_VIDEO_FORMAT_YV12:
++#ifdef HW_PLATFORM_IMX6
++        // Note: The following was just implemented for YUV video format. The above formats are not tested
++        // with the Vivante mapping method. They will still use the glTexImage2D method!
++        material = new VideoMaterialImpl<qtvideosink_glsl_vivanteFragmentShader>;
++        material->initVivanteTextureInfo(
++                    (format.videoFormat() == GST_VIDEO_FORMAT_YV12) ? GL_VIV_YV12 : GL_VIV_I420,
++                    format.frameSize());
++#else
+         material = new VideoMaterialImpl<qtvideosink_glsl_yuvPlanarFragmentShader>;
+         material->initYuv420PTextureInfo(
+             (format.videoFormat() == GST_VIDEO_FORMAT_YV12) /* uvSwapped */,
+             format.frameSize());
++#endif
+         break;
+ 
+     default:
+@@ -315,6 +347,18 @@ void VideoMaterial::initYuv420PTextureInfo(bool uvSwapped, const QSize &size)
+       qSwap (m_textureOffsets[1], m_textureOffsets[2]);
+ }
+ 
++#ifdef HW_PLATFORM_IMX6
++void VideoMaterial::initVivanteTextureInfo(
++        GLuint format, const QSize &size)
++{
++    m_textureFormat = format;
++    m_textureCount = 1;
++    m_textureWidths[0] = size.width();
++    m_textureHeights[0] = size.height();
++    m_textureOffsets[0] = 0;
++}
++#endif
++
+ void VideoMaterial::init(GstVideoColorMatrix colorMatrixType)
+ {
+     glGenTextures(m_textureCount, m_textureIds);
+@@ -426,12 +470,46 @@ void VideoMaterial::bind()
+         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]);
++
++#ifdef HW_PLATFORM_IMX6
++        QOpenGLContext *glcontext = QOpenGLContext::currentContext();
++        static PFNGLTEXDIRECTINVALIDATEVIVPROC glTexDirectInvalidateVIV_LOCAL = 0;
++        glTexDirectInvalidateVIV_LOCAL = reinterpret_cast<PFNGLTEXDIRECTINVALIDATEVIVPROC>(glcontext->getProcAddress("glTexDirectInvalidateVIV"));
++
++        glTexDirectInvalidateVIV_LOCAL(GL_TEXTURE_2D);
++#endif
+     }
+ }
+ 
+ void VideoMaterial::bindTexture(int i, const quint8 *data)
+ {
+     glBindTexture(GL_TEXTURE_2D, m_textureIds[i]);
++
++#ifdef HW_PLATFORM_IMX6
++    QOpenGLContext *glcontext = QOpenGLContext::currentContext();
++    static PFNGLTEXDIRECTVIVMAPPROC glTexDirectVIVMap_LOCAL = 0;
++    static PFNGLTEXDIRECTINVALIDATEVIVPROC glTexDirectInvalidateVIV_LOCAL = 0;
++
++    if (glTexDirectVIVMap_LOCAL == 0 || glTexDirectInvalidateVIV_LOCAL == 0) {
++        glTexDirectVIVMap_LOCAL = reinterpret_cast<PFNGLTEXDIRECTVIVMAPPROC>(glcontext->getProcAddress("glTexDirectVIVMap"));
++        glTexDirectInvalidateVIV_LOCAL = reinterpret_cast<PFNGLTEXDIRECTINVALIDATEVIVPROC>(glcontext->getProcAddress("glTexDirectInvalidateVIV"));
++    }
++    if (glTexDirectVIVMap_LOCAL == 0 || glTexDirectInvalidateVIV_LOCAL == 0) {
++        qWarning() << Q_FUNC_INFO << "couldn't find \"glTexDirectVIVMap\" and/or \"glTexDirectInvalidateVIV\" => do nothing and return";
++        return;
++    }
++
++    void *bits = (void*)data;
++    GLuint physical = ~0U;
++
++    glTexDirectVIVMap_LOCAL(
++                GL_TEXTURE_2D,
++                m_textureWidths[i],
++                m_textureHeights[i],
++                m_textureFormat,
++                &bits,
++                &physical);
++#else
+     glTexImage2D(
+         GL_TEXTURE_2D,
+         0,
+@@ -442,9 +520,15 @@ void VideoMaterial::bindTexture(int i, const quint8 *data)
+         m_textureFormat,
+         m_textureType,
+         data + m_textureOffsets[i]);
++#endif
++
+     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);
++
++#ifdef HW_PLATFORM_IMX6
++    glTexDirectInvalidateVIV_LOCAL(GL_TEXTURE_2D);
++#endif
+ }
+ 
+diff --git a/elements/gstqtvideosink/painters/videomaterial.h b/elements/gstqtvideosink/painters/videomaterial.h
+index 90a6379..6a918e9 100644
+--- a/elements/gstqtvideosink/painters/videomaterial.h
++++ b/elements/gstqtvideosink/painters/videomaterial.h
+@@ -19,6 +19,11 @@
+ #ifndef VIDEOMATERIAL_H
+ #define VIDEOMATERIAL_H
+ 
++#ifdef HW_PLATFORM_IMX6
++#include <GLES2/gl2.h>
++#include <GLES2/gl2ext.h>
++#endif
++
+ #include "../utils/bufferformat.h"
+ #include <QSize>
+ #include <QMutex>
+@@ -47,6 +52,9 @@ protected:
+     void initRgbTextureInfo(GLenum internalFormat, GLuint format,
+                             GLenum type, const QSize &size);
+     void initYuv420PTextureInfo(bool uvSwapped, const QSize &size);
++#ifdef HW_PLATFORM_IMX6
++    void initVivanteTextureInfo(GLuint format, const QSize &size);
++#endif
+     void init(GstVideoColorMatrix colorMatrixType);
+ 
+ private:
+-- 
+1.7.9.5
+
diff --git a/recipes-qt/qt5/qtgstreamer/0002-Set-playbin-s-flags-as-native-video-audio-in-case-of.patch b/recipes-qt/qt5/qtgstreamer/0002-Set-playbin-s-flags-as-native-video-audio-in-case-of.patch
new file mode 100644
index 0000000..1d95727
--- /dev/null
+++ b/recipes-qt/qt5/qtgstreamer/0002-Set-playbin-s-flags-as-native-video-audio-in-case-of.patch
@@ -0,0 +1,60 @@
+From c580e55d6a3a7bdb549580c9f6f11501fc642711 Mon Sep 17 00:00:00 2001
+From: Ilya Smelykh <ilya.smelykh at gmail.com>
+Date: Thu, 31 Jul 2014 22:48:44 +0700
+Subject: [PATCH] Set playbin's flags as native-video+audio in case of IMX6
+ platform.
+
+---
+ examples/qmlplayer2/CMakeLists.txt |  4 ++++
+ examples/qmlplayer2/player.cpp     | 16 +++++++++++++++-
+ 2 files changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/examples/qmlplayer2/CMakeLists.txt b/examples/qmlplayer2/CMakeLists.txt
+index cbd58ee..abb8b46 100644
+--- a/examples/qmlplayer2/CMakeLists.txt
++++ b/examples/qmlplayer2/CMakeLists.txt
+@@ -28,3 +28,7 @@ add_executable(qmlplayer2
+ )
+ target_link_libraries(qmlplayer2 ${QTGSTREAMER_QUICK_LIBRARIES})
+ qt4or5_use_modules(qmlplayer2 Core Gui Quick2 Qml)
++
++if (USE_HW_PLATFORM)
++     add_definitions(${QTGSTREAMER_HW_PLATFORM})
++endif()
+\ No newline at end of file
+diff --git a/examples/qmlplayer2/player.cpp b/examples/qmlplayer2/player.cpp
+index 9baf3b3..0ced449 100644
+--- a/examples/qmlplayer2/player.cpp
++++ b/examples/qmlplayer2/player.cpp
+@@ -55,13 +55,27 @@ void Player::stop()
+     }
+ }
+ 
++typedef enum {
++   GST_PLAY_FLAG_VIDEO         = (1 << 0),
++   GST_PLAY_FLAG_AUDIO         = (1 << 1),
++   GST_PLAY_FLAG_TEXT          = (1 << 2),
++   GST_PLAY_FLAG_VIS           = (1 << 3),
++   GST_PLAY_FLAG_SOFT_VOLUME   = (1 << 4),
++   GST_PLAY_FLAG_NATIVE_AUDIO  = (1 << 5),
++   GST_PLAY_FLAG_NATIVE_VIDEO  = (1 << 6),
++   GST_PLAY_FLAG_DOWNLOAD      = (1 << 7),
++   GST_PLAY_FLAG_BUFFERING     = (1 << 8)
++} GstPlayFlags;
++
+ void Player::setUri(const QString & uri)
+ {
+     if (!m_pipeline) {
+         m_pipeline = QGst::ElementFactory::make("playbin").dynamicCast<QGst::Pipeline>();
+         if (m_pipeline) {
+             m_pipeline->setProperty("video-sink", m_videoSink);
+-
++#ifdef HW_PLATFORM_IMX6
++            m_pipeline->setProperty("flags", GST_PLAY_FLAG_NATIVE_VIDEO | GST_PLAY_FLAG_AUDIO);
++#endif
+             //watch the bus for messages
+             QGst::BusPtr bus = m_pipeline->bus();
+             bus->addSignalWatch();
+-- 
+1.9.1
+
diff --git a/recipes-qt/qt5/qtgstreamer_git.bb b/recipes-qt/qt5/qtgstreamer_git.bb
new file mode 100644
index 0000000..27cb26a
--- /dev/null
+++ b/recipes-qt/qt5/qtgstreamer_git.bb
@@ -0,0 +1,44 @@
+require ${PN}.inc
+
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://COPYING;md5=2d5025d4aa3495befef8f17206a5b0a1"
+SECTION = "multimedia"
+
+SRC_URI = " \
+    git://anongit.freedesktop.org/gstreamer/qt-gstreamer \
+    file://0001-Added-i.MX6-zero-copy-rendering-implementation.patch \
+    file://0002-qtgstreamer-Temporarry-set-native-video-playbin-s-fl.patch \
+"
+
+SRCREV = "2a9664aff4980380afb93720795d326dfc76785f"
+S = "${WORKDIR}/git"
+
+FILES_${PN} += "\
+    ${libdir}/gstreamer-1.0/* \
+"
+
+FILES_${PN}-dbg += "\
+    ${libdir}/gstreamer-1.0/.debug/* \
+"
+
+FILES_${PN}-examples += "\
+    ${libdir}/gt5/examples/${PN}/* \
+"
+
+inherit cmake_qt5
+
+export EXTRA_OECMAKE = "-DQT_VERSION=5 \
+                        -DHW_PLATFORM=imx6 \
+                        -DOE_QMAKE_PATH_EXTERNAL_HOST_BINS=${STAGING_DIR_NATIVE}/usr/bin/qt5/ \
+                        -DUSE_QT_PLUGIN_DIR=OFF \
+                        -DCMAKE_SKIP_INSTALL_RPATH=YES \
+                        -DCMAKE_SKIP_RPATH=YES \
+"
+
+EXTRA_OECONF += "--disable-rpath"
+
+do_install_append() {
+#    install ${B}/examples/qmlplayer2/qmlplayer2 ${D}/usr/share/qt5/examples/qt-gstreamer/
+    install -d ${D}${datadir}/qt5/examples/${P}
+    install -m 0755 ${B}/examples/qmlplayer2/qmlplayer2 ${D}${datadir}/qt5/examples/${P}
+}
\ No newline at end of file
-- 
1.9.1




More information about the Openembedded-devel mailing list