summaryrefslogtreecommitdiffstats
path: root/src/multimedia/video/qvideoframe.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/multimedia/video/qvideoframe.cpp')
-rw-r--r--src/multimedia/video/qvideoframe.cpp126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/multimedia/video/qvideoframe.cpp b/src/multimedia/video/qvideoframe.cpp
index 4e9e28a4d..f0495577c 100644
--- a/src/multimedia/video/qvideoframe.cpp
+++ b/src/multimedia/video/qvideoframe.cpp
@@ -33,8 +33,10 @@
#include "qvideoframe.h"
+#include "qvideoframe_p.h"
#include "qimagevideobuffer_p.h"
#include "qmemoryvideobuffer_p.h"
+#include "qvideoframeconversionhelper_p.h"
#include <qimage.h>
#include <qpair.h>
@@ -654,6 +656,8 @@ bool QVideoFrame::map(QAbstractVideoBuffer::MapMode mode)
d->data[2] = d->data[1] + (d->bytesPerLine[1] * d->size.height() / 2);
break;
}
+ default:
+ break;
}
d->mappedCount++;
@@ -994,11 +998,133 @@ QImage::Format QVideoFrame::imageFormatFromPixelFormat(PixelFormat format)
case Format_AdobeDng:
return QImage::Format_Invalid;
case Format_User:
+ default:
return QImage::Format_Invalid;
}
return QImage::Format_Invalid;
}
+
+extern void QT_FASTCALL qt_convert_BGRA32_to_ARGB32(const QVideoFrame&, uchar*);
+extern void QT_FASTCALL qt_convert_BGR24_to_ARGB32(const QVideoFrame&, uchar*);
+extern void QT_FASTCALL qt_convert_BGR565_to_ARGB32(const QVideoFrame&, uchar*);
+extern void QT_FASTCALL qt_convert_BGR555_to_ARGB32(const QVideoFrame&, uchar*);
+extern void QT_FASTCALL qt_convert_AYUV444_to_ARGB32(const QVideoFrame&, uchar*);
+extern void QT_FASTCALL qt_convert_YUV444_to_ARGB32(const QVideoFrame&, uchar*);
+extern void QT_FASTCALL qt_convert_YUV420P_to_ARGB32(const QVideoFrame&, uchar*);
+extern void QT_FASTCALL qt_convert_YV12_to_ARGB32(const QVideoFrame&, uchar*);
+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*);
+
+static VideoFrameConvertFunc qConvertFuncs[QVideoFrame::NPixelFormats] = {
+ /* Format_Invalid */ Q_NULLPTR, // Not needed
+ /* Format_ARGB32 */ Q_NULLPTR, // Not needed
+ /* Format_ARGB32_Premultiplied */ Q_NULLPTR, // Not needed
+ /* Format_RGB32 */ Q_NULLPTR, // Not needed
+ /* Format_RGB24 */ Q_NULLPTR, // Not needed
+ /* Format_RGB565 */ Q_NULLPTR, // Not needed
+ /* Format_RGB555 */ Q_NULLPTR, // Not needed
+ /* Format_ARGB8565_Premultiplied */ Q_NULLPTR, // Not needed
+ /* Format_BGRA32 */ qt_convert_BGRA32_to_ARGB32,
+ /* Format_BGRA32_Premultiplied */ qt_convert_BGRA32_to_ARGB32,
+ /* Format_BGR32 */ qt_convert_BGRA32_to_ARGB32,
+ /* Format_BGR24 */ qt_convert_BGR24_to_ARGB32,
+ /* Format_BGR565 */ qt_convert_BGR565_to_ARGB32,
+ /* Format_BGR555 */ qt_convert_BGR555_to_ARGB32,
+ /* Format_BGRA5658_Premultiplied */ Q_NULLPTR,
+ /* Format_AYUV444 */ qt_convert_AYUV444_to_ARGB32,
+ /* Format_AYUV444_Premultiplied */ Q_NULLPTR,
+ /* Format_YUV444 */ qt_convert_YUV444_to_ARGB32,
+ /* Format_YUV420P */ qt_convert_YUV420P_to_ARGB32,
+ /* Format_YV12 */ qt_convert_YV12_to_ARGB32,
+ /* Format_UYVY */ qt_convert_UYVY_to_ARGB32,
+ /* Format_YUYV */ qt_convert_YUYV_to_ARGB32,
+ /* Format_NV12 */ qt_convert_NV12_to_ARGB32,
+ /* Format_NV21 */ qt_convert_NV21_to_ARGB32,
+ /* Format_IMC1 */ Q_NULLPTR,
+ /* Format_IMC2 */ Q_NULLPTR,
+ /* Format_IMC3 */ Q_NULLPTR,
+ /* Format_IMC4 */ Q_NULLPTR,
+ /* Format_Y8 */ Q_NULLPTR,
+ /* Format_Y16 */ Q_NULLPTR,
+ /* Format_Jpeg */ Q_NULLPTR, // Not needed
+ /* Format_CameraRaw */ Q_NULLPTR,
+ /* Format_AdobeDng */ Q_NULLPTR
+};
+
+static void qInitConvertFuncsAsm()
+{
+#ifdef QT_COMPILER_SUPPORTS_SSE2
+ extern void QT_FASTCALL qt_convert_BGRA32_to_ARGB32_sse2(const QVideoFrame&, uchar*);
+ if (qCpuHasFeature(SSE2)){
+ qConvertFuncs[QVideoFrame::Format_BGRA32] = qt_convert_BGRA32_to_ARGB32_sse2;
+ qConvertFuncs[QVideoFrame::Format_BGRA32_Premultiplied] = qt_convert_BGRA32_to_ARGB32_sse2;
+ qConvertFuncs[QVideoFrame::Format_BGR32] = qt_convert_BGRA32_to_ARGB32_sse2;
+ }
+#endif
+#ifdef QT_COMPILER_SUPPORTS_SSSE3
+ extern void QT_FASTCALL qt_convert_BGRA32_to_ARGB32_ssse3(const QVideoFrame&, uchar*);
+ if (qCpuHasFeature(SSSE3)){
+ qConvertFuncs[QVideoFrame::Format_BGRA32] = qt_convert_BGRA32_to_ARGB32_ssse3;
+ qConvertFuncs[QVideoFrame::Format_BGRA32_Premultiplied] = qt_convert_BGRA32_to_ARGB32_ssse3;
+ qConvertFuncs[QVideoFrame::Format_BGR32] = qt_convert_BGRA32_to_ARGB32_ssse3;
+ }
+#endif
+#ifdef QT_COMPILER_SUPPORTS_AVX2
+ extern void QT_FASTCALL qt_convert_BGRA32_to_ARGB32_avx2(const QVideoFrame&, uchar*);
+ if (qCpuHasFeature(AVX2)){
+ qConvertFuncs[QVideoFrame::Format_BGRA32] = qt_convert_BGRA32_to_ARGB32_avx2;
+ qConvertFuncs[QVideoFrame::Format_BGRA32_Premultiplied] = qt_convert_BGRA32_to_ARGB32_avx2;
+ qConvertFuncs[QVideoFrame::Format_BGR32] = qt_convert_BGRA32_to_ARGB32_avx2;
+ }
+#endif
+}
+
+/*!
+ \internal
+*/
+QImage qt_imageFromVideoFrame(const QVideoFrame &f)
+{
+ QVideoFrame &frame = const_cast<QVideoFrame&>(f);
+ QImage result;
+
+ if (!frame.isValid() || !frame.map(QAbstractVideoBuffer::ReadOnly))
+ return result;
+
+ // Formats supported by QImage don't need conversion
+ QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat());
+ if (imageFormat != QImage::Format_Invalid) {
+ result = QImage(frame.bits(), frame.width(), frame.height(), imageFormat).copy();
+ }
+
+ // Load from JPG
+ else if (frame.pixelFormat() == QVideoFrame::Format_Jpeg) {
+ result.loadFromData(frame.bits(), frame.mappedBytes(), "JPG");
+ }
+
+ // Need conversion
+ else {
+ static bool initAsmFuncsDone = false;
+ if (!initAsmFuncsDone) {
+ qInitConvertFuncsAsm();
+ initAsmFuncsDone = true;
+ }
+ VideoFrameConvertFunc convert = qConvertFuncs[frame.pixelFormat()];
+ if (!convert) {
+ qWarning() << Q_FUNC_INFO << ": unsupported pixel format" << frame.pixelFormat();
+ } else {
+ result = QImage(frame.width(), frame.height(), QImage::Format_ARGB32);
+ convert(frame, result.bits());
+ }
+ }
+
+ frame.unmap();
+
+ return result;
+}
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, QVideoFrame::PixelFormat pf)
{