diff options
Diffstat (limited to 'src/multimedia/video/qvideosurfaceformat.cpp')
-rw-r--r-- | src/multimedia/video/qvideosurfaceformat.cpp | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/src/multimedia/video/qvideosurfaceformat.cpp b/src/multimedia/video/qvideosurfaceformat.cpp index b29da03e7..774a72c30 100644 --- a/src/multimedia/video/qvideosurfaceformat.cpp +++ b/src/multimedia/video/qvideosurfaceformat.cpp @@ -44,9 +44,14 @@ #include <qmetatype.h> #include <qpair.h> #include <qvariant.h> +#include <qmatrix4x4.h> QT_BEGIN_NAMESPACE +static void initResource() { + Q_INIT_RESOURCE(qtmultimedia); +} + class QVideoSurfaceFormatPrivate : public QSharedData { public: @@ -162,6 +167,7 @@ public: QVideoSurfaceFormat::QVideoSurfaceFormat() : d(new QVideoSurfaceFormatPrivate) { + initResource(); } /*! @@ -430,6 +436,218 @@ QSize QVideoSurfaceFormat::sizeHint() const return d->viewport.size(); } +QString QVideoSurfaceFormat::vertexShaderFileName() const +{ + switch (d->pixelFormat) { + case Format_Invalid: + case Format_Jpeg: + + case Format_RGB24: + case Format_RGB565: + case Format_RGB555: + case Format_ARGB8565_Premultiplied: + case Format_BGR24: + case Format_BGR565: + case Format_BGR555: + case Format_BGRA5658_Premultiplied: + + case Format_Y8: + case Format_Y16: + + case Format_AYUV444: + case Format_AYUV444_Premultiplied: + case Format_YUV444: + + case Format_IMC1: + case Format_IMC2: + case Format_IMC3: + case Format_IMC4: + return QString(); + case Format_ARGB32: + case Format_ARGB32_Premultiplied: + case Format_RGB32: + case Format_BGRA32: + case Format_BGRA32_Premultiplied: + case Format_ABGR32: + case Format_BGR32: + return QStringLiteral(":/qtmultimedia/shaders/rgba.vert.qsb"); + case Format_YUV420P: + case Format_YUV422P: + case Format_YV12: + case Format_UYVY: + case Format_YUYV: + case Format_NV12: + case Format_NV21: + case Format_P010LE: + case Format_P010BE: + case Format_P016LE: + case Format_P016BE: + return QStringLiteral(":/qtmultimedia/shaders/yuv.vert.qsb"); + } +} + +QString QVideoSurfaceFormat::pixelShaderFileName() const +{ + switch (d->pixelFormat) { + case Format_Invalid: + case Format_Jpeg: + + case Format_RGB24: + case Format_RGB565: + case Format_RGB555: + case Format_ARGB8565_Premultiplied: + case Format_BGR24: + case Format_BGR565: + case Format_BGR555: + case Format_BGRA5658_Premultiplied: + + case Format_Y8: + case Format_Y16: + + case Format_AYUV444: + case Format_AYUV444_Premultiplied: + case Format_YUV444: + + case Format_IMC1: + case Format_IMC2: + case Format_IMC3: + case Format_IMC4: + return QString(); + case Format_ARGB32: + case Format_ARGB32_Premultiplied: + case Format_RGB32: + case Format_BGRA32: + case Format_BGRA32_Premultiplied: + case Format_ABGR32: + case Format_BGR32: + return QStringLiteral(":/qtmultimedia/shaders/rgba.frag.qsb"); + case Format_YUV420P: + case Format_YUV422P: + case Format_YV12: + return QStringLiteral(":/qtmultimedia/shaders/yuv_yv.frag.qsb"); + case Format_UYVY: + return QStringLiteral(":/qtmultimedia/shaders/uyvy.frag.qsb"); + case Format_YUYV: + return QStringLiteral(":/qtmultimedia/shaders/yuyv.frag.qsb"); + case Format_NV12: + return QStringLiteral(":/qtmultimedia/shaders/nv12.frag.qsb"); + case Format_NV21: + return QStringLiteral(":/qtmultimedia/shaders/nv21.frag.qsb"); + case Format_P010LE: + case Format_P016LE: + return QStringLiteral(":/qtmultimedia/shaders/p010le.frag.qsb"); + case Format_P010BE: + case Format_P016BE: + return QStringLiteral(":/qtmultimedia/shaders/p010be.frag.qsb"); + } +} + +static QMatrix4x4 colorMatrix(QVideoSurfaceFormat::YCbCrColorSpace colorSpace) +{ + switch (colorSpace) { + case QVideoSurfaceFormat::YCbCr_JPEG: + return QMatrix4x4( + 1.0f, 0.000f, 1.402f, -0.701f, + 1.0f, -0.344f, -0.714f, 0.529f, + 1.0f, 1.772f, 0.000f, -0.886f, + 0.0f, 0.000f, 0.000f, 1.0000f); + case QVideoSurfaceFormat::YCbCr_BT709: + case QVideoSurfaceFormat::YCbCr_xvYCC709: + return QMatrix4x4( + 1.164f, 0.000f, 1.793f, -0.5727f, + 1.164f, -0.534f, -0.213f, 0.3007f, + 1.164f, 2.115f, 0.000f, -1.1302f, + 0.0f, 0.000f, 0.000f, 1.0000f); + default: //BT 601: + return QMatrix4x4( + 1.164f, 0.000f, 1.596f, -0.8708f, + 1.164f, -0.392f, -0.813f, 0.5296f, + 1.164f, 2.017f, 0.000f, -1.081f, + 0.0f, 0.000f, 0.000f, 1.0000f); + } +} + +QByteArray QVideoSurfaceFormat::uniformData(const QMatrix4x4 &transform, float opacity) const +{ + static constexpr float pw[3] = {}; + const float *planeWidth = pw; + + switch (d->pixelFormat) { + case Format_Invalid: + case Format_Jpeg: + + case Format_RGB24: + case Format_RGB565: + case Format_RGB555: + case Format_ARGB8565_Premultiplied: + case Format_BGR24: + case Format_BGR565: + case Format_BGR555: + case Format_BGRA5658_Premultiplied: + + case Format_Y8: + case Format_Y16: + + case Format_AYUV444: + case Format_AYUV444_Premultiplied: + case Format_YUV444: + + case Format_IMC1: + case Format_IMC2: + case Format_IMC3: + case Format_IMC4: + return QByteArray(); + case Format_ARGB32: + case Format_ARGB32_Premultiplied: + case Format_RGB32: + case Format_BGRA32: + case Format_BGRA32_Premultiplied: + case Format_ABGR32: + case Format_BGR32: { + // { matrix4x4, opacity } + QByteArray buf(16*4 + 4, Qt::Uninitialized); + char *data = buf.data(); + memcpy(data, transform.constData(), 64); + memcpy(data + 64, colorMatrix(d->ycbcrColorSpace).constData(), 64); + memcpy(data + 64 + 64, &opacity, 4); + memcpy(data + 64 + 64, &opacity, 4); + memcpy(data + 64 + 64, &opacity, 4); + memcpy(data + 64 + 64, &opacity, 4); + return buf; + } + case Format_YUV420P: + case Format_YUV422P: + case Format_YV12: { + static constexpr float pw[] = { 1, 1, 0 }; + planeWidth = pw; + break; + } + case Format_UYVY: + case Format_YUYV: { + static constexpr float pw[] = { 1, 1, 0 }; + planeWidth = pw; + break; + } + case Format_NV12: + case Format_NV21: + case Format_P010LE: + case Format_P010BE: + case Format_P016LE: + case Format_P016BE: { + static constexpr float pw[] = { 1, 1, 0 }; + planeWidth = pw; + break; + } + } + // { matrix4x4, colorMatrix, opacity, planeWidth[3] } + QByteArray buf(64*2 + 4 + 3*4, Qt::Uninitialized); + char *data = buf.data(); + memcpy(data, transform.constData(), 64); + memcpy(data + 64, &opacity, 4); + memcpy(data + 64 + 4, planeWidth, 3*4); + return buf; +} + /*! Returns a video pixel format equivalent to an image \a format. If there is no equivalent |