diff options
Diffstat (limited to 'src/multimedia/video/qvideoframeconversionhelper.cpp')
-rw-r--r-- | src/multimedia/video/qvideoframeconversionhelper.cpp | 141 |
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 |