diff options
author | Jøger Hansegård <joger.hansegard@qt.io> | 2024-04-23 19:27:24 +0200 |
---|---|---|
committer | Jøger Hansegård <joger.hansegard@qt.io> | 2024-05-02 16:08:49 +0200 |
commit | 0f37234ac6dab1d5f63dabe63902a15e8ef96d4d (patch) | |
tree | 443633b6a2bb81104aaf2c9684647b5a6bc2a70d | |
parent | 0fad5b681bf15a739280ef78a75a501e870680a8 (diff) |
Extend tests to cover YUYV and UYVY pixel formats
Task-number: QTBUG-124537
Task-number: QTBUG-124647
Pick-to: 6.7 6.5
Change-Id: Ia80df913cea9abdf976cbdfa1c3508df948bf7db
Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io>
18 files changed, 75 insertions, 13 deletions
diff --git a/tests/auto/unit/multimedia/qvideoframe/tst_qvideoframe.cpp b/tests/auto/unit/multimedia/qvideoframe/tst_qvideoframe.cpp index 607479412..c3dd6e71a 100644 --- a/tests/auto/unit/multimedia/qvideoframe/tst_qvideoframe.cpp +++ b/tests/auto/unit/multimedia/qvideoframe/tst_qvideoframe.cpp @@ -257,21 +257,27 @@ void tst_QVideoFrame::create_data() { QTest::addColumn<QSize>("size"); QTest::addColumn<QVideoFrameFormat::PixelFormat>("pixelFormat"); - QTest::addColumn<int>("bytes"); QTest::addColumn<int>("bytesPerLine"); QTest::newRow("64x64 ARGB32") << QSize(64, 64) - << QVideoFrameFormat::Format_ARGB8888; + << QVideoFrameFormat::Format_ARGB8888 + << 64*4; QTest::newRow("32x256 YUV420P") << QSize(32, 256) - << QVideoFrameFormat::Format_YUV420P; + << QVideoFrameFormat::Format_YUV420P + << 32; + QTest::newRow("32x256 UYVY") + << QSize(32, 256) + << QVideoFrameFormat::Format_UYVY + << 32*2; } void tst_QVideoFrame::create() { QFETCH(QSize, size); QFETCH(QVideoFrameFormat::PixelFormat, pixelFormat); + QFETCH(int, bytesPerLine); QVideoFrame frame(QVideoFrameFormat(size, pixelFormat)); @@ -285,6 +291,9 @@ void tst_QVideoFrame::create() QCOMPARE(frame.height(), size.height()); QCOMPARE(frame.startTime(), qint64(-1)); QCOMPARE(frame.endTime(), qint64(-1)); + frame.map(QVideoFrame::ReadOnly); + QCOMPARE(frame.bytesPerLine(0), bytesPerLine); + frame.unmap(); } void tst_QVideoFrame::createInvalid_data() diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_AdobeRgb_Full.png b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_AdobeRgb_Full.png Binary files differnew file mode 100644 index 000000000..4fd00f938 --- /dev/null +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_AdobeRgb_Full.png diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_AdobeRgb_Video.png b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_AdobeRgb_Video.png Binary files differnew file mode 100644 index 000000000..4fd00f938 --- /dev/null +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_AdobeRgb_Video.png diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT2020_Full.png b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT2020_Full.png Binary files differnew file mode 100644 index 000000000..309454576 --- /dev/null +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT2020_Full.png diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT2020_Video.png b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT2020_Video.png Binary files differnew file mode 100644 index 000000000..f97e71817 --- /dev/null +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT2020_Video.png diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT601_Full.png b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT601_Full.png Binary files differnew file mode 100644 index 000000000..d513a8123 --- /dev/null +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT601_Full.png diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT601_Video.png b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT601_Video.png Binary files differnew file mode 100644 index 000000000..6e9c36b39 --- /dev/null +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT601_Video.png diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT709_Full.png b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT709_Full.png Binary files differnew file mode 100644 index 000000000..c0568cb62 --- /dev/null +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT709_Full.png diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT709_Video.png b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT709_Video.png Binary files differnew file mode 100644 index 000000000..207fc0be1 --- /dev/null +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_uyvy_BT709_Video.png diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_AdobeRgb_Full.png b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_AdobeRgb_Full.png Binary files differnew file mode 100644 index 000000000..4fd00f938 --- /dev/null +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_AdobeRgb_Full.png diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_AdobeRgb_Video.png b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_AdobeRgb_Video.png Binary files differnew file mode 100644 index 000000000..4fd00f938 --- /dev/null +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_AdobeRgb_Video.png diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT2020_Full.png b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT2020_Full.png Binary files differnew file mode 100644 index 000000000..309454576 --- /dev/null +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT2020_Full.png diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT2020_Video.png b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT2020_Video.png Binary files differnew file mode 100644 index 000000000..f97e71817 --- /dev/null +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT2020_Video.png diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT601_Full.png b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT601_Full.png Binary files differnew file mode 100644 index 000000000..d513a8123 --- /dev/null +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT601_Full.png diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT601_Video.png b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT601_Video.png Binary files differnew file mode 100644 index 000000000..6e9c36b39 --- /dev/null +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT601_Video.png diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT709_Full.png b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT709_Full.png Binary files differnew file mode 100644 index 000000000..c0568cb62 --- /dev/null +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT709_Full.png diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT709_Video.png b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT709_Video.png Binary files differnew file mode 100644 index 000000000..207fc0be1 --- /dev/null +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/testdata/umbrellas.jpg_yuyv_BT709_Video.png diff --git a/tests/auto/unit/multimedia/qvideoframecolormanagement/tst_qvideoframecolormanagement.cpp b/tests/auto/unit/multimedia/qvideoframecolormanagement/tst_qvideoframecolormanagement.cpp index 31337603e..83e78d2d8 100644 --- a/tests/auto/unit/multimedia/qvideoframecolormanagement/tst_qvideoframecolormanagement.cpp +++ b/tests/auto/unit/multimedia/qvideoframecolormanagement/tst_qvideoframecolormanagement.cpp @@ -62,6 +62,10 @@ QString toString(QVideoFrameFormat::PixelFormat f) return "420p"; case QVideoFrameFormat::Format_YUV422P: return "422p"; + case QVideoFrameFormat::Format_UYVY: + return "uyvy"; + case QVideoFrameFormat::Format_YUYV: + return "yuyv"; default: Q_ASSERT(false); return ""; // Not implemented yet @@ -73,7 +77,8 @@ std::vector<QVideoFrameFormat::PixelFormat> pixelFormats() return { QVideoFrameFormat::Format_NV12, QVideoFrameFormat::Format_NV21, QVideoFrameFormat::Format_IMC1, QVideoFrameFormat::Format_IMC2, QVideoFrameFormat::Format_IMC3, QVideoFrameFormat::Format_IMC4, - QVideoFrameFormat::Format_YUV420P, QVideoFrameFormat::Format_YUV422P }; + QVideoFrameFormat::Format_YUV420P, QVideoFrameFormat::Format_YUV422P, + QVideoFrameFormat::Format_UYVY, QVideoFrameFormat::Format_YUYV }; } QString toString(QVideoFrameFormat::ColorSpace s) @@ -155,10 +160,10 @@ constexpr uchar double2uchar(double v) return static_cast<uchar>(std::clamp(v + 0.5, 0.5, 255.5)); } -constexpr void rgb2y(const QRgb &rgb, uchar *y) +constexpr uchar rgb2y(const QRgb &rgb) { const double Y = rgb2yuv_bt709_full.Y(rgb); - y[0] = double2uchar(Y); + return double2uchar(Y); } constexpr uchar rgb2u(const QRgb &rgb) @@ -173,19 +178,19 @@ constexpr uchar rgb2v(const QRgb &rgb) return double2uchar(V); } -void rgb2y(const QImage &image, QVideoFrame &frame, int yPlane) +void rgb2y_planar(const QImage &image, QVideoFrame &frame, int yPlane) { uchar *bits = frame.bits(yPlane); for (int row = 0; row < image.height(); ++row) { for (int col = 0; col < image.width(); ++col) { const QRgb pixel = image.pixel(col, row); - rgb2y(pixel, bits + col); + bits[col] = rgb2y(pixel); } bits += frame.bytesPerLine(yPlane); } } -void rgb2uv(const QImage &image, QVideoFrame &frame) +void rgb2uv_planar(const QImage &image, QVideoFrame &frame) { uchar *vBits = nullptr; uchar *uBits = nullptr; @@ -254,7 +259,7 @@ void rgb2uv(const QImage &image, QVideoFrame &frame) } } -void naive_rgbToYuv(const QImage &image, QVideoFrame &frame) +void naive_rgbToYuv_planar(const QImage &image, QVideoFrame &frame) { Q_ASSERT(image.format() == QImage::Format_RGB32); Q_ASSERT(frame.planeCount() > 1); @@ -262,8 +267,53 @@ void naive_rgbToYuv(const QImage &image, QVideoFrame &frame) frame.map(QVideoFrame::WriteOnly); - rgb2y(image, frame, 0); - rgb2uv(image, frame); + rgb2y_planar(image, frame, 0); + rgb2uv_planar(image, frame); + + frame.unmap(); +} + +void naive_rgbToYuv422(const QImage &image, QVideoFrame &frame) +{ + // Packed format uyvy or yuyv. Each 32 bit frame sample represents + // two pixels with distinct y values, but shared u and v values + Q_ASSERT(image.format() == QImage::Format_RGB32); + Q_ASSERT(frame.planeCount() == 1); + Q_ASSERT(image.size() == frame.size()); + + const QVideoFrameFormat::PixelFormat format = frame.pixelFormat(); + + Q_ASSERT(format == QVideoFrameFormat::Format_UYVY || format == QVideoFrameFormat::Format_YUYV); + + constexpr int plane = 0; + frame.map(QVideoFrame::WriteOnly); + + uchar *line = frame.bits(plane); + for (int row = 0; row < image.height(); ++row) { + uchar *bits = line; + for (int col = 0; col < image.width() - 1; col += 2) { + // Handle to image pixels at a time + const QRgb pixel0 = image.pixel(col, row); + const QRgb pixel1 = image.pixel(col + 1, row); + + // Down-sample u and v channels + bits[0] = (rgb2u(pixel0) + rgb2u(pixel1)) / 2; + bits[2] = (rgb2v(pixel0) + rgb2v(pixel1)) / 2; + + // But not the y-channel + bits[1] = rgb2y(pixel0); + bits[3] = rgb2y(pixel1); + + // Swizzle fom uyuv to yuyv + if (format == QVideoFrameFormat::Format_YUYV) { + std::swap(bits[0], bits[1]); + std::swap(bits[2], bits[3]); + } + + bits += 4; + } + line += frame.bytesPerLine(plane); + } frame.unmap(); } @@ -285,7 +335,10 @@ QVideoFrame createTestFrame(const TestParams ¶ms, const QImage &image) || params.pixelFormat == QVideoFrameFormat::Format_NV21 || params.pixelFormat == QVideoFrameFormat::Format_YUV420P || params.pixelFormat == QVideoFrameFormat::Format_YUV422P) { - naive_rgbToYuv(image, frame); + naive_rgbToYuv_planar(image, frame); + } else if (params.pixelFormat == QVideoFrameFormat::Format_UYVY + || params.pixelFormat == QVideoFrameFormat::Format_YUYV) { + naive_rgbToYuv422(image, frame); } else { qDebug() << "Not implemented yet"; Q_ASSERT(false); |