1 /*
2  * Copyright 2017, 2020-2021, 2023 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_video_common.h"
10 #if defined(SDK_OS_FREE_RTOS)
11 #include "FreeRTOS.h"
12 #include "task.h"
13 #endif
14 
15 /*******************************************************************************
16  * Code
17  ******************************************************************************/
18 
VIDEO_IsYUV(video_pixel_format_t format)19 bool VIDEO_IsYUV(video_pixel_format_t format)
20 {
21     if ((kVIDEO_PixelFormatYUYV == format) || (kVIDEO_PixelFormatYVYU == format) ||
22         (kVIDEO_PixelFormatUYVY == format) || (kVIDEO_PixelFormatVYUY == format) ||
23         (kVIDEO_PixelFormatXYVU == format) || (kVIDEO_PixelFormatXYUV == format))
24     {
25         return true;
26     }
27     else
28     {
29         return false;
30     }
31 }
32 
VIDEO_DelayMs(uint32_t ms)33 void VIDEO_DelayMs(uint32_t ms)
34 {
35 #if defined(SDK_OS_FREE_RTOS)
36     TickType_t tick;
37 
38     tick = ms * configTICK_RATE_HZ / 1000U;
39 
40     tick = (0U == tick) ? 1U : tick;
41 
42     vTaskDelay(tick);
43 #else
44     while (0U != (ms--))
45     {
46         SDK_DelayAtLeastUs(1000U, SystemCoreClock);
47     }
48 #endif
49 }
50 
VIDEO_GetPixelSizeBits(video_pixel_format_t pixelFormat)51 uint8_t VIDEO_GetPixelSizeBits(video_pixel_format_t pixelFormat)
52 {
53     uint8_t ret;
54 
55     switch (pixelFormat)
56     {
57         case kVIDEO_PixelFormatXRGB8888:
58         case kVIDEO_PixelFormatRGBX8888:
59         case kVIDEO_PixelFormatXBGR8888:
60         case kVIDEO_PixelFormatBGRX8888:
61         case kVIDEO_PixelFormatXYUV:
62         case kVIDEO_PixelFormatXYVU:
63             ret = 32;
64             break;
65 
66         case kVIDEO_PixelFormatRGB888:
67         case kVIDEO_PixelFormatBGR888:
68             ret = 24;
69             break;
70 
71         case kVIDEO_PixelFormatRGB565:
72         case kVIDEO_PixelFormatBGR565:
73         case kVIDEO_PixelFormatXRGB1555:
74         case kVIDEO_PixelFormatRGBX5551:
75         case kVIDEO_PixelFormatXBGR1555:
76         case kVIDEO_PixelFormatBGRX5551:
77         case kVIDEO_PixelFormatXRGB4444:
78         case kVIDEO_PixelFormatRGBX4444:
79         case kVIDEO_PixelFormatXBGR4444:
80         case kVIDEO_PixelFormatBGRX4444:
81         case kVIDEO_PixelFormatYUYV:
82         case kVIDEO_PixelFormatYVYU:
83         case kVIDEO_PixelFormatUYVY:
84         case kVIDEO_PixelFormatVYUY:
85             ret = 16;
86             break;
87 
88         case kVIDEO_PixelFormatRAW8:
89         case kVIDEO_PixelFormatLUT8:
90             ret = 8;
91             break;
92 
93         default:
94             ret = 0;
95             break;
96     }
97 
98     return ret;
99 }
100 
VIDEO_RINGBUF_Init(video_ringbuf_t * ringbuf,void ** buf,uint32_t size)101 status_t VIDEO_RINGBUF_Init(video_ringbuf_t *ringbuf, void **buf, uint32_t size)
102 {
103     assert(ringbuf != NULL);
104 
105     ringbuf->rear  = 0;
106     ringbuf->front = 0;
107     ringbuf->size  = size;
108     ringbuf->buf   = buf;
109 
110     return kStatus_Success;
111 }
112 
VIDEO_RINGBUF_Get(video_ringbuf_t * ringbuf,void ** item)113 status_t VIDEO_RINGBUF_Get(video_ringbuf_t *ringbuf, void **item)
114 {
115     uint32_t front_next;
116 
117     /* To fix IAR Pa082 warning. */
118     uint32_t rear  = ringbuf->rear;
119     uint32_t front = ringbuf->front;
120 
121     if (rear != front)
122     {
123         *item = ringbuf->buf[ringbuf->front];
124 
125         /*
126          * Here don't use ringbuf->front = (ringbuf->front + 1) % ringbuf->size,
127          * because mod operation might be slow.
128          */
129         front_next = (ringbuf->front + 1U);
130 
131         /* Use two steps to make sure ringbuf->front is always a valid value. */
132         ringbuf->front = (front_next == ringbuf->size) ? 0UL : front_next;
133 
134         return kStatus_Success;
135     }
136     else
137     {
138         return kStatus_Fail;
139     }
140 }
141 
VIDEO_RINGBUF_Put(video_ringbuf_t * ringbuf,void * item)142 status_t VIDEO_RINGBUF_Put(video_ringbuf_t *ringbuf, void *item)
143 {
144     /*
145      * Here don't use ringbuf->rear = (ringbuf->rear + 1) % ringbuf->size,
146      * because mod operation might be slow.
147      */
148     uint32_t rear_next = ringbuf->rear + 1U;
149 
150     rear_next = (rear_next == ringbuf->size) ? 0U : rear_next;
151 
152     if (rear_next != ringbuf->front)
153     {
154         ringbuf->buf[ringbuf->rear] = item;
155         ringbuf->rear               = rear_next;
156 
157         return kStatus_Success;
158     }
159     /* No room. */
160     else
161     {
162         return kStatus_Fail;
163     }
164 }
165 
VIDEO_RINGBUF_GetLength(video_ringbuf_t * ringbuf)166 uint32_t VIDEO_RINGBUF_GetLength(video_ringbuf_t *ringbuf)
167 {
168     uint32_t ret;
169 
170     /* To fix IAR Pa082 warning. */
171     uint32_t rear  = ringbuf->rear;
172     uint32_t front = ringbuf->front;
173 
174     ret = (rear + ringbuf->size) - front;
175 
176     if (ret >= ringbuf->size)
177     {
178         ret -= ringbuf->size;
179     }
180 
181     return ret;
182 }
183 
VIDEO_RINGBUF_IsEmpty(video_ringbuf_t * ringbuf)184 bool VIDEO_RINGBUF_IsEmpty(video_ringbuf_t *ringbuf)
185 {
186     /* To fix IAR Pa082 warning. */
187     uint32_t rear  = ringbuf->rear;
188     uint32_t front = ringbuf->front;
189 
190     if (rear == front)
191     {
192         return true;
193     }
194     else
195     {
196         return false;
197     }
198 }
199 
VIDEO_RINGBUF_IsFull(video_ringbuf_t * ringbuf)200 bool VIDEO_RINGBUF_IsFull(video_ringbuf_t *ringbuf)
201 {
202     uint32_t rear  = ringbuf->rear;
203     uint32_t front = ringbuf->front;
204 
205     rear++;
206 
207     if (rear >= ringbuf->size)
208     {
209         rear = 0;
210     }
211 
212     if (rear == front)
213     {
214         return true;
215     }
216     else
217     {
218         return false;
219     }
220 }
221 
VIDEO_MEMPOOL_Init(video_mempool_t * mempool,void * initMem,uint32_t size,uint32_t count)222 status_t VIDEO_MEMPOOL_Init(video_mempool_t *mempool, void *initMem, uint32_t size, uint32_t count)
223 {
224     (void)memset(mempool, 0, sizeof(video_mempool_t));
225 
226     while (0U != (count--))
227     {
228         VIDEO_MEMPOOL_Put(mempool, initMem);
229         initMem = &((uint8_t *)initMem)[size];
230     }
231 
232     return kStatus_Success;
233 }
234 
VIDEO_MEMPOOL_InitEmpty(video_mempool_t * mempool)235 void VIDEO_MEMPOOL_InitEmpty(video_mempool_t *mempool)
236 {
237     mempool->pool = NULL;
238     mempool->cnt  = 0;
239 }
240 
VIDEO_MEMPOOL_Put(video_mempool_t * mempool,void * mem)241 void VIDEO_MEMPOOL_Put(video_mempool_t *mempool, void *mem)
242 {
243     *(void **)mem = mempool->pool;
244     mempool->pool = mem;
245     mempool->cnt++;
246 }
247 
VIDEO_MEMPOOL_Get(video_mempool_t * mempool)248 void *VIDEO_MEMPOOL_Get(video_mempool_t *mempool)
249 {
250     void *mem = mempool->pool;
251 
252     if (NULL != mem)
253     {
254         mempool->cnt--;
255         mempool->pool = *(void **)mem;
256     }
257 
258     return mem;
259 }
260 
VIDEO_MEMPOOL_GetCount(video_mempool_t * mempool)261 uint32_t VIDEO_MEMPOOL_GetCount(video_mempool_t *mempool)
262 {
263     return mempool->cnt;
264 }
265 
VIDEO_STACK_Init(video_stack_t * stack,void ** buf,uint32_t size)266 status_t VIDEO_STACK_Init(video_stack_t *stack, void **buf, uint32_t size)
267 {
268     stack->buf      = buf;
269     stack->maxCount = size;
270     stack->top      = 0U;
271 
272     return kStatus_Success;
273 }
274 
VIDEO_STACK_Pop(video_stack_t * stack,void ** item)275 status_t VIDEO_STACK_Pop(video_stack_t *stack, void **item)
276 {
277     status_t status;
278 
279     if (stack->top > 0U)
280     {
281         *item  = stack->buf[--stack->top];
282         status = kStatus_Success;
283     }
284     else
285     {
286         *item  = NULL;
287         status = kStatus_Fail;
288     }
289 
290     return status;
291 }
292 
VIDEO_STACK_Push(video_stack_t * stack,void * item)293 status_t VIDEO_STACK_Push(video_stack_t *stack, void *item)
294 {
295     status_t status;
296 
297     if (stack->top < (stack->maxCount))
298     {
299         stack->buf[stack->top++] = item;
300         status                   = kStatus_Success;
301     }
302     else
303     {
304         status = kStatus_Fail;
305     }
306 
307     return status;
308 }
309