1 /**
2 * @file
3 *
4 * @brief Public APIs for Video.
5 */
6
7 /*
8 * Copyright (c) 2019 Linaro Limited.
9 *
10 * SPDX-License-Identifier: Apache-2.0
11 */
12 #ifndef ZEPHYR_INCLUDE_VIDEO_H_
13 #define ZEPHYR_INCLUDE_VIDEO_H_
14
15 /**
16 * @brief Video Interface
17 * @defgroup video_interface Video Interface
18 * @since 2.1
19 * @version 1.0.0
20 * @ingroup io_interfaces
21 * @{
22 */
23
24 #include <zephyr/device.h>
25 #include <stddef.h>
26 #include <zephyr/kernel.h>
27
28 #include <zephyr/types.h>
29
30 #include <zephyr/drivers/video-controls.h>
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36
37 /**
38 * @struct video_format
39 * @brief Video format structure
40 *
41 * Used to configure frame format.
42 */
43 struct video_format {
44 /** FourCC pixel format value (\ref video_pixel_formats) */
45 uint32_t pixelformat;
46 /** frame width in pixels. */
47 uint32_t width;
48 /** frame height in pixels. */
49 uint32_t height;
50 /**
51 * @brief line stride.
52 *
53 * This is the number of bytes that needs to be added to the address in the
54 * first pixel of a row in order to go to the address of the first pixel of
55 * the next row (>=width).
56 */
57 uint32_t pitch;
58 };
59
60
61 /**
62 * @struct video_format_cap
63 * @brief Video format capability
64 *
65 * Used to describe a video endpoint format capability.
66 */
67 struct video_format_cap {
68 /** FourCC pixel format value (\ref video_pixel_formats). */
69 uint32_t pixelformat;
70 /** minimum supported frame width in pixels. */
71 uint32_t width_min;
72 /** maximum supported frame width in pixels. */
73 uint32_t width_max;
74 /** minimum supported frame height in pixels. */
75 uint32_t height_min;
76 /** maximum supported frame height in pixels. */
77 uint32_t height_max;
78 /** width step size in pixels. */
79 uint16_t width_step;
80 /** height step size in pixels. */
81 uint16_t height_step;
82 };
83
84 /**
85 * @struct video_caps
86 * @brief Video format capabilities
87 *
88 * Used to describe video endpoint capabilities.
89 */
90 struct video_caps {
91 /** list of video format capabilities (zero terminated). */
92 const struct video_format_cap *format_caps;
93 /** minimal count of video buffers to enqueue before being able to start
94 * the stream.
95 */
96 uint8_t min_vbuf_count;
97 };
98
99 /**
100 * @struct video_buffer
101 * @brief Video buffer structure
102 *
103 * Represent a video frame.
104 */
105 struct video_buffer {
106 /** pointer to driver specific data. */
107 void *driver_data;
108 /** pointer to the start of the buffer. */
109 uint8_t *buffer;
110 /** size of the buffer in bytes. */
111 uint32_t size;
112 /** number of bytes occupied by the valid data in the buffer. */
113 uint32_t bytesused;
114 /** time reference in milliseconds at which the last data byte was
115 * actually received for input endpoints or to be consumed for output
116 * endpoints.
117 */
118 uint32_t timestamp;
119 };
120
121 /**
122 * @brief video_endpoint_id enum
123 *
124 * Identify the video device endpoint.
125 */
126 enum video_endpoint_id {
127 VIDEO_EP_NONE,
128 VIDEO_EP_ANY,
129 VIDEO_EP_IN,
130 VIDEO_EP_OUT,
131 };
132
133 /**
134 * @brief video_event enum
135 *
136 * Identify video event.
137 */
138 enum video_signal_result {
139 VIDEO_BUF_DONE,
140 VIDEO_BUF_ABORTED,
141 VIDEO_BUF_ERROR,
142 };
143
144 /**
145 * @typedef video_api_set_format_t
146 * @brief Set video format
147 *
148 * See video_set_format() for argument descriptions.
149 */
150 typedef int (*video_api_set_format_t)(const struct device *dev,
151 enum video_endpoint_id ep,
152 struct video_format *fmt);
153
154 /**
155 * @typedef video_api_get_format_t
156 * @brief Get current video format
157 *
158 * See video_get_format() for argument descriptions.
159 */
160 typedef int (*video_api_get_format_t)(const struct device *dev,
161 enum video_endpoint_id ep,
162 struct video_format *fmt);
163
164 /**
165 * @typedef video_api_enqueue_t
166 * @brief Enqueue a buffer in the driver’s incoming queue.
167 *
168 * See video_enqueue() for argument descriptions.
169 */
170 typedef int (*video_api_enqueue_t)(const struct device *dev,
171 enum video_endpoint_id ep,
172 struct video_buffer *buf);
173
174 /**
175 * @typedef video_api_dequeue_t
176 * @brief Dequeue a buffer from the driver’s outgoing queue.
177 *
178 * See video_dequeue() for argument descriptions.
179 */
180 typedef int (*video_api_dequeue_t)(const struct device *dev,
181 enum video_endpoint_id ep,
182 struct video_buffer **buf,
183 k_timeout_t timeout);
184
185 /**
186 * @typedef video_api_flush_t
187 * @brief Flush endpoint buffers, buffer are moved from incoming queue to
188 * outgoing queue.
189 *
190 * See video_flush() for argument descriptions.
191 */
192 typedef int (*video_api_flush_t)(const struct device *dev,
193 enum video_endpoint_id ep,
194 bool cancel);
195
196 /**
197 * @typedef video_api_stream_start_t
198 * @brief Start the capture or output process.
199 *
200 * See video_stream_start() for argument descriptions.
201 */
202 typedef int (*video_api_stream_start_t)(const struct device *dev);
203
204 /**
205 * @typedef video_api_stream_stop_t
206 * @brief Stop the capture or output process.
207 *
208 * See video_stream_stop() for argument descriptions.
209 */
210 typedef int (*video_api_stream_stop_t)(const struct device *dev);
211
212 /**
213 * @typedef video_api_set_ctrl_t
214 * @brief Set a video control value.
215 *
216 * See video_set_ctrl() for argument descriptions.
217 */
218 typedef int (*video_api_set_ctrl_t)(const struct device *dev,
219 unsigned int cid,
220 void *value);
221
222 /**
223 * @typedef video_api_get_ctrl_t
224 * @brief Get a video control value.
225 *
226 * See video_get_ctrl() for argument descriptions.
227 */
228 typedef int (*video_api_get_ctrl_t)(const struct device *dev,
229 unsigned int cid,
230 void *value);
231
232 /**
233 * @typedef video_api_get_caps_t
234 * @brief Get capabilities of a video endpoint.
235 *
236 * See video_get_caps() for argument descriptions.
237 */
238 typedef int (*video_api_get_caps_t)(const struct device *dev,
239 enum video_endpoint_id ep,
240 struct video_caps *caps);
241
242 /**
243 * @typedef video_api_set_signal_t
244 * @brief Register/Unregister poll signal for buffer events.
245 *
246 * See video_set_signal() for argument descriptions.
247 */
248 typedef int (*video_api_set_signal_t)(const struct device *dev,
249 enum video_endpoint_id ep,
250 struct k_poll_signal *signal);
251
252 __subsystem struct video_driver_api {
253 /* mandatory callbacks */
254 video_api_set_format_t set_format;
255 video_api_get_format_t get_format;
256 video_api_stream_start_t stream_start;
257 video_api_stream_stop_t stream_stop;
258 video_api_get_caps_t get_caps;
259 /* optional callbacks */
260 video_api_enqueue_t enqueue;
261 video_api_dequeue_t dequeue;
262 video_api_flush_t flush;
263 video_api_set_ctrl_t set_ctrl;
264 video_api_set_ctrl_t get_ctrl;
265 video_api_set_signal_t set_signal;
266 };
267
268 /**
269 * @brief Set video format.
270 *
271 * Configure video device with a specific format.
272 *
273 * @param dev Pointer to the device structure for the driver instance.
274 * @param ep Endpoint ID.
275 * @param fmt Pointer to a video format struct.
276 *
277 * @retval 0 Is successful.
278 * @retval -EINVAL If parameters are invalid.
279 * @retval -ENOTSUP If format is not supported.
280 * @retval -EIO General input / output error.
281 */
video_set_format(const struct device * dev,enum video_endpoint_id ep,struct video_format * fmt)282 static inline int video_set_format(const struct device *dev,
283 enum video_endpoint_id ep,
284 struct video_format *fmt)
285 {
286 const struct video_driver_api *api =
287 (const struct video_driver_api *)dev->api;
288
289 if (api->set_format == NULL) {
290 return -ENOSYS;
291 }
292
293 return api->set_format(dev, ep, fmt);
294 }
295
296 /**
297 * @brief Get video format.
298 *
299 * Get video device current video format.
300 *
301 * @param dev Pointer to the device structure for the driver instance.
302 * @param ep Endpoint ID.
303 * @param fmt Pointer to video format struct.
304 *
305 * @retval pointer to video format
306 */
video_get_format(const struct device * dev,enum video_endpoint_id ep,struct video_format * fmt)307 static inline int video_get_format(const struct device *dev,
308 enum video_endpoint_id ep,
309 struct video_format *fmt)
310 {
311 const struct video_driver_api *api =
312 (const struct video_driver_api *)dev->api;
313
314 if (api->get_format == NULL) {
315 return -ENOSYS;
316 }
317
318 return api->get_format(dev, ep, fmt);
319 }
320
321 /**
322 * @brief Enqueue a video buffer.
323 *
324 * Enqueue an empty (capturing) or filled (output) video buffer in the driver’s
325 * endpoint incoming queue.
326 *
327 * @param dev Pointer to the device structure for the driver instance.
328 * @param ep Endpoint ID.
329 * @param buf Pointer to the video buffer.
330 *
331 * @retval 0 Is successful.
332 * @retval -EINVAL If parameters are invalid.
333 * @retval -EIO General input / output error.
334 */
video_enqueue(const struct device * dev,enum video_endpoint_id ep,struct video_buffer * buf)335 static inline int video_enqueue(const struct device *dev,
336 enum video_endpoint_id ep,
337 struct video_buffer *buf)
338 {
339 const struct video_driver_api *api =
340 (const struct video_driver_api *)dev->api;
341
342 if (api->enqueue == NULL) {
343 return -ENOSYS;
344 }
345
346 return api->enqueue(dev, ep, buf);
347 }
348
349 /**
350 * @brief Dequeue a video buffer.
351 *
352 * Dequeue a filled (capturing) or displayed (output) buffer from the driver’s
353 * endpoint outgoing queue.
354 *
355 * @param dev Pointer to the device structure for the driver instance.
356 * @param ep Endpoint ID.
357 * @param buf Pointer a video buffer pointer.
358 * @param timeout Timeout
359 *
360 * @retval 0 Is successful.
361 * @retval -EINVAL If parameters are invalid.
362 * @retval -EIO General input / output error.
363 */
video_dequeue(const struct device * dev,enum video_endpoint_id ep,struct video_buffer ** buf,k_timeout_t timeout)364 static inline int video_dequeue(const struct device *dev,
365 enum video_endpoint_id ep,
366 struct video_buffer **buf,
367 k_timeout_t timeout)
368 {
369 const struct video_driver_api *api =
370 (const struct video_driver_api *)dev->api;
371
372 if (api->dequeue == NULL) {
373 return -ENOSYS;
374 }
375
376 return api->dequeue(dev, ep, buf, timeout);
377 }
378
379
380 /**
381 * @brief Flush endpoint buffers.
382 *
383 * A call to flush finishes when all endpoint buffers have been moved from
384 * incoming queue to outgoing queue. Either because canceled or fully processed
385 * through the video function.
386 *
387 * @param dev Pointer to the device structure for the driver instance.
388 * @param ep Endpoint ID.
389 * @param cancel If true, cancel buffer processing instead of waiting for
390 * completion.
391 *
392 * @retval 0 Is successful, -ERRNO code otherwise.
393 */
video_flush(const struct device * dev,enum video_endpoint_id ep,bool cancel)394 static inline int video_flush(const struct device *dev,
395 enum video_endpoint_id ep,
396 bool cancel)
397 {
398 const struct video_driver_api *api =
399 (const struct video_driver_api *)dev->api;
400
401 if (api->flush == NULL) {
402 return -ENOSYS;
403 }
404
405 return api->flush(dev, ep, cancel);
406 }
407
408 /**
409 * @brief Start the video device function.
410 *
411 * video_stream_start is called to enter ‘streaming’ state (capture, output...).
412 * The driver may receive buffers with video_enqueue() before video_stream_start
413 * is called. If driver/device needs a minimum number of buffers before being
414 * able to start streaming, then driver set the min_vbuf_count to the related
415 * endpoint capabilities.
416 *
417 * @retval 0 Is successful.
418 * @retval -EIO General input / output error.
419 */
video_stream_start(const struct device * dev)420 static inline int video_stream_start(const struct device *dev)
421 {
422 const struct video_driver_api *api =
423 (const struct video_driver_api *)dev->api;
424
425 if (api->stream_start == NULL) {
426 return -ENOSYS;
427 }
428
429 return api->stream_start(dev);
430 }
431
432 /**
433 * @brief Stop the video device function.
434 *
435 * On video_stream_stop, driver must stop any transactions or wait until they
436 * finish.
437 *
438 * @retval 0 Is successful.
439 * @retval -EIO General input / output error.
440 */
video_stream_stop(const struct device * dev)441 static inline int video_stream_stop(const struct device *dev)
442 {
443 const struct video_driver_api *api =
444 (const struct video_driver_api *)dev->api;
445 int ret;
446
447 if (api->stream_stop == NULL) {
448 return -ENOSYS;
449 }
450
451 ret = api->stream_stop(dev);
452 video_flush(dev, VIDEO_EP_ANY, true);
453
454 return ret;
455 }
456
457 /**
458 * @brief Get the capabilities of a video endpoint.
459 *
460 * @param dev Pointer to the device structure for the driver instance.
461 * @param ep Endpoint ID.
462 * @param caps Pointer to the video_caps struct to fill.
463 *
464 * @retval 0 Is successful, -ERRNO code otherwise.
465 */
video_get_caps(const struct device * dev,enum video_endpoint_id ep,struct video_caps * caps)466 static inline int video_get_caps(const struct device *dev,
467 enum video_endpoint_id ep,
468 struct video_caps *caps)
469 {
470 const struct video_driver_api *api =
471 (const struct video_driver_api *)dev->api;
472
473 if (api->get_caps == NULL) {
474 return -ENOSYS;
475 }
476
477 return api->get_caps(dev, ep, caps);
478 }
479
480 /**
481 * @brief Set the value of a control.
482 *
483 * This set the value of a video control, value type depends on control ID, and
484 * must be interpreted accordingly.
485 *
486 * @param dev Pointer to the device structure for the driver instance.
487 * @param cid Control ID.
488 * @param value Pointer to the control value.
489 *
490 * @retval 0 Is successful.
491 * @retval -EINVAL If parameters are invalid.
492 * @retval -ENOTSUP If format is not supported.
493 * @retval -EIO General input / output error.
494 */
video_set_ctrl(const struct device * dev,unsigned int cid,void * value)495 static inline int video_set_ctrl(const struct device *dev, unsigned int cid,
496 void *value)
497 {
498 const struct video_driver_api *api =
499 (const struct video_driver_api *)dev->api;
500
501 if (api->set_ctrl == NULL) {
502 return -ENOSYS;
503 }
504
505 return api->set_ctrl(dev, cid, value);
506 }
507
508 /**
509 * @brief Get the current value of a control.
510 *
511 * This retrieve the value of a video control, value type depends on control ID,
512 * and must be interpreted accordingly.
513 *
514 * @param dev Pointer to the device structure for the driver instance.
515 * @param cid Control ID.
516 * @param value Pointer to the control value.
517 *
518 * @retval 0 Is successful.
519 * @retval -EINVAL If parameters are invalid.
520 * @retval -ENOTSUP If format is not supported.
521 * @retval -EIO General input / output error.
522 */
video_get_ctrl(const struct device * dev,unsigned int cid,void * value)523 static inline int video_get_ctrl(const struct device *dev, unsigned int cid,
524 void *value)
525 {
526 const struct video_driver_api *api =
527 (const struct video_driver_api *)dev->api;
528
529 if (api->get_ctrl == NULL) {
530 return -ENOSYS;
531 }
532
533 return api->get_ctrl(dev, cid, value);
534 }
535
536 /**
537 * @brief Register/Unregister k_poll signal for a video endpoint.
538 *
539 * Register a poll signal to the endpoint, which will be signaled on frame
540 * completion (done, aborted, error). Registering a NULL poll signal
541 * unregisters any previously registered signal.
542 *
543 * @param dev Pointer to the device structure for the driver instance.
544 * @param ep Endpoint ID.
545 * @param signal Pointer to k_poll_signal
546 *
547 * @retval 0 Is successful, -ERRNO code otherwise.
548 */
video_set_signal(const struct device * dev,enum video_endpoint_id ep,struct k_poll_signal * signal)549 static inline int video_set_signal(const struct device *dev,
550 enum video_endpoint_id ep,
551 struct k_poll_signal *signal)
552 {
553 const struct video_driver_api *api =
554 (const struct video_driver_api *)dev->api;
555
556 if (api->set_signal == NULL) {
557 return -ENOSYS;
558 }
559
560 return api->set_signal(dev, ep, signal);
561 }
562
563 /**
564 * @brief Allocate aligned video buffer.
565 *
566 * @param size Size of the video buffer (in bytes).
567 * @param align Alignment of the requested memory, must be a power of two.
568 *
569 * @retval pointer to allocated video buffer
570 */
571 struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align);
572
573 /**
574 * @brief Allocate video buffer.
575 *
576 * @param size Size of the video buffer (in bytes).
577 *
578 * @retval pointer to allocated video buffer
579 */
580 struct video_buffer *video_buffer_alloc(size_t size);
581
582 /**
583 * @brief Release a video buffer.
584 *
585 * @param buf Pointer to the video buffer to release.
586 */
587 void video_buffer_release(struct video_buffer *buf);
588
589
590 /* fourcc - four-character-code */
591 #define video_fourcc(a, b, c, d)\
592 ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
593
594
595 /**
596 * @defgroup video_pixel_formats Video pixel formats
597 * @{
598 */
599
600 /**
601 * @name Bayer formats
602 * @{
603 */
604
605 /** BGGR8 pixel format */
606 #define VIDEO_PIX_FMT_BGGR8 video_fourcc('B', 'G', 'G', 'R') /* 8 BGBG.. GRGR.. */
607 /** GBRG8 pixel format */
608 #define VIDEO_PIX_FMT_GBRG8 video_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */
609 /** GRBG8 pixel format */
610 #define VIDEO_PIX_FMT_GRBG8 video_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */
611 /** RGGB8 pixel format */
612 #define VIDEO_PIX_FMT_RGGB8 video_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */
613
614 /**
615 * @}
616 */
617
618 /**
619 * @name RGB formats
620 * @{
621 */
622
623 /** RGB565 pixel format */
624 #define VIDEO_PIX_FMT_RGB565 video_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */
625
626 /** XRGB32 pixel format */
627 #define VIDEO_PIX_FMT_XRGB32 video_fourcc('B', 'X', '2', '4') /* 32 XRGB-8-8-8-8 */
628
629 /**
630 * @}
631 */
632
633 /**
634 * @name YUV formats
635 * @{
636 */
637
638 /** YUYV pixel format */
639 #define VIDEO_PIX_FMT_YUYV video_fourcc('Y', 'U', 'Y', 'V') /* 16 Y0-Cb0 Y1-Cr0 */
640
641 /** XYUV32 pixel format */
642 #define VIDEO_PIX_FMT_XYUV32 video_fourcc('X', 'Y', 'U', 'V') /* 32 XYUV-8-8-8-8 */
643
644 /**
645 *
646 * @}
647 */
648
649 /**
650 * @name JPEG formats
651 * @{
652 */
653
654 /** JPEG pixel format */
655 #define VIDEO_PIX_FMT_JPEG video_fourcc('J', 'P', 'E', 'G') /* 8 JPEG */
656
657 /**
658 * @}
659 */
660
661 /**
662 * @}
663 */
664
665 #ifdef __cplusplus
666 }
667 #endif
668
669 /**
670 * @}
671 */
672
673 #endif /* ZEPHYR_INCLUDE_VIDEO_H_ */
674