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.1.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 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 /*
35 * Flag used by @ref video_caps structure to indicate endpoint operates on
36 * buffers the size of the video frame
37 */
38 #define LINE_COUNT_HEIGHT (-1)
39
40 /**
41 * @struct video_format
42 * @brief Video format structure
43 *
44 * Used to configure frame format.
45 */
46 struct video_format {
47 /** FourCC pixel format value (\ref video_pixel_formats) */
48 uint32_t pixelformat;
49 /** frame width in pixels. */
50 uint32_t width;
51 /** frame height in pixels. */
52 uint32_t height;
53 /**
54 * @brief line stride.
55 *
56 * This is the number of bytes that needs to be added to the address in the
57 * first pixel of a row in order to go to the address of the first pixel of
58 * the next row (>=width).
59 */
60 uint32_t pitch;
61 };
62
63 /**
64 * @struct video_format_cap
65 * @brief Video format capability
66 *
67 * Used to describe a video endpoint format capability.
68 */
69 struct video_format_cap {
70 /** FourCC pixel format value (\ref video_pixel_formats). */
71 uint32_t pixelformat;
72 /** minimum supported frame width in pixels. */
73 uint32_t width_min;
74 /** maximum supported frame width in pixels. */
75 uint32_t width_max;
76 /** minimum supported frame height in pixels. */
77 uint32_t height_min;
78 /** maximum supported frame height in pixels. */
79 uint32_t height_max;
80 /** width step size in pixels. */
81 uint16_t width_step;
82 /** height step size in pixels. */
83 uint16_t height_step;
84 };
85
86 /**
87 * @struct video_caps
88 * @brief Video format capabilities
89 *
90 * Used to describe video endpoint capabilities.
91 */
92 struct video_caps {
93 /** list of video format capabilities (zero terminated). */
94 const struct video_format_cap *format_caps;
95 /** minimal count of video buffers to enqueue before being able to start
96 * the stream.
97 */
98 uint8_t min_vbuf_count;
99 /** Denotes minimum line count of a video buffer that this endpoint
100 * can fill or process. Each line is expected to consume the number
101 * of bytes the selected video format's pitch uses, so the video
102 * buffer must be at least `pitch` * `min_line_count` bytes.
103 * `LINE_COUNT_HEIGHT` is a special value, indicating the endpoint
104 * only supports video buffers with at least enough bytes to store
105 * a full video frame
106 */
107 int16_t min_line_count;
108 /**
109 * Denotes maximum line count of a video buffer that this endpoint
110 * can fill or process. Similar constraints to `min_line_count`,
111 * but `LINE_COUNT_HEIGHT` indicates that the endpoint will never
112 * fill or process more than a full video frame in one video buffer.
113 */
114 int16_t max_line_count;
115 };
116
117 /**
118 * @struct video_buffer
119 * @brief Video buffer structure
120 *
121 * Represent a video frame.
122 */
123 struct video_buffer {
124 /** pointer to driver specific data. */
125 void *driver_data;
126 /** pointer to the start of the buffer. */
127 uint8_t *buffer;
128 /** size of the buffer in bytes. */
129 uint32_t size;
130 /** number of bytes occupied by the valid data in the buffer. */
131 uint32_t bytesused;
132 /** time reference in milliseconds at which the last data byte was
133 * actually received for input endpoints or to be consumed for output
134 * endpoints.
135 */
136 uint32_t timestamp;
137 /** Line offset within frame this buffer represents, from the
138 * beginning of the frame. This offset is given in pixels,
139 * so `line_offset` * `pitch` provides offset from the start of
140 * the frame in bytes.
141 */
142 uint16_t line_offset;
143 };
144
145 /**
146 * @brief video_frmival_type enum
147 *
148 * Supported frame interval type of a video device.
149 */
150 enum video_frmival_type {
151 /** discrete frame interval type */
152 VIDEO_FRMIVAL_TYPE_DISCRETE = 1,
153 /** stepwise frame interval type */
154 VIDEO_FRMIVAL_TYPE_STEPWISE = 2,
155 };
156
157 /**
158 * @struct video_frmival
159 * @brief Video frame interval structure
160 *
161 * Used to describe a video frame interval.
162 */
163 struct video_frmival {
164 /** numerator of the frame interval */
165 uint32_t numerator;
166 /** denominator of the frame interval */
167 uint32_t denominator;
168 };
169
170 /**
171 * @struct video_frmival_stepwise
172 * @brief Video frame interval stepwise structure
173 *
174 * Used to describe the video frame interval stepwise type.
175 */
176 struct video_frmival_stepwise {
177 /** minimum frame interval in seconds */
178 struct video_frmival min;
179 /** maximum frame interval in seconds */
180 struct video_frmival max;
181 /** frame interval step size in seconds */
182 struct video_frmival step;
183 };
184
185 /**
186 * @struct video_frmival_enum
187 * @brief Video frame interval enumeration structure
188 *
189 * Used to describe the supported video frame intervals of a given video format.
190 */
191 struct video_frmival_enum {
192 /** frame interval index during enumeration */
193 uint32_t index;
194 /** video format for which the query is made */
195 const struct video_format *format;
196 /** frame interval type the device supports */
197 enum video_frmival_type type;
198 /** the actual frame interval */
199 union {
200 struct video_frmival discrete;
201 struct video_frmival_stepwise stepwise;
202 };
203 };
204
205 /**
206 * @brief video_endpoint_id enum
207 *
208 * Identify the video device endpoint.
209 */
210 enum video_endpoint_id {
211 /** Targets some part of the video device not bound to an endpoint */
212 VIDEO_EP_NONE = -1,
213 /** Targets all input or output endpoints of the device */
214 VIDEO_EP_ALL = -2,
215 /** Targets all input endpoints of the device: those consuming data */
216 VIDEO_EP_IN = -3,
217 /** Targets all output endpoints of the device: those producing data */
218 VIDEO_EP_OUT = -4,
219 };
220
221 /**
222 * @brief video_event enum
223 *
224 * Identify video event.
225 */
226 enum video_signal_result {
227 VIDEO_BUF_DONE,
228 VIDEO_BUF_ABORTED,
229 VIDEO_BUF_ERROR,
230 };
231
232 /**
233 * @typedef video_api_set_format_t
234 * @brief Set video format
235 *
236 * See video_set_format() for argument descriptions.
237 */
238 typedef int (*video_api_set_format_t)(const struct device *dev, enum video_endpoint_id ep,
239 struct video_format *fmt);
240
241 /**
242 * @typedef video_api_get_format_t
243 * @brief Get current video format
244 *
245 * See video_get_format() for argument descriptions.
246 */
247 typedef int (*video_api_get_format_t)(const struct device *dev, enum video_endpoint_id ep,
248 struct video_format *fmt);
249
250 /**
251 * @typedef video_api_set_frmival_t
252 * @brief Set video frame interval
253 *
254 * See video_set_frmival() for argument descriptions.
255 */
256 typedef int (*video_api_set_frmival_t)(const struct device *dev, enum video_endpoint_id ep,
257 struct video_frmival *frmival);
258
259 /**
260 * @typedef video_api_get_frmival_t
261 * @brief Get current video frame interval
262 *
263 * See video_get_frmival() for argument descriptions.
264 */
265 typedef int (*video_api_get_frmival_t)(const struct device *dev, enum video_endpoint_id ep,
266 struct video_frmival *frmival);
267
268 /**
269 * @typedef video_api_enum_frmival_t
270 * @brief List all supported frame intervals of a given format
271 *
272 * See video_enum_frmival() for argument descriptions.
273 */
274 typedef int (*video_api_enum_frmival_t)(const struct device *dev, enum video_endpoint_id ep,
275 struct video_frmival_enum *fie);
276
277 /**
278 * @typedef video_api_enqueue_t
279 * @brief Enqueue a buffer in the driver’s incoming queue.
280 *
281 * See video_enqueue() for argument descriptions.
282 */
283 typedef int (*video_api_enqueue_t)(const struct device *dev, enum video_endpoint_id ep,
284 struct video_buffer *buf);
285
286 /**
287 * @typedef video_api_dequeue_t
288 * @brief Dequeue a buffer from the driver’s outgoing queue.
289 *
290 * See video_dequeue() for argument descriptions.
291 */
292 typedef int (*video_api_dequeue_t)(const struct device *dev, enum video_endpoint_id ep,
293 struct video_buffer **buf, k_timeout_t timeout);
294
295 /**
296 * @typedef video_api_flush_t
297 * @brief Flush endpoint buffers, buffer are moved from incoming queue to
298 * outgoing queue.
299 *
300 * See video_flush() for argument descriptions.
301 */
302 typedef int (*video_api_flush_t)(const struct device *dev, enum video_endpoint_id ep, bool cancel);
303
304 /**
305 * @typedef video_api_set_stream_t
306 * @brief Start or stop streaming on the video device.
307 *
308 * Start (enable == true) or stop (enable == false) streaming on the video device.
309 *
310 * @param dev Pointer to the device structure.
311 * @param enable If true, start streaming, otherwise stop streaming.
312 *
313 * @retval 0 on success, otherwise a negative errno code.
314 */
315 typedef int (*video_api_set_stream_t)(const struct device *dev, bool enable);
316
317 /**
318 * @typedef video_api_set_ctrl_t
319 * @brief Set a video control value.
320 *
321 * See video_set_ctrl() for argument descriptions.
322 */
323 typedef int (*video_api_set_ctrl_t)(const struct device *dev, unsigned int cid, void *value);
324
325 /**
326 * @typedef video_api_get_ctrl_t
327 * @brief Get a video control value.
328 *
329 * See video_get_ctrl() for argument descriptions.
330 */
331 typedef int (*video_api_get_ctrl_t)(const struct device *dev, unsigned int cid, void *value);
332
333 /**
334 * @typedef video_api_get_caps_t
335 * @brief Get capabilities of a video endpoint.
336 *
337 * See video_get_caps() for argument descriptions.
338 */
339 typedef int (*video_api_get_caps_t)(const struct device *dev, enum video_endpoint_id ep,
340 struct video_caps *caps);
341
342 /**
343 * @typedef video_api_set_signal_t
344 * @brief Register/Unregister poll signal for buffer events.
345 *
346 * See video_set_signal() for argument descriptions.
347 */
348 typedef int (*video_api_set_signal_t)(const struct device *dev, enum video_endpoint_id ep,
349 struct k_poll_signal *signal);
350
351 __subsystem struct video_driver_api {
352 /* mandatory callbacks */
353 video_api_set_format_t set_format;
354 video_api_get_format_t get_format;
355 video_api_set_stream_t set_stream;
356 video_api_get_caps_t get_caps;
357 /* optional callbacks */
358 video_api_enqueue_t enqueue;
359 video_api_dequeue_t dequeue;
360 video_api_flush_t flush;
361 video_api_set_ctrl_t set_ctrl;
362 video_api_get_ctrl_t get_ctrl;
363 video_api_set_signal_t set_signal;
364 video_api_set_frmival_t set_frmival;
365 video_api_get_frmival_t get_frmival;
366 video_api_enum_frmival_t enum_frmival;
367 };
368
369 /**
370 * @brief Set video format.
371 *
372 * Configure video device with a specific format.
373 *
374 * @param dev Pointer to the device structure for the driver instance.
375 * @param ep Endpoint ID.
376 * @param fmt Pointer to a video format struct.
377 *
378 * @retval 0 Is successful.
379 * @retval -EINVAL If parameters are invalid.
380 * @retval -ENOTSUP If format is not supported.
381 * @retval -EIO General input / output error.
382 */
video_set_format(const struct device * dev,enum video_endpoint_id ep,struct video_format * fmt)383 static inline int video_set_format(const struct device *dev, enum video_endpoint_id ep,
384 struct video_format *fmt)
385 {
386 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
387
388 if (api->set_format == NULL) {
389 return -ENOSYS;
390 }
391
392 return api->set_format(dev, ep, fmt);
393 }
394
395 /**
396 * @brief Get video format.
397 *
398 * Get video device current video format.
399 *
400 * @param dev Pointer to the device structure for the driver instance.
401 * @param ep Endpoint ID.
402 * @param fmt Pointer to video format struct.
403 *
404 * @retval pointer to video format
405 */
video_get_format(const struct device * dev,enum video_endpoint_id ep,struct video_format * fmt)406 static inline int video_get_format(const struct device *dev, enum video_endpoint_id ep,
407 struct video_format *fmt)
408 {
409 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
410
411 if (api->get_format == NULL) {
412 return -ENOSYS;
413 }
414
415 return api->get_format(dev, ep, fmt);
416 }
417
418 /**
419 * @brief Set video frame interval.
420 *
421 * Configure video device with a specific frame interval.
422 *
423 * Drivers must not return an error solely because the requested interval doesn’t match the device
424 * capabilities. They must instead modify the interval to match what the hardware can provide.
425 *
426 * @param dev Pointer to the device structure for the driver instance.
427 * @param ep Endpoint ID.
428 * @param frmival Pointer to a video frame interval struct.
429 *
430 * @retval 0 If successful.
431 * @retval -ENOSYS If API is not implemented.
432 * @retval -EINVAL If parameters are invalid.
433 * @retval -EIO General input / output error.
434 */
video_set_frmival(const struct device * dev,enum video_endpoint_id ep,struct video_frmival * frmival)435 static inline int video_set_frmival(const struct device *dev, enum video_endpoint_id ep,
436 struct video_frmival *frmival)
437 {
438 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
439
440 if (api->set_frmival == NULL) {
441 return -ENOSYS;
442 }
443
444 return api->set_frmival(dev, ep, frmival);
445 }
446
447 /**
448 * @brief Get video frame interval.
449 *
450 * Get current frame interval of the video device.
451 *
452 * @param dev Pointer to the device structure for the driver instance.
453 * @param ep Endpoint ID.
454 * @param frmival Pointer to a video frame interval struct.
455 *
456 * @retval 0 If successful.
457 * @retval -ENOSYS If API is not implemented.
458 * @retval -EINVAL If parameters are invalid.
459 * @retval -EIO General input / output error.
460 */
video_get_frmival(const struct device * dev,enum video_endpoint_id ep,struct video_frmival * frmival)461 static inline int video_get_frmival(const struct device *dev, enum video_endpoint_id ep,
462 struct video_frmival *frmival)
463 {
464 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
465
466 if (api->get_frmival == NULL) {
467 return -ENOSYS;
468 }
469
470 return api->get_frmival(dev, ep, frmival);
471 }
472
473 /**
474 * @brief List video frame intervals.
475 *
476 * List all supported video frame intervals of a given format.
477 *
478 * Applications should fill the pixelformat, width and height fields of the
479 * video_frmival_enum struct first to form a query. Then, the index field is
480 * used to iterate through the supported frame intervals list.
481 *
482 * @param dev Pointer to the device structure for the driver instance.
483 * @param ep Endpoint ID.
484 * @param fie Pointer to a video frame interval enumeration struct.
485 *
486 * @retval 0 If successful.
487 * @retval -ENOSYS If API is not implemented.
488 * @retval -EINVAL If parameters are invalid.
489 * @retval -EIO General input / output error.
490 */
video_enum_frmival(const struct device * dev,enum video_endpoint_id ep,struct video_frmival_enum * fie)491 static inline int video_enum_frmival(const struct device *dev, enum video_endpoint_id ep,
492 struct video_frmival_enum *fie)
493 {
494 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
495
496 if (api->enum_frmival == NULL) {
497 return -ENOSYS;
498 }
499
500 return api->enum_frmival(dev, ep, fie);
501 }
502
503 /**
504 * @brief Enqueue a video buffer.
505 *
506 * Enqueue an empty (capturing) or filled (output) video buffer in the driver’s
507 * endpoint incoming queue.
508 *
509 * @param dev Pointer to the device structure for the driver instance.
510 * @param ep Endpoint ID.
511 * @param buf Pointer to the video buffer.
512 *
513 * @retval 0 Is successful.
514 * @retval -EINVAL If parameters are invalid.
515 * @retval -EIO General input / output error.
516 */
video_enqueue(const struct device * dev,enum video_endpoint_id ep,struct video_buffer * buf)517 static inline int video_enqueue(const struct device *dev, enum video_endpoint_id ep,
518 struct video_buffer *buf)
519 {
520 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
521
522 if (api->enqueue == NULL) {
523 return -ENOSYS;
524 }
525
526 return api->enqueue(dev, ep, buf);
527 }
528
529 /**
530 * @brief Dequeue a video buffer.
531 *
532 * Dequeue a filled (capturing) or displayed (output) buffer from the driver’s
533 * endpoint outgoing queue.
534 *
535 * @param dev Pointer to the device structure for the driver instance.
536 * @param ep Endpoint ID.
537 * @param buf Pointer a video buffer pointer.
538 * @param timeout Timeout
539 *
540 * @retval 0 Is successful.
541 * @retval -EINVAL If parameters are invalid.
542 * @retval -EIO General input / output error.
543 */
video_dequeue(const struct device * dev,enum video_endpoint_id ep,struct video_buffer ** buf,k_timeout_t timeout)544 static inline int video_dequeue(const struct device *dev, enum video_endpoint_id ep,
545 struct video_buffer **buf, k_timeout_t timeout)
546 {
547 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
548
549 if (api->dequeue == NULL) {
550 return -ENOSYS;
551 }
552
553 return api->dequeue(dev, ep, buf, timeout);
554 }
555
556 /**
557 * @brief Flush endpoint buffers.
558 *
559 * A call to flush finishes when all endpoint buffers have been moved from
560 * incoming queue to outgoing queue. Either because canceled or fully processed
561 * through the video function.
562 *
563 * @param dev Pointer to the device structure for the driver instance.
564 * @param ep Endpoint ID.
565 * @param cancel If true, cancel buffer processing instead of waiting for
566 * completion.
567 *
568 * @retval 0 Is successful, -ERRNO code otherwise.
569 */
video_flush(const struct device * dev,enum video_endpoint_id ep,bool cancel)570 static inline int video_flush(const struct device *dev, enum video_endpoint_id ep, bool cancel)
571 {
572 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
573
574 if (api->flush == NULL) {
575 return -ENOSYS;
576 }
577
578 return api->flush(dev, ep, cancel);
579 }
580
581 /**
582 * @brief Start the video device function.
583 *
584 * video_stream_start is called to enter ‘streaming’ state (capture, output...).
585 * The driver may receive buffers with video_enqueue() before video_stream_start
586 * is called. If driver/device needs a minimum number of buffers before being
587 * able to start streaming, then driver set the min_vbuf_count to the related
588 * endpoint capabilities.
589 *
590 * @retval 0 Is successful.
591 * @retval -EIO General input / output error.
592 */
video_stream_start(const struct device * dev)593 static inline int video_stream_start(const struct device *dev)
594 {
595 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
596
597 if (api->set_stream == NULL) {
598 return -ENOSYS;
599 }
600
601 return api->set_stream(dev, true);
602 }
603
604 /**
605 * @brief Stop the video device function.
606 *
607 * On video_stream_stop, driver must stop any transactions or wait until they
608 * finish.
609 *
610 * @retval 0 Is successful.
611 * @retval -EIO General input / output error.
612 */
video_stream_stop(const struct device * dev)613 static inline int video_stream_stop(const struct device *dev)
614 {
615 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
616 int ret;
617
618 if (api->set_stream == NULL) {
619 return -ENOSYS;
620 }
621
622 ret = api->set_stream(dev, false);
623 video_flush(dev, VIDEO_EP_ALL, true);
624
625 return ret;
626 }
627
628 /**
629 * @brief Get the capabilities of a video endpoint.
630 *
631 * @param dev Pointer to the device structure for the driver instance.
632 * @param ep Endpoint ID.
633 * @param caps Pointer to the video_caps struct to fill.
634 *
635 * @retval 0 Is successful, -ERRNO code otherwise.
636 */
video_get_caps(const struct device * dev,enum video_endpoint_id ep,struct video_caps * caps)637 static inline int video_get_caps(const struct device *dev, enum video_endpoint_id ep,
638 struct video_caps *caps)
639 {
640 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
641
642 if (api->get_caps == NULL) {
643 return -ENOSYS;
644 }
645
646 return api->get_caps(dev, ep, caps);
647 }
648
649 /**
650 * @brief Set the value of a control.
651 *
652 * This set the value of a video control, value type depends on control ID, and
653 * must be interpreted accordingly.
654 *
655 * @param dev Pointer to the device structure for the driver instance.
656 * @param cid Control ID.
657 * @param value Pointer to the control value.
658 *
659 * @retval 0 Is successful.
660 * @retval -EINVAL If parameters are invalid.
661 * @retval -ENOTSUP If format is not supported.
662 * @retval -EIO General input / output error.
663 */
video_set_ctrl(const struct device * dev,unsigned int cid,void * value)664 static inline int video_set_ctrl(const struct device *dev, unsigned int cid, void *value)
665 {
666 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
667
668 if (api->set_ctrl == NULL) {
669 return -ENOSYS;
670 }
671
672 return api->set_ctrl(dev, cid, value);
673 }
674
675 /**
676 * @brief Get the current value of a control.
677 *
678 * This retrieve the value of a video control, value type depends on control ID,
679 * and must be interpreted accordingly.
680 *
681 * @param dev Pointer to the device structure for the driver instance.
682 * @param cid Control ID.
683 * @param value Pointer to the control value.
684 *
685 * @retval 0 Is successful.
686 * @retval -EINVAL If parameters are invalid.
687 * @retval -ENOTSUP If format is not supported.
688 * @retval -EIO General input / output error.
689 */
video_get_ctrl(const struct device * dev,unsigned int cid,void * value)690 static inline int video_get_ctrl(const struct device *dev, unsigned int cid, void *value)
691 {
692 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
693
694 if (api->get_ctrl == NULL) {
695 return -ENOSYS;
696 }
697
698 return api->get_ctrl(dev, cid, value);
699 }
700
701 /**
702 * @brief Register/Unregister k_poll signal for a video endpoint.
703 *
704 * Register a poll signal to the endpoint, which will be signaled on frame
705 * completion (done, aborted, error). Registering a NULL poll signal
706 * unregisters any previously registered signal.
707 *
708 * @param dev Pointer to the device structure for the driver instance.
709 * @param ep Endpoint ID.
710 * @param signal Pointer to k_poll_signal
711 *
712 * @retval 0 Is successful, -ERRNO code otherwise.
713 */
video_set_signal(const struct device * dev,enum video_endpoint_id ep,struct k_poll_signal * signal)714 static inline int video_set_signal(const struct device *dev, enum video_endpoint_id ep,
715 struct k_poll_signal *signal)
716 {
717 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
718
719 if (api->set_signal == NULL) {
720 return -ENOSYS;
721 }
722
723 return api->set_signal(dev, ep, signal);
724 }
725
726 /**
727 * @brief Allocate aligned video buffer.
728 *
729 * @param size Size of the video buffer (in bytes).
730 * @param align Alignment of the requested memory, must be a power of two.
731 * @param timeout Timeout duration or K_NO_WAIT
732 *
733 * @retval pointer to allocated video buffer
734 */
735 struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align, k_timeout_t timeout);
736
737 /**
738 * @brief Allocate video buffer.
739 *
740 * @param size Size of the video buffer (in bytes).
741 * @param timeout Timeout duration or K_NO_WAIT
742 *
743 * @retval pointer to allocated video buffer
744 */
745 struct video_buffer *video_buffer_alloc(size_t size, k_timeout_t timeout);
746
747 /**
748 * @brief Release a video buffer.
749 *
750 * @param buf Pointer to the video buffer to release.
751 */
752 void video_buffer_release(struct video_buffer *buf);
753
754 /**
755 * @brief Search for a format that matches in a list of capabilities
756 *
757 * @param fmts The format capability list to search.
758 * @param fmt The format to find in the list.
759 * @param idx The pointer to a number of the first format that matches.
760 *
761 * @return 0 when a format is found.
762 * @return -ENOENT when no matching format is found.
763 */
764 int video_format_caps_index(const struct video_format_cap *fmts, const struct video_format *fmt,
765 size_t *idx);
766
767 /**
768 * @brief Compute the difference between two frame intervals
769 *
770 * @param frmival Frame interval to turn into microseconds.
771 *
772 * @return The frame interval value in microseconds.
773 */
video_frmival_nsec(const struct video_frmival * frmival)774 static inline uint64_t video_frmival_nsec(const struct video_frmival *frmival)
775 {
776 return (uint64_t)NSEC_PER_SEC * frmival->numerator / frmival->denominator;
777 }
778
779 /**
780 * @brief Find the closest match to a frame interval value within a stepwise frame interval.
781 *
782 * @param stepwise The stepwise frame interval range to search
783 * @param desired The frame interval for which find the closest match
784 * @param match The resulting frame interval closest to @p desired
785 */
786 void video_closest_frmival_stepwise(const struct video_frmival_stepwise *stepwise,
787 const struct video_frmival *desired,
788 struct video_frmival *match);
789
790 /**
791 * @brief Find the closest match to a frame interval value within a video device.
792 *
793 * To compute the closest match, fill @p match with the following fields:
794 *
795 * - @c match->format to the @ref video_format of interest.
796 * - @c match->type to @ref VIDEO_FRMIVAL_TYPE_DISCRETE.
797 * - @c match->discrete to the desired frame interval.
798 *
799 * The result will be loaded into @p match, with the following fields set:
800 *
801 * - @c match->discrete to the value of the closest frame interval.
802 * - @c match->index to the index of the closest frame interval.
803 *
804 * @param dev Video device to query.
805 * @param ep Video endpoint ID to query.
806 * @param match Frame interval enumerator with the query, and loaded with the result.
807 */
808 void video_closest_frmival(const struct device *dev, enum video_endpoint_id ep,
809 struct video_frmival_enum *match);
810
811 /**
812 * @defgroup video_pixel_formats Video pixel formats
813 * The @c | characters separate the pixels, and spaces separate the bytes.
814 * The uppercase letter represents the most significant bit.
815 * The lowercase letters represent the rest of the bits.
816 * @{
817 */
818
819 /**
820 * @brief Four-character-code uniquely identifying the pixel format
821 */
822 #define VIDEO_FOURCC(a, b, c, d) \
823 ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
824
825 /**
826 * @brief Convert a four-character-string to a four-character-code
827 *
828 * Convert a string literal or variable into a four-character-code
829 * as defined by @ref VIDEO_FOURCC.
830 *
831 * @param str String to be converted
832 * @return Four-character-code.
833 */
834 #define VIDEO_FOURCC_FROM_STR(str) VIDEO_FOURCC((str)[0], (str)[1], (str)[2], (str)[3])
835
836 /**
837 * @brief Convert a four-character-code to a four-character-string
838 *
839 * Convert a four-character code as defined by @ref VIDEO_FOURCC into a string that can be used
840 * anywhere, such as in debug logs with the %s print formatter.
841 *
842 * @param fourcc The 32-bit four-character-code integer to be converted, in CPU-native endinaness.
843 * @return Four-character-string built out of it.
844 */
845 #define VIDEO_FOURCC_TO_STR(fourcc) \
846 ((char[]){ \
847 (char)((fourcc) & 0xFF), \
848 (char)(((fourcc) >> 8) & 0xFF), \
849 (char)(((fourcc) >> 16) & 0xFF), \
850 (char)(((fourcc) >> 24) & 0xFF), \
851 '\0' \
852 })
853
854 /**
855 * @name Bayer formats (R, G, B channels).
856 *
857 * The full color information is spread over multiple pixels.
858 *
859 * @{
860 */
861
862 /**
863 * @verbatim
864 * | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | ...
865 * | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | ...
866 * @endverbatim
867 */
868 #define VIDEO_PIX_FMT_BGGR8 VIDEO_FOURCC('B', 'A', '8', '1')
869
870 /**
871 * @verbatim
872 * | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | ...
873 * | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | ...
874 * @endverbatim
875 */
876 #define VIDEO_PIX_FMT_GBRG8 VIDEO_FOURCC('G', 'B', 'R', 'G')
877
878 /**
879 * @verbatim
880 * | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | ...
881 * | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | ...
882 * @endverbatim
883 */
884 #define VIDEO_PIX_FMT_GRBG8 VIDEO_FOURCC('G', 'R', 'B', 'G')
885
886 /**
887 * @verbatim
888 * | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | ...
889 * | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | ...
890 * @endverbatim
891 */
892 #define VIDEO_PIX_FMT_RGGB8 VIDEO_FOURCC('R', 'G', 'G', 'B')
893
894 /**
895 * @}
896 */
897
898 /**
899 * @name RGB formats
900 * Per-color (R, G, B) channels.
901 * @{
902 */
903
904 /**
905 * 5 red bits [15:11], 6 green bits [10:5], 5 blue bits [4:0].
906 * This 16-bit integer is then packed in big endian format over two bytes:
907 *
908 * @verbatim
909 * 15.....8 7......0
910 * | RrrrrGgg gggBbbbb | ...
911 * @endverbatim
912 */
913 #define VIDEO_PIX_FMT_RGB565X VIDEO_FOURCC('R', 'G', 'B', 'R')
914
915 /**
916 * 5 red bits [15:11], 6 green bits [10:5], 5 blue bits [4:0].
917 * This 16-bit integer is then packed in little endian format over two bytes:
918 *
919 * @verbatim
920 * 7......0 15.....8
921 * | gggBbbbb RrrrrGgg | ...
922 * @endverbatim
923 */
924 #define VIDEO_PIX_FMT_RGB565 VIDEO_FOURCC('R', 'G', 'B', 'P')
925
926 /**
927 * The first byte is empty (X) for each pixel.
928 *
929 * @verbatim
930 * | Xxxxxxxx Rrrrrrrr Gggggggg Bbbbbbbb | ...
931 * @endverbatim
932 */
933 #define VIDEO_PIX_FMT_XRGB32 VIDEO_FOURCC('B', 'X', '2', '4')
934
935 /**
936 * @}
937 */
938
939 /**
940 * @name YUV formats
941 * Luminance (Y) and chrominance (U, V) channels.
942 * @{
943 */
944
945 /**
946 * There is either a missing channel per pixel, U or V.
947 * The value is to be averaged over 2 pixels to get the value of individual pixel.
948 *
949 * @verbatim
950 * | Yyyyyyyy Uuuuuuuu | Yyyyyyyy Vvvvvvvv | ...
951 * @endverbatim
952 */
953 #define VIDEO_PIX_FMT_YUYV VIDEO_FOURCC('Y', 'U', 'Y', 'V')
954
955 /**
956 * The first byte is empty (X) for each pixel.
957 *
958 * @verbatim
959 * | Xxxxxxxx Yyyyyyyy Uuuuuuuu Vvvvvvvv | ...
960 * @endverbatim
961 */
962 #define VIDEO_PIX_FMT_XYUV32 VIDEO_FOURCC('X', 'Y', 'U', 'V')
963
964 /**
965 * @}
966 */
967
968 /**
969 * @name Compressed formats
970 * @{
971 */
972
973 /**
974 * Both JPEG (single frame) and Motion-JPEG (MJPEG, multiple JPEG frames concatenated)
975 */
976 #define VIDEO_PIX_FMT_JPEG VIDEO_FOURCC('J', 'P', 'E', 'G')
977
978 /**
979 * @}
980 */
981
982 /**
983 * @brief Get number of bits per pixel of a pixel format
984 *
985 * @param pixfmt FourCC pixel format value (@ref video_pixel_formats).
986 *
987 * @retval 0 if the format is unhandled or if it is variable number of bits
988 * @retval bit size of one pixel for this format
989 */
video_bits_per_pixel(uint32_t pixfmt)990 static inline unsigned int video_bits_per_pixel(uint32_t pixfmt)
991 {
992 switch (pixfmt) {
993 case VIDEO_PIX_FMT_BGGR8:
994 case VIDEO_PIX_FMT_GBRG8:
995 case VIDEO_PIX_FMT_GRBG8:
996 case VIDEO_PIX_FMT_RGGB8:
997 return 8;
998 case VIDEO_PIX_FMT_RGB565:
999 case VIDEO_PIX_FMT_YUYV:
1000 return 16;
1001 case VIDEO_PIX_FMT_XRGB32:
1002 case VIDEO_PIX_FMT_XYUV32:
1003 return 32;
1004 default:
1005 /* Variable number of bits per pixel or unknown format */
1006 return 0;
1007 }
1008 }
1009
1010 /**
1011 * @}
1012 */
1013
1014 #ifdef __cplusplus
1015 }
1016 #endif
1017
1018 /**
1019 * @}
1020 */
1021
1022 #endif /* ZEPHYR_INCLUDE_VIDEO_H_ */
1023