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