summaryrefslogtreecommitdiffstats
path: root/src/multimedia/video
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2021-03-17 09:31:23 +0100
committerLars Knoll <lars.knoll@qt.io>2021-04-06 08:03:44 +0000
commit981afaafaec6123179587cdaffedca76644205ae (patch)
tree762c9a062395a0b2f223ac41e2262ba86d881829 /src/multimedia/video
parent090b588665caf4fe56c737172ab9b7268fe45867 (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.cpp15
-rw-r--r--src/multimedia/video/qvideoframe.h6
-rw-r--r--src/multimedia/video/qvideoframeconversionhelper.cpp63
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