diff --git a/src/VideoStreaming/VideoStreaming.pri b/src/VideoStreaming/VideoStreaming.pri index 32b2cfa944c2a1431ae612444aea49cb1ede4e0c..9f09c6cbc63a9120950ea5a57ec0f00da1776c7a 100644 --- a/src/VideoStreaming/VideoStreaming.pri +++ b/src/VideoStreaming/VideoStreaming.pri @@ -132,6 +132,7 @@ VideoEnabled { $$PWD/gstqtvideosink/painters/videonode.h \ $$PWD/gstqtvideosink/utils/bufferformat.h \ $$PWD/gstqtvideosink/utils/utils.h \ + $$PWD/gstqtvideosink/utils/glutils.h \ SOURCES += \ $$PWD/gstqtvideosink/delegates/basedelegate.cpp \ diff --git a/src/VideoStreaming/gstqtvideosink/delegates/qtvideosinkdelegate.cpp b/src/VideoStreaming/gstqtvideosink/delegates/qtvideosinkdelegate.cpp index f03fefc3e630086b4e1e5a1bdb09abaaec9f5447..fd46d2a6f59b4512ff88241fe8a399c03ccbfac4 100644 --- a/src/VideoStreaming/gstqtvideosink/delegates/qtvideosinkdelegate.cpp +++ b/src/VideoStreaming/gstqtvideosink/delegates/qtvideosinkdelegate.cpp @@ -28,6 +28,8 @@ #include #include +#include "glutils.h" + QtVideoSinkDelegate::QtVideoSinkDelegate(GstElement *sink, QObject *parent) : BaseDelegate(sink, parent) , m_painter(0) @@ -137,20 +139,22 @@ void QtVideoSinkDelegate::setGLContext(QGLContext *context) if (m_glContext) { m_glContext->makeCurrent(); - - const QByteArray extensions(reinterpret_cast(glGetString(GL_EXTENSIONS))); - GST_LOG_OBJECT(m_sink, "Available GL extensions: %s", extensions.constData()); + QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); + if (funcs) { + const QByteArray extensions(reinterpret_cast(funcs->glGetString(GL_EXTENSIONS))); + GST_LOG_OBJECT(m_sink, "Available GL extensions: %s", extensions.constData()); #ifndef QT_OPENGL_ES - if (extensions.contains("ARB_fragment_program")) - m_supportedPainters |= ArbFp; + if (extensions.contains("ARB_fragment_program")) + m_supportedPainters |= ArbFp; #endif #ifndef QT_OPENGL_ES_2 - if (QGLShaderProgram::hasOpenGLShaderPrograms(m_glContext) + if (QGLShaderProgram::hasOpenGLShaderPrograms(m_glContext) && extensions.contains("ARB_shader_objects")) #endif - m_supportedPainters |= Glsl; + m_supportedPainters |= Glsl; + } } GST_LOG_OBJECT(m_sink, "Done setting GL context. m_supportedPainters=%x", (int) m_supportedPainters); @@ -227,7 +231,6 @@ void QtVideoSinkDelegate::changePainter(const BufferFormat & format) void QtVideoSinkDelegate::destroyPainter() { GST_LOG_OBJECT(m_sink, "Destroying painter"); - delete m_painter; m_painter = 0; } @@ -240,6 +243,5 @@ bool QtVideoSinkDelegate::event(QEvent *event) destroyPainter(); } } - return BaseDelegate::event(event); } diff --git a/src/VideoStreaming/gstqtvideosink/painters/openglsurfacepainter.cpp b/src/VideoStreaming/gstqtvideosink/painters/openglsurfacepainter.cpp index 0acbb4ab72cbcf08c1d2e23a5e18994fa1391e07..dbdad9ba3db5512a37c2d7f57997a515c393c84b 100644 --- a/src/VideoStreaming/gstqtvideosink/painters/openglsurfacepainter.cpp +++ b/src/VideoStreaming/gstqtvideosink/painters/openglsurfacepainter.cpp @@ -24,6 +24,8 @@ #include "openglsurfacepainter.h" #include +#include "glutils.h" + #ifndef GL_TEXTURE0 # define GL_TEXTURE0 0x84C0 # define GL_TEXTURE1 0x84C1 @@ -58,8 +60,7 @@ OpenGLSurfacePainter::OpenGLSurfacePainter() , m_videoColorMatrix(GST_VIDEO_COLOR_MATRIX_UNKNOWN) { #ifndef QT_OPENGL_ES - glActiveTexture = (_glActiveTexture) QGLContext::currentContext()->getProcAddress( - QLatin1String("glActiveTexture")); + glActiveTexture = (_glActiveTexture) QGLContext::currentContext()->getProcAddress(QLatin1String("glActiveTexture")); #endif } @@ -178,24 +179,28 @@ void OpenGLSurfacePainter::paint(quint8 *data, QPainter *painter, const PaintAreas & areas) { + QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); + if (!funcs) + return; + // 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); + bool stencilTestEnabled = funcs->glIsEnabled(GL_STENCIL_TEST); + bool scissorTestEnabled = funcs->glIsEnabled(GL_SCISSOR_TEST); painter->beginNativePainting(); if (stencilTestEnabled) - glEnable(GL_STENCIL_TEST); + funcs->glEnable(GL_STENCIL_TEST); if (scissorTestEnabled) - glEnable(GL_SCISSOR_TEST); + funcs->glEnable(GL_SCISSOR_TEST); const GLfloat vertexCoordArray[] = QRECT_TO_GLMATRIX(areas.videoArea); - const GLfloat txLeft = areas.sourceRect.left(); - const GLfloat txRight = areas.sourceRect.right(); - const GLfloat txTop = areas.sourceRect.top(); - const GLfloat txBottom = areas.sourceRect.bottom(); + const GLfloat txLeft = areas.sourceRect.left(); + const GLfloat txRight = areas.sourceRect.right(); + const GLfloat txTop = areas.sourceRect.top(); + const GLfloat txBottom = areas.sourceRect.bottom(); const GLfloat textureCoordArray[] = { @@ -206,8 +211,8 @@ void OpenGLSurfacePainter::paint(quint8 *data, }; for (int i = 0; i < m_textureCount; ++i) { - glBindTexture(GL_TEXTURE_2D, m_textureIds[i]); - glTexImage2D( + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[i]); + funcs->glTexImage2D( GL_TEXTURE_2D, 0, m_textureInternalFormat, @@ -217,10 +222,10 @@ void OpenGLSurfacePainter::paint(quint8 *data, 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); + funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } paintImpl(painter, vertexCoordArray, textureCoordArray); @@ -392,22 +397,19 @@ ArbFpSurfacePainter::ArbFpSurfacePainter() , 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")); + 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); + QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); + if (!funcs) + return; const char *program = 0; @@ -467,7 +469,7 @@ void ArbFpSurfacePainter::init(const BufferFormat &format) glGenProgramsARB(1, &m_programId); - GLenum glError = glGetError(); + GLenum glError = funcs->glGetError(); if (glError != GL_NO_ERROR) { throw QString("ARBfb Shader allocation error ") + QString::number(static_cast(glError), 16); @@ -479,27 +481,28 @@ void ArbFpSurfacePainter::init(const BufferFormat &format) qstrlen(program), reinterpret_cast(program)); - if ((glError = glGetError()) != GL_NO_ERROR) { - const GLubyte* errorString = glGetString(GL_PROGRAM_ERROR_STRING_ARB); - + if ((glError = funcs->glGetError()) != GL_NO_ERROR) { + const GLubyte* errorString = funcs->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(glError), 16) + reinterpret_cast(errorString); } else { - glGenTextures(m_textureCount, m_textureIds); + funcs->glGenTextures(m_textureCount, m_textureIds); } } } void ArbFpSurfacePainter::cleanup() { - glDeleteTextures(m_textureCount, m_textureIds); - glDeleteProgramsARB(1, &m_programId); - + QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); + if (funcs) + { + funcs->glDeleteTextures(m_textureCount, m_textureIds); + glDeleteProgramsARB(1, &m_programId); + } m_textureCount = 0; m_programId = 0; } @@ -509,8 +512,11 @@ void ArbFpSurfacePainter::paintImpl(const QPainter *painter, const GLfloat *textureCoordArray) { Q_UNUSED(painter); + QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); + if (!funcs) + return; - glEnable(GL_FRAGMENT_PROGRAM_ARB); + funcs->glEnable(GL_FRAGMENT_PROGRAM_ARB); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_programId); glProgramLocalParameter4fARB( @@ -535,28 +541,28 @@ void ArbFpSurfacePainter::paintImpl(const QPainter *painter, m_colorMatrix(2, 2), m_colorMatrix(2, 3)); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); + funcs->glActiveTexture(GL_TEXTURE0); + funcs->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); + funcs->glActiveTexture(GL_TEXTURE1); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); + funcs->glActiveTexture(GL_TEXTURE2); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); + funcs->glActiveTexture(GL_TEXTURE0); } - glVertexPointer(2, GL_FLOAT, 0, vertexCoordArray); - glTexCoordPointer(2, GL_FLOAT, 0, textureCoordArray); + funcs->glVertexPointer(2, GL_FLOAT, 0, vertexCoordArray); + funcs->glTexCoordPointer(2, GL_FLOAT, 0, textureCoordArray); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + funcs->glEnableClientState(GL_VERTEX_ARRAY); + funcs->glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + funcs->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisable(GL_FRAGMENT_PROGRAM_ARB); + funcs->glDisableClientState(GL_VERTEX_ARRAY); + funcs->glDisableClientState(GL_TEXTURE_COORD_ARRAY); + funcs->glDisable(GL_FRAGMENT_PROGRAM_ARB); } #endif @@ -724,14 +730,19 @@ void GlslSurfacePainter::init(const BufferFormat &format) throw QString("Shader link error ") + m_program.log(); } - glGenTextures(m_textureCount, m_textureIds); + QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); + if (funcs) + funcs->glGenTextures(m_textureCount, m_textureIds); } void GlslSurfacePainter::cleanup() { - glDeleteTextures(m_textureCount, m_textureIds); - m_program.removeAllShaders(); - + QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); + if (funcs) + { + funcs->glDeleteTextures(m_textureCount, m_textureIds); + m_program.removeAllShaders(); + } m_textureCount = 0; } @@ -739,8 +750,8 @@ 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 int deviceWidth = painter->device()->width(); + const int deviceHeight = painter->device()->height(); const QTransform transform = painter->deviceTransform(); @@ -780,27 +791,31 @@ void GlslSurfacePainter::paintImpl(const QPainter *painter, m_program.setAttributeArray("textureCoordArray", textureCoordArray, 2); m_program.setUniformValue("positionMatrix", positionMatrix); + QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); + if (!funcs) + return; + 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); + funcs->glActiveTexture(GL_TEXTURE0); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); + funcs->glActiveTexture(GL_TEXTURE1); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); + funcs->glActiveTexture(GL_TEXTURE2); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); + funcs->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]); + funcs->glActiveTexture(GL_TEXTURE0); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); m_program.setUniformValue("texRgb", 0); } m_program.setUniformValue("colorMatrix", m_colorMatrix); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + funcs->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); m_program.release(); } diff --git a/src/VideoStreaming/gstqtvideosink/painters/videomaterial.cpp b/src/VideoStreaming/gstqtvideosink/painters/videomaterial.cpp index 7ed24f57dfb8ca7f5858244fa79cb1b4b479f539..67daa4fc440694409d587924becfcac2c735cda8 100644 --- a/src/VideoStreaming/gstqtvideosink/painters/videomaterial.cpp +++ b/src/VideoStreaming/gstqtvideosink/painters/videomaterial.cpp @@ -26,9 +26,10 @@ #include #include -#include #include +#include "glutils.h" + static const char * const qtvideosink_glsl_vertexShader = "uniform highp mat4 qt_Matrix; \n" "attribute highp vec4 qt_VertexPosition; \n" @@ -256,7 +257,13 @@ VideoMaterial::VideoMaterial() VideoMaterial::~VideoMaterial() { if (!m_textureSize.isEmpty()) - glDeleteTextures(m_textureCount, m_textureIds); + { + QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); + if (funcs) + { + funcs->glDeleteTextures(m_textureCount, m_textureIds); + } + } gst_buffer_replace(&m_frame, NULL); } @@ -323,9 +330,13 @@ void VideoMaterial::initYuv420PTextureInfo(bool uvSwapped, const QSize &size) void VideoMaterial::init(GstVideoColorMatrix colorMatrixType) { - glGenTextures(m_textureCount, m_textureIds); - m_colorMatrixType = colorMatrixType; - updateColors(0, 0, 0, 0); + QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); + if (funcs) + { + funcs->glGenTextures(m_textureCount, m_textureIds); + m_colorMatrixType = colorMatrixType; + updateColors(0, 0, 0, 0); + } } void VideoMaterial::setCurrentFrame(GstBuffer *buffer) @@ -411,7 +422,10 @@ void VideoMaterial::updateColors(int brightness, int contrast, int hue, int satu void VideoMaterial::bind() { - QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions(); + QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); + if (!funcs) + return; + GstBuffer *frame = NULL; m_frameMutex.lock(); @@ -422,28 +436,32 @@ void VideoMaterial::bind() if (frame) { GstMapInfo info; gst_buffer_map(frame, &info, GST_MAP_READ); - functions->glActiveTexture(GL_TEXTURE1); + funcs->glActiveTexture(GL_TEXTURE1); bindTexture(1, info.data); - functions->glActiveTexture(GL_TEXTURE2); + funcs->glActiveTexture(GL_TEXTURE2); bindTexture(2, info.data); - functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit + funcs->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit bindTexture(0, info.data); gst_buffer_unmap(frame, &info); gst_buffer_unref(frame); } 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]); + funcs->glActiveTexture(GL_TEXTURE1); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); + funcs->glActiveTexture(GL_TEXTURE2); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); + funcs->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); } } void VideoMaterial::bindTexture(int i, const quint8 *data) { - glBindTexture(GL_TEXTURE_2D, m_textureIds[i]); - glTexImage2D( + QOpenGLFunctionsDef *funcs = getQOpenGLFunctions(); + if (!funcs) + return; + + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[i]); + funcs->glTexImage2D( GL_TEXTURE_2D, 0, m_textureInternalFormat, @@ -453,9 +471,9 @@ void VideoMaterial::bindTexture(int i, const quint8 *data) m_textureFormat, m_textureType, data + m_textureOffsets[i]); - 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); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } diff --git a/src/VideoStreaming/gstqtvideosink/utils/glutils.h b/src/VideoStreaming/gstqtvideosink/utils/glutils.h new file mode 100644 index 0000000000000000000000000000000000000000..2ff461d20e19128922c9d72fba6dcf8bf38414ed --- /dev/null +++ b/src/VideoStreaming/gstqtvideosink/utils/glutils.h @@ -0,0 +1,43 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2009, 2015 QGROUNDCONTROL PROJECT + +This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + +======================================================================*/ + +/** + * @file + * @brief QGC Video Item + * @author Gus Grubba + */ + +#ifndef GLUTILS_H +#define GLUTILS_H + +#ifdef __android__ +#include +#define getQOpenGLFunctions() QOpenGLContext::currentContext()->functions() +#define QOpenGLFunctionsDef QOpenGLFunctions +#else +#include +#define getQOpenGLFunctions() QOpenGLContext::currentContext()->versionFunctions() +#define QOpenGLFunctionsDef QOpenGLFunctions_2_0 +#endif + +#endif