Ocean
FrameConverterYVU24.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_YVU_24_H
9 #define META_OCEAN_CV_FRAME_CONVERTER_YVU_24_H
10 
11 #include "ocean/cv/CV.h"
12 #include "ocean/cv/FrameChannels.h"
14 
15 #include "ocean/base/Worker.h"
16 
17 namespace Ocean
18 {
19 
20 namespace CV
21 {
22 
23 /**
24  * This class provides functions to convert frames with YVU24 pixel format to other pixel formats.
25  * See Frame::PixelFormat for details of the YVU24 pixel format.<br>
26  * @ingroup cv
27  */
28 class OCEAN_CV_EXPORT FrameConverterYVU24 : public FrameConverter
29 {
30  public:
31 
32  /**
33  * Converts a YVU 24 bit frame to a BGR 24 bit frame using the conversion.
34  * @param source The source frame buffer, must be valid
35  * @param target The target frame buffer, must be valid
36  * @param width The width of the frame in pixel, with range [1, infinity)
37  * @param height The height of the frame in pixel, with range [1, infinity)
38  * @param flag Determining the type of conversion
39  * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
40  * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
41  * @param worker Optional worker object to distribute the computation
42  */
43  static inline void convertYVU24ToBGR24(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
44 
45  /**
46  * Converts a YVU 24 bit frame to a RGB 24 bit frame using the conversion.
47  * @param source The source frame buffer, must be valid
48  * @param target The target frame buffer, must be valid
49  * @param width The width of the frame in pixel, with range [1, infinity)
50  * @param height The height of the frame in pixel, with range [1, infinity)
51  * @param flag Determining the type of conversion
52  * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
53  * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
54  * @param worker Optional worker object to distribute the computation
55  */
56  static inline void convertYVU24ToRGB24(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
57 
58  /**
59  * Converts a YVU 24 bit frame to a Y 8 bit frame using the conversion.
60  * @param source The source frame buffer, must be valid
61  * @param target The target frame buffer, must be valid
62  * @param width The width of the frame in pixel, with range [1, infinity)
63  * @param height The height of the frame in pixel, with range [1, infinity)
64  * @param flag Determining the type of conversion
65  * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
66  * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
67  * @param worker Optional worker object to distribute the computation
68  */
69  static inline void convertYVU24ToY8(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
70 
71  /**
72  * Converts a YVU 24 bit frame to a YUV 24 bit frame using the conversion.
73  * @param source The source frame buffer, must be valid
74  * @param target The target frame buffer, must be valid
75  * @param width The width of the frame in pixel, with range [1, infinity)
76  * @param height The height of the frame in pixel, with range [1, infinity)
77  * @param flag Determining the type of conversion
78  * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
79  * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
80  * @param worker Optional worker object to distribute the computation
81  */
82  static inline void convertYVU24ToYUV24(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
83 
84  /**
85  * Converts a YVU 24 bit frame to a YVU 24 bit frame using the conversion.
86  * @param source The source frame buffer, must be valid
87  * @param target The target frame buffer, must be valid
88  * @param width The width of the frame in pixel, with range [1, infinity)
89  * @param height The height of the frame in pixel, with range [1, infinity)
90  * @param flag Determining the type of conversion
91  * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
92  * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
93  * @param worker Optional worker object to distribute the computation
94  */
95  static inline void convertYVU24ToYVU24(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
96 
97  /**
98  * Converts a YVU 24 bit frame to a Y_V_U 12 bit frame using the conversion.
99  * @param source The source frame buffer, with (width * 3 + targetPaddingElements) * height elements, must be valid
100  * @param yTarget The y target frame buffer, with (width + yPaddingElements) * height elements, must be valid
101  * @param vTarget The v target frame buffer, with (2 * width/2 + vPaddingElements) * height/2 elements, must be valid
102  * @param uTarget The u target frame buffer, with (2 * width/2 + uPaddingElements) * height/2 elements, must be valid
103  * @param width The width of the frame in pixel, with range [2, infinity), must be a multiple of 2
104  * @param height The height of the frame in pixel, with range [2, infinity), must be a multiple of 2
105  * @param flag Determining the type of conversion
106  * @param sourcePaddingElements The number of padding elements at the end of each source row, in (uint8_t) elements, with range [0, infinity)
107  * @param yTargetPaddingElements The number of padding elements at the end of each y-target row, in (uint8_t) elements, with range [0, infinity)
108  * @param vTargetPaddingElements The number of padding elements at the end of each v-target row, in (uint8_t) elements, with range [0, infinity)
109  * @param uTargetPaddingElements The number of padding elements at the end of each u-target row, in (uint8_t) elements, with range [0, infinity)
110  * @param worker Optional worker object to distribute the computation
111  */
112  static inline void convertYVU24ToY_V_U12(const uint8_t* source, uint8_t* yTarget, uint8_t* vTarget, uint8_t* uTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int vTargetPaddingElements, const unsigned int uTargetPaddingElements, Worker* worker = nullptr);
113 
114  /**
115  * Converts one YVU 24 bit pixel to a RGB 24 bit pixel.
116  * @param y Y pixel value to convert
117  * @param v V pixel value to convert
118  * @param u U pixel value to convert
119  * @param r Resulting r pixel value
120  * @param g Resulting g pixel value
121  * @param b Resulting b pixel value
122  */
123  static inline void convertYVU24ToRGB24Pixel(const uint8_t y, const uint8_t v, const uint8_t u, uint8_t& r, uint8_t& g, uint8_t& b);
124 };
125 
126 inline void FrameConverterYVU24::convertYVU24ToBGR24(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
127 {
128  ocean_assert(source != nullptr && target != nullptr);
129  ocean_assert(width >= 1u && height >= 1u);
130 
131  const unsigned int sourceStrideElements = width * 3u + sourcePaddingElements;
132  const unsigned int targetStrideElements = width * 3u + targetPaddingElements;
133 
134  // precise color space conversion:
135  // | B | | 1.1639404296875 0.0 2.0179443359375 -276.919921875 | | Y |
136  // | G | = | 1.1639404296875 -0.81298828125 -0.3909912109375 135.486328125 | * | V |
137  // | R | | 1.1639404296875 1.595947265625 0.0 -222.904296875 | | U |
138  // | 1 |
139 
140  // approximation:
141  // | B | | 1192 0 2066 -277 | | Y |
142  // | G | = | 1192 -833 -400 135 | * | U |
143  // | R | | 1192 1634 0 -223 | | V |
144  // | 1 |
145 
146  const int parameters[12] = {1192, 1192, 1192, 0, -833, 1634, 2066, -400, 0, -277, 135, -223};
147 
148  const bool areContinuous = sourcePaddingElements == 0u && targetPaddingElements == 0u;
149 
150  FrameConverter::convertGenericPixelFormat(source, target, width, height, sourceStrideElements, targetStrideElements, flag, CV::FrameChannels::convertRow3ChannelsTo3Channels8BitPerChannel10BitPrecision, CV::FrameChannels::reverseRowPixelOrderInPlace<uint8_t, 3u>, areContinuous, parameters, worker);
151 }
152 
153 inline void FrameConverterYVU24::convertYVU24ToRGB24(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
154 {
155  ocean_assert(source != nullptr && target != nullptr);
156  ocean_assert(width >= 1u && height >= 1u);
157 
158  const unsigned int sourceStrideElements = width * 3u + sourcePaddingElements;
159  const unsigned int targetStrideElements = width * 3u + targetPaddingElements;
160 
161  // precise color space conversion:
162  // | R | | 1.1639404296875 1.595947265625 0.0 -222.904296875 | | Y |
163  // | G | = | 1.1639404296875 -0.81298828125 -0.3909912109375 135.486328125 | * | V |
164  // | B | | 1.1639404296875 0.0 2.0179443359375 -276.919921875 | | U |
165  // | 1 |
166 
167  // approximation:
168  // | R | | 1192 1634 0 -223 | | Y |
169  // | G | = | 1192 -833 -400 135 | * | U |
170  // | B | | 1192 0 2066 -277 | | V |
171  // | 1 |
172 
173  const int parameters[12] = {1192, 1192, 1192, 1634, -833, 0, 0, -400, 2066, -223, 135, -277};
174 
175  const bool areContinuous = sourcePaddingElements == 0u && targetPaddingElements == 0u;
176 
177  FrameConverter::convertGenericPixelFormat(source, target, width, height, sourceStrideElements, targetStrideElements, flag, CV::FrameChannels::convertRow3ChannelsTo3Channels8BitPerChannel10BitPrecision, CV::FrameChannels::reverseRowPixelOrderInPlace<uint8_t, 3u>, areContinuous, parameters, worker);
178 }
179 
180 inline void FrameConverterYVU24::convertYVU24ToY8(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
181 {
182  ocean_assert(source != nullptr && target != nullptr);
183  ocean_assert(width >= 1u && height >= 1u);
184 
185  // source frame Y V U
186  // 0 1 2
187  // target frame Y
188  // pattern 0
189  constexpr unsigned int shufflePattern = 0x0u;
190 
191  FrameChannels::shuffleChannels<uint8_t, 3u, 1u, shufflePattern>(source, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
192 }
193 
194 inline void FrameConverterYVU24::convertYVU24ToYUV24(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
195 {
196  ocean_assert(source != nullptr && target != nullptr);
197  ocean_assert(width >= 1u && height >= 1u);
198 
199  // source frame Y V U
200  // 0 1 2
201  // target frame Y U V
202  // pattern 0 2 1
203  constexpr unsigned int shufflePattern = 0x120u;
204 
205  FrameChannels::shuffleChannels<uint8_t, 3u, 3u, shufflePattern>(source, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
206 }
207 
208 inline void FrameConverterYVU24::convertYVU24ToYVU24(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
209 {
210  ocean_assert(source != nullptr && target != nullptr);
211  ocean_assert(width >= 1u && height >= 1u);
212 
213  FrameChannels::transformGeneric<uint8_t, 3u>(source, target, width, height, flag, sourcePaddingElements, targetPaddingElements, worker);
214 }
215 
216 inline void FrameConverterYVU24::convertYVU24ToY_V_U12(const uint8_t* source, uint8_t* yTarget, uint8_t* vTarget, uint8_t* uTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int vTargetPaddingElements, const unsigned int uTargetPaddingElements, Worker* worker)
217 {
218  ocean_assert(source != nullptr && yTarget != nullptr && vTarget != nullptr && uTarget != nullptr);
219 
220  ocean_assert(width >= 2u && width % 2u == 0u);
221  ocean_assert(height >= 2u && height % 2u == 0u);
222 
223  if (width < 2u || height < 2u || width % 2u != 0u || height % 2u != 0u)
224  {
225  return;
226  }
227 
228  const unsigned int options[4] = {sourcePaddingElements, yTargetPaddingElements, vTargetPaddingElements, uTargetPaddingElements};
229 
230  void* targets[3] =
231  {
232  yTarget,
233  vTarget,
234  uTarget
235  };
236 
237  FrameConverter::convertArbitraryPixelFormat((const void**)(&source), targets, width, height, flag, 2u, FrameConverter::mapTwoRows_1Plane3Channels_To_1Plane1ChannelAnd2Planes1ChannelDownsampled2x2_8BitPerChannel<0u, 1u, 2u>, options, worker);
238 }
239 
240 inline void FrameConverterYVU24::convertYVU24ToRGB24Pixel(const uint8_t y, const uint8_t v, const uint8_t u, uint8_t& r, uint8_t& g, uint8_t& b)
241 {
242  const int y_ = (y - 16) * 298 + 128;
243  const int v_ = v - 128;
244  const int u_ = u - 128;
245 
246  r = (uint8_t)(minmax(0, (y_ + 409 * v_) >> 8, 255));
247  g = (uint8_t)(minmax(0, (y_ - 100 * u_ - 208 * v_) >> 8, 255));
248  b = (uint8_t)(minmax(0, (y_ + 516 * u_) >> 8, 255));
249 }
250 
251 }
252 
253 }
254 
255 #endif // META_OCEAN_CV_FRAME_CONVERTER_YVU_24_H
static void convertRow3ChannelsTo3Channels8BitPerChannel10BitPrecision(const uint8_t *source, uint8_t *target, const size_t size, const void *parameters)
Converts a row of pixels with 3 channels to pixels with 3 channels by a linear combination of the thr...
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 convertGenericPixelFormat(const TSource *source, TTarget *target, const unsigned int width, const unsigned int height, const unsigned int sourceStrideElements, const unsigned int targetStrideElements, const ConversionFlag flag, const RowConversionFunction< TSource, TTarget > rowConversionFunction, const RowReversePixelOrderInPlaceFunction< TTarget > targetReversePixelOrderInPlaceFunction, const bool areContinuous, const void *options, Worker *worker)
Converts a frame with generic pixel format (e.g., RGBA32, BGR24, YUV24, ...) to a frame with generic ...
Definition: FrameConverter.h:3160
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:3183
This class provides functions to convert frames with YVU24 pixel format to other pixel formats.
Definition: FrameConverterYVU24.h:29
static void convertYVU24ToRGB24Pixel(const uint8_t y, const uint8_t v, const uint8_t u, uint8_t &r, uint8_t &g, uint8_t &b)
Converts one YVU 24 bit pixel to a RGB 24 bit pixel.
Definition: FrameConverterYVU24.h:240
static void convertYVU24ToBGR24(const uint8_t *source, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a YVU 24 bit frame to a BGR 24 bit frame using the conversion.
Definition: FrameConverterYVU24.h:126
static void convertYVU24ToY_V_U12(const uint8_t *source, uint8_t *yTarget, uint8_t *vTarget, uint8_t *uTarget, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int yTargetPaddingElements, const unsigned int vTargetPaddingElements, const unsigned int uTargetPaddingElements, Worker *worker=nullptr)
Converts a YVU 24 bit frame to a Y_V_U 12 bit frame using the conversion.
Definition: FrameConverterYVU24.h:216
static void convertYVU24ToRGB24(const uint8_t *source, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a YVU 24 bit frame to a RGB 24 bit frame using the conversion.
Definition: FrameConverterYVU24.h:153
static void convertYVU24ToYVU24(const uint8_t *source, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a YVU 24 bit frame to a YVU 24 bit frame using the conversion.
Definition: FrameConverterYVU24.h:208
static void convertYVU24ToY8(const uint8_t *source, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a YVU 24 bit frame to a Y 8 bit frame using the conversion.
Definition: FrameConverterYVU24.h:180
static void convertYVU24ToYUV24(const uint8_t *source, uint8_t *target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Converts a YVU 24 bit frame to a YUV 24 bit frame using the conversion.
Definition: FrameConverterYVU24.h:194
This class implements a worker able to distribute function calls over different threads.
Definition: Worker.h:33
T minmax(const T &lowerBoundary, const T &value, const T &upperBoundary)
This function fits a given parameter into a specified value range.
Definition: base/Utilities.h:903
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15