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() |
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(); |