From 0a6a1883b6dde64b195a564a0c02a949d7718b25 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 21 Apr 2021 11:42:33 +0200 Subject: Fix tst_qvideoframe test failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I25bceb948518ba49053ae87484bdd8375b616b20 Reviewed-by: André de la Rocha Reviewed-by: Lars Knoll --- src/multimedia/video/qvideoframe.cpp | 4 +- src/multimedia/video/qvideotexturehelper.cpp | 60 +++++++++++++++------------- src/multimedia/video/qvideotexturehelper_p.h | 9 +++-- 3 files changed, 41 insertions(+), 32 deletions(-) (limited to 'src/multimedia/video') diff --git a/src/multimedia/video/qvideoframe.cpp b/src/multimedia/video/qvideoframe.cpp index 8f95706bb..a120d850b 100644 --- a/src/multimedia/video/qvideoframe.cpp +++ b/src/multimedia/video/qvideoframe.cpp @@ -291,7 +291,7 @@ QVideoFrame::QVideoFrame(const QVideoFrameFormat &format) // Check the memory was successfully allocated. if (!data.isEmpty()) - d->buffer = new QMemoryVideoBuffer(data, textureDescription->stride*format.frameWidth()); + d->buffer = new QMemoryVideoBuffer(data, textureDescription->strideForWidth(format.frameWidth())); } } @@ -751,6 +751,8 @@ int QVideoFrame::planeCount() const */ quint64 QVideoFrame::textureHandle(int plane) const { + if (!d->buffer) + return 0; return d->buffer->textureHandle(plane); } diff --git a/src/multimedia/video/qvideotexturehelper.cpp b/src/multimedia/video/qvideotexturehelper.cpp index 77ad98f3e..4ff64a3e4 100644 --- a/src/multimedia/video/qvideotexturehelper.cpp +++ b/src/multimedia/video/qvideotexturehelper.cpp @@ -46,166 +46,170 @@ namespace QVideoTextureHelper static const TextureDescription descriptions[QVideoFrameFormat::NPixelFormats] = { // Format_Invalid { 0, 0, - [](QSize) { return 0; }, + [](int, int) { return 0; }, { QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat}, { { 1, 1 }, { 1, 1 }, { 1, 1 } } }, // Format_ARGB32 { 1, 4, - [](QSize s) { return 4*s.width()*s.height(); }, + [](int stride, int height) { return stride*height; }, { QRhiTexture::BGRA8, QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 1, 1 }, { 1, 1 } } }, // Format_ARGB32_Premultiplied { 1, 4, - [](QSize s) { return 4*s.width()*s.height(); }, + [](int stride, int height) { return stride*height; }, { QRhiTexture::BGRA8, QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 1, 1 }, { 1, 1 } } }, // Format_RGB32 { 1, 4, - [](QSize s) { return 4*s.width()*s.height(); }, + [](int stride, int height) { return stride*height; }, { QRhiTexture::BGRA8, QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 1, 1 }, { 1, 1 } } }, // Format_BGRA32 { 1, 4, - [](QSize s) { return 4*s.width()*s.height(); }, + [](int stride, int height) { return stride*height; }, { QRhiTexture::BGRA8, QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 1, 1 }, { 1, 1 } } }, // Format_BGRA32_Premultiplied { 1, 4, - [](QSize s) { return 4*s.width()*s.height(); }, + [](int stride, int height) { return stride*height; }, { QRhiTexture::BGRA8, QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 1, 1 }, { 1, 1 } } }, // Format_ABGR32 { 1, 4, - [](QSize s) { return 4*s.width()*s.height(); }, + [](int stride, int height) { return stride*height; }, { QRhiTexture::BGRA8, QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 1, 1 }, { 1, 1 } } }, // Format_BGR32 { 1, 4, - [](QSize s) { return 4*s.width()*s.height(); }, + [](int stride, int height) { return stride*height; }, { QRhiTexture::BGRA8, QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 1, 1 }, { 1, 1 } } }, // Format_AYUV444 { 1, 4, - [](QSize s) { return 4*s.width()*s.height(); }, + [](int stride, int height) { return stride*height; }, { QRhiTexture::BGRA8, QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 1, 1 }, { 1, 1 } } }, // Format_AYUV444_Premultiplied { 1, 4, - [](QSize s) { return 4*s.width()*s.height(); }, + [](int stride, int height) { return stride*height; }, { QRhiTexture::BGRA8, QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 1, 1 }, { 1, 1 } } }, // Format_YUV420P { 3, 1, - [](QSize s) { return 3*s.width()*s.height() / 2; }, + [](int stride, int height) { return stride * ((height * 3 / 2 + 1) & ~1); }, { QRhiTexture::R8, QRhiTexture::R8, QRhiTexture::R8 }, { { 1, 1 }, { 2, 2 }, { 2, 2 } } }, // Format_YUV422P { 3, 1, - [](QSize s) { return 2*s.width()*s.height(); }, + [](int stride, int height) { return stride * ((height * 3 / 2 + 1) & ~1); }, { QRhiTexture::R8, QRhiTexture::R8, QRhiTexture::R8 }, { { 1, 1 }, { 2, 1 }, { 2, 1 } } }, // Format_YV12 { 3, 1, - [](QSize s) { return 2*s.width()*s.height(); }, + [](int stride, int height) { return stride * ((height * 3 / 2 + 1) & ~1); }, { QRhiTexture::R8, QRhiTexture::R8, QRhiTexture::R8 }, { { 1, 1 }, { 2, 2 }, { 2, 2 } } }, // Format_UYVY { 1, 2, - [](QSize s) { return 2*s.width()*s.height(); }, + [](int stride, int height) { return stride*height; }, { QRhiTexture::BGRA8, QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat }, { { 2, 1 }, { 1, 1 }, { 1, 1 } } }, // Format_YUYV { 1, 2, - [](QSize s) { return 2*s.width()*s.height(); }, + [](int stride, int height) { return stride*height; }, { QRhiTexture::BGRA8, QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat }, { { 2, 1 }, { 1, 1 }, { 1, 1 } } }, // Format_NV12 { 2, 1, - [](QSize s) { return 3*s.width()*s.height() / 2; }, + [](int stride, int height) { return stride * ((height * 3 / 2 + 1) & ~1); }, { QRhiTexture::R8, QRhiTexture::RG8, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 2, 2 }, { 1, 1 } } }, // Format_NV21 { 2, 1, - [](QSize s) { return 3*s.width()*s.height() / 2; }, + [](int stride, int height) { return stride * ((height * 3 / 2 + 1) & ~1); }, { QRhiTexture::R8, QRhiTexture::RG8, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 2, 2 }, { 1, 1 } } }, // Format_IMC1 { 3, 1, - [](QSize s) { + [](int stride, int height) { // IMC1 requires that U and V components are aligned on a multiple of 16 lines - return s.width()*((s.height()*3/2 + 15) & ~15 + s.height()/2); + int h = (height + 15) & ~15; + h += 2*((h/2) + 15 & ~15); + return stride * h; }, { QRhiTexture::R8, QRhiTexture::R8, QRhiTexture::R8 }, { { 1, 1 }, { 2, 2 }, { 2, 2 } } }, // Format_IMC2 { 2, 1, - [](QSize s) { return 2*s.width()*s.height(); }, + [](int stride, int height) { return 2*stride*height; }, { QRhiTexture::R8, QRhiTexture::R8, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 1, 2 }, { 1, 1 } } }, // Format_IMC3 { 3, 1, - [](QSize s) { + [](int stride, int height) { // IMC3 requires that U and V components are aligned on a multiple of 16 lines - return s.width()*((s.height()*3/2 + 15) & ~15 + s.height()/2); + int h = (height + 15) & ~15; + h += 2*((h/2) + 15 & ~15); + return stride * h; }, { QRhiTexture::R8, QRhiTexture::R8, QRhiTexture::R8 }, { { 1, 1 }, { 2, 2 }, { 2, 2 } } }, // Format_IMC4 { 2, 1, - [](QSize s) { return 2*s.width()*s.height(); }, + [](int stride, int height) { return 2*stride*height; }, { QRhiTexture::R8, QRhiTexture::R8, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 1, 2 }, { 1, 1 } } }, // Format_Y8 { 1, 1, - [](QSize s) { return s.width()*s.height(); }, + [](int stride, int height) { return stride*height; }, { QRhiTexture::R8, QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 1, 1 }, { 1, 1 } } }, // Format_Y16 { 1, 2, - [](QSize s) { return 2*s.width()*s.height(); }, + [](int stride, int height) { return stride*height; }, { QRhiTexture::R16, QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 1, 1 }, { 1, 1 } } }, // Format_P010 { 2, 2, - [](QSize s) { return 3*s.width()*s.height(); }, + [](int stride, int height) { return stride * ((height * 3 / 2 + 1) & ~1); }, { QRhiTexture::R16, QRhiTexture::RG16, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 2, 2 }, { 1, 1 } } }, // Format_P016 { 2, 2, - [](QSize s) { return 3*s.width()*s.height(); }, + [](int stride, int height) { return stride * ((height * 3 / 2 + 1) & ~1); }, { QRhiTexture::R16, QRhiTexture::RG16, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 2, 2 }, { 1, 1 } } }, // Format_Jpeg { 1, 0, - [](QSize) { return 0; }, + [](int, int) { return 0; }, { QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat, QRhiTexture::UnknownFormat }, { { 1, 1 }, { 1, 1 }, { 1, 1 } } } diff --git a/src/multimedia/video/qvideotexturehelper_p.h b/src/multimedia/video/qvideotexturehelper_p.h index e0b72243a..a984101e5 100644 --- a/src/multimedia/video/qvideotexturehelper_p.h +++ b/src/multimedia/video/qvideotexturehelper_p.h @@ -57,11 +57,14 @@ struct TextureDescription int x; int y; }; - using BytesForSize = int(*)(QSize s); + using BytesRequired = int(*)(int stride, int height); + + inline int strideForWidth(int width) const { return (width*strideFactor + 15) & ~15; } + inline int bytesForSize(QSize s) const { return bytesRequired(strideForWidth(s.width()), s.height()); } int nplanes; - int stride; - BytesForSize bytesForSize; + int strideFactor; + BytesRequired bytesRequired; QRhiTexture::Format textureFormat[maxPlanes]; SizeScale sizeScale[maxPlanes]; }; -- cgit v1.2.3