1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #ifndef QVIDEOFRAMECONVERSIONHELPER_P_H |
5 | #define QVIDEOFRAMECONVERSIONHELPER_P_H |
6 | |
7 | // |
8 | // W A R N I N G |
9 | // ------------- |
10 | // |
11 | // This file is not part of the Qt API. It exists purely as an |
12 | // implementation detail. This header file may change from version to |
13 | // version without notice, or even be removed. |
14 | // |
15 | // We mean it. |
16 | // |
17 | |
18 | #include <qvideoframe.h> |
19 | #include <private/qsimd_p.h> |
20 | |
21 | QT_BEGIN_NAMESPACE |
22 | |
23 | // Converts to RGB32 or ARGB32_Premultiplied |
24 | typedef void (QT_FASTCALL *VideoFrameConvertFunc)(const QVideoFrame &frame, uchar *output); |
25 | typedef void(QT_FASTCALL *PixelsCopyFunc)(uint32_t *dst, const uint32_t *src, size_t size, uint32_t mask); |
26 | |
27 | VideoFrameConvertFunc qConverterForFormat(QVideoFrameFormat::PixelFormat format); |
28 | |
29 | void Q_MULTIMEDIA_EXPORT qCopyPixelsWithAlphaMask(uint32_t *dst, |
30 | const uint32_t *src, |
31 | size_t size, |
32 | QVideoFrameFormat::PixelFormat format, |
33 | bool srcAlphaVaries); |
34 | |
35 | void Q_MULTIMEDIA_EXPORT qCopyPixelsWithMask(uint32_t *dst, const uint32_t *src, size_t size, uint32_t mask); |
36 | |
37 | uint32_t Q_MULTIMEDIA_EXPORT qAlphaMask(QVideoFrameFormat::PixelFormat format); |
38 | |
39 | template<int a, int r, int g, int b> |
40 | struct ArgbPixel |
41 | { |
42 | quint32 data; |
43 | inline quint32 convert() const |
44 | { |
45 | #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN |
46 | return (((data >> (8*a)) & 0xff) << 24) |
47 | | (((data >> (8*r)) & 0xff) << 16) |
48 | | (((data >> (8*g)) & 0xff) << 8) |
49 | | ((data >> (8*b)) & 0xff); |
50 | #else |
51 | return (((data >> (32-8*a)) & 0xff) << 24) |
52 | | (((data >> (32-8*r)) & 0xff) << 16) |
53 | | (((data >> (32-8*g)) & 0xff) << 8) |
54 | | ((data >> (32-8*b)) & 0xff); |
55 | #endif |
56 | } |
57 | }; |
58 | |
59 | template<int r, int g, int b> |
60 | struct RgbPixel |
61 | { |
62 | quint32 data; |
63 | inline quint32 convert() const |
64 | { |
65 | #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN |
66 | return 0xff000000 |
67 | | (((data >> (8*r)) & 0xff) << 16) |
68 | | (((data >> (8*g)) & 0xff) << 8) |
69 | | ((data >> (8*b)) & 0xff); |
70 | #else |
71 | return 0xff000000 |
72 | | (((data >> (32-8*r)) & 0xff) << 16) |
73 | | (((data >> (32-8*g)) & 0xff) << 8) |
74 | | ((data >> (32-8*b)) & 0xff); |
75 | #endif |
76 | } |
77 | }; |
78 | |
79 | template<typename Y> |
80 | struct YPixel |
81 | { |
82 | Y data; |
83 | static constexpr uint shift = (sizeof(Y) - 1)*8; |
84 | inline quint32 convert() const |
85 | { |
86 | uint y = (data >> shift) & 0xff; |
87 | return (0xff000000) |
88 | | (y << 16) |
89 | | (y << 8) |
90 | | (y); |
91 | } |
92 | |
93 | }; |
94 | |
95 | |
96 | using ARGB8888 = ArgbPixel<0, 1, 2, 3>; |
97 | using ABGR8888 = ArgbPixel<0, 3, 2, 1>; |
98 | using RGBA8888 = ArgbPixel<3, 0, 1, 2>; |
99 | using BGRA8888 = ArgbPixel<3, 2, 1, 0>; |
100 | using XRGB8888 = RgbPixel<1, 2, 3>; |
101 | using XBGR8888 = RgbPixel<3, 2, 1>; |
102 | using RGBX8888 = RgbPixel<0, 1, 2>; |
103 | using BGRX8888 = RgbPixel<2, 1, 0>; |
104 | |
105 | #define FETCH_INFO_PACKED(frame) \ |
106 | const uchar *src = frame.bits(0); \ |
107 | int stride = frame.bytesPerLine(0); \ |
108 | int width = frame.width(); \ |
109 | int height = frame.height(); |
110 | |
111 | #define FETCH_INFO_BIPLANAR(frame) \ |
112 | const uchar *plane1 = frame.bits(0); \ |
113 | const uchar *plane2 = frame.bits(1); \ |
114 | int plane1Stride = frame.bytesPerLine(0); \ |
115 | int plane2Stride = frame.bytesPerLine(1); \ |
116 | int width = frame.width(); \ |
117 | int height = frame.height(); |
118 | |
119 | #define FETCH_INFO_TRIPLANAR(frame) \ |
120 | const uchar *plane1 = frame.bits(0); \ |
121 | const uchar *plane2 = frame.bits(1); \ |
122 | const uchar *plane3 = frame.bits(2); \ |
123 | int plane1Stride = frame.bytesPerLine(0); \ |
124 | int plane2Stride = frame.bytesPerLine(1); \ |
125 | int plane3Stride = frame.bytesPerLine(2); \ |
126 | int width = frame.width(); \ |
127 | int height = frame.height(); \ |
128 | |
129 | #define MERGE_LOOPS(width, height, stride, bpp) \ |
130 | if (stride == width * bpp) { \ |
131 | width *= height; \ |
132 | height = 1; \ |
133 | stride = 0; \ |
134 | } |
135 | |
136 | #define ALIGN(boundary, ptr, x, length) \ |
137 | for (; ((reinterpret_cast<qintptr>(ptr) & (boundary - 1)) != 0) && x < length; ++x) |
138 | |
139 | QT_END_NAMESPACE |
140 | |
141 | #endif // QVIDEOFRAMECONVERSIONHELPER_P_H |
142 | |
143 | |