summaryrefslogtreecommitdiffstats
path: root/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qtmultimediaquicktools/qsgvideonode_yuv.cpp')
-rw-r--r--src/qtmultimediaquicktools/qsgvideonode_yuv.cpp47
1 files changed, 41 insertions, 6 deletions
diff --git a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp
index 9eff9dbd6..43cd5a2b2 100644
--- a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp
+++ b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp
@@ -44,6 +44,28 @@
#include <QtGui/QOpenGLFunctions>
#include <QtGui/QOpenGLShaderProgram>
+#ifndef GL_RED
+#define GL_RED 0x1903
+#endif
+#ifndef GL_GREEN
+#define GL_GREEN 0x1904
+#endif
+#ifndef GL_RG
+#define GL_RG 0x8227
+#endif
+#ifndef GL_TEXTURE_SWIZZLE_R
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#endif
+#ifndef GL_TEXTURE_SWIZZLE_G
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#endif
+#ifndef GL_TEXTURE_SWIZZLE_B
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#endif
+#ifndef GL_TEXTURE_SWIZZLE_A
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#endif
+
QT_BEGIN_NAMESPACE
QList<QVideoFrame::PixelFormat> QSGVideoNodeFactory_YUV::supportedPixelFormats(
@@ -335,6 +357,8 @@ QSGVideoMaterial_YUV::~QSGVideoMaterial_YUV()
void QSGVideoMaterial_YUV::bind()
{
QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions();
+ QSurfaceFormat::OpenGLContextProfile profile = QOpenGLContext::currentContext()->format().profile();
+
QMutexLocker lock(&m_frameMutex);
if (m_frame.isValid()) {
if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) {
@@ -350,12 +374,16 @@ void QSGVideoMaterial_YUV::bind()
}
GLint previousAlignment;
+ const GLenum texFormat1 = (profile == QSurfaceFormat::CoreProfile) ? GL_RED : GL_LUMINANCE;
+ const GLenum texFormat2 = (profile == QSurfaceFormat::CoreProfile) ? GL_RG : GL_LUMINANCE_ALPHA;
+
functions->glGetIntegerv(GL_UNPACK_ALIGNMENT, &previousAlignment);
functions->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
if (m_format.pixelFormat() == QVideoFrame::Format_UYVY
|| m_format.pixelFormat() == QVideoFrame::Format_YUYV) {
int fw = m_frame.width();
+
m_planeWidth[0] = fw;
// In YUYV texture the UV plane appears with the 1/2 of image and Y width.
m_planeWidth[1] = fw / 2;
@@ -367,7 +395,7 @@ void QSGVideoMaterial_YUV::bind()
bindTexture(m_textureIds[1], m_planeWidth[1], m_frame.height(), m_frame.bits(), GL_RGBA);
functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit
// Either red (YUYV) or alpha (UYVY) values are used as source of Y
- bindTexture(m_textureIds[0], m_planeWidth[0], m_frame.height(), m_frame.bits(), GL_LUMINANCE_ALPHA);
+ bindTexture(m_textureIds[0], m_planeWidth[0], m_frame.height(), m_frame.bits(), texFormat2);
} else if (m_format.pixelFormat() == QVideoFrame::Format_NV12
|| m_format.pixelFormat() == QVideoFrame::Format_NV21) {
const int y = 0;
@@ -376,9 +404,9 @@ void QSGVideoMaterial_YUV::bind()
m_planeWidth[0] = m_planeWidth[1] = qreal(fw) / m_frame.bytesPerLine(y);
functions->glActiveTexture(GL_TEXTURE1);
- bindTexture(m_textureIds[1], m_frame.bytesPerLine(uv) / 2, fh / 2, m_frame.bits(uv), GL_LUMINANCE_ALPHA);
+ bindTexture(m_textureIds[1], m_frame.bytesPerLine(uv) / 2, fh / 2, m_frame.bits(uv), texFormat2);
functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit
- bindTexture(m_textureIds[0], m_frame.bytesPerLine(y), fh, m_frame.bits(y), GL_LUMINANCE);
+ bindTexture(m_textureIds[0], m_frame.bytesPerLine(y), fh, m_frame.bits(y), texFormat1);
} else { // YUV420P || YV12
const int y = 0;
@@ -389,11 +417,11 @@ void QSGVideoMaterial_YUV::bind()
m_planeWidth[1] = m_planeWidth[2] = qreal(fw) / (2 * m_frame.bytesPerLine(u));
functions->glActiveTexture(GL_TEXTURE1);
- bindTexture(m_textureIds[1], m_frame.bytesPerLine(u), fh / 2, m_frame.bits(u), GL_LUMINANCE);
+ bindTexture(m_textureIds[1], m_frame.bytesPerLine(u), fh / 2, m_frame.bits(u), texFormat1);
functions->glActiveTexture(GL_TEXTURE2);
- bindTexture(m_textureIds[2], m_frame.bytesPerLine(v), fh / 2, m_frame.bits(v), GL_LUMINANCE);
+ bindTexture(m_textureIds[2], m_frame.bytesPerLine(v), fh / 2, m_frame.bits(v), texFormat1);
functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit
- bindTexture(m_textureIds[0], m_frame.bytesPerLine(y), fh, m_frame.bits(y), GL_LUMINANCE);
+ bindTexture(m_textureIds[0], m_frame.bytesPerLine(y), fh, m_frame.bits(y), texFormat1);
}
functions->glPixelStorei(GL_UNPACK_ALIGNMENT, previousAlignment);
@@ -415,6 +443,13 @@ void QSGVideoMaterial_YUV::bindTexture(int id, int w, int h, const uchar *bits,
QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions();
functions->glBindTexture(GL_TEXTURE_2D, id);
functions->glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, bits);
+ // replacement for GL_LUMINANCE_ALPHA in core profile
+ if (format == GL_RG) {
+ functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
+ functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED);
+ functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
+ functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_GREEN);
+ }
functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);