1 /*
2  * Copyright 2017, 2020-2021, 2023 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef _FSL_VIDEO_COMMON_H_
10 #define _FSL_VIDEO_COMMON_H_
11 
12 #include "fsl_common.h"
13 
14 /*
15  * Change log:
16  *
17  *   1.1.0
18  *     - Add stack function which supports LIFO item management.
19  *
20  *   1.0.5
21  *     - Fix IAR Pa082 warning.
22  *
23  *   1.0.4
24  *     - Add LUT8 definition.
25  *
26  *   1.0.3
27  *     - Add RAW8 definition.
28  *
29  *   1.0.2
30  *     - Fixed MISRA-C 2012 issues.
31  *
32  *   1.0.1
33  *     - Update the VIDEO_DelayMs for bare metal.
34  *
35  *   1.0.0
36  *     - Initial version
37  */
38 
39 /*******************************************************************************
40  * Definitions
41  ******************************************************************************/
42 
43 /*! @brief Pixel format FOURCC. */
44 #define FSL_VIDEO_FOURCC(a, b, c, d) \
45     ((uint32_t)(a) | ((uint32_t)(b) << 8U) | ((uint32_t)(c) << 16U) | ((uint32_t)(d) << 24U))
46 
47 /*! @brief Macro to define resolution. */
48 #define FSL_VIDEO_RESOLUTION(width, height) ((uint32_t)(width) | ((uint32_t)(height) << 16U))
49 
50 #define FSL_VIDEO_EXTRACT_WIDTH(resolution)  ((uint16_t)((resolution)&0xFFFFU))
51 #define FSL_VIDEO_EXTRACT_HEIGHT(resolution) ((uint16_t)((resolution) >> 16U))
52 
53 /*! @brief Pixel format definition. */
54 typedef enum _video_pixel_format
55 {
56     /* RAW */
57     kVIDEO_PixelFormatRAW8 = FSL_VIDEO_FOURCC('G', 'R', 'B', 'G'), /*!< RAW8, GRBG. */
58 
59     /* LUT/palette */
60     kVIDEO_PixelFormatLUT8 = FSL_VIDEO_FOURCC('L', 'U', 'T', '8'), /*!< 8-bit Indexed Color. */
61 
62     /* RGB */
63     kVIDEO_PixelFormatXRGB8888 = FSL_VIDEO_FOURCC('X', 'R', '2', '4'), /*!< 32-bit XRGB8888. */
64     kVIDEO_PixelFormatRGBX8888 = FSL_VIDEO_FOURCC('R', 'X', '2', '4'), /*!< 32-bit RGBX8888. */
65     kVIDEO_PixelFormatXBGR8888 = FSL_VIDEO_FOURCC('X', 'B', '2', '4'), /*!< 32-bit XBGR8888. */
66     kVIDEO_PixelFormatBGRX8888 = FSL_VIDEO_FOURCC('B', 'X', '2', '4'), /*!< 32-bit BGRX8888. */
67 
68     kVIDEO_PixelFormatRGB888 = FSL_VIDEO_FOURCC('R', 'G', '2', '4'), /*!< 24-bit RGB888. */
69     kVIDEO_PixelFormatBGR888 = FSL_VIDEO_FOURCC('B', 'G', '2', '4'), /*!< 24-bit BGR888. */
70 
71     kVIDEO_PixelFormatRGB565 = FSL_VIDEO_FOURCC('R', 'G', '1', '6'), /*!< 16-bit RGB565. */
72     kVIDEO_PixelFormatBGR565 = FSL_VIDEO_FOURCC('B', 'G', '1', '6'), /*!< 16-bit BGR565. */
73 
74     kVIDEO_PixelFormatXRGB1555 = FSL_VIDEO_FOURCC('X', 'R', '1', '5'), /*!< 16-bit XRGB1555. */
75     kVIDEO_PixelFormatRGBX5551 = FSL_VIDEO_FOURCC('R', 'X', '1', '5'), /*!< 16-bit RGBX5551. */
76     kVIDEO_PixelFormatXBGR1555 = FSL_VIDEO_FOURCC('X', 'B', '1', '5'), /*!< 16-bit XBGR1555. */
77     kVIDEO_PixelFormatBGRX5551 = FSL_VIDEO_FOURCC('B', 'X', '1', '5'), /*!< 16-bit BGRX5551. */
78 
79     kVIDEO_PixelFormatXRGB4444 = FSL_VIDEO_FOURCC('X', 'R', '1', '2'), /*!< 16-bit XRGB4444. */
80     kVIDEO_PixelFormatRGBX4444 = FSL_VIDEO_FOURCC('R', 'X', '1', '2'), /*!< 16-bit RGBX4444. */
81     kVIDEO_PixelFormatXBGR4444 = FSL_VIDEO_FOURCC('X', 'B', '1', '2'), /*!< 16-bit XBGR4444. */
82     kVIDEO_PixelFormatBGRX4444 = FSL_VIDEO_FOURCC('B', 'X', '1', '2'), /*!< 16-bit BGRX4444. */
83 
84     /* YUV. */
85     kVIDEO_PixelFormatYUYV = FSL_VIDEO_FOURCC('Y', 'U', 'Y', 'V'), /*!< YUV422, Y-U-Y-V. */
86     kVIDEO_PixelFormatYVYU = FSL_VIDEO_FOURCC('Y', 'V', 'Y', 'U'), /*!< YUV422, Y-V-Y-U. */
87     kVIDEO_PixelFormatUYVY = FSL_VIDEO_FOURCC('U', 'Y', 'V', 'Y'), /*!< YUV422, U-Y-V-Y. */
88     kVIDEO_PixelFormatVYUY = FSL_VIDEO_FOURCC('V', 'Y', 'U', 'Y'), /*!< YUV422, V-Y-U-Y. */
89 
90     kVIDEO_PixelFormatXYUV = FSL_VIDEO_FOURCC('X', 'Y', 'U', 'V'), /*!< YUV444, X-Y-U-V. */
91     kVIDEO_PixelFormatXYVU = FSL_VIDEO_FOURCC('X', 'Y', 'V', 'U'), /*!< YUV444, X-Y-V-U. */
92 } video_pixel_format_t;
93 
94 /*! @brief Resolution definition. */
95 typedef enum _video_resolution
96 {
97     kVIDEO_ResolutionVGA   = FSL_VIDEO_RESOLUTION(640, 480),   /*!< VGA, 640 * 480 */
98     kVIDEO_ResolutionQVGA  = FSL_VIDEO_RESOLUTION(320, 240),   /*!< QVGA, 320 * 240 */
99     kVIDEO_ResolutionQQVGA = FSL_VIDEO_RESOLUTION(160, 120),   /*!< QQVGA, 160 * 120 */
100     kVIDEO_ResolutionCIF   = FSL_VIDEO_RESOLUTION(352, 288),   /*!< CIF, 352 * 288 */
101     kVIDEO_ResolutionQCIF  = FSL_VIDEO_RESOLUTION(176, 144),   /*!< QCIF, 176 * 144 */
102     kVIDEO_ResolutionQQCIF = FSL_VIDEO_RESOLUTION(88, 72),     /*!< QQCIF, 88 * 72 */
103     kVIDEO_Resolution720P  = FSL_VIDEO_RESOLUTION(1280, 720),  /*!< 720P, 1280 * 720 */
104     kVIDEO_Resolution1080P = FSL_VIDEO_RESOLUTION(1920, 1080), /*!< 1080P, 1920 * 1280*/
105     kVIDEO_ResolutionWXGA  = FSL_VIDEO_RESOLUTION(1280, 800),  /*!< WXGA, 1280 * 800 */
106 } video_resolution_t;
107 
108 /*!
109  * @brief Ring buffer structure.
110  *
111  * There is one empty room reserved in the ring buffer, used to distinguish
112  * whether the ring buffer is full or empty. When rear equals front, it is empty;
113  * when rear+1 equals front, it is full.
114  */
115 typedef struct
116 {
117     volatile uint32_t rear;  /*!< Pointer to save the incoming item. */
118     volatile uint32_t front; /*!< Pointer to read out the item. */
119     void *volatile *buf;     /*!< Memory to the ring buffer. */
120     uint32_t size;           /*!< Ring buffer total size. */
121 } video_ringbuf_t;
122 
123 /*!
124  * @brief Memory pool structure.
125  */
126 typedef struct
127 {
128     void *volatile pool;   /*!< Pointer to the pool.         */
129     volatile uint32_t cnt; /*!< Count of memory blocks in the pool. */
130 } video_mempool_t;
131 
132 /*!
133  * @brief Stack structure.
134  */
135 typedef struct
136 {
137     void **buf;            /*!< Pointer to the memory to store the items. */
138     volatile uint32_t top; /*!< Current top stack top. */
139     uint32_t maxCount;     /*!< Maximal count of items can be stored in the stack. */
140 } video_stack_t;
141 
142 /*******************************************************************************
143  * API
144  ******************************************************************************/
145 
146 #if defined(__cplusplus)
147 extern "C" {
148 #endif
149 
150 /*!
151  * @name Common
152  * @{
153  */
154 
155 /*!
156  * @brief Check the pixel format is YUV or not.
157  *
158  * @param format Pixel format.
159  */
160 bool VIDEO_IsYUV(video_pixel_format_t format);
161 
162 /*!
163  * @brief Delay the specific time.
164  *
165  * @param ms How many milli-second to delay.
166  */
167 void VIDEO_DelayMs(uint32_t ms);
168 
169 /*!
170  * @brief Get the pixel size in bits.
171  *
172  * @param pixelFormat The pixel format.
173  * @return Bits per pixel.
174  */
175 uint8_t VIDEO_GetPixelSizeBits(video_pixel_format_t pixelFormat);
176 
177 /* @} */
178 
179 /*!
180  * @name Ring buffer.
181  * @{
182  */
183 
184 /*!
185  * @brief Initializes ring buffer.
186  *
187  * @param ringbuf Pointer to the ring buffer handle.
188  * @param buf Memory to save the items.
189  * @param size Size of the @p buf.
190  * @return Returns @ref kStatus_Success if initialize success, otherwise returns
191  * error code.
192  */
193 status_t VIDEO_RINGBUF_Init(video_ringbuf_t *ringbuf, void **buf, uint32_t size);
194 
195 /*!
196  * @brief Get one item from the ring buffer.
197  *
198  * @param ringbuf Pointer to the ring buffer handle.
199  * @param item Memory to save the item.
200  * @return Returns @ref kStatus_Success if get success, otherwise returns
201  * error code.
202  */
203 status_t VIDEO_RINGBUF_Get(video_ringbuf_t *ringbuf, void **item);
204 
205 /*!
206  * @brief Put one item to the ring buffer.
207  *
208  * @param ringbuf Pointer to the ring buffer handle.
209  * @param item The new item to save.
210  * @return Returns @ref kStatus_Success if put success, otherwise returns
211  * error code.
212  */
213 status_t VIDEO_RINGBUF_Put(video_ringbuf_t *ringbuf, void *item);
214 
215 /*!
216  * @brief Get current count of items in the ring buffer.
217  *
218  * @param ringbuf Pointer to the ring buffer handle.
219  * @return Returns the item count.
220  */
221 uint32_t VIDEO_RINGBUF_GetLength(video_ringbuf_t *ringbuf);
222 
223 /*!
224  * @brief Check whether the ring buffer is empty.
225  *
226  * @param ringbuf Pointer to the ring buffer handle.
227  * @return Returns true if the ring buffer is empty, otherwise returns false.
228  */
229 bool VIDEO_RINGBUF_IsEmpty(video_ringbuf_t *ringbuf);
230 
231 /*!
232  * @brief Check whether the ring buffer is full.
233  *
234  * @param ringbuf Pointer to the ring buffer handle.
235  * @return Returns true if the ring buffer is full, otherwise returns false.
236  */
237 bool VIDEO_RINGBUF_IsFull(video_ringbuf_t *ringbuf);
238 /* @} */
239 
240 /*!
241  * @name Memory Pool
242  *
243  * User can put memory block to the pool, or get memory block from the pool.
244  * There is no count limitation to put memory block in to the pool. The memory
245  * content in the pool might be modified.
246  *
247  * The memory block should be 4-byte aligned, and the dividable by 4-byte.
248  *
249  * @{
250  */
251 
252 /*!
253  * @brief Initializes memory pool.
254  *
255  * Initializes memory pool. Initial memory blocks in the memory pool is optional.
256  * If initial blocks are used, user should specify the initial block size and count.
257  *
258  * @param mempool Pointer to the memory pool handle.
259  * @param initMem Initial memory blocks to saved in the pool.
260  * @param size Every memory block's size (bytes) in the @p initMem.
261  * @param count Number of memory blocks @p initMem.
262  * @return Returns @ref kStatus_Success if initialize success, otherwise returns
263  * error code.
264  */
265 status_t VIDEO_MEMPOOL_Init(video_mempool_t *mempool, void *initMem, uint32_t size, uint32_t count);
266 
267 /*!
268  * @brief Create an empty memory pool.
269  *
270  * @param mempool Pointer to the memory pool handle.
271  */
272 void VIDEO_MEMPOOL_InitEmpty(video_mempool_t *mempool);
273 
274 /*!
275  * @brief Put memory block in the pool.
276  *
277  * @param mempool Pointer to the memory pool handle.
278  * @param mem Pointer to the memory block.
279  */
280 void VIDEO_MEMPOOL_Put(video_mempool_t *mempool, void *mem);
281 
282 /*!
283  * @brief Get memory block in the pool.
284  *
285  * @param mempool Pointer to the memory pool handle.
286  * @return The memory block get from pool. If the pool is empty, returns NULL.
287  */
288 void *VIDEO_MEMPOOL_Get(video_mempool_t *mempool);
289 
290 /*!
291  * @brief How many memory blocks in the pool.
292  *
293  * @param mempool Pointer to the memory pool handle.
294  * @return The memory block count in the pool
295  */
296 uint32_t VIDEO_MEMPOOL_GetCount(video_mempool_t *mempool);
297 
298 /* @} */
299 
300 /*!
301  * @name Stack which supports LIFO item management.
302  * @{
303  */
304 
305 /*!
306  * @brief Initializes stack.
307  *
308  * @param stack Pointer to the stack handle.
309  * @param buf Memory to save the items.
310  * @param size Size of the @p buf.
311  * @return Returns @ref kStatus_Success if initialize success, otherwise returns
312  * error code.
313  */
314 status_t VIDEO_STACK_Init(video_stack_t *stack, void **buf, uint32_t size);
315 
316 /*!
317  * @brief Pop one item from the stack.
318  *
319  * @param stack Pointer to the stack handle.
320  * @param item Memory to save the item.
321  * @return Returns @ref kStatus_Success if get success, returns
322  * kStatus_Fail if the stack is empty.
323  */
324 status_t VIDEO_STACK_Pop(video_stack_t *stack, void **item);
325 
326 /*!
327  * @brief Put one item to the stack.
328  *
329  * @param stack Pointer to the stack handle.
330  * @param item The new item to save.
331  * @return Returns @ref kStatus_Success if put success, returns
332  * kStatus_Fail if the stack is full.
333  */
334 status_t VIDEO_STACK_Push(video_stack_t *stack, void *item);
335 
336 /*!
337  * @brief Get current count of items in the stack.
338  *
339  * @param stack Pointer to the stack handle.
340  * @return Returns the item count.
341  */
VIDEO_STACK_GetCount(video_stack_t * stack)342 static inline uint32_t VIDEO_STACK_GetCount(video_stack_t *stack)
343 {
344     return stack->top;
345 }
346 
347 /*!
348  * @brief Get maxiumal count of items in the stack.
349  *
350  * @param stack Pointer to the stack handle.
351  * @return Returns the maxiumal count of items in the stack.
352  */
VIDEO_STACK_GetMaxCount(video_stack_t * stack)353 static inline uint32_t VIDEO_STACK_GetMaxCount(video_stack_t *stack)
354 {
355     return stack->maxCount;
356 }
357 
358 /* @} */
359 
360 #if defined(__cplusplus)
361 }
362 #endif
363 
364 #endif /* _FSL_VIDEO_COMMON_H_ */
365