Ocean
Loading...
Searching...
No Matches
FrameConverterY_VU12.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_CV_FRAME_CONVERTER_Y_VU_12_H
9#define META_OCEAN_CV_FRAME_CONVERTER_Y_VU_12_H
10
11#include "ocean/cv/CV.h"
14
15namespace Ocean
16{
17
18namespace CV
19{
20
21/**
22 * This class provides functions to convert frames with Y_VU12 pixel format.
23 * @ingroup cv
24 */
25class OCEAN_CV_EXPORT FrameConverterY_VU12 : public FrameConverter
26{
27 public:
28
29 /**
30 * Converts a Y_VU12 frame to an 8 bit gray scale frame into a second image buffer.
31 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
32 * @param vuSource The vu source frame buffer, with (2 * width/2 + vuPaddingElements) * height/2 elements, can be invalid, as this parameter is not used
33 * @param target The target frame buffer, with (width + targetPaddingElements) * height elements, must be valid
34 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
35 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
36 * @param flag Determining the type of conversion
37 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
38 * @param vuSourcePaddingElements The number of padding elements at the end of each vu-source row, in (uint8_t) elements, with range [0, infinity), actually this parameter is not used
39 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
40 * @param worker Optional worker object to distribute the computational to several CPU cores
41 */
42 static inline void convertY_VU12ToY8(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
43
44 /**
45 * Converts a Y_VU12 frame to an 24 bit BGR frame into a second image buffer.
46 * <pre>
47 * YVU input value range: [16, 235]x[16, 240]x[16, 240]
48 * BGR output value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
49 * </pre>
50 * Note: In case the given source memory contains y and uv data without any padding elements, 'vuSource' is given by 'uvSource = ySource + width * height'.
51 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
52 * @param vuSource The vu source frame buffer, with (2 * width/2 + vvuPaddingElements) * height/2 elements, must be valid
53 * @param target The target frame buffer, with (3 * width + targetPaddingElements) * height elements, must be valid
54 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
55 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
56 * @param flag Determining the type of conversion
57 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
58 * @param vuSourcePaddingElements The number of padding elements at the end of each vu-source row, in (uint8_t) elements, with range [0, infinity)
59 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
60 * @param worker Optional worker object to distribute the computational to several CPU cores
61 */
62 static inline void convertY_VU12LimitedRangeToBGR24FullRange(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
63
64 /**
65 * Converts a full range Y_VU12 frame to a full range BGRA32 frame into a second image buffer applying a transformation similar to BT.601.
66 * The actual transformation is close to the official BT.601 standard and used on Android for conversion from Y'UV420sp (NV21).<br>
67 * <pre>
68 * YVU input value range: [0, 255]x[0, 255]x[0, 255]
69 * BGRA output value range: [0, 255]x[0, 255]x[0, 255]x[0, 255]
70 * </pre>
71 * Note: In case the given source memory contains y and uv data without any padding elements, 'vuSource' is given by 'uvSource = ySource + width * height'.
72 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
73 * @param vuSource The vu source frame buffer, with (2 * width/2 + vvuPaddingElements) * height/2 elements, must be valid
74 * @param target The target frame buffer, with (3 * width + targetPaddingElements) * height elements, must be valid
75 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
76 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
77 * @param flag Determining the type of conversion
78 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
79 * @param vuSourcePaddingElements The number of padding elements at the end of each vu-source row, in (uint8_t) elements, with range [0, infinity)
80 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
81 * @param alphaValue The value of the alpha channel to be set, with range [0, 255]
82 * @param worker Optional worker object to distribute the computational to several CPU cores
83 */
84 static inline void convertY_VU12FullRangeToBGRA32FullRangeAndroid(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, const uint8_t alphaValue = 0xFF, Worker* worker = nullptr);
85
86 /**
87 * Converts a Y_VU12 frame to an 24 bit RGB frame into a second image buffer.
88 * <pre>
89 * YVU input value range: [16, 235]x[16, 240]x[16, 240]
90 * RGB output value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
91 * </pre>
92 * Note: In case the given source memory contains y and uv data without any padding elements, 'vuSource' is given by 'uvSource = ySource + width * height'.
93 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
94 * @param vuSource The vu source frame buffer, with (2 * width/2 + vvuPaddingElements) * height/2 elements, must be valid
95 * @param target The target frame buffer, with (3 * width + targetPaddingElements) * height elements, must be valid
96 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
97 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
98 * @param flag Determining the type of conversion
99 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
100 * @param vuSourcePaddingElements The number of padding elements at the end of each vu-source row, in (uint8_t) elements, with range [0, infinity)
101 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
102 * @param worker Optional worker object to distribute the computational to several CPU cores
103 */
104 static inline void convertY_VU12LimitedRangeToRGB24FullRange(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
105
106 /**
107 * Converts a Y_VU12 full range frame to an 24 bit RGB frame into a second image buffer.
108 * <pre>
109 * YVU input value range: [0, 255]x[0, 255]x[0, 255]
110 * RGB output value range: [0, 255]x[0, 255]x[0, 255]
111 * </pre>
112 * Note: In case the given source memory contains y and uv data without any padding elements, 'vuSource' is given by 'uvSource = ySource + width * height'.
113 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
114 * @param vuSource The vu source frame buffer, with (2 * width/2 + vvuPaddingElements) * height/2 elements, must be valid
115 * @param target The target frame buffer, with (3 * width + targetPaddingElements) * height elements, must be valid
116 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
117 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
118 * @param flag Determining the type of conversion
119 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
120 * @param vuSourcePaddingElements The number of padding elements at the end of each vu-source row, in (uint8_t) elements, with range [0, infinity)
121 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
122 * @param worker Optional worker object to distribute the computational to several CPU cores
123 */
124 static inline void convertY_VU12FullRangeToRGB24FullRangePrecision6Bit(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
125
126 /**
127 * Converts a Y_VU12 frame to an 24 bit YUV frame into a second image buffer.
128 * Note: In case the given source memory contains y and uv data without any padding elements, 'vuSource' is given by 'uvSource = ySource + width * height'.
129 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
130 * @param vuSource The vu source frame buffer, with (2 * width/2 + vvuPaddingElements) * height/2 elements, must be valid
131 * @param target The target frame buffer, with (3 * width + targetPaddingElements) * height elements, must be valid
132 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
133 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
134 * @param flag Determining the type of conversion
135 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
136 * @param vuSourcePaddingElements The number of padding elements at the end of each vu-source row, in (uint8_t) elements, with range [0, infinity)
137 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
138 * @param worker Optional worker object to distribute the computational to several CPU cores
139 */
140 static inline void convertY_VU12ToYUV24(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
141
142 /**
143 * Converts a Y_VU12 frame to an 24 bit YVU frame into a second image buffer.
144 * Note: In case the given source memory contains y and uv data without any padding elements, 'vuSource' is given by 'uvSource = ySource + width * height'.
145 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
146 * @param vuSource The vu source frame buffer, with (2 * width/2 + vvuPaddingElements) * height/2 elements, must be valid
147 * @param target The target frame buffer, with (3 * width + targetPaddingElements) * height elements, must be valid
148 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
149 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
150 * @param flag Determining the type of conversion
151 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
152 * @param vuSourcePaddingElements The number of padding elements at the end of each vu-source row, in (uint8_t) elements, with range [0, infinity)
153 * @param targetPaddingElements The number of padding elements at the end of each target row, in (uint8_t) elements, with range [0, infinity)
154 * @param worker Optional worker object to distribute the computational to several CPU cores
155 */
156 static inline void convertY_VU12ToYVU24(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
157
158 /**
159 * Converts a Y_VU12 frame to a Y_UV12 frame into a second image buffer.
160 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
161 * @param vuSource The vu source frame buffer, with (2 * width/2 + vuPaddingElements) * height/2 elements, must be valid
162 * @param yTarget The target frame buffer, with (width + yTargetPaddingElements) * height elements, must be valid
163 * @param uvTarget The target frame buffer, with (2 * width/2 + uvTargetPaddingElements) * height/2 elements, must be valid
164 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
165 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
166 * @param flag Determining the type of conversion
167 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
168 * @param vuSourcePaddingElements The number of padding elements at the end of each vu-source row, in (uint8_t) elements, with range [0, infinity)
169 * @param yTargetPaddingElements The number of padding elements at the end of each y-target row, in (uint8_t) elements, with range [0, infinity)
170 * @param uvTargetPaddingElements The number of padding elements at the end of each uv-target row, in (uint8_t) elements, with range [0, infinity)
171 * @param worker Optional worker object to distribute the computational to several CPU cores
172 */
173 static inline void convertY_VU12ToY_UV12(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* yTarget, uint8_t* uvTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uvTargetPaddingElements, Worker* worker = nullptr);
174
175 /**
176 * Converts a Y_VU12 frame to a Y_U_V12 frame into a second image buffer.
177 * @param ySource The y source frame buffer, with (width + yPaddingElements) * height elements, must be valid
178 * @param vuSource The vu source frame buffer, with (2 * width/2 + vuPaddingElements) * height/2 elements, must be valid
179 * @param yTarget The target frame buffer, with (width + yTargetPaddingElements) * height elements, must be valid
180 * @param uTarget The target frame buffer, with (width/2 + uTargetPaddingElements) * height/2 elements, must be valid
181 * @param vTarget The target frame buffer, with (width/2 + vTargetPaddingElements) * height/2 elements, must be valid
182 * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
183 * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
184 * @param flag Determining the type of conversion
185 * @param ySourcePaddingElements The number of padding elements at the end of each y-source row, in (uint8_t) elements, with range [0, infinity)
186 * @param vuSourcePaddingElements The number of padding elements at the end of each vu-source row, in (uint8_t) elements, with range [0, infinity)
187 * @param yTargetPaddingElements The number of padding elements at the end of each y-target row, in (uint8_t) elements, with range [0, infinity)
188 * @param uTargetPaddingElements The number of padding elements at the end of each u-target row, in (uint8_t) elements, with range [0, infinity)
189 * @param vTargetPaddingElements The number of padding elements at the end of each v-target row, in (uint8_t) elements, with range [0, infinity)
190 * @param worker Optional worker object to distribute the computational to several CPU cores
191 */
192 static inline void convertY_VU12ToY_U_V12(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* yTarget, uint8_t* uTarget, uint8_t* vTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uTargetPaddingElements, const unsigned int vTargetPaddingElements, Worker* worker = nullptr);
193
194 protected:
195
196 /**
197 * Converts one row of an image with Y_UV12 pixel format to one row of an image with BGRA32 pixel format.
198 * This function needs one plane with the first channel and another plane/block of 2x2 sub-sampled pixels containing the second and third channels.<br>
199 * The layout of the options parameters is as follows:
200 * <pre>
201 * options[0] uint32_t: sourcePlanePaddingElements
202 * options[1] uint32_t: sourceZippedPaddingElements
203 * options[2] uint32_t: targetZippedPaddingElements
204 * options[3] uint32_t: alphaValue
205 * </pre>
206 * @param sources The pointer to the first and second memory block of the source image, must be valid
207 * @param targets The one pointer to the target image, must be valid
208 * @param multipleRowIndex The index of the multiple-row to be handled, with range [0, height / multipleRowsPerIteration - 1]
209 * @param width The width of the frame in pixel, with range [1, infinity)
210 * @param height The height of the frame in pixel, with range [multipleRowsPerIteration, infinity)
211 * @param conversionFlag The conversion to be applied
212 * @param options The 4 options parameters: 3 padding parameters, 1 alpha value parameter, must be valid
213 */
214 static void convertOneRowY_VU12FullRangeToBGRA32FullRangeAndroidPrecision6Bit(const void** sources, void** targets, const unsigned int multipleRowIndex, const unsigned int width, const unsigned int height, const ConversionFlag conversionFlag, const void* options);
215
216 /**
217 * Converts two rows of an image with Y_UV12 pixel format to two rows of an image with BGRA32 pixel format.
218 * This function needs one plane with the first channel and another plane/block of 2x2 sub-sampled pixels containing the second and third channels.<br>
219 * The layout of the options parameters is as follows:
220 * <pre>
221 * options[0] uint32_t: sourcePlanePaddingElements
222 * options[1] uint32_t: sourceZippedPaddingElements
223 * options[2] uint32_t: targetZippedPaddingElements
224 * options[3] uint32_t: alphaValue
225 * </pre>
226 * @param sources The pointer to the first and second memory block of the source image, must be valid
227 * @param targets The one pointer to the target image, must be valid
228 * @param multipleRowIndex The index of the multiple-row to be handled, with range [0, height / multipleRowsPerIteration - 1]
229 * @param width The width of the frame in pixel, with range [1, infinity)
230 * @param height The height of the frame in pixel, with range [multipleRowsPerIteration, infinity)
231 * @param conversionFlag The conversion to be applied
232 * @param options The 4 options parameters: 3 padding parameters, 1 alpha value parameter, must be valid
233 */
234 static void convertTwoRowsY_VU12FullRangeToBGRA32FullRangeAndroidPrecision6Bit(const void** sources, void** targets, const unsigned int multipleRowIndex, const unsigned int width, const unsigned int height, const ConversionFlag conversionFlag, const void* options);
235};
236
237inline void FrameConverterY_VU12::convertY_VU12ToY8(const uint8_t* ySource, const uint8_t* /* vuSource */, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int /* vuSourcePaddingElements */, const unsigned int targetPaddingElements, Worker* worker)
238{
239 ocean_assert(ySource != nullptr && target != nullptr);
240 ocean_assert(width >= 1u && height >= 1u);
241
242 FrameChannels::transformGeneric<uint8_t, 1u>(ySource, target, width, height, flag, ySourcePaddingElements, targetPaddingElements, worker);
243}
244
245inline void FrameConverterY_VU12::convertY_VU12LimitedRangeToBGR24FullRange(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
246{
247 ocean_assert(ySource != nullptr && vuSource != nullptr && target != nullptr);
248
249 ocean_assert(width >= 2u && width % 2u == 0u);
250 ocean_assert(height >= 2u && height % 2u == 0u);
251
252 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
253 {
254 return;
255 }
256
257 // YVU input value range: [16, 235]x[16, 240]x[16, 240]
258 // BGR output value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
259
260 // precise color space conversion:
261 // | B | | 1.1639404296875 0.0 2.0179443359375 -276.919921875 | | Y |
262 // | G | = | 1.1639404296875 -0.81298828125 -0.3909912109375 135.486328125 | * | V |
263 // | R | | 1.1639404296875 1.595947265625 0.0 -222.904296875 | | U |
264 // | 1 |
265
266#if 1
267
268 // Approximation with 6 bit precision:
269 // | B | | 75 0 128 | | Y - 16 |
270 // 64 * | G | = | 75 -52 -25 | * | V - 128 |
271 // | R | | 75 102 0 | | U - 128 |
272
273 const int options[3 + 12] =
274 {
275 // padding parameters
276 int(ySourcePaddingElements), int(vuSourcePaddingElements), int(targetPaddingElements),
277
278 // multiplication parameters
279 75, 75, 75, 0, -52, 102, 128, -25, 0,
280
281 // bias/translation parameters
282 16, 128, 128
283 };
284
285 const void* sources[2] =
286 {
287 ySource,
288 vuSource
289 };
290
292
293#else
294
295 // Approximation with 10 bit precision:
296 // | B | | 1192 0 2066 -277 | | Y |
297 // | G | = | 1192 -833 -400 135 | * | V |
298 // | R | | 1192 1634 0 -223 | | U |
299 // | 1 |
300
301 const int options[3 + 12] =
302 {
303 // padding parameters
304 int(ySourcePaddingElements), int(vuSourcePaddingElements), int(targetPaddingElements),
305
306 // multiplication parameters (with denominator 1024)
307 1192, 1192, 1192, 0, -833, 1634, 2066, -400, 0,
308
309 // bias/translation parameters (with denominator 1)
310 -277, 135, -223
311 };
312
313 const void* sources[2] =
314 {
315 ySource,
316 vuSource
317 };
318
319 FrameConverter::convertArbitraryPixelFormat(sources, (void**)(&target), width, height, flag, 1u, FrameConverter::convertOneRow1PlaneAnd2ChannelsZippedDownsampled2x2ToZipped3Channels8BitPerChannelPrecision10Bit, options, worker);
320
321#endif
322
323}
324
325inline void FrameConverterY_VU12::convertY_VU12FullRangeToBGRA32FullRangeAndroid(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, const uint8_t alphaValue, Worker* worker)
326{
327 ocean_assert(ySource != nullptr && vuSource != nullptr && target != nullptr);
328
329 ocean_assert(width >= 2u && width % 2u == 0u);
330 ocean_assert(height >= 2u && height % 2u == 0u);
331
332 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
333 {
334 return;
335 }
336
337 const int options[3 + 1] =
338 {
339 // padding parameters
340 int(ySourcePaddingElements), int(vuSourcePaddingElements), int(targetPaddingElements),
341
342 // alpha value
343 int(alphaValue)
344 };
345
346 const void* sources[2] =
347 {
348 ySource,
349 vuSource
350 };
351
352#if 1
354#else
356#endif
357
358}
359
360inline void FrameConverterY_VU12::convertY_VU12LimitedRangeToRGB24FullRange(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
361{
362 ocean_assert(ySource != nullptr && vuSource != nullptr && target != nullptr);
363
364 ocean_assert(width >= 2u && width % 2u == 0u);
365 ocean_assert(height >= 2u && height % 2u == 0u);
366
367 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
368 {
369 return;
370 }
371
372 // YVU input value range: [16, 235]x[16, 240]x[16, 240]
373 // RGB output value range: [ 0, 255]x[ 0, 255]x[ 0, 255]
374
375 // precise color space conversion:
376 // | R | | 1.1639404296875 1.595947265625 0.0 -222.904296875 | | Y |
377 // | G | = | 1.1639404296875 -0.81298828125 -0.3909912109375 135.486328125 | * | V |
378 // | B | | 1.1639404296875 0.0 2.0179443359375 -276.919921875 | | U |
379 // | 1 |
380
381#if 1
382
383 // Approximation with 6 bit precision:
384 // | R | | 75 102 0 | | Y - 16 |
385 // 64 * | G | = | 75 -52 -25 | * | V - 128 |
386 // | B | | 75 0 128 | | U - 128 |
387
388 const int options[3 + 12] =
389 {
390 // padding parameters
391 int(ySourcePaddingElements), int(vuSourcePaddingElements), int(targetPaddingElements),
392
393 // multiplication parameters
394 75, 75, 75, 102, -52, 0, 0, -25, 128,
395
396 // bias/translation parameters
397 16, 128, 128
398 };
399
400 const void* sources[2] =
401 {
402 ySource,
403 vuSource
404 };
405
407
408#else
409
410 // Approximation with 10 bit precision:
411 // | R | | 1192 1634 0 -223 | | Y |
412 // | G | = | 1192 -833 -400 135 | * | U |
413 // | B | | 1192 0 2066 -277 | | V |
414 // | 1 |
415
416 const int options[3 + 12] =
417 {
418 // padding parameters
419 int(ySourcePaddingElements), int(vuSourcePaddingElements), int(targetPaddingElements),
420
421 // multiplication parameters (with denominator 1024)
422 1192, 1192, 1192, 1634, -833, 0, 0, -400, 2066,
423
424 // bias/translation parameters (with denominator 1)
425 -223, 135, -277
426 };
427
428 const void* sources[2] =
429 {
430 ySource,
431 vuSource
432 };
433
434 FrameConverter::convertArbitraryPixelFormat(sources, (void**)(&target), width, height, flag, 1u, FrameConverter::convertOneRow1PlaneAnd2ChannelsZippedDownsampled2x2ToZipped3Channels8BitPerChannelPrecision10Bit, options, worker);
435
436#endif
437
438}
439
440inline void FrameConverterY_VU12::convertY_VU12FullRangeToRGB24FullRangePrecision6Bit(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
441{
442 ocean_assert(ySource != nullptr && vuSource != nullptr && target != nullptr);
443
444 ocean_assert(width >= 2u && width % 2u == 0u);
445 ocean_assert(height >= 2u && height % 2u == 0u);
446
447 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
448 {
449 return;
450 }
451
452 /*
453 * | R | | 1.0 1.402 0.0 1.402 -179.456 | | Y |
454 * | G | = | 1.0 -0.71414 -0.34414 -0.71414 135.45984 | * | V |
455 * | B | | 1.0 0.0 1.772 0.0 -226.816 | | U |
456 * | 1 |
457 *
458 * Approximation with 6 bit precision:
459 * | R | | 64 90 0 | | Y |
460 * 64 * | G | = | 64 -46 -22 | * | V - 128 |
461 * | B | | 64 0 113 | | U - 128 |
462 */
463
464 const int options[3 + 12] =
465 {
466 // padding parameters
467 int(ySourcePaddingElements), int(vuSourcePaddingElements), int(targetPaddingElements),
468
469 // multiplication parameters
470 64, 64, 64, 90, -46, 0, 0, -22, 113,
471
472 // bias/translation parameters
473 0, 128, 128
474 };
475
476 const void* sources[2] =
477 {
478 ySource,
479 vuSource
480 };
481
483}
484
485inline void FrameConverterY_VU12::convertY_VU12ToYUV24(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
486{
487 ocean_assert(ySource != nullptr && vuSource != nullptr && target != nullptr);
488
489 ocean_assert(width >= 2u && width % 2u == 0u);
490 ocean_assert(height >= 2u && height % 2u == 0u);
491
492 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
493 {
494 return;
495 }
496
497 const unsigned int options[3] = {ySourcePaddingElements, vuSourcePaddingElements, targetPaddingElements};
498
499 const void* sources[2] =
500 {
501 ySource,
502 vuSource
503 };
504
505 FrameConverter::convertArbitraryPixelFormat(sources, (void**)(&target), width, height, flag, 2u, FrameConverter::mapTwoRows_1Plane1ChannelAnd1Plane2ChannelsDownsampled2x2_To_1Plane3Channels_8BitPerChannel<0u, 2u, 1u>, options, worker);
506}
507
508inline void FrameConverterY_VU12::convertY_VU12ToYVU24(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
509{
510 ocean_assert(ySource != nullptr && vuSource != nullptr && target != nullptr);
511
512 ocean_assert(width >= 2u && width % 2u == 0u);
513 ocean_assert(height >= 2u && height % 2u == 0u);
514
515 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
516 {
517 return;
518 }
519
520 const unsigned int options[3] = {ySourcePaddingElements, vuSourcePaddingElements, targetPaddingElements};
521
522 const void* sources[2] =
523 {
524 ySource,
525 vuSource
526 };
527
528 FrameConverter::convertArbitraryPixelFormat(sources, (void**)(&target), width, height, flag, 2u, FrameConverter::mapTwoRows_1Plane1ChannelAnd1Plane2ChannelsDownsampled2x2_To_1Plane3Channels_8BitPerChannel<0u, 1u, 2u>, options, worker);
529}
530
531inline void FrameConverterY_VU12::convertY_VU12ToY_UV12(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* yTarget, uint8_t* uvTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uvTargetPaddingElements, Worker* worker)
532{
533 ocean_assert(ySource != nullptr && vuSource != nullptr && yTarget != nullptr && uvTarget != nullptr);
534
535 ocean_assert(width >= 2u && width % 2u == 0u);
536 ocean_assert(height >= 2u && height % 2u == 0u);
537
538 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
539 {
540 return;
541 }
542
543 // first, we handle the y-plane
544 FrameChannels::transformGeneric<uint8_t, 1u>(ySource, yTarget, width, height, flag, ySourcePaddingElements, yTargetPaddingElements, worker);
545
546 // now we handle the vu-plane
547
548 FrameChannels::reverseChannelOrder<uint8_t, 2u>(vuSource, uvTarget, width / 2u, height / 2u, flag, vuSourcePaddingElements, uvTargetPaddingElements, worker);
549}
550
551inline void FrameConverterY_VU12::convertY_VU12ToY_U_V12(const uint8_t* ySource, const uint8_t* vuSource, uint8_t* yTarget, uint8_t* uTarget, uint8_t* vTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uTargetPaddingElements, const unsigned int vTargetPaddingElements, Worker* worker)
552{
553 ocean_assert(ySource != nullptr && vuSource != nullptr && yTarget != nullptr && uTarget != nullptr && vTarget != nullptr);
554
555 ocean_assert(width >= 2u && width % 2u == 0u);
556 ocean_assert(height >= 2u && height % 2u == 0u);
557
558 if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
559 {
560 return;
561 }
562
563 // first, we handle the y-plane
564 FrameChannels::transformGeneric<uint8_t, 1u>(ySource, yTarget, width, height, flag, ySourcePaddingElements, yTargetPaddingElements, worker);
565
566 // now we handle the vu-plane
567
568 const unsigned int options[3] = {vuSourcePaddingElements, vTargetPaddingElements, uTargetPaddingElements};
569
570 void* targets[2] =
571 {
572 vTarget,
573 uTarget
574 };
575
576 FrameConverter::convertArbitraryPixelFormat((const void**)(&vuSource), targets, width / 2u, height / 2u, flag, 1u, FrameConverter::mapOneRow_1Plane2Channels_To_2Planes1Channel_8BitPerChannel, options, worker);
577}
578
579}
580
581}
582
583#endif // META_OCEAN_CV_FRAME_CONVERTER_Y_VU_12_H
This is the base class for all frame converter classes.
Definition FrameConverter.h:32
ConversionFlag
Definition of individual conversion flags.
Definition FrameConverter.h:39
static void convertTwoRows_1Plane1ChannelAnd1Plane2ChannelsDownsampled2x2_To_1Plane3Channels_8BitPerChannel_Precision6Bit(const void **sources, void **targets, const unsigned int multipleRowIndex, const unsigned int width, const unsigned int height, const ConversionFlag conversionFlag, const void *options)
Converts two rows of an image with e.g., a Y_UV12 pixel format to two rows of an image with e....
static void mapOneRow_1Plane2Channels_To_2Planes1Channel_8BitPerChannel(const void **sources, void **targets, const unsigned int multipleRowIndex, const unsigned int width, const unsigned int height, const ConversionFlag conversionFlag, const void *options)
Maps one row of a 1-plane, 2-channel image to two planes with 1 channels.
static void convertArbitraryPixelFormat(const void **sources, void **targets, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int multipleRowsPerIteration, const MultipleRowsConversionFunction multipleRowsConversionFunction, const void *options, Worker *worker)
Converts a frame with arbitrary pixel format (e.g., Y_UV12, Y_VU12, YUYV16, ...) to a frame with arbi...
Definition FrameConverter.h:3248
This class provides functions to convert frames with Y_VU12 pixel format.
Definition FrameConverterY_VU12.h:26
static void convertY_VU12LimitedRangeToBGR24FullRange(const uint8_t *ySource, const uint8_t *vuSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a Y_VU12 frame to an 24 bit BGR frame into a second image buffer.
Definition FrameConverterY_VU12.h:245
static void convertY_VU12FullRangeToBGRA32FullRangeAndroid(const uint8_t *ySource, const uint8_t *vuSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, const uint8_t alphaValue=0xFF, Worker *worker=nullptr)
Converts a full range Y_VU12 frame to a full range BGRA32 frame into a second image buffer applying a...
Definition FrameConverterY_VU12.h:325
static void convertTwoRowsY_VU12FullRangeToBGRA32FullRangeAndroidPrecision6Bit(const void **sources, void **targets, const unsigned int multipleRowIndex, const unsigned int width, const unsigned int height, const ConversionFlag conversionFlag, const void *options)
Converts two rows of an image with Y_UV12 pixel format to two rows of an image with BGRA32 pixel form...
static void convertY_VU12LimitedRangeToRGB24FullRange(const uint8_t *ySource, const uint8_t *vuSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a Y_VU12 frame to an 24 bit RGB frame into a second image buffer.
Definition FrameConverterY_VU12.h:360
static void convertY_VU12ToY8(const uint8_t *ySource, const uint8_t *vuSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a Y_VU12 frame to an 8 bit gray scale frame into a second image buffer.
Definition FrameConverterY_VU12.h:237
static void convertY_VU12ToY_UV12(const uint8_t *ySource, const uint8_t *vuSource, uint8_t *yTarget, uint8_t *uvTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uvTargetPaddingElements, Worker *worker=nullptr)
Converts a Y_VU12 frame to a Y_UV12 frame into a second image buffer.
Definition FrameConverterY_VU12.h:531
static void convertY_VU12ToY_U_V12(const uint8_t *ySource, const uint8_t *vuSource, uint8_t *yTarget, uint8_t *uTarget, uint8_t *vTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int uTargetPaddingElements, const unsigned int vTargetPaddingElements, Worker *worker=nullptr)
Converts a Y_VU12 frame to a Y_U_V12 frame into a second image buffer.
Definition FrameConverterY_VU12.h:551
static void convertY_VU12ToYVU24(const uint8_t *ySource, const uint8_t *vuSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a Y_VU12 frame to an 24 bit YVU frame into a second image buffer.
Definition FrameConverterY_VU12.h:508
static void convertOneRowY_VU12FullRangeToBGRA32FullRangeAndroidPrecision6Bit(const void **sources, void **targets, const unsigned int multipleRowIndex, const unsigned int width, const unsigned int height, const ConversionFlag conversionFlag, const void *options)
Converts one row of an image with Y_UV12 pixel format to one row of an image with BGRA32 pixel format...
static void convertY_VU12ToYUV24(const uint8_t *ySource, const uint8_t *vuSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a Y_VU12 frame to an 24 bit YUV frame into a second image buffer.
Definition FrameConverterY_VU12.h:485
static void convertY_VU12FullRangeToRGB24FullRangePrecision6Bit(const uint8_t *ySource, const uint8_t *vuSource, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int ySourcePaddingElements, const unsigned int vuSourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a Y_VU12 full range frame to an 24 bit RGB frame into a second image buffer.
Definition FrameConverterY_VU12.h:440
This class implements a worker able to distribute function calls over different threads.
Definition Worker.h:33
The namespace covering the entire Ocean framework.
Definition Accessor.h:15