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_stream_start_t
306 * @brief Start the capture or output process.
307 *
308 * See video_stream_start() for argument descriptions.
309 */
310 typedef int (*video_api_stream_start_t)(const struct device *dev);
311
312 /**
313 * @typedef video_api_stream_stop_t
314 * @brief Stop the capture or output process.
315 *
316 * See video_stream_stop() for argument descriptions.
317 */
318 typedef int (*video_api_stream_stop_t)(const struct device *dev);
319
320 /**
321 * @typedef video_api_set_ctrl_t
322 * @brief Set a video control value.
323 *
324 * See video_set_ctrl() for argument descriptions.
325 */
326 typedef int (*video_api_set_ctrl_t)(const struct device *dev, unsigned int cid, void *value);
327
328 /**
329 * @typedef video_api_get_ctrl_t
330 * @brief Get a video control value.
331 *
332 * See video_get_ctrl() for argument descriptions.
333 */
334 typedef int (*video_api_get_ctrl_t)(const struct device *dev, unsigned int cid, void *value);
335
336 /**
337 * @typedef video_api_get_caps_t
338 * @brief Get capabilities of a video endpoint.
339 *
340 * See video_get_caps() for argument descriptions.
341 */
342 typedef int (*video_api_get_caps_t)(const struct device *dev, enum video_endpoint_id ep,
343 struct video_caps *caps);
344
345 /**
346 * @typedef video_api_set_signal_t
347 * @brief Register/Unregister poll signal for buffer events.
348 *
349 * See video_set_signal() for argument descriptions.
350 */
351 typedef int (*video_api_set_signal_t)(const struct device *dev, enum video_endpoint_id ep,
352 struct k_poll_signal *signal);
353
354 __subsystem struct video_driver_api {
355 /* mandatory callbacks */
356 video_api_set_format_t set_format;
357 video_api_get_format_t get_format;
358 video_api_stream_start_t stream_start;
359 video_api_stream_stop_t stream_stop;
360 video_api_get_caps_t get_caps;
361 /* optional callbacks */
362 video_api_enqueue_t enqueue;
363 video_api_dequeue_t dequeue;
364 video_api_flush_t flush;
365 video_api_set_ctrl_t set_ctrl;
366 video_api_get_ctrl_t get_ctrl;
367 video_api_set_signal_t set_signal;
368 video_api_set_frmival_t set_frmival;
369 video_api_get_frmival_t get_frmival;
370 video_api_enum_frmival_t enum_frmival;
371 };
372
373 /**
374 * @brief Set video format.
375 *
376 * Configure video device with a specific format.
377 *
378 * @param dev Pointer to the device structure for the driver instance.
379 * @param ep Endpoint ID.
380 * @param fmt Pointer to a video format struct.
381 *
382 * @retval 0 Is successful.
383 * @retval -EINVAL If parameters are invalid.
384 * @retval -ENOTSUP If format is not supported.
385 * @retval -EIO General input / output error.
386 */
video_set_format(const struct device * dev,enum video_endpoint_id ep,struct video_format * fmt)387 static inline int video_set_format(const struct device *dev, enum video_endpoint_id ep,
388 struct video_format *fmt)
389 {
390 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
391
392 if (api->set_format == NULL) {
393 return -ENOSYS;
394 }
395
396 return api->set_format(dev, ep, fmt);
397 }
398
399 /**
400 * @brief Get video format.
401 *
402 * Get video device current video format.
403 *
404 * @param dev Pointer to the device structure for the driver instance.
405 * @param ep Endpoint ID.
406 * @param fmt Pointer to video format struct.
407 *
408 * @retval pointer to video format
409 */
video_get_format(const struct device * dev,enum video_endpoint_id ep,struct video_format * fmt)410 static inline int video_get_format(const struct device *dev, enum video_endpoint_id ep,
411 struct video_format *fmt)
412 {
413 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
414
415 if (api->get_format == NULL) {
416 return -ENOSYS;
417 }
418
419 return api->get_format(dev, ep, fmt);
420 }
421
422 /**
423 * @brief Set video frame interval.
424 *
425 * Configure video device with a specific frame interval.
426 *
427 * Drivers must not return an error solely because the requested interval doesn’t match the device
428 * capabilities. They must instead modify the interval to match what the hardware can provide.
429 *
430 * @param dev Pointer to the device structure for the driver instance.
431 * @param ep Endpoint ID.
432 * @param frmival Pointer to a video frame interval struct.
433 *
434 * @retval 0 If successful.
435 * @retval -ENOSYS If API is not implemented.
436 * @retval -EINVAL If parameters are invalid.
437 * @retval -EIO General input / output error.
438 */
video_set_frmival(const struct device * dev,enum video_endpoint_id ep,struct video_frmival * frmival)439 static inline int video_set_frmival(const struct device *dev, enum video_endpoint_id ep,
440 struct video_frmival *frmival)
441 {
442 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
443
444 if (api->set_frmival == NULL) {
445 return -ENOSYS;
446 }
447
448 return api->set_frmival(dev, ep, frmival);
449 }
450
451 /**
452 * @brief Get video frame interval.
453 *
454 * Get current frame interval of the video device.
455 *
456 * @param dev Pointer to the device structure for the driver instance.
457 * @param ep Endpoint ID.
458 * @param frmival Pointer to a video frame interval struct.
459 *
460 * @retval 0 If successful.
461 * @retval -ENOSYS If API is not implemented.
462 * @retval -EINVAL If parameters are invalid.
463 * @retval -EIO General input / output error.
464 */
video_get_frmival(const struct device * dev,enum video_endpoint_id ep,struct video_frmival * frmival)465 static inline int video_get_frmival(const struct device *dev, enum video_endpoint_id ep,
466 struct video_frmival *frmival)
467 {
468 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
469
470 if (api->get_frmival == NULL) {
471 return -ENOSYS;
472 }
473
474 return api->get_frmival(dev, ep, frmival);
475 }
476
477 /**
478 * @brief List video frame intervals.
479 *
480 * List all supported video frame intervals of a given format.
481 *
482 * Applications should fill the pixelformat, width and height fields of the
483 * video_frmival_enum struct first to form a query. Then, the index field is
484 * used to iterate through the supported frame intervals list.
485 *
486 * @param dev Pointer to the device structure for the driver instance.
487 * @param ep Endpoint ID.
488 * @param fie Pointer to a video frame interval enumeration struct.
489 *
490 * @retval 0 If successful.
491 * @retval -ENOSYS If API is not implemented.
492 * @retval -EINVAL If parameters are invalid.
493 * @retval -EIO General input / output error.
494 */
video_enum_frmival(const struct device * dev,enum video_endpoint_id ep,struct video_frmival_enum * fie)495 static inline int video_enum_frmival(const struct device *dev, enum video_endpoint_id ep,
496 struct video_frmival_enum *fie)
497 {
498 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
499
500 if (api->enum_frmival == NULL) {
501 return -ENOSYS;
502 }
503
504 return api->enum_frmival(dev, ep, fie);
505 }
506
507 /**
508 * @brief Enqueue a video buffer.
509 *
510 * Enqueue an empty (capturing) or filled (output) video buffer in the driver’s
511 * endpoint incoming queue.
512 *
513 * @param dev Pointer to the device structure for the driver instance.
514 * @param ep Endpoint ID.
515 * @param buf Pointer to the video buffer.
516 *
517 * @retval 0 Is successful.
518 * @retval -EINVAL If parameters are invalid.
519 * @retval -EIO General input / output error.
520 */
video_enqueue(const struct device * dev,enum video_endpoint_id ep,struct video_buffer * buf)521 static inline int video_enqueue(const struct device *dev, enum video_endpoint_id ep,
522 struct video_buffer *buf)
523 {
524 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
525
526 if (api->enqueue == NULL) {
527 return -ENOSYS;
528 }
529
530 return api->enqueue(dev, ep, buf);
531 }
532
533 /**
534 * @brief Dequeue a video buffer.
535 *
536 * Dequeue a filled (capturing) or displayed (output) buffer from the driver’s
537 * endpoint outgoing queue.
538 *
539 * @param dev Pointer to the device structure for the driver instance.
540 * @param ep Endpoint ID.
541 * @param buf Pointer a video buffer pointer.
542 * @param timeout Timeout
543 *
544 * @retval 0 Is successful.
545 * @retval -EINVAL If parameters are invalid.
546 * @retval -EIO General input / output error.
547 */
video_dequeue(const struct device * dev,enum video_endpoint_id ep,struct video_buffer ** buf,k_timeout_t timeout)548 static inline int video_dequeue(const struct device *dev, enum video_endpoint_id ep,
549 struct video_buffer **buf, k_timeout_t timeout)
550 {
551 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
552
553 if (api->dequeue == NULL) {
554 return -ENOSYS;
555 }
556
557 return api->dequeue(dev, ep, buf, timeout);
558 }
559
560 /**
561 * @brief Flush endpoint buffers.
562 *
563 * A call to flush finishes when all endpoint buffers have been moved from
564 * incoming queue to outgoing queue. Either because canceled or fully processed
565 * through the video function.
566 *
567 * @param dev Pointer to the device structure for the driver instance.
568 * @param ep Endpoint ID.
569 * @param cancel If true, cancel buffer processing instead of waiting for
570 * completion.
571 *
572 * @retval 0 Is successful, -ERRNO code otherwise.
573 */
video_flush(const struct device * dev,enum video_endpoint_id ep,bool cancel)574 static inline int video_flush(const struct device *dev, enum video_endpoint_id ep, bool cancel)
575 {
576 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
577
578 if (api->flush == NULL) {
579 return -ENOSYS;
580 }
581
582 return api->flush(dev, ep, cancel);
583 }
584
585 /**
586 * @brief Start the video device function.
587 *
588 * video_stream_start is called to enter ‘streaming’ state (capture, output...).
589 * The driver may receive buffers with video_enqueue() before video_stream_start
590 * is called. If driver/device needs a minimum number of buffers before being
591 * able to start streaming, then driver set the min_vbuf_count to the related
592 * endpoint capabilities.
593 *
594 * @retval 0 Is successful.
595 * @retval -EIO General input / output error.
596 */
video_stream_start(const struct device * dev)597 static inline int video_stream_start(const struct device *dev)
598 {
599 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
600
601 if (api->stream_start == NULL) {
602 return -ENOSYS;
603 }
604
605 return api->stream_start(dev);
606 }
607
608 /**
609 * @brief Stop the video device function.
610 *
611 * On video_stream_stop, driver must stop any transactions or wait until they
612 * finish.
613 *
614 * @retval 0 Is successful.
615 * @retval -EIO General input / output error.
616 */
video_stream_stop(const struct device * dev)617 static inline int video_stream_stop(const struct device *dev)
618 {
619 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
620 int ret;
621
622 if (api->stream_stop == NULL) {
623 return -ENOSYS;
624 }
625
626 ret = api->stream_stop(dev);
627 video_flush(dev, VIDEO_EP_ALL, true);
628
629 return ret;
630 }
631
632 /**
633 * @brief Get the capabilities of a video endpoint.
634 *
635 * @param dev Pointer to the device structure for the driver instance.
636 * @param ep Endpoint ID.
637 * @param caps Pointer to the video_caps struct to fill.
638 *
639 * @retval 0 Is successful, -ERRNO code otherwise.
640 */
video_get_caps(const struct device * dev,enum video_endpoint_id ep,struct video_caps * caps)641 static inline int video_get_caps(const struct device *dev, enum video_endpoint_id ep,
642 struct video_caps *caps)
643 {
644 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
645
646 if (api->get_caps == NULL) {
647 return -ENOSYS;
648 }
649
650 return api->get_caps(dev, ep, caps);
651 }
652
653 /**
654 * @brief Set the value of a control.
655 *
656 * This set the value of a video control, value type depends on control ID, and
657 * must be interpreted accordingly.
658 *
659 * @param dev Pointer to the device structure for the driver instance.
660 * @param cid Control ID.
661 * @param value Pointer to the control value.
662 *
663 * @retval 0 Is successful.
664 * @retval -EINVAL If parameters are invalid.
665 * @retval -ENOTSUP If format is not supported.
666 * @retval -EIO General input / output error.
667 */
video_set_ctrl(const struct device * dev,unsigned int cid,void * value)668 static inline int video_set_ctrl(const struct device *dev, unsigned int cid, void *value)
669 {
670 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
671
672 if (api->set_ctrl == NULL) {
673 return -ENOSYS;
674 }
675
676 return api->set_ctrl(dev, cid, value);
677 }
678
679 /**
680 * @brief Get the current value of a control.
681 *
682 * This retrieve the value of a video control, value type depends on control ID,
683 * and must be interpreted accordingly.
684 *
685 * @param dev Pointer to the device structure for the driver instance.
686 * @param cid Control ID.
687 * @param value Pointer to the control value.
688 *
689 * @retval 0 Is successful.
690 * @retval -EINVAL If parameters are invalid.
691 * @retval -ENOTSUP If format is not supported.
692 * @retval -EIO General input / output error.
693 */
video_get_ctrl(const struct device * dev,unsigned int cid,void * value)694 static inline int video_get_ctrl(const struct device *dev, unsigned int cid, void *value)
695 {
696 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
697
698 if (api->get_ctrl == NULL) {
699 return -ENOSYS;
700 }
701
702 return api->get_ctrl(dev, cid, value);
703 }
704
705 /**
706 * @brief Register/Unregister k_poll signal for a video endpoint.
707 *
708 * Register a poll signal to the endpoint, which will be signaled on frame
709 * completion (done, aborted, error). Registering a NULL poll signal
710 * unregisters any previously registered signal.
711 *
712 * @param dev Pointer to the device structure for the driver instance.
713 * @param ep Endpoint ID.
714 * @param signal Pointer to k_poll_signal
715 *
716 * @retval 0 Is successful, -ERRNO code otherwise.
717 */
video_set_signal(const struct device * dev,enum video_endpoint_id ep,struct k_poll_signal * signal)718 static inline int video_set_signal(const struct device *dev, enum video_endpoint_id ep,
719 struct k_poll_signal *signal)
720 {
721 const struct video_driver_api *api = (const struct video_driver_api *)dev->api;
722
723 if (api->set_signal == NULL) {
724 return -ENOSYS;
725 }
726
727 return api->set_signal(dev, ep, signal);
728 }
729
730 /**
731 * @brief Allocate aligned video buffer.
732 *
733 * @param size Size of the video buffer (in bytes).
734 * @param align Alignment of the requested memory, must be a power of two.
735 * @param timeout Timeout duration or K_NO_WAIT
736 *
737 * @retval pointer to allocated video buffer
738 */
739 struct video_buffer *video_buffer_aligned_alloc(size_t size, size_t align, k_timeout_t timeout);
740
741 /**
742 * @brief Allocate video buffer.
743 *
744 * @param size Size of the video buffer (in bytes).
745 * @param timeout Timeout duration or K_NO_WAIT
746 *
747 * @retval pointer to allocated video buffer
748 */
749 struct video_buffer *video_buffer_alloc(size_t size, k_timeout_t timeout);
750
751 /**
752 * @brief Release a video buffer.
753 *
754 * @param buf Pointer to the video buffer to release.
755 */
756 void video_buffer_release(struct video_buffer *buf);
757
758 /**
759 * @brief Search for a format that matches in a list of capabilities
760 *
761 * @param fmts The format capability list to search.
762 * @param fmt The format to find in the list.
763 * @param idx The pointer to a number of the first format that matches.
764 *
765 * @return 0 when a format is found.
766 * @return -ENOENT when no matching format is found.
767 */
768 int video_format_caps_index(const struct video_format_cap *fmts, const struct video_format *fmt,
769 size_t *idx);
770
771 /**
772 * @brief Compute the difference between two frame intervals
773 *
774 * @param frmival Frame interval to turn into microseconds.
775 *
776 * @return The frame interval value in microseconds.
777 */
video_frmival_nsec(const struct video_frmival * frmival)778 static inline uint64_t video_frmival_nsec(const struct video_frmival *frmival)
779 {
780 return (uint64_t)NSEC_PER_SEC * frmival->numerator / frmival->denominator;
781 }
782
783 /**
784 * @brief Find the closest match to a frame interval value within a stepwise frame interval.
785 *
786 * @param stepwise The stepwise frame interval range to search
787 * @param desired The frame interval for which find the closest match
788 * @param match The resulting frame interval closest to @p desired
789 */
790 void video_closest_frmival_stepwise(const struct video_frmival_stepwise *stepwise,
791 const struct video_frmival *desired,
792 struct video_frmival *match);
793
794 /**
795 * @brief Find the closest match to a frame interval value within a video device.
796 *
797 * To compute the closest match, fill @p match with the following fields:
798 *
799 * - @c match->format to the @ref video_format of interest.
800 * - @c match->type to @ref VIDEO_FRMIVAL_TYPE_DISCRETE.
801 * - @c match->discrete to the desired frame interval.
802 *
803 * The result will be loaded into @p match, with the following fields set:
804 *
805 * - @c match->discrete to the value of the closest frame interval.
806 * - @c match->index to the index of the closest frame interval.
807 *
808 * @param dev Video device to query.
809 * @param ep Video endpoint ID to query.
810 * @param match Frame interval enumerator with the query, and loaded with the result.
811 */
812 void video_closest_frmival(const struct device *dev, enum video_endpoint_id ep,
813 struct video_frmival_enum *match);
814
815 /* fourcc - four-character-code */
816 #define video_fourcc(a, b, c, d) \
817 ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
818
819 /**
820 * @defgroup video_pixel_formats Video pixel formats
821 * @{
822 */
823
824 /**
825 * @name Bayer formats
826 * @{
827 */
828
829 /** BGGR8 pixel format */
830 #define VIDEO_PIX_FMT_BGGR8 video_fourcc('B', 'G', 'G', 'R') /* 8 BGBG.. GRGR.. */
831 /** GBRG8 pixel format */
832 #define VIDEO_PIX_FMT_GBRG8 video_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */
833 /** GRBG8 pixel format */
834 #define VIDEO_PIX_FMT_GRBG8 video_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */
835 /** RGGB8 pixel format */
836 #define VIDEO_PIX_FMT_RGGB8 video_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */
837
838 /**
839 * @}
840 */
841
842 /**
843 * @name RGB formats
844 * @{
845 */
846
847 /** RGB565 pixel format */
848 #define VIDEO_PIX_FMT_RGB565 video_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */
849
850 /** XRGB32 pixel format */
851 #define VIDEO_PIX_FMT_XRGB32 video_fourcc('B', 'X', '2', '4') /* 32 XRGB-8-8-8-8 */
852
853 /**
854 * @}
855 */
856
857 /**
858 * @name YUV formats
859 * @{
860 */
861
862 /** YUYV pixel format */
863 #define VIDEO_PIX_FMT_YUYV video_fourcc('Y', 'U', 'Y', 'V') /* 16 Y0-Cb0 Y1-Cr0 */
864
865 /** XYUV32 pixel format */
866 #define VIDEO_PIX_FMT_XYUV32 video_fourcc('X', 'Y', 'U', 'V') /* 32 XYUV-8-8-8-8 */
867
868 /**
869 *
870 * @}
871 */
872
873 /**
874 * @name JPEG formats
875 * @{
876 */
877
878 /** JPEG pixel format */
879 #define VIDEO_PIX_FMT_JPEG video_fourcc('J', 'P', 'E', 'G') /* 8 JPEG */
880
881 /**
882 * @}
883 */
884
885 /**
886 * @}
887 */
888
889 /**
890 * @brief Get number of bytes per pixel of a pixel format
891 *
892 * @param pixfmt FourCC pixel format value (\ref video_pixel_formats).
893 */
video_pix_fmt_bpp(uint32_t pixfmt)894 static inline unsigned int video_pix_fmt_bpp(uint32_t pixfmt)
895 {
896 switch (pixfmt) {
897 case VIDEO_PIX_FMT_BGGR8:
898 case VIDEO_PIX_FMT_GBRG8:
899 case VIDEO_PIX_FMT_GRBG8:
900 case VIDEO_PIX_FMT_RGGB8:
901 return 1;
902 case VIDEO_PIX_FMT_RGB565:
903 case VIDEO_PIX_FMT_YUYV:
904 return 2;
905 case VIDEO_PIX_FMT_XRGB32:
906 case VIDEO_PIX_FMT_XYUV32:
907 return 4;
908 default:
909 return 0;
910 }
911 }
912
913 #ifdef __cplusplus
914 }
915 #endif
916
917 /**
918 * @}
919 */
920
921 #endif /* ZEPHYR_INCLUDE_VIDEO_H_ */
922