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