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

Carlos Rafael Giani dv at pseudoterminal.org
Thu Jul 31 19:32:37 UTC 2014


The patches are imx6 specific, so they should not be part of meta-qt5. 
Instead, add them to meta-fsl-arm , write a .bbappend for them.

Also, I am confused. The summary at the beginning lists: 
"0002-Set-playbin-s-flags-as-native-video-audio-in-case-of.patch" , but 
in the recipe I see 
"0002-qtgstreamer-Temporarry-set-native-video-playbin-s-fl.patch" ?



On 07/31/2014 06:37 PM, Ilya Smelykh wrote:
> ---
>   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




More information about the Openembedded-devel mailing list