qtmobility/src/multimedia/qpaintervideosurface.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 5 453da2cfceef
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
    37 **
    37 **
    38 ** $QT_END_LICENSE$
    38 ** $QT_END_LICENSE$
    39 **
    39 **
    40 ****************************************************************************/
    40 ****************************************************************************/
    41 
    41 
    42 #include <qpaintervideosurface_p.h>
    42 #include "qpaintervideosurface_p.h"
    43 
    43 
    44 #include <qmath.h>
    44 #include <qmath.h>
    45 
    45 
    46 #include <qpainter.h>
    46 #include <qpainter.h>
    47 #include <qvariant.h>
    47 #include <qvariant.h>
   358 
   358 
   359 void QVideoSurfaceGLPainter::updateColors(int brightness, int contrast, int hue, int saturation)
   359 void QVideoSurfaceGLPainter::updateColors(int brightness, int contrast, int hue, int saturation)
   360 {
   360 {
   361     const qreal b = brightness / 200.0;
   361     const qreal b = brightness / 200.0;
   362     const qreal c = contrast / 100.0 + 1.0;
   362     const qreal c = contrast / 100.0 + 1.0;
   363     const qreal h = hue / 200.0;
   363     const qreal h = hue / 100.0;
   364     const qreal s = saturation / 100.0 + 1.0;
   364     const qreal s = saturation / 100.0 + 1.0;
   365 
   365 
   366     const qreal cosH = qCos(M_PI * h);
   366     const qreal cosH = qCos(M_PI * h);
   367     const qreal sinH = qSin(M_PI * h);
   367     const qreal sinH = qSin(M_PI * h);
   368 
   368 
   369     const qreal h11 = -0.4728 * cosH + 0.7954 * sinH + 1.4728;
   369     const qreal h11 =  0.787 * cosH - 0.213 * sinH + 0.213;
   370     const qreal h21 = -0.9253 * cosH - 0.0118 * sinH + 0.9523;
   370     const qreal h21 = -0.213 * cosH + 0.143 * sinH + 0.213;
   371     const qreal h31 =  0.4525 * cosH + 0.8072 * sinH - 0.4524;
   371     const qreal h31 = -0.213 * cosH - 0.787 * sinH + 0.213;
   372 
   372 
   373     const qreal h12 =  1.4728 * cosH - 1.3728 * sinH - 1.4728;
   373     const qreal h12 = -0.715 * cosH - 0.715 * sinH + 0.715;
   374     const qreal h22 =  1.9253 * cosH + 0.5891 * sinH - 0.9253;
   374     const qreal h22 =  0.285 * cosH + 0.140 * sinH + 0.715;
   375     const qreal h32 = -0.4525 * cosH - 1.9619 * sinH + 0.4525;
   375     const qreal h32 = -0.715 * cosH + 0.715 * sinH + 0.715;
   376 
   376 
   377     const qreal h13 =  1.4728 * cosH - 0.2181 * sinH - 1.4728;
   377     const qreal h13 = -0.072 * cosH + 0.928 * sinH + 0.072;
   378     const qreal h23 =  0.9253 * cosH + 1.1665 * sinH - 0.9253;
   378     const qreal h23 = -0.072 * cosH - 0.283 * sinH + 0.072;
   379     const qreal h33 =  0.5475 * cosH - 1.3846 * sinH + 0.4525;
   379     const qreal h33 =  0.928 * cosH + 0.072 * sinH + 0.072;
   380 
   380 
   381     const qreal sr = (1.0 - s) * 0.3086;
   381     const qreal sr = (1.0 - s) * 0.3086;
   382     const qreal sg = (1.0 - s) * 0.6094;
   382     const qreal sg = (1.0 - s) * 0.6094;
   383     const qreal sb = (1.0 - s) * 0.0820;
   383     const qreal sb = (1.0 - s) * 0.0820;
   384 
   384 
   527     "DP4 result.color.x, yuv, matrix[0];\n"
   527     "DP4 result.color.x, yuv, matrix[0];\n"
   528     "DP4 result.color.y, yuv, matrix[1];\n"
   528     "DP4 result.color.y, yuv, matrix[1];\n"
   529     "DP4 result.color.z, yuv, matrix[2];\n"
   529     "DP4 result.color.z, yuv, matrix[2];\n"
   530     "END";
   530     "END";
   531 
   531 
       
   532 // Paints a YUV444 frame.
       
   533 static const char *qt_arbfp_xyuvShaderProgram =
       
   534     "!!ARBfp1.0\n"
       
   535     "PARAM matrix[4] = { program.local[0..2],"
       
   536     "{ 0.0, 0.0, 0.0, 1.0 } };\n"
       
   537     "TEMP ayuv;\n"
       
   538     "TEX ayuv, fragment.texcoord[0], texture[0], 2D;\n"
       
   539     "MOV ayuv.x, matrix[3].w;\n"
       
   540     "DP4 result.color.x, ayuv.yzwx, matrix[0];\n"
       
   541     "DP4 result.color.y, ayuv.yzwx, matrix[1];\n"
       
   542     "DP4 result.color.z, ayuv.yzwx, matrix[2];\n"
       
   543     "END";
       
   544 
       
   545 // Paints a AYUV444 frame.
       
   546 static const char *qt_arbfp_ayuvShaderProgram =
       
   547     "!!ARBfp1.0\n"
       
   548     "PARAM matrix[4] = { program.local[0..2],"
       
   549     "{ 0.0, 0.0, 0.0, 1.0 } };\n"
       
   550     "TEMP ayuv;\n"
       
   551     "TEX ayuv, fragment.texcoord[0], texture[0], 2D;\n"
       
   552     "MOV ayuv.x, matrix[3].w;\n"
       
   553     "DP4 result.color.x, ayuv.yzwx, matrix[0];\n"
       
   554     "DP4 result.color.y, ayuv.yzwx, matrix[1];\n"
       
   555     "DP4 result.color.z, ayuv.yzwx, matrix[2];\n"
       
   556     "TEX result.color.w, fragment.texcoord[0], texture, 2D;\n"
       
   557     "END";
   532 
   558 
   533 class QVideoSurfaceArbFpPainter : public QVideoSurfaceGLPainter
   559 class QVideoSurfaceArbFpPainter : public QVideoSurfaceGLPainter
   534 {
   560 {
   535 public:
   561 public:
   536     QVideoSurfaceArbFpPainter(QGLContext *context);
   562     QVideoSurfaceArbFpPainter(QGLContext *context);
   575     glProgramLocalParameter4fARB = (_glProgramLocalParameter4fARB) m_context->getProcAddress(
   601     glProgramLocalParameter4fARB = (_glProgramLocalParameter4fARB) m_context->getProcAddress(
   576                 QLatin1String("glProgramLocalParameter4fARB"));
   602                 QLatin1String("glProgramLocalParameter4fARB"));
   577 
   603 
   578     m_imagePixelFormats
   604     m_imagePixelFormats
   579             << QVideoFrame::Format_RGB32
   605             << QVideoFrame::Format_RGB32
       
   606             << QVideoFrame::Format_BGR32
   580             << QVideoFrame::Format_ARGB32
   607             << QVideoFrame::Format_ARGB32
   581             << QVideoFrame::Format_RGB24
   608             << QVideoFrame::Format_RGB24
       
   609             << QVideoFrame::Format_BGR24
   582             << QVideoFrame::Format_RGB565
   610             << QVideoFrame::Format_RGB565
       
   611             << QVideoFrame::Format_AYUV444
       
   612             << QVideoFrame::Format_YUV444
   583             << QVideoFrame::Format_YV12
   613             << QVideoFrame::Format_YV12
   584             << QVideoFrame::Format_YUV420P;
   614             << QVideoFrame::Format_YUV420P;
   585     m_glPixelFormats
   615     m_glPixelFormats
   586             << QVideoFrame::Format_RGB32
   616             << QVideoFrame::Format_RGB32
   587             << QVideoFrame::Format_ARGB32;
   617             << QVideoFrame::Format_ARGB32;
   601         switch (format.pixelFormat()) {
   631         switch (format.pixelFormat()) {
   602         case QVideoFrame::Format_RGB32:
   632         case QVideoFrame::Format_RGB32:
   603             initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
   633             initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
   604             program = qt_arbfp_xrgbShaderProgram;
   634             program = qt_arbfp_xrgbShaderProgram;
   605             break;
   635             break;
       
   636         case QVideoFrame::Format_BGR32:
       
   637             initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
       
   638             program = qt_arbfp_rgbShaderProgram;
       
   639             break;
   606         case QVideoFrame::Format_ARGB32:
   640         case QVideoFrame::Format_ARGB32:
   607             initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
   641             initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
   608             program = qt_arbfp_argbShaderProgram;
   642             program = qt_arbfp_argbShaderProgram;
   609             break;
   643             break;
   610         case QVideoFrame::Format_RGB24:
   644         case QVideoFrame::Format_RGB24:
   611             initRgbTextureInfo(GL_RGB8, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
   645             initRgbTextureInfo(GL_RGB8, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
   612             program = qt_arbfp_argbShaderProgram;
   646             program = qt_arbfp_rgbShaderProgram;
       
   647             break;
       
   648         case QVideoFrame::Format_BGR24:
       
   649             initRgbTextureInfo(GL_RGB8, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
       
   650             program = qt_arbfp_xrgbShaderProgram;
   613             break;
   651             break;
   614         case QVideoFrame::Format_RGB565:
   652         case QVideoFrame::Format_RGB565:
   615             initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize());
   653             initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize());
   616             program = qt_arbfp_rgbShaderProgram;
   654             program = qt_arbfp_rgbShaderProgram;
       
   655             break;
       
   656         case QVideoFrame::Format_YUV444:
       
   657             initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
       
   658             program = qt_arbfp_xyuvShaderProgram;
       
   659             m_yuv = true;
       
   660             break;
       
   661         case QVideoFrame::Format_AYUV444:
       
   662             initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
       
   663             program = qt_arbfp_ayuvShaderProgram;
       
   664             m_yuv = true;
   617             break;
   665             break;
   618         case QVideoFrame::Format_YV12:
   666         case QVideoFrame::Format_YV12:
   619             initYv12TextureInfo(format.frameSize());
   667             initYv12TextureInfo(format.frameSize());
   620             program = qt_arbfp_yuvPlanarShaderProgram;
   668             program = qt_arbfp_yuvPlanarShaderProgram;
   621             break;
   669             break;
   701 QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::paint(
   749 QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::paint(
   702         const QRectF &target, QPainter *painter, const QRectF &source)
   750         const QRectF &target, QPainter *painter, const QRectF &source)
   703 {
   751 {
   704     if (m_frame.isValid()) {
   752     if (m_frame.isValid()) {
   705         painter->beginNativePainting();
   753         painter->beginNativePainting();
       
   754 
       
   755         glEnable(GL_STENCIL_TEST);
       
   756         glEnable(GL_SCISSOR_TEST);
   706 
   757 
   707         const float txLeft = source.left() / m_frameSize.width();
   758         const float txLeft = source.left() / m_frameSize.width();
   708         const float txRight = source.right() / m_frameSize.width();
   759         const float txRight = source.right() / m_frameSize.width();
   709         const float txTop = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom
   760         const float txTop = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom
   710                 ? source.top() / m_frameSize.height()
   761                 ? source.top() / m_frameSize.height()
   782 
   833 
   783         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   834         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   784         glDisableClientState(GL_VERTEX_ARRAY);
   835         glDisableClientState(GL_VERTEX_ARRAY);
   785         glDisable(GL_FRAGMENT_PROGRAM_ARB);
   836         glDisable(GL_FRAGMENT_PROGRAM_ARB);
   786 
   837 
       
   838         glDisable(GL_STENCIL_TEST);
       
   839         glDisable(GL_SCISSOR_TEST);
       
   840 
   787         painter->endNativePainting();
   841         painter->endNativePainting();
   788     }
   842     }
   789     return QAbstractVideoSurface::NoError;
   843     return QAbstractVideoSurface::NoError;
   790 }
   844 }
   791 
   845 
   852         "           texture2D(texV, textureCoord.st).r,\n"
   906         "           texture2D(texV, textureCoord.st).r,\n"
   853         "           1.0);\n"
   907         "           1.0);\n"
   854         "    gl_FragColor = colorMatrix * color;\n"
   908         "    gl_FragColor = colorMatrix * color;\n"
   855         "}\n";
   909         "}\n";
   856 
   910 
       
   911 // Paints a YUV444 frame.
       
   912 static const char *qt_glsl_xyuvShaderProgram =
       
   913         "uniform sampler2D texRgb;\n"
       
   914         "uniform mediump mat4 colorMatrix;\n"
       
   915         "varying highp vec2 textureCoord;\n"
       
   916         "void main(void)\n"
       
   917         "{\n"
       
   918         "    highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).gba, 1.0);\n"
       
   919         "    gl_FragColor = colorMatrix * color;\n"
       
   920         "}\n";
       
   921 
       
   922 // Paints a AYUV444 frame.
       
   923 static const char *qt_glsl_ayuvShaderProgram =
       
   924         "uniform sampler2D texRgb;\n"
       
   925         "uniform mediump mat4 colorMatrix;\n"
       
   926         "varying highp vec2 textureCoord;\n"
       
   927         "void main(void)\n"
       
   928         "{\n"
       
   929         "    highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).gba, 1.0);\n"
       
   930         "    color = colorMatrix * color;\n"
       
   931         "    gl_FragColor = vec4(color.rgb, texture2D(texRgb, textureCoord.st).r);\n"
       
   932         "}\n";
   857 
   933 
   858 class QVideoSurfaceGlslPainter : public QVideoSurfaceGLPainter
   934 class QVideoSurfaceGlslPainter : public QVideoSurfaceGLPainter
   859 {
   935 {
   860 public:
   936 public:
   861     QVideoSurfaceGlslPainter(QGLContext *context);
   937     QVideoSurfaceGlslPainter(QGLContext *context);
   875     : QVideoSurfaceGLPainter(context)
   951     : QVideoSurfaceGLPainter(context)
   876     , m_program(context)
   952     , m_program(context)
   877 {
   953 {
   878     m_imagePixelFormats
   954     m_imagePixelFormats
   879             << QVideoFrame::Format_RGB32
   955             << QVideoFrame::Format_RGB32
       
   956             << QVideoFrame::Format_BGR32
   880             << QVideoFrame::Format_ARGB32
   957             << QVideoFrame::Format_ARGB32
   881 #ifndef QT_OPENGL_ES
   958 #ifndef QT_OPENGL_ES
   882             << QVideoFrame::Format_RGB24
   959             << QVideoFrame::Format_RGB24
       
   960             << QVideoFrame::Format_BGR24
   883 #endif
   961 #endif
   884             << QVideoFrame::Format_RGB565
   962             << QVideoFrame::Format_RGB565
       
   963             << QVideoFrame::Format_YUV444
       
   964             << QVideoFrame::Format_AYUV444
   885             << QVideoFrame::Format_YV12
   965             << QVideoFrame::Format_YV12
   886             << QVideoFrame::Format_YUV420P;
   966             << QVideoFrame::Format_YUV420P;
   887     m_glPixelFormats
   967     m_glPixelFormats
   888             << QVideoFrame::Format_RGB32
   968             << QVideoFrame::Format_RGB32
   889             << QVideoFrame::Format_ARGB32;
   969             << QVideoFrame::Format_ARGB32;
   903         switch (format.pixelFormat()) {
   983         switch (format.pixelFormat()) {
   904         case QVideoFrame::Format_RGB32:
   984         case QVideoFrame::Format_RGB32:
   905             initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
   985             initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
   906             fragmentProgram = qt_glsl_xrgbShaderProgram;
   986             fragmentProgram = qt_glsl_xrgbShaderProgram;
   907             break;
   987             break;
       
   988         case QVideoFrame::Format_BGR32:
       
   989             initRgbTextureInfo(GL_RGB, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
       
   990             fragmentProgram = qt_glsl_rgbShaderProgram;
       
   991             break;
   908         case QVideoFrame::Format_ARGB32:
   992         case QVideoFrame::Format_ARGB32:
   909             initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
   993             initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
   910             fragmentProgram = qt_glsl_argbShaderProgram;
   994             fragmentProgram = qt_glsl_argbShaderProgram;
   911             break;
   995             break;
   912 #ifndef QT_OPENGL_ES
   996 #ifndef QT_OPENGL_ES
   913         case QVideoFrame::Format_RGB24:
   997         case QVideoFrame::Format_RGB24:
   914             initRgbTextureInfo(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
   998             initRgbTextureInfo(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
   915             fragmentProgram = qt_glsl_rgbShaderProgram;
   999             fragmentProgram = qt_glsl_rgbShaderProgram;
   916             break;
  1000             break;
       
  1001         case QVideoFrame::Format_BGR24:
       
  1002             initRgbTextureInfo(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
       
  1003             fragmentProgram = qt_glsl_argbShaderProgram;
       
  1004             break;
   917 #endif
  1005 #endif
   918         case QVideoFrame::Format_RGB565:
  1006         case QVideoFrame::Format_RGB565:
   919             initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize());
  1007             initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize());
   920             fragmentProgram = qt_glsl_rgbShaderProgram;
  1008             fragmentProgram = qt_glsl_rgbShaderProgram;
       
  1009             break;
       
  1010         case QVideoFrame::Format_YUV444:
       
  1011             initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
       
  1012             fragmentProgram = qt_glsl_xyuvShaderProgram;
       
  1013             m_yuv = true;
       
  1014             break;
       
  1015         case QVideoFrame::Format_AYUV444:
       
  1016             initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
       
  1017             fragmentProgram = qt_glsl_ayuvShaderProgram;
       
  1018             m_yuv = true;
   921             break;
  1019             break;
   922         case QVideoFrame::Format_YV12:
  1020         case QVideoFrame::Format_YV12:
   923             initYv12TextureInfo(format.frameSize());
  1021             initYv12TextureInfo(format.frameSize());
   924             fragmentProgram = qt_glsl_yuvPlanarShaderProgram;
  1022             fragmentProgram = qt_glsl_yuvPlanarShaderProgram;
   925             break;
  1023             break;
   984 QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::paint(
  1082 QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::paint(
   985         const QRectF &target, QPainter *painter, const QRectF &source)
  1083         const QRectF &target, QPainter *painter, const QRectF &source)
   986 {
  1084 {
   987     if (m_frame.isValid()) {
  1085     if (m_frame.isValid()) {
   988         painter->beginNativePainting();
  1086         painter->beginNativePainting();
       
  1087 
       
  1088         glEnable(GL_STENCIL_TEST);
       
  1089         glEnable(GL_SCISSOR_TEST);
   989 
  1090 
   990         const int width = QGLContext::currentContext()->device()->width();
  1091         const int width = QGLContext::currentContext()->device()->width();
   991         const int height = QGLContext::currentContext()->device()->height();
  1092         const int height = QGLContext::currentContext()->device()->height();
   992 
  1093 
   993         const QTransform transform = painter->deviceTransform();
  1094         const QTransform transform = painter->deviceTransform();
  1083 
  1184 
  1084         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  1185         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  1085 
  1186 
  1086         m_program.release();
  1187         m_program.release();
  1087 
  1188 
       
  1189 
       
  1190         glDisable(GL_SCISSOR_TEST);
       
  1191         glDisable(GL_STENCIL_TEST);
  1088         painter->endNativePainting();
  1192         painter->endNativePainting();
  1089     }
  1193     }
  1090     return QAbstractVideoSurface::NoError;
  1194     return QAbstractVideoSurface::NoError;
  1091 }
  1195 }
  1092 
  1196