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