summaryrefslogtreecommitdiff
path: root/elements/gstqtvideosink/painters
diff options
context:
space:
mode:
authorGeorge Kiagiadakis <george.kiagiadakis@collabora.com>2013-10-14 11:21:31 +0200
committerGeorge Kiagiadakis <george.kiagiadakis@collabora.com>2013-10-18 18:07:55 +0200
commit7d9a800163a92cdbfcc38aa24591c8ad20a6bb19 (patch)
treedaf826cdb7c5476a6c56dbd9a7ecd3c9d7c3cf8d /elements/gstqtvideosink/painters
parentd46c146834c7fff787094e1b715c973a17998a27 (diff)
qtvideosink: Distribute classes into subdirectories for easier code navigation
Diffstat (limited to 'elements/gstqtvideosink/painters')
-rw-r--r--elements/gstqtvideosink/painters/abstractsurfacepainter.h42
-rw-r--r--elements/gstqtvideosink/painters/genericsurfacepainter.cpp101
-rw-r--r--elements/gstqtvideosink/painters/genericsurfacepainter.h51
-rw-r--r--elements/gstqtvideosink/painters/openglsurfacepainter.cpp797
-rw-r--r--elements/gstqtvideosink/painters/openglsurfacepainter.h135
5 files changed, 1126 insertions, 0 deletions
diff --git a/elements/gstqtvideosink/painters/abstractsurfacepainter.h b/elements/gstqtvideosink/painters/abstractsurfacepainter.h
new file mode 100644
index 0000000..3e90a77
--- /dev/null
+++ b/elements/gstqtvideosink/painters/abstractsurfacepainter.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@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 version 2.1
+ as published by the Free Software Foundation.
+
+ 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 ABSTRACTSURFACEPAINTER_H
+#define ABSTRACTSURFACEPAINTER_H
+
+#include "../utils/bufferformat.h"
+#include <QRectF>
+
+class QPainter;
+
+/** Common interface for all the painters */
+class AbstractSurfacePainter
+{
+public:
+ virtual ~AbstractSurfacePainter() {}
+
+ virtual bool supportsFormat(GstVideoFormat format) const = 0;
+
+ virtual void init(const BufferFormat & format) = 0;
+ virtual void cleanup() = 0;
+
+ virtual void paint(quint8 *data, const BufferFormat & frameFormat, const QRectF & clipRect,
+ QPainter *painter, const PaintAreas & areas) = 0;
+
+ virtual void updateColors(int brightness, int contrast, int hue, int saturation) = 0;
+};
+
+#endif
diff --git a/elements/gstqtvideosink/painters/genericsurfacepainter.cpp b/elements/gstqtvideosink/painters/genericsurfacepainter.cpp
new file mode 100644
index 0000000..864ea18
--- /dev/null
+++ b/elements/gstqtvideosink/painters/genericsurfacepainter.cpp
@@ -0,0 +1,101 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@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 version 2.1
+ as published by the Free Software Foundation.
+
+ 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 "genericsurfacepainter.h"
+#include <QPainter>
+
+GenericSurfacePainter::GenericSurfacePainter()
+ : m_imageFormat(QImage::Format_Invalid)
+{
+}
+
+//static
+QSet<GstVideoFormat> GenericSurfacePainter::supportedPixelFormats()
+{
+ return QSet<GstVideoFormat>()
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ << GST_VIDEO_FORMAT_ARGB
+ << GST_VIDEO_FORMAT_xRGB
+#else
+ << GST_VIDEO_FORMAT_BGRA
+ << GST_VIDEO_FORMAT_BGRx
+#endif
+ << GST_VIDEO_FORMAT_RGB
+ << GST_VIDEO_FORMAT_RGB16
+ ;
+}
+
+void GenericSurfacePainter::init(const BufferFormat &format)
+{
+ switch (format.videoFormat()) {
+ // QImage is shitty and reads integers instead of bytes,
+ // thus it is affected by the host's endianness
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ case GST_VIDEO_FORMAT_ARGB:
+#else
+ case GST_VIDEO_FORMAT_BGRA:
+#endif
+ m_imageFormat = QImage::Format_ARGB32;
+ break;
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ case GST_VIDEO_FORMAT_xRGB:
+#else
+ case GST_VIDEO_FORMAT_BGRx:
+#endif
+ m_imageFormat = QImage::Format_RGB32;
+ break;
+ //16-bit RGB formats use host's endianness in GStreamer
+ //FIXME-0.11 do endianness checks like above if semantics have changed
+ case GST_VIDEO_FORMAT_RGB16:
+ m_imageFormat = QImage::Format_RGB16;
+ break;
+ //This is not affected by endianness
+ case GST_VIDEO_FORMAT_RGB:
+ m_imageFormat = QImage::Format_RGB888;
+ break;
+ default:
+ throw QString("Unsupported format");
+ }
+}
+
+void GenericSurfacePainter::cleanup()
+{
+ m_imageFormat = QImage::Format_Invalid;
+}
+
+void GenericSurfacePainter::paint(quint8 *data,
+ const BufferFormat & frameFormat,
+ const QRectF & clipRect,
+ QPainter *painter,
+ const PaintAreas & areas)
+{
+ Q_ASSERT(m_imageFormat != QImage::Format_Invalid);
+
+ QImage image(
+ data,
+ frameFormat.frameSize().width(),
+ frameFormat.frameSize().height(),
+ frameFormat.bytesPerLine(),
+ m_imageFormat);
+
+ painter->fillRect(areas.blackArea1, Qt::black);
+ painter->drawImage(areas.videoArea, image, clipRect);
+ painter->fillRect(areas.blackArea2, Qt::black);
+}
+
+void GenericSurfacePainter::updateColors(int, int, int, int)
+{
+}
diff --git a/elements/gstqtvideosink/painters/genericsurfacepainter.h b/elements/gstqtvideosink/painters/genericsurfacepainter.h
new file mode 100644
index 0000000..66325df
--- /dev/null
+++ b/elements/gstqtvideosink/painters/genericsurfacepainter.h
@@ -0,0 +1,51 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011 Collabora Ltd. <info@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 version 2.1
+ as published by the Free Software Foundation.
+
+ 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 GENERICSURFACEPAINTER_H
+#define GENERICSURFACEPAINTER_H
+
+#include "abstractsurfacepainter.h"
+#include <QSet>
+#include <QImage>
+
+/**
+ * Generic painter that paints using the QPainter API.
+ * No colorspace conversion is done and no colors adjustment either.
+ */
+class GenericSurfacePainter : public AbstractSurfacePainter
+{
+public:
+ GenericSurfacePainter();
+
+ static QSet<GstVideoFormat> supportedPixelFormats();
+
+ virtual bool supportsFormat(GstVideoFormat format) const {
+ return supportedPixelFormats().contains(format);
+ }
+
+ virtual void init(const BufferFormat &format);
+ virtual void cleanup();
+
+ virtual void paint(quint8 *data, const BufferFormat & frameFormat, const QRectF & clipRect,
+ QPainter *painter, const PaintAreas & areas);
+
+ virtual void updateColors(int brightness, int contrast, int hue, int saturation);
+
+private:
+ QImage::Format m_imageFormat;
+};
+
+#endif // GENERICSURFACEPAINTER_H
diff --git a/elements/gstqtvideosink/painters/openglsurfacepainter.cpp b/elements/gstqtvideosink/painters/openglsurfacepainter.cpp
new file mode 100644
index 0000000..b3598ec
--- /dev/null
+++ b/elements/gstqtvideosink/painters/openglsurfacepainter.cpp
@@ -0,0 +1,797 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@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 version 2.1
+ as published by the Free Software Foundation.
+
+ 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 "openglsurfacepainter.h"
+#include <QtCore/qmath.h>
+
+#ifndef GL_TEXTURE0
+# define GL_TEXTURE0 0x84C0
+# define GL_TEXTURE1 0x84C1
+# define GL_TEXTURE2 0x84C2
+#endif
+
+#ifndef GL_PROGRAM_ERROR_STRING_ARB
+# define GL_PROGRAM_ERROR_STRING_ARB 0x8874
+#endif
+
+#ifndef GL_UNSIGNED_SHORT_5_6_5
+# define GL_UNSIGNED_SHORT_5_6_5 33635
+#endif
+
+#ifndef GL_CLAMP_TO_EDGE
+# define GL_CLAMP_TO_EDGE 0x812F
+#endif
+
+#define QRECT_TO_GLMATRIX(rect) \
+ { \
+ GLfloat(rect.left()) , GLfloat(rect.bottom() + 1), \
+ GLfloat(rect.right() + 1), GLfloat(rect.bottom() + 1), \
+ GLfloat(rect.left()) , GLfloat(rect.top()), \
+ GLfloat(rect.right() + 1), GLfloat(rect.top()) \
+ }
+
+OpenGLSurfacePainter::OpenGLSurfacePainter()
+ : m_textureFormat(0)
+ , m_textureInternalFormat(0)
+ , m_textureType(0)
+ , m_textureCount(0)
+ , m_videoColorMatrix(GST_VIDEO_COLOR_MATRIX_UNKNOWN)
+{
+#ifndef QT_OPENGL_ES
+ glActiveTexture = (_glActiveTexture) QGLContext::currentContext()->getProcAddress(
+ QLatin1String("glActiveTexture"));
+#endif
+}
+
+//static
+QSet<GstVideoFormat> OpenGLSurfacePainter::supportedPixelFormats()
+{
+ 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
+ ;
+}
+
+void OpenGLSurfacePainter::updateColors(int brightness, int contrast, int hue, int saturation)
+{
+ const qreal b = brightness / 200.0;
+ const qreal c = contrast / 100.0 + 1.0;
+ const qreal h = hue / 100.0;
+ const qreal s = saturation / 100.0 + 1.0;
+
+ const qreal cosH = qCos(M_PI * h);
+ const qreal sinH = qSin(M_PI * h);
+
+ const qreal h11 = 0.787 * cosH - 0.213 * sinH + 0.213;
+ const qreal h21 = -0.213 * cosH + 0.143 * sinH + 0.213;
+ const qreal h31 = -0.213 * cosH - 0.787 * sinH + 0.213;
+
+ const qreal h12 = -0.715 * cosH - 0.715 * sinH + 0.715;
+ const qreal h22 = 0.285 * cosH + 0.140 * sinH + 0.715;
+ const qreal h32 = -0.715 * cosH + 0.715 * sinH + 0.715;
+
+ const qreal h13 = -0.072 * cosH + 0.928 * sinH + 0.072;
+ const qreal h23 = -0.072 * cosH - 0.283 * sinH + 0.072;
+ const qreal h33 = 0.928 * cosH + 0.072 * sinH + 0.072;
+
+ const qreal sr = (1.0 - s) * 0.3086;
+ const qreal sg = (1.0 - s) * 0.6094;
+ const qreal sb = (1.0 - s) * 0.0820;
+
+ const qreal sr_s = sr + s;
+ const qreal sg_s = sg + s;
+ const qreal sb_s = sr + s;
+
+ const float m4 = (s + sr + sg + sb) * (0.5 - 0.5 * c + b);
+
+ m_colorMatrix(0, 0) = c * (sr_s * h11 + sg * h21 + sb * h31);
+ m_colorMatrix(0, 1) = c * (sr_s * h12 + sg * h22 + sb * h32);
+ m_colorMatrix(0, 2) = c * (sr_s * h13 + sg * h23 + sb * h33);
+ m_colorMatrix(0, 3) = m4;
+
+ m_colorMatrix(1, 0) = c * (sr * h11 + sg_s * h21 + sb * h31);
+ m_colorMatrix(1, 1) = c * (sr * h12 + sg_s * h22 + sb * h32);
+ m_colorMatrix(1, 2) = c * (sr * h13 + sg_s * h23 + sb * h33);
+ m_colorMatrix(1, 3) = m4;
+
+ m_colorMatrix(2, 0) = c * (sr * h11 + sg * h21 + sb_s * h31);
+ m_colorMatrix(2, 1) = c * (sr * h12 + sg * h22 + sb_s * h32);
+ m_colorMatrix(2, 2) = c * (sr * h13 + sg * h23 + sb_s * h33);
+ m_colorMatrix(2, 3) = m4;
+
+ m_colorMatrix(3, 0) = 0.0;
+ m_colorMatrix(3, 1) = 0.0;
+ m_colorMatrix(3, 2) = 0.0;
+ m_colorMatrix(3, 3) = 1.0;
+
+ switch (m_videoColorMatrix) {
+#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:
+ 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);
+ break;
+ default:
+ break;
+ }
+}
+
+void OpenGLSurfacePainter::paint(quint8 *data,
+ const BufferFormat & frameFormat,
+ const QRectF & clipRect,
+ QPainter *painter,
+ const PaintAreas & areas)
+{
+ // if these are enabled, we need to reenable them after beginNativePainting()
+ // has been called, as they may get disabled
+ bool stencilTestEnabled = glIsEnabled(GL_STENCIL_TEST);
+ bool scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);
+
+ painter->beginNativePainting();
+
+ if (stencilTestEnabled)
+ glEnable(GL_STENCIL_TEST);
+ if (scissorTestEnabled)
+ glEnable(GL_SCISSOR_TEST);
+
+ const GLfloat vertexCoordArray[] = QRECT_TO_GLMATRIX(areas.videoArea);
+
+ const GLfloat txLeft = clipRect.left() / frameFormat.frameSize().width();
+ const GLfloat txRight = (clipRect.right() + 1) / frameFormat.frameSize().width();
+ const GLfloat txTop = clipRect.top() / frameFormat.frameSize().height();
+ const GLfloat txBottom = (clipRect.bottom() + 1) / frameFormat.frameSize().height();
+
+ const GLfloat textureCoordArray[] =
+ {
+ txLeft , txBottom,
+ txRight, txBottom,
+ txLeft , txTop,
+ txRight, txTop
+ };
+
+ for (int i = 0; i < m_textureCount; ++i) {
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[i]);
+ glTexImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ m_textureInternalFormat,
+ m_textureWidths[i],
+ m_textureHeights[i],
+ 0,
+ m_textureFormat,
+ m_textureType,
+ data + m_textureOffsets[i]);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ }
+
+ paintImpl(painter, vertexCoordArray, textureCoordArray);
+
+ painter->endNativePainting();
+ painter->fillRect(areas.blackArea1, Qt::black);
+ painter->fillRect(areas.blackArea2, Qt::black);
+}
+
+void OpenGLSurfacePainter::initRgbTextureInfo(
+ 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_textureInternalFormat = internalFormat;
+ m_textureFormat = format;
+ m_textureType = type;
+ m_textureCount = 1;
+ m_textureWidths[0] = size.width();
+ m_textureHeights[0] = size.height();
+ m_textureOffsets[0] = 0;
+}
+
+void OpenGLSurfacePainter::initYuv420PTextureInfo(const QSize &size)
+{
+ 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;
+}
+
+void OpenGLSurfacePainter::initYv12TextureInfo(const QSize &size)
+{
+ 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();
+}
+
+#ifndef QT_OPENGL_ES
+
+# ifndef GL_FRAGMENT_PROGRAM_ARB
+# define GL_FRAGMENT_PROGRAM_ARB 0x8804
+# define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875
+# endif
+
+// Interprets the RGBA texture as in fact being BGRx and paints it.
+static const char *qt_arbfp_bgrxShaderProgram =
+ "!!ARBfp1.0\n"
+ "PARAM matrix[4] = { program.local[0..2],"
+ "{ 0.0, 0.0, 0.0, 1.0 } };\n"
+ "TEMP bgrx;\n"
+ "TEX bgrx.xyz, fragment.texcoord[0], texture[0], 2D;\n"
+ "MOV bgrx.w, matrix[3].w;\n"
+ "DP4 result.color.x, bgrx.zyxw, matrix[0];\n"
+ "DP4 result.color.y, bgrx.zyxw, matrix[1];\n"
+ "DP4 result.color.z, bgrx.zyxw, matrix[2];\n"
+ "END";
+
+// Interprets the RGBA texture as in fact being BGRA and paints it.
+static const char *qt_arbfp_bgraShaderProgram =
+ "!!ARBfp1.0\n"
+ "PARAM matrix[4] = { program.local[0..2],"
+ "{ 0.0, 0.0, 0.0, 1.0 } };\n"
+ "TEMP bgra;\n"
+ "TEX bgra, fragment.texcoord[0], texture[0], 2D;\n"
+ "MOV bgra.w, matrix[3].w;\n"
+ "DP4 result.color.x, bgra.zyxw, matrix[0];\n"
+ "DP4 result.color.y, bgra.zyxw, matrix[1];\n"
+ "DP4 result.color.z, bgra.zyxw, matrix[2];\n"
+ "TEX result.color.w, fragment.texcoord[0], texture, 2D;\n"
+ "END";
+
+// Interprets the RGBA texture as in fact being xRGB and paints it.
+static const char *qt_arbfp_xrgbShaderProgram =
+ "!!ARBfp1.0\n"
+ "PARAM matrix[4] = { program.local[0..2],"
+ "{ 0.0, 0.0, 0.0, 1.0 } };\n"
+ "TEMP xrgb;\n"
+ "TEX xrgb, fragment.texcoord[0], texture[0], 2D;\n"
+ "MOV xrgb.x, matrix[3].w;\n"
+ "DP4 result.color.x, xrgb.yzwx, matrix[0];\n"
+ "DP4 result.color.y, xrgb.yzwx, matrix[1];\n"
+ "DP4 result.color.z, xrgb.yzwx, matrix[2];\n"
+ "END";
+
+// Interprets the RGBA texture as in fact being ARGB and paints it.
+static const char *qt_arbfp_argbShaderProgram =
+ "!!ARBfp1.0\n"
+ "PARAM matrix[4] = { program.local[0..2],"
+ "{ 0.0, 0.0, 0.0, 1.0 } };\n"
+ "TEMP argb;\n"
+ "TEX argb, fragment.texcoord[0], texture[0], 2D;\n"
+ "MOV argb.x, matrix[3].w;\n"
+ "DP4 result.color.x, argb.yzwx, matrix[0];\n"
+ "DP4 result.color.y, argb.yzwx, matrix[1];\n"
+ "DP4 result.color.z, argb.yzwx, matrix[2];\n"
+ "TEX result.color.w, fragment.texcoord[0], texture, 2D;\n"
+ "END";
+
+// Paints RGB frames without doing any color channel flipping.
+static const char *qt_arbfp_rgbxShaderProgram =
+ "!!ARBfp1.0\n"
+ "PARAM matrix[4] = { program.local[0..2],"
+ "{ 0.0, 0.0, 0.0, 1.0 } };\n"
+ "TEMP rgb;\n"
+ "TEX rgb.xyz, fragment.texcoord[0], texture[0], 2D;\n"
+ "MOV rgb.w, matrix[3].w;\n"
+ "DP4 result.color.x, rgb, matrix[0];\n"
+ "DP4 result.color.y, rgb, matrix[1];\n"
+ "DP4 result.color.z, rgb, matrix[2];\n"
+ "END";
+
+// Paints a YUV420P or YV12 frame.
+static const char *qt_arbfp_yuvPlanarShaderProgram =
+ "!!ARBfp1.0\n"
+ "PARAM matrix[4] = { program.local[0..2],"
+ "{ 0.0, 0.0, 0.0, 1.0 } };\n"
+ "TEMP yuv;\n"
+ "TEX yuv.x, fragment.texcoord[0], texture[0], 2D;\n"
+ "TEX yuv.y, fragment.texcoord[0], texture[1], 2D;\n"
+ "TEX yuv.z, fragment.texcoord[0], texture[2], 2D;\n"
+ "MOV yuv.w, matrix[3].w;\n"
+ "DP4 result.color.x, yuv, matrix[0];\n"
+ "DP4 result.color.y, yuv, matrix[1];\n"
+ "DP4 result.color.z, yuv, matrix[2];\n"
+ "END";
+
+
+
+ArbFpSurfacePainter::ArbFpSurfacePainter()
+ : OpenGLSurfacePainter()
+ , m_programId(0)
+{
+ const QGLContext *context = QGLContext::currentContext();
+
+ glProgramStringARB = (_glProgramStringARB) context->getProcAddress(
+ QLatin1String("glProgramStringARB"));
+ glBindProgramARB = (_glBindProgramARB) context->getProcAddress(
+ QLatin1String("glBindProgramARB"));
+ glDeleteProgramsARB = (_glDeleteProgramsARB) context->getProcAddress(
+ QLatin1String("glDeleteProgramsARB"));
+ glGenProgramsARB = (_glGenProgramsARB) context->getProcAddress(
+ QLatin1String("glGenProgramsARB"));
+ glProgramLocalParameter4fARB = (_glProgramLocalParameter4fARB) context->getProcAddress(
+ QLatin1String("glProgramLocalParameter4fARB"));
+}
+
+void ArbFpSurfacePainter::init(const BufferFormat &format)
+{
+ Q_ASSERT(m_textureCount == 0);
+
+ const char *program = 0;
+
+ switch (format.videoFormat()) {
+ case GST_VIDEO_FORMAT_BGRx:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ program = qt_arbfp_bgrxShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_xRGB:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ program = qt_arbfp_xrgbShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_BGRA:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ program = qt_arbfp_bgraShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_ARGB:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ program = qt_arbfp_argbShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_RGB:
+ initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
+ program = qt_arbfp_rgbxShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_BGR:
+ initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
+ program = qt_arbfp_bgrxShaderProgram;
+ 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:
+ initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize());
+ program = qt_arbfp_rgbxShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_v308:
+ initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
+ program = qt_arbfp_rgbxShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_AYUV:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ program = qt_arbfp_argbShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_YV12:
+ initYv12TextureInfo(format.frameSize());
+ program = qt_arbfp_yuvPlanarShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_I420:
+ initYuv420PTextureInfo(format.frameSize());
+ program = qt_arbfp_yuvPlanarShaderProgram;
+ break;
+ default:
+ Q_ASSERT(false);
+ break;
+ }
+
+ m_videoColorMatrix = format.colorMatrix();
+
+ glGenProgramsARB(1, &m_programId);
+
+ GLenum glError = glGetError();
+ if (glError != GL_NO_ERROR) {
+ throw QString("ARBfb Shader allocation error ") +
+ QString::number(static_cast<int>(glError), 16);
+ } else {
+ glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_programId);
+ glProgramStringARB(
+ GL_FRAGMENT_PROGRAM_ARB,
+ GL_PROGRAM_FORMAT_ASCII_ARB,
+ qstrlen(program),
+ reinterpret_cast<const GLvoid *>(program));
+
+ if ((glError = glGetError()) != GL_NO_ERROR) {
+ const GLubyte* errorString = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
+
+ glDeleteProgramsARB(1, &m_programId);
+ m_textureCount = 0;
+ m_programId = 0;
+
+ throw QString("ARBfp Shader compile error ") +
+ QString::number(static_cast<int>(glError), 16) +
+ reinterpret_cast<const char *>(errorString);
+ } else {
+ glGenTextures(m_textureCount, m_textureIds);
+ }
+ }
+}
+
+void ArbFpSurfacePainter::cleanup()
+{
+ glDeleteTextures(m_textureCount, m_textureIds);
+ glDeleteProgramsARB(1, &m_programId);
+
+ m_textureCount = 0;
+ m_programId = 0;
+}
+
+void ArbFpSurfacePainter::paintImpl(const QPainter *painter,
+ const GLfloat *vertexCoordArray,
+ const GLfloat *textureCoordArray)
+{
+ Q_UNUSED(painter);
+
+ glEnable(GL_FRAGMENT_PROGRAM_ARB);
+ glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_programId);
+
+ glProgramLocalParameter4fARB(
+ GL_FRAGMENT_PROGRAM_ARB,
+ 0,
+ m_colorMatrix(0, 0),
+ m_colorMatrix(0, 1),
+ m_colorMatrix(0, 2),
+ m_colorMatrix(0, 3));
+ glProgramLocalParameter4fARB(
+ GL_FRAGMENT_PROGRAM_ARB,
+ 1,
+ m_colorMatrix(1, 0),
+ m_colorMatrix(1, 1),
+ m_colorMatrix(1, 2),
+ m_colorMatrix(1, 3));
+ glProgramLocalParameter4fARB(
+ GL_FRAGMENT_PROGRAM_ARB,
+ 2,
+ m_colorMatrix(2, 0),
+ m_colorMatrix(2, 1),
+ m_colorMatrix(2, 2),
+ m_colorMatrix(2, 3));
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);
+
+ if (m_textureCount == 3) {
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[1]);
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[2]);
+ glActiveTexture(GL_TEXTURE0);
+ }
+
+ glVertexPointer(2, GL_FLOAT, 0, vertexCoordArray);
+ glTexCoordPointer(2, GL_FLOAT, 0, textureCoordArray);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisable(GL_FRAGMENT_PROGRAM_ARB);
+}
+
+#endif
+
+static const char *qt_glsl_vertexShaderProgram =
+ "attribute highp vec4 vertexCoordArray;\n"
+ "attribute highp vec2 textureCoordArray;\n"
+ "uniform highp mat4 positionMatrix;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main(void)\n"
+ "{\n"
+ " gl_Position = positionMatrix * vertexCoordArray;\n"
+ " textureCoord = textureCoordArray;\n"
+ "}\n";
+
+// Interprets the RGBA texture as in fact being BGRx and paints it.
+static const char *qt_glsl_bgrxShaderProgram =
+ "uniform sampler2D texRgb;\n"
+ "uniform mediump mat4 colorMatrix;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main(void)\n"
+ "{\n"
+ " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).bgr, 1.0);\n"
+ " gl_FragColor = colorMatrix * color;\n"
+ "}\n";
+
+// Interprets the RGBA texture as in fact being BGRA and paints it.
+static const char *qt_glsl_bgraShaderProgram =
+ "uniform sampler2D texRgb;\n"
+ "uniform mediump mat4 colorMatrix;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main(void)\n"
+ "{\n"
+ " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).bgr, 1.0);\n"
+ " color = colorMatrix * color;\n"
+ " gl_FragColor = vec4(color.rgb, texture2D(texRgb, textureCoord.st).a);\n"
+ "}\n";
+
+// Interprets the RGBA texture as in fact being xRGB and paints it.
+static const char *qt_glsl_xrgbShaderProgram =
+ "uniform sampler2D texRgb;\n"
+ "uniform mediump mat4 colorMatrix;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main(void)\n"
+ "{\n"
+ " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).gba, 1.0);\n"
+ " gl_FragColor = colorMatrix * color;\n"
+ "}\n";
+
+// Interprets the RGBA texture as in fact being ARGB and paints it.
+static const char *qt_glsl_argbShaderProgram =
+ "uniform sampler2D texRgb;\n"
+ "uniform mediump mat4 colorMatrix;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main(void)\n"
+ "{\n"
+ " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).gba, 1.0);\n"
+ " color = colorMatrix * color;\n"
+ " gl_FragColor = vec4(color.rgb, texture2D(texRgb, textureCoord.st).r);\n"
+ "}\n";
+
+// Paints RGB frames without doing any color channel flipping.
+static const char *qt_glsl_rgbxShaderProgram =
+ "uniform sampler2D texRgb;\n"
+ "uniform mediump mat4 colorMatrix;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main(void)\n"
+ "{\n"
+ " highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).rgb, 1.0);\n"
+ " gl_FragColor = colorMatrix * color;\n"
+ "}\n";
+
+// Paints planar yuv frames.
+static const char *qt_glsl_yuvPlanarShaderProgram =
+ "uniform sampler2D texY;\n"
+ "uniform sampler2D texU;\n"
+ "uniform sampler2D texV;\n"
+ "uniform mediump mat4 colorMatrix;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main(void)\n"
+ "{\n"
+ " highp vec4 color = vec4(\n"
+ " texture2D(texY, textureCoord.st).r,\n"
+ " texture2D(texU, textureCoord.st).r,\n"
+ " texture2D(texV, textureCoord.st).r,\n"
+ " 1.0);\n"
+ " gl_FragColor = colorMatrix * color;\n"
+ "}\n";
+
+
+GlslSurfacePainter::GlslSurfacePainter()
+ : OpenGLSurfacePainter()
+{
+}
+
+void GlslSurfacePainter::init(const BufferFormat &format)
+{
+ Q_ASSERT(m_textureCount == 0);
+
+ const char *fragmentProgram = 0;
+
+ switch (format.videoFormat()) {
+ case GST_VIDEO_FORMAT_BGRx:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ fragmentProgram = qt_glsl_bgrxShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_xRGB:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ fragmentProgram = qt_glsl_xrgbShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_BGRA:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ fragmentProgram = qt_glsl_bgraShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_ARGB:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ fragmentProgram = qt_glsl_argbShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_RGB:
+ initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
+ fragmentProgram = qt_glsl_rgbxShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_BGR:
+ initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
+ fragmentProgram = qt_glsl_bgrxShaderProgram;
+ 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:
+ initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize());
+ fragmentProgram = qt_glsl_rgbxShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_v308:
+ initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
+ fragmentProgram = qt_glsl_rgbxShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_AYUV:
+ initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
+ fragmentProgram = qt_glsl_argbShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_YV12:
+ initYv12TextureInfo(format.frameSize());
+ fragmentProgram = qt_glsl_yuvPlanarShaderProgram;
+ break;
+ case GST_VIDEO_FORMAT_I420:
+ initYuv420PTextureInfo(format.frameSize());
+ fragmentProgram = qt_glsl_yuvPlanarShaderProgram;
+ break;
+ default:
+ Q_ASSERT(false);
+ break;
+ }
+
+ m_videoColorMatrix = format.colorMatrix();
+
+ if (!m_program.addShaderFromSourceCode(QGLShader::Vertex, qt_glsl_vertexShaderProgram)) {
+ throw QString("Vertex shader compile error ") + m_program.log();
+ }
+
+ if (!m_program.addShaderFromSourceCode(QGLShader::Fragment, fragmentProgram)) {
+ throw QString("Shader compile error ") + m_program.log();
+ }
+
+ if(!m_program.link()) {
+ throw QString("Shader link error ") + m_program.log();
+ }
+
+ glGenTextures(m_textureCount, m_textureIds);
+}
+
+void GlslSurfacePainter::cleanup()
+{
+ glDeleteTextures(m_textureCount, m_textureIds);
+ m_program.removeAllShaders();
+
+ m_textureCount = 0;
+}
+
+void GlslSurfacePainter::paintImpl(const QPainter *painter,
+ const GLfloat *vertexCoordArray,
+ const GLfloat *textureCoordArray)
+{
+ const int deviceWidth = painter->device()->width();
+ const int deviceHeight = painter->device()->height();
+
+ const QTransform transform = painter->deviceTransform();
+
+ const GLfloat wfactor = 2.0 / deviceWidth;
+ const GLfloat hfactor = -2.0 / deviceHeight;
+
+ const GLfloat positionMatrix[4][4] =
+ {
+ {
+ /*(0,0)*/ GLfloat(wfactor * transform.m11() - transform.m13()),
+ /*(0,1)*/ GLfloat(hfactor * transform.m12() + transform.m13()),
+ /*(0,2)*/ 0.0,
+ /*(0,3)*/ GLfloat(transform.m13())
+ }, {
+ /*(1,0)*/ GLfloat(wfactor * transform.m21() - transform.m23()),
+ /*(1,1)*/ GLfloat(hfactor * transform.m22() + transform.m23()),
+ /*(1,2)*/ 0.0,
+ /*(1,3)*/ GLfloat(transform.m23())
+ }, {
+ /*(2,0)*/ 0.0,
+ /*(2,1)*/ 0.0,
+ /*(2,2)*/ -1.0,
+ /*(2,3)*/ 0.0
+ }, {
+ /*(3,0)*/ GLfloat(wfactor * transform.dx() - transform.m33()),
+ /*(3,1)*/ GLfloat(hfactor * transform.dy() + transform.m33()),
+ /*(3,2)*/ 0.0,
+ /*(3,3)*/ GLfloat(transform.m33())
+ }
+ };
+
+ m_program.bind();
+
+ m_program.enableAttributeArray("vertexCoordArray");
+ m_program.enableAttributeArray("textureCoordArray");
+ m_program.setAttributeArray("vertexCoordArray", vertexCoordArray, 2);
+ m_program.setAttributeArray("textureCoordArray", textureCoordArray, 2);
+ m_program.setUniformValue("positionMatrix", positionMatrix);
+
+ if (m_textureCount == 3) {
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[1]);
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[2]);
+ glActiveTexture(GL_TEXTURE0);
+
+ m_program.setUniformValue("texY", 0);
+ m_program.setUniformValue("texU", 1);
+ m_program.setUniformValue("texV", 2);
+ } else {
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);
+
+ m_program.setUniformValue("texRgb", 0);
+ }
+ m_program.setUniformValue("colorMatrix", m_colorMatrix);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ m_program.release();
+}
diff --git a/elements/gstqtvideosink/painters/openglsurfacepainter.h b/elements/gstqtvideosink/painters/openglsurfacepainter.h
new file mode 100644
index 0000000..c1e2dd0
--- /dev/null
+++ b/elements/gstqtvideosink/painters/openglsurfacepainter.h
@@ -0,0 +1,135 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). <qt-info@nokia.com>
+ Copyright (C) 2011-2012 Collabora Ltd. <info@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 version 2.1
+ as published by the Free Software Foundation.
+
+ 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 OPENGLSURFACEPAINTER_H
+#define OPENGLSURFACEPAINTER_H
+
+#ifndef GST_QT_VIDEO_SINK_NO_OPENGL
+
+#include "abstractsurfacepainter.h"
+#include <QGLShaderProgram>
+
+#ifndef Q_WS_MAC
+# ifndef APIENTRYP
+# ifdef APIENTRY
+# define APIENTRYP APIENTRY *
+# else
+# define APIENTRY
+# define APIENTRYP *
+# endif
+# endif
+#else
+# define APIENTRY
+# define APIENTRYP *
+#endif
+
+class OpenGLSurfacePainter : public AbstractSurfacePainter
+{
+public:
+ OpenGLSurfacePainter();
+
+ static QSet<GstVideoFormat> supportedPixelFormats();
+
+ virtual bool supportsFormat(GstVideoFormat format) const {
+ return supportedPixelFormats().contains(format);
+ }
+
+ virtual void updateColors(int brightness, int contrast, int hue, int saturation);
+ virtual void paint(quint8 *data, const BufferFormat & frameFormat, const QRectF & clipRect,
+ QPainter *painter, const PaintAreas & areas);
+
+protected:
+ void initRgbTextureInfo(GLenum internalFormat, GLuint format, GLenum type, const QSize &size);
+ void initYuv420PTextureInfo(const QSize &size);
+ void initYv12TextureInfo(const QSize &size);
+
+ virtual void paintImpl(const QPainter *painter,
+ const GLfloat *vertexCoordArray,
+ const GLfloat *textureCoordArray) = 0;
+
+#ifndef QT_OPENGL_ES
+ typedef void (APIENTRY *_glActiveTexture) (GLenum);
+ _glActiveTexture glActiveTexture;
+#endif
+
+ GLenum m_textureFormat;
+ GLuint m_textureInternalFormat;
+ GLenum m_textureType;
+ int m_textureCount;
+ GLuint m_textureIds[3];
+ int m_textureWidths[3];
+ int m_textureHeights[3];
+ int m_textureOffsets[3];
+
+ QMatrix4x4 m_colorMatrix;
+ GstVideoColorMatrix m_videoColorMatrix;
+};
+
+#ifndef QT_OPENGL_ES
+
+class ArbFpSurfacePainter : public OpenGLSurfacePainter
+{
+public:
+ ArbFpSurfacePainter();
+
+ virtual void init(const BufferFormat & format);
+ virtual void cleanup();
+
+protected:
+ virtual void paintImpl(const QPainter *painter,
+ const GLfloat *vertexCoordArray,
+ const GLfloat *textureCoordArray);
+
+private:
+ typedef void (APIENTRY *_glProgramStringARB) (GLenum, GLenum, GLsizei, const GLvoid *);
+ typedef void (APIENTRY *_glBindProgramARB) (GLenum, GLuint);
+ typedef void (APIENTRY *_glDeleteProgramsARB) (GLsizei, const GLuint *);
+ typedef void (APIENTRY *_glGenProgramsARB) (GLsizei, GLuint *);
+ typedef void (APIENTRY *_glProgramLocalParameter4fARB) (
+ GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
+ typedef void (APIENTRY *_glActiveTexture) (GLenum);
+
+ _glProgramStringARB glProgramStringARB;
+ _glBindProgramARB glBindProgramARB;
+ _glDeleteProgramsARB glDeleteProgramsARB;
+ _glGenProgramsARB glGenProgramsARB;
+ _glProgramLocalParameter4fARB glProgramLocalParameter4fARB;
+
+ GLuint m_programId;
+};
+
+#endif
+
+class GlslSurfacePainter : public OpenGLSurfacePainter
+{
+public:
+ GlslSurfacePainter();
+
+ virtual void init(const BufferFormat & format);
+ virtual void cleanup();
+
+protected:
+ virtual void paintImpl(const QPainter *painter,
+ const GLfloat *vertexCoordArray,
+ const GLfloat *textureCoordArray);
+
+private:
+ QGLShaderProgram m_program;
+};
+
+#endif // GST_QT_VIDEO_SINK_NO_OPENGL
+
+#endif // OPENGLSURFACEPAINTER_H