summaryrefslogtreecommitdiffstats
path: root/src/multimedia/video/qvideoframeconversionhelper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/multimedia/video/qvideoframeconversionhelper.cpp')
-rw-r--r--src/multimedia/video/qvideoframeconversionhelper.cpp141
1 files changed, 88 insertions, 53 deletions
diff --git a/src/multimedia/video/qvideoframeconversionhelper.cpp b/src/multimedia/video/qvideoframeconversionhelper.cpp
index b49fc539f..1b570b74f 100644
--- a/src/multimedia/video/qvideoframeconversionhelper.cpp
+++ b/src/multimedia/video/qvideoframeconversionhelper.cpp
@@ -1,45 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qvideoframeconversionhelper_p.h"
#include "qrgb.h"
+#include <mutex>
+
QT_BEGIN_NAMESPACE
#define CLAMP(n) (n > 255 ? 255 : (n < 0 ? 0 : n))
@@ -67,6 +33,7 @@ static inline void planarYUV420_to_ARGB32(const uchar *y, int yStride,
quint32 *rgb,
int width, int height)
{
+ height &= ~1;
quint32 *rgb0 = rgb;
quint32 *rgb1 = rgb + width;
@@ -415,6 +382,7 @@ static inline void planarYUV420_16bit_to_ARGB32(const uchar *y, int yStride,
quint32 *rgb,
int width, int height)
{
+ height &= ~1;
quint32 *rgb0 = rgb;
quint32 *rgb1 = rgb + width;
@@ -494,6 +462,14 @@ static void QT_FASTCALL qt_convert_Y_to_ARGB32(const QVideoFrame &frame, uchar *
MERGE_LOOPS(width, height, stride, 1)
}
+template<typename Pixel>
+static void QT_FASTCALL qt_copy_pixels_with_mask(Pixel *dst, const Pixel *src, size_t size,
+ Pixel mask)
+{
+ for (size_t x = 0; x < size; ++x)
+ dst[x] = src[x] | mask;
+}
+
static VideoFrameConvertFunc qConvertFuncs[QVideoFrameFormat::NPixelFormats] = {
/* Format_Invalid */ nullptr, // Not needed
/* Format_ARGB8888 */ qt_convert_to_ARGB32<ARGB8888>,
@@ -526,24 +502,32 @@ static VideoFrameConvertFunc qConvertFuncs[QVideoFrameFormat::NPixelFormats] = {
/* Format_Jpeg */ nullptr, // Not needed
};
-static void qInitConvertFuncsAsm()
+static PixelsCopyFunc qPixelsCopyFunc = qt_copy_pixels_with_mask<uint32_t>;
+
+static std::once_flag InitFuncsAsmFlag;
+
+static void qInitFuncsAsm()
{
#ifdef QT_COMPILER_SUPPORTS_SSE2
extern void QT_FASTCALL qt_convert_ARGB8888_to_ARGB32_sse2(const QVideoFrame &frame, uchar *output);
extern void QT_FASTCALL qt_convert_ABGR8888_to_ARGB32_sse2(const QVideoFrame &frame, uchar *output);
extern void QT_FASTCALL qt_convert_RGBA8888_to_ARGB32_sse2(const QVideoFrame &frame, uchar *output);
extern void QT_FASTCALL qt_convert_BGRA8888_to_ARGB32_sse2(const QVideoFrame &frame, uchar *output);
+ extern void QT_FASTCALL qt_copy_pixels_with_mask_sse2(uint32_t * dst, const uint32_t *src, size_t size, uint32_t mask);
+
if (qCpuHasFeature(SSE2)){
qConvertFuncs[QVideoFrameFormat::Format_ARGB8888] = qt_convert_ARGB8888_to_ARGB32_sse2;
qConvertFuncs[QVideoFrameFormat::Format_ARGB8888_Premultiplied] = qt_convert_ARGB8888_to_ARGB32_sse2;
qConvertFuncs[QVideoFrameFormat::Format_XRGB8888] = qt_convert_ARGB8888_to_ARGB32_sse2;
qConvertFuncs[QVideoFrameFormat::Format_BGRA8888] = qt_convert_BGRA8888_to_ARGB32_sse2;
qConvertFuncs[QVideoFrameFormat::Format_BGRA8888_Premultiplied] = qt_convert_BGRA8888_to_ARGB32_sse2;
- qConvertFuncs[QVideoFrameFormat::Format_XBGR8888] = qt_convert_BGRA8888_to_ARGB32_sse2;
+ qConvertFuncs[QVideoFrameFormat::Format_BGRX8888] = qt_convert_BGRA8888_to_ARGB32_sse2;
qConvertFuncs[QVideoFrameFormat::Format_ABGR8888] = qt_convert_ABGR8888_to_ARGB32_sse2;
qConvertFuncs[QVideoFrameFormat::Format_XBGR8888] = qt_convert_ABGR8888_to_ARGB32_sse2;
- qConvertFuncs[QVideoFrameFormat::Format_BGRA8888] = qt_convert_BGRA8888_to_ARGB32_sse2;
- qConvertFuncs[QVideoFrameFormat::Format_BGRA8888] = qt_convert_BGRA8888_to_ARGB32_sse2;
+ qConvertFuncs[QVideoFrameFormat::Format_RGBA8888] = qt_convert_RGBA8888_to_ARGB32_sse2;
+ qConvertFuncs[QVideoFrameFormat::Format_RGBX8888] = qt_convert_RGBA8888_to_ARGB32_sse2;
+
+ qPixelsCopyFunc = qt_copy_pixels_with_mask_sse2;
}
#endif
#ifdef QT_COMPILER_SUPPORTS_SSSE3
@@ -557,11 +541,11 @@ static void qInitConvertFuncsAsm()
qConvertFuncs[QVideoFrameFormat::Format_XRGB8888] = qt_convert_ARGB8888_to_ARGB32_ssse3;
qConvertFuncs[QVideoFrameFormat::Format_BGRA8888] = qt_convert_BGRA8888_to_ARGB32_ssse3;
qConvertFuncs[QVideoFrameFormat::Format_BGRA8888_Premultiplied] = qt_convert_BGRA8888_to_ARGB32_ssse3;
- qConvertFuncs[QVideoFrameFormat::Format_XBGR8888] = qt_convert_BGRA8888_to_ARGB32_ssse3;
+ qConvertFuncs[QVideoFrameFormat::Format_BGRX8888] = qt_convert_BGRA8888_to_ARGB32_ssse3;
qConvertFuncs[QVideoFrameFormat::Format_ABGR8888] = qt_convert_ABGR8888_to_ARGB32_ssse3;
qConvertFuncs[QVideoFrameFormat::Format_XBGR8888] = qt_convert_ABGR8888_to_ARGB32_ssse3;
- qConvertFuncs[QVideoFrameFormat::Format_BGRA8888] = qt_convert_BGRA8888_to_ARGB32_ssse3;
- qConvertFuncs[QVideoFrameFormat::Format_BGRA8888] = qt_convert_BGRA8888_to_ARGB32_ssse3;
+ qConvertFuncs[QVideoFrameFormat::Format_RGBA8888] = qt_convert_RGBA8888_to_ARGB32_ssse3;
+ qConvertFuncs[QVideoFrameFormat::Format_RGBX8888] = qt_convert_RGBA8888_to_ARGB32_ssse3;
}
#endif
#ifdef QT_COMPILER_SUPPORTS_AVX2
@@ -569,31 +553,82 @@ static void qInitConvertFuncsAsm()
extern void QT_FASTCALL qt_convert_ABGR8888_to_ARGB32_avx2(const QVideoFrame &frame, uchar *output);
extern void QT_FASTCALL qt_convert_RGBA8888_to_ARGB32_avx2(const QVideoFrame &frame, uchar *output);
extern void QT_FASTCALL qt_convert_BGRA8888_to_ARGB32_avx2(const QVideoFrame &frame, uchar *output);
+ extern void QT_FASTCALL qt_copy_pixels_with_mask_avx2(uint32_t * dst, const uint32_t *src, size_t size, uint32_t mask);
if (qCpuHasFeature(AVX2)){
qConvertFuncs[QVideoFrameFormat::Format_ARGB8888] = qt_convert_ARGB8888_to_ARGB32_avx2;
qConvertFuncs[QVideoFrameFormat::Format_ARGB8888_Premultiplied] = qt_convert_ARGB8888_to_ARGB32_avx2;
qConvertFuncs[QVideoFrameFormat::Format_XRGB8888] = qt_convert_ARGB8888_to_ARGB32_avx2;
qConvertFuncs[QVideoFrameFormat::Format_BGRA8888] = qt_convert_BGRA8888_to_ARGB32_avx2;
qConvertFuncs[QVideoFrameFormat::Format_BGRA8888_Premultiplied] = qt_convert_BGRA8888_to_ARGB32_avx2;
- qConvertFuncs[QVideoFrameFormat::Format_XBGR8888] = qt_convert_BGRA8888_to_ARGB32_avx2;
+ qConvertFuncs[QVideoFrameFormat::Format_BGRX8888] = qt_convert_BGRA8888_to_ARGB32_avx2;
qConvertFuncs[QVideoFrameFormat::Format_ABGR8888] = qt_convert_ABGR8888_to_ARGB32_avx2;
qConvertFuncs[QVideoFrameFormat::Format_XBGR8888] = qt_convert_ABGR8888_to_ARGB32_avx2;
- qConvertFuncs[QVideoFrameFormat::Format_BGRA8888] = qt_convert_BGRA8888_to_ARGB32_avx2;
- qConvertFuncs[QVideoFrameFormat::Format_BGRA8888] = qt_convert_BGRA8888_to_ARGB32_avx2;
+ qConvertFuncs[QVideoFrameFormat::Format_RGBA8888] = qt_convert_RGBA8888_to_ARGB32_avx2;
+ qConvertFuncs[QVideoFrameFormat::Format_RGBX8888] = qt_convert_RGBA8888_to_ARGB32_avx2;
+
+ qPixelsCopyFunc = qt_copy_pixels_with_mask_avx2;
}
#endif
}
VideoFrameConvertFunc qConverterForFormat(QVideoFrameFormat::PixelFormat format)
{
- static bool initAsmFuncsDone = false;
- if (!initAsmFuncsDone) {
- qInitConvertFuncsAsm();
- initAsmFuncsDone = true;
- }
+ std::call_once(InitFuncsAsmFlag, &qInitFuncsAsm);
+
VideoFrameConvertFunc convert = qConvertFuncs[format];
return convert;
}
+void Q_MULTIMEDIA_EXPORT qCopyPixelsWithAlphaMask(uint32_t *dst,
+ const uint32_t *src,
+ size_t pixCount,
+ QVideoFrameFormat::PixelFormat format,
+ bool srcAlphaVaries)
+{
+ if (pixCount == 0)
+ return;
+
+ const auto mask = qAlphaMask(format);
+
+ if (srcAlphaVaries || (src[0] & mask) != mask)
+ qCopyPixelsWithMask(dst, src, pixCount, mask);
+ else
+ memcpy(dst, src, pixCount * 4);
+}
+
+void qCopyPixelsWithMask(uint32_t *dst, const uint32_t *src, size_t size, uint32_t mask)
+{
+ std::call_once(InitFuncsAsmFlag, &qInitFuncsAsm);
+
+ qPixelsCopyFunc(dst, src, size, mask);
+}
+
+uint32_t qAlphaMask(QVideoFrameFormat::PixelFormat format)
+{
+ switch (format) {
+ case QVideoFrameFormat::Format_ARGB8888:
+ case QVideoFrameFormat::Format_ARGB8888_Premultiplied:
+ case QVideoFrameFormat::Format_XRGB8888:
+ case QVideoFrameFormat::Format_ABGR8888:
+ case QVideoFrameFormat::Format_XBGR8888:
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ return 0xff;
+#else
+ return 0xff000000;
+#endif
+ case QVideoFrameFormat::Format_BGRA8888:
+ case QVideoFrameFormat::Format_BGRA8888_Premultiplied:
+ case QVideoFrameFormat::Format_BGRX8888:
+ case QVideoFrameFormat::Format_RGBA8888:
+ case QVideoFrameFormat::Format_RGBX8888:
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ return 0xff000000;
+#else
+ return 0xff;
+#endif
+ default:
+ return 0;
+ }
+}
QT_END_NAMESPACE