diff options
author | Lars Knoll <lars.knoll@qt.io> | 2021-03-17 09:31:23 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2021-04-06 08:03:44 +0000 |
commit | 981afaafaec6123179587cdaffedca76644205ae (patch) | |
tree | 762c9a062395a0b2f223ac41e2262ba86d881829 /src/multimedia/video | |
parent | 090b588665caf4fe56c737172ab9b7268fe45867 (diff) |
Add support for P010 and P016 video formats
I've got some content in those formats and we should be able to render
them in Software.
This works now and is actually reasonable fast (but could be better if
we add SSE/AVX versions of the converter).
Change-Id: Ib42162124c9e203b228272b6d1c1849ce00e295a
Reviewed-by: Doris Verria <doris.verria@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/multimedia/video')
-rw-r--r-- | src/multimedia/video/qvideoframe.cpp | 15 | ||||
-rw-r--r-- | src/multimedia/video/qvideoframe.h | 6 | ||||
-rw-r--r-- | src/multimedia/video/qvideoframeconversionhelper.cpp | 63 |
3 files changed, 84 insertions, 0 deletions
diff --git a/src/multimedia/video/qvideoframe.cpp b/src/multimedia/video/qvideoframe.cpp index b2b4eb8e3..b6186f2d1 100644 --- a/src/multimedia/video/qvideoframe.cpp +++ b/src/multimedia/video/qvideoframe.cpp @@ -970,6 +970,8 @@ extern void QT_FASTCALL qt_convert_UYVY_to_ARGB32(const QVideoFrame&, uchar*); extern void QT_FASTCALL qt_convert_YUYV_to_ARGB32(const QVideoFrame&, uchar*); extern void QT_FASTCALL qt_convert_NV12_to_ARGB32(const QVideoFrame&, uchar*); extern void QT_FASTCALL qt_convert_NV21_to_ARGB32(const QVideoFrame&, uchar*); +extern void QT_FASTCALL qt_convert_P016LE_to_ARGB32(const QVideoFrame &, uchar*); +extern void QT_FASTCALL qt_convert_P016BE_to_ARGB32(const QVideoFrame &, uchar*); static VideoFrameConvertFunc qConvertFuncs[QVideoFrame::NPixelFormats] = { /* Format_Invalid */ nullptr, // Not needed @@ -1004,6 +1006,10 @@ static VideoFrameConvertFunc qConvertFuncs[QVideoFrame::NPixelFormats] = { /* Format_IMC4 */ nullptr, /* Format_Y8 */ nullptr, /* Format_Y16 */ nullptr, + /* Format_P010LE */ qt_convert_P016LE_to_ARGB32, + /* Format_P010BE */ qt_convert_P016BE_to_ARGB32, + /* Format_P016LE */ qt_convert_P016LE_to_ARGB32, + /* Format_P016BE */ qt_convert_P016BE_to_ARGB32, /* Format_Jpeg */ nullptr, // Not needed /* Format_CameraRaw */ nullptr, /* Format_AdobeDng */ nullptr, @@ -1049,6 +1055,7 @@ QImage QVideoFrame::image() const if (!frame.isValid() || !frame.map(QVideoFrame::ReadOnly)) return result; + qDebug() << "converting video frame:" << frame.pixelFormat(); // Formats supported by QImage don't need conversion QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat()); if (imageFormat != QImage::Format_Invalid) { @@ -1151,6 +1158,14 @@ QDebug operator<<(QDebug dbg, QVideoFrame::PixelFormat pf) return dbg << "Format_Y8"; case QVideoFrame::Format_Y16: return dbg << "Format_Y16"; + case QVideoFrame::Format_P010LE: + return dbg << "Format_P010LE"; + case QVideoFrame::Format_P010BE: + return dbg << "Format_P010BE"; + case QVideoFrame::Format_P016LE: + return dbg << "Format_P016LE"; + case QVideoFrame::Format_P016BE: + return dbg << "Format_P016BE"; case QVideoFrame::Format_Jpeg: return dbg << "Format_Jpeg"; case QVideoFrame::Format_AdobeDng: diff --git a/src/multimedia/video/qvideoframe.h b/src/multimedia/video/qvideoframe.h index 369cd17b2..4f0abef40 100644 --- a/src/multimedia/video/qvideoframe.h +++ b/src/multimedia/video/qvideoframe.h @@ -92,6 +92,12 @@ public: Format_Y8, Format_Y16, + Format_P010LE, + Format_P010BE, + + Format_P016LE, + Format_P016BE, + Format_Jpeg, Format_CameraRaw, diff --git a/src/multimedia/video/qvideoframeconversionhelper.cpp b/src/multimedia/video/qvideoframeconversionhelper.cpp index 3a461592f..919e150df 100644 --- a/src/multimedia/video/qvideoframeconversionhelper.cpp +++ b/src/multimedia/video/qvideoframeconversionhelper.cpp @@ -351,4 +351,67 @@ void QT_FASTCALL qt_convert_BGR555_to_ARGB32(const QVideoFrame &frame, uchar *ou } } +static inline void planarYUV420_16bit_to_ARGB32(const uchar *y, int yStride, + const uchar *u, int uStride, + const uchar *v, int vStride, + int uvPixelStride, + quint32 *rgb, + int width, int height) +{ + quint32 *rgb0 = rgb; + quint32 *rgb1 = rgb + width; + + for (int j = 0; j < height; j += 2) { + const uchar *lineY0 = y; + const uchar *lineY1 = y + yStride; + const uchar *lineU = u; + const uchar *lineV = v; + + for (int i = 0; i < width; i += 2) { + EXPAND_UV(*lineU, *lineV); + lineU += uvPixelStride; + lineV += uvPixelStride; + + *rgb0++ = qYUVToARGB32(*lineY0, rv, guv, bu); + lineY0 += 2; + *rgb0++ = qYUVToARGB32(*lineY0, rv, guv, bu); + lineY0 += 2; + *rgb1++ = qYUVToARGB32(*lineY1, rv, guv, bu); + lineY1 += 2; + *rgb1++ = qYUVToARGB32(*lineY1, rv, guv, bu); + lineY1 += 2; + } + + y += yStride << 1; // stride * 2 + u += uStride; + v += vStride; + rgb0 += width; + rgb1 += width; + } +} + +void QT_FASTCALL qt_convert_P016LE_to_ARGB32(const QVideoFrame &frame, uchar *output) +{ + FETCH_INFO_BIPLANAR(frame) + planarYUV420_16bit_to_ARGB32(plane1 + 1, plane1Stride, + plane2 + 1, plane2Stride, + plane2 + 3, plane2Stride, + 4, + reinterpret_cast<quint32*>(output), + width, height); + +} + +void QT_FASTCALL qt_convert_P016BE_to_ARGB32(const QVideoFrame &frame, uchar *output) +{ + FETCH_INFO_BIPLANAR(frame) + planarYUV420_16bit_to_ARGB32(plane1, plane1Stride, + plane2, plane2Stride, + plane2 + 2, plane2Stride, + 4, + reinterpret_cast<quint32*>(output), + width, height); + +} + QT_END_NAMESPACE |