• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define OVERLAY_DEBUG 1
18 #define LOG_TAG "Overlay"
19 
20 #include <fcntl.h>
21 #include <errno.h>
22 #include <cutils/log.h>
23 #include <hardware/overlay.h>
24 #include <linux/videodev.h>
25 #include <sys/ioctl.h>
26 #include <sys/mman.h>
27 #include "v4l2_utils.h"
28 
29 #define LOG_FUNCTION_NAME    LOGV("%s: %s",  __FILE__, __FUNCTION__);
30 
31 #ifndef LOGE
32 #define LOGE(fmt,args...) \
33         do { printf(fmt, ##args); } \
34         while (0)
35 #endif
36 
37 #ifndef LOGI
38 #define LOGI(fmt,args...) \
39         do { LOGE(fmt, ##args); } \
40         while (0)
41 #endif
42 #define V4L2_CID_PRIV_OFFSET			0x00530000
43 #define V4L2_CID_PRIV_ROTATION		(V4L2_CID_PRIVATE_BASE \
44 						+ V4L2_CID_PRIV_OFFSET + 0)
45 #define V4L2_CID_PRIV_COLORKEY		(V4L2_CID_PRIVATE_BASE \
46 						+ V4L2_CID_PRIV_OFFSET + 1)
47 #define V4L2_CID_PRIV_COLORKEY_EN	(V4L2_CID_PRIVATE_BASE \
48 						+ V4L2_CID_PRIV_OFFSET + 2)
49 
50 
51 
v4l2_overlay_get(int name)52 int v4l2_overlay_get(int name) {
53     int result = -1;
54     switch (name) {
55         case OVERLAY_MINIFICATION_LIMIT:
56             result = 4; // 0 = no limit
57             break;
58         case OVERLAY_MAGNIFICATION_LIMIT:
59             result = 2; // 0 = no limit
60             break;
61         case OVERLAY_SCALING_FRAC_BITS:
62             result = 0; // 0 = infinite
63             break;
64         case OVERLAY_ROTATION_STEP_DEG:
65             result = 90; // 90 rotation steps (for instance)
66             break;
67         case OVERLAY_HORIZONTAL_ALIGNMENT:
68             result = 1; // 1-pixel alignment
69             break;
70         case OVERLAY_VERTICAL_ALIGNMENT:
71             result = 1; // 1-pixel alignment
72             break;
73         case OVERLAY_WIDTH_ALIGNMENT:
74             result = 1; // 1-pixel alignment
75             break;
76         case OVERLAY_HEIGHT_ALIGNMENT:
77             result = 1; // 1-pixel alignment
78             break;
79     }
80     return result;
81 }
82 
v4l2_overlay_open(int id)83 int v4l2_overlay_open(int id)
84 {
85     LOG_FUNCTION_NAME
86 
87     if (id == V4L2_OVERLAY_PLANE_VIDEO1)
88         return open("/dev/video1", O_RDWR);
89     else if (id == V4L2_OVERLAY_PLANE_VIDEO2)
90         return open("/dev/video2", O_RDWR);
91     return -EINVAL;
92 }
93 
dump_pixfmt(struct v4l2_pix_format * pix)94 void dump_pixfmt(struct v4l2_pix_format *pix)
95 {
96     LOGI("w: %d\n", pix->width);
97     LOGI("h: %d\n", pix->height);
98     LOGI("color: %x\n", pix->colorspace);
99     switch (pix->pixelformat) {
100         case V4L2_PIX_FMT_YUYV:
101             LOGI ("YUYV\n");
102             break;
103         case V4L2_PIX_FMT_UYVY:
104             LOGI ("UYVY\n");
105             break;
106         case V4L2_PIX_FMT_RGB565:
107             LOGI ("RGB565\n");
108             break;
109         case V4L2_PIX_FMT_RGB565X:
110             LOGI ("RGB565X\n");
111             break;
112         default:
113             LOGI("not supported\n");
114     }
115 }
116 
dump_crop(struct v4l2_crop * crop)117 void dump_crop(struct v4l2_crop *crop)
118 {
119     LOGI("crop l: %d ", crop->c.left);
120     LOGI("crop t: %d ", crop->c.top);
121     LOGI("crop w: %d ", crop->c.width);
122     LOGI("crop h: %d\n", crop->c.height);
123 }
124 
dump_window(struct v4l2_window * win)125 void dump_window(struct v4l2_window *win)
126 {
127     LOGI("window l: %d ", win->w.left);
128     LOGI("window t: %d ", win->w.top);
129     LOGI("window w: %d ", win->w.width);
130     LOGI("window h: %d\n", win->w.height);
131 }
v4l2_overlay_dump_state(int fd)132 void v4l2_overlay_dump_state(int fd)
133 {
134     struct v4l2_format format;
135     struct v4l2_crop crop;
136     int ret;
137 
138     LOGI("dumping driver state:");
139     format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
140     ret = ioctl(fd, VIDIOC_G_FMT, &format);
141     if (ret < 0)
142         return;
143     LOGI("output pixfmt:\n");
144     dump_pixfmt(&format.fmt.pix);
145 
146     format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
147     ret = ioctl(fd, VIDIOC_G_FMT, &format);
148     if (ret < 0)
149         return;
150     LOGI("v4l2_overlay window:\n");
151     dump_window(&format.fmt.win);
152 
153     crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
154     ret = ioctl(fd, VIDIOC_G_CROP, &crop);
155     if (ret < 0)
156         return;
157     LOGI("output crop:\n");
158     dump_crop(&crop);
159 /*
160     crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
161     ret = ioctl(fd, VIDIOC_G_CROP, &crop);
162     if (ret < 0)
163         return;
164     LOGI("ovelay crop:\n");
165     dump_crop(&crop);
166 */
167 }
168 
error(int fd,const char * msg)169 static void error(int fd, const char *msg)
170 {
171   LOGE("Error = %s from %s", strerror(errno), msg);
172 #ifdef OVERLAY_DEBUG
173   v4l2_overlay_dump_state(fd);
174 #endif
175 }
176 
v4l2_overlay_ioctl(int fd,int req,void * arg,const char * msg)177 static int v4l2_overlay_ioctl(int fd, int req, void *arg, const char* msg)
178 {
179     int ret;
180     ret = ioctl(fd, req, arg);
181     if (ret < 0) {
182         error(fd, msg);
183         return -1;
184     }
185     return 0;
186 }
187 
configure_pixfmt(struct v4l2_pix_format * pix,int32_t fmt,uint32_t w,uint32_t h)188 int configure_pixfmt(struct v4l2_pix_format *pix, int32_t fmt,
189                      uint32_t w, uint32_t h)
190 {
191     LOG_FUNCTION_NAME
192 
193     int fd;
194 
195     switch (fmt) {
196         case OVERLAY_FORMAT_RGBA_8888:
197             return -1;
198         case OVERLAY_FORMAT_RGB_565:
199             pix->pixelformat = V4L2_PIX_FMT_RGB565;
200             break;
201         case OVERLAY_FORMAT_BGRA_8888:
202             return -1;
203         case OVERLAY_FORMAT_YCbCr_422_SP:
204             break;
205         case OVERLAY_FORMAT_YCbCr_420_SP:
206             return -1;
207         case OVERLAY_FORMAT_YCbYCr_422_I:
208             pix->pixelformat = V4L2_PIX_FMT_YUYV;
209             break;
210         case OVERLAY_FORMAT_CbYCrY_422_I:
211             pix->pixelformat = V4L2_PIX_FMT_UYVY;
212             break;
213         case OVERLAY_FORMAT_YCbYCr_420_I:
214             return -1;
215         case OVERLAY_FORMAT_CbYCrY_420_I:
216             return -1;
217         default:
218             return -1;
219     }
220     pix->width = w;
221     pix->height = h;
222     return 0;
223 }
224 
configure_window(struct v4l2_window * win,int32_t w,int32_t h,int32_t x,int32_t y)225 static void configure_window(struct v4l2_window *win, int32_t w,
226                              int32_t h, int32_t x, int32_t y)
227 {
228     LOG_FUNCTION_NAME
229 
230     win->w.left = x;
231     win->w.top = y;
232     win->w.width = w;
233     win->w.height = h;
234 }
235 
get_window(struct v4l2_format * format,int32_t * x,int32_t * y,int32_t * w,int32_t * h)236 void get_window(struct v4l2_format *format, int32_t *x,
237                 int32_t *y, int32_t *w, int32_t *h)
238 {
239     LOG_FUNCTION_NAME
240 
241     *x = format->fmt.win.w.left;
242     *y = format->fmt.win.w.top;
243     *w = format->fmt.win.w.width;
244     *h = format->fmt.win.w.height;
245 }
246 
v4l2_overlay_init(int fd,uint32_t w,uint32_t h,uint32_t fmt)247 int v4l2_overlay_init(int fd, uint32_t w, uint32_t h, uint32_t fmt)
248 {
249     LOG_FUNCTION_NAME
250 
251     struct v4l2_format format;
252     int ret;
253 
254     /* configure the v4l2_overlay framebuffer */
255     /*
256     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf, "get fbuf");
257     if (ret)
258         return ret;
259     if (fbuf.fmt.pixelformat != dst_format) {
260         fbuf.fmt.pixelformat = dst_format;
261         ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "set fbuf");
262         if (ret)
263             return ret;
264     }
265     */
266 
267     format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
268     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get format");
269     if (ret)
270         return ret;
271     LOGI("v4l2_overlay_init:: w=%d h=%d\n", format.fmt.pix.width, format.fmt.pix.height);
272 
273     format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
274     configure_pixfmt(&format.fmt.pix, fmt, w, h);
275     LOGI("v4l2_overlay_init:: w=%d h=%d\n", format.fmt.pix.width, format.fmt.pix.height);
276     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &format, "set output format");
277 
278     format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
279     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get output format");
280     LOGI("v4l2_overlay_init:: w=%d h=%d\n", format.fmt.pix.width, format.fmt.pix.height);
281     return ret;
282 }
283 
v4l2_overlay_get_input_size_and_format(int fd,uint32_t * w,uint32_t * h,uint32_t * fmt)284 int v4l2_overlay_get_input_size_and_format(int fd, uint32_t *w, uint32_t *h, uint32_t *fmt)
285 {
286     LOG_FUNCTION_NAME
287 
288     struct v4l2_format format;
289     int ret;
290 
291     format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
292     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get format");
293     *w = format.fmt.pix.width;
294     *h = format.fmt.pix.height;
295     //if (format.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY)
296     if (format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
297         *fmt = OVERLAY_FORMAT_CbYCrY_422_I;
298     else return -EINVAL;
299     return ret;
300 }
301 
v4l2_overlay_set_position(int fd,int32_t x,int32_t y,int32_t w,int32_t h)302 int v4l2_overlay_set_position(int fd, int32_t x, int32_t y, int32_t w, int32_t h)
303 {
304     LOG_FUNCTION_NAME
305 
306     struct v4l2_format format;
307     int ret;
308 
309      /* configure the src format pix */
310     /* configure the dst v4l2_overlay window */
311     format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
312     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format,
313                              "get v4l2_overlay format");
314     if (ret)
315        return ret;
316     LOGI("v4l2_overlay_set_position:: w=%d h=%d", format.fmt.win.w.width, format.fmt.win.w.height);
317 
318     configure_window(&format.fmt.win, w, h, x, y);
319 
320     format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
321     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &format,
322                              "set v4l2_overlay format");
323     LOGI("v4l2_overlay_set_position:: w=%d h=%d", format.fmt.win.w.width, format.fmt.win.w.height);
324 
325     if (ret)
326        return ret;
327     v4l2_overlay_dump_state(fd);
328 
329     return 0;
330 }
331 
v4l2_overlay_get_position(int fd,int32_t * x,int32_t * y,int32_t * w,int32_t * h)332 int v4l2_overlay_get_position(int fd, int32_t *x, int32_t *y, int32_t *w, int32_t *h)
333 {
334     struct v4l2_format format;
335     int ret;
336 
337     format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
338     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get v4l2_overlay format");
339     if (ret)
340        return ret;
341     get_window(&format, x, y, w, h);
342     return 0;
343 }
344 
v4l2_overlay_set_crop(int fd,uint32_t x,uint32_t y,uint32_t w,uint32_t h)345 int v4l2_overlay_set_crop(int fd, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
346 {
347     LOG_FUNCTION_NAME
348 
349     struct v4l2_crop crop;
350     int ret;
351 
352     crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
353     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_CROP, &crop, "get crop");
354     crop.c.left = x;
355     crop.c.top = y;
356     crop.c.width = w;
357     crop.c.height = h;
358     crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
359 
360     return v4l2_overlay_ioctl(fd, VIDIOC_S_CROP, &crop, "set crop");
361 }
362 
v4l2_overlay_get_crop(int fd,uint32_t * x,uint32_t * y,uint32_t * w,uint32_t * h)363 int v4l2_overlay_get_crop(int fd, uint32_t *x, uint32_t *y, uint32_t *w, uint32_t *h)
364 {
365     LOG_FUNCTION_NAME
366 
367     struct v4l2_crop crop;
368     int ret;
369 
370     crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
371     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_CROP, &crop, "get crop");
372     *x = crop.c.left;
373     *y = crop.c.top;
374     *w = crop.c.width;
375     *h = crop.c.height;
376     return ret;
377 }
378 
v4l2_overlay_set_rotation(int fd,int degree,int step)379 int v4l2_overlay_set_rotation(int fd, int degree, int step)
380 {
381     LOG_FUNCTION_NAME
382 
383     int ret;
384     struct v4l2_control ctrl;
385 
386     ctrl.id = V4L2_CID_ROTATE;
387     ctrl.value = degree;
388     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_CTRL, &ctrl, "set rotation");
389 
390     return ret;
391 }
392 
v4l2_overlay_set_colorkey(int fd,int enable,int colorkey)393 int v4l2_overlay_set_colorkey(int fd, int enable, int colorkey)
394 {
395     LOG_FUNCTION_NAME
396 
397     int ret;
398     struct v4l2_framebuffer fbuf;
399     struct v4l2_format fmt;
400 
401     memset(&fbuf, 0, sizeof(fbuf));
402     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf, "get transparency enables");
403 
404     if (ret)
405         return ret;
406 
407     if (enable)
408         fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY;
409     else
410         fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY;
411 
412     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "enable colorkey");
413 
414     if (ret)
415         return ret;
416 
417     if (enable)
418 
419     {
420         memset(&fmt, 0, sizeof(fmt));
421         fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
422         ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &fmt, "get colorkey");
423 
424         if (ret)
425             return ret;
426 
427         fmt.fmt.win.chromakey = colorkey & 0xFFFFFF;
428 
429         ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &fmt, "set colorkey");
430     }
431 
432     return ret;
433 }
434 
v4l2_overlay_set_global_alpha(int fd,int enable,int alpha)435 int v4l2_overlay_set_global_alpha(int fd, int enable, int alpha)
436 {
437     LOG_FUNCTION_NAME
438 
439     int ret;
440     struct v4l2_framebuffer fbuf;
441     struct v4l2_format fmt;
442 
443     memset(&fbuf, 0, sizeof(fbuf));
444     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf, "get transparency enables");
445 
446     if (ret)
447         return ret;
448 
449     if (enable)
450         fbuf.flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
451     else
452         fbuf.flags &= ~V4L2_FBUF_FLAG_GLOBAL_ALPHA;
453 
454     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "enable global alpha");
455 
456     if (ret)
457         return ret;
458 
459     if (enable)
460     {
461         memset(&fmt, 0, sizeof(fmt));
462         fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
463         ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &fmt, "get global alpha");
464 
465         if (ret)
466             return ret;
467 
468         fmt.fmt.win.global_alpha = alpha & 0xFF;
469 
470         ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &fmt, "set global alpha");
471     }
472 
473     return ret;
474 }
475 
v4l2_overlay_set_local_alpha(int fd,int enable)476 int v4l2_overlay_set_local_alpha(int fd, int enable)
477 {
478     int ret;
479     struct v4l2_framebuffer fbuf;
480 
481     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf,
482                              "get transparency enables");
483 
484     if (ret)
485         return ret;
486 
487     if (enable)
488         fbuf.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
489     else
490         fbuf.flags &= ~V4L2_FBUF_FLAG_LOCAL_ALPHA;
491 
492     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "enable global alpha");
493 
494     return ret;
495 }
496 
v4l2_overlay_req_buf(int fd,uint32_t * num_bufs,int cacheable_buffers)497 int v4l2_overlay_req_buf(int fd, uint32_t *num_bufs, int cacheable_buffers)
498 {
499     LOG_FUNCTION_NAME
500 
501     struct v4l2_requestbuffers reqbuf;
502     int ret, i;
503     reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
504     reqbuf.memory = V4L2_MEMORY_MMAP;
505     reqbuf.count = *num_bufs;
506     //reqbuf.reserved[0] = cacheable_buffers;
507     ret = ioctl(fd, VIDIOC_REQBUFS, &reqbuf);
508     if (ret < 0) {
509         error(fd, "reqbuf ioctl");
510         return ret;
511     }
512     LOGI("%d buffers allocated %d requested\n", reqbuf.count, 4);
513     if (reqbuf.count > *num_bufs) {
514         error(fd, "Not enough buffer structs passed to get_buffers");
515         return -ENOMEM;
516     }
517     *num_bufs = reqbuf.count;
518     LOGI("buffer cookie is %d\n", reqbuf.type);
519     return 0;
520 }
521 
is_mmaped(struct v4l2_buffer * buf)522 static int is_mmaped(struct v4l2_buffer *buf)
523 {
524     return buf->flags == V4L2_BUF_FLAG_MAPPED;
525 }
526 
is_queued(struct v4l2_buffer * buf)527 static int is_queued(struct v4l2_buffer *buf)
528 {
529     /* is either on the input or output queue in the kernel */
530     return (buf->flags & V4L2_BUF_FLAG_QUEUED) ||
531            (buf->flags & V4L2_BUF_FLAG_DONE);
532 }
533 
is_dequeued(struct v4l2_buffer * buf)534 static int is_dequeued(struct v4l2_buffer *buf)
535 {
536     /* is on neither input or output queue in kernel */
537     return (!(buf->flags & V4L2_BUF_FLAG_QUEUED) &&
538             !(buf->flags & V4L2_BUF_FLAG_DONE));
539 }
540 
v4l2_overlay_query_buffer(int fd,int index,struct v4l2_buffer * buf)541 int v4l2_overlay_query_buffer(int fd, int index, struct v4l2_buffer *buf)
542 {
543     LOG_FUNCTION_NAME
544 
545     memset(buf, 0, sizeof(struct v4l2_buffer));
546 
547     buf->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
548     buf->memory = V4L2_MEMORY_MMAP;
549     buf->index = index;
550     LOGI("query buffer, mem=%u type=%u index=%u\n", buf->memory, buf->type,
551          buf->index);
552     return v4l2_overlay_ioctl(fd, VIDIOC_QUERYBUF, buf, "querybuf ioctl");
553 }
554 
v4l2_overlay_map_buf(int fd,int index,void ** start,size_t * len)555 int v4l2_overlay_map_buf(int fd, int index, void **start, size_t *len)
556 {
557     LOG_FUNCTION_NAME
558 
559     struct v4l2_buffer buf;
560     int ret;
561 
562     ret = v4l2_overlay_query_buffer(fd, index, &buf);
563     if (ret)
564         return ret;
565 
566     if (is_mmaped(&buf)) {
567         LOGE("Trying to mmap buffers that are already mapped!\n");
568         return -EINVAL;
569     }
570 
571     *len = buf.length;
572     *start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED,
573                   fd, buf.m.offset);
574     if (*start == MAP_FAILED) {
575         LOGE("map failed, length=%u offset=%u\n", buf.length, buf.m.offset);
576         return -EINVAL;
577     }
578     return 0;
579 }
580 
v4l2_overlay_unmap_buf(void * start,size_t len)581 int v4l2_overlay_unmap_buf(void *start, size_t len)
582 {
583     LOG_FUNCTION_NAME
584 
585   return munmap(start, len);
586 }
587 
588 
v4l2_overlay_get_caps(int fd,struct v4l2_capability * caps)589 int v4l2_overlay_get_caps(int fd, struct v4l2_capability *caps)
590 {
591     return v4l2_overlay_ioctl(fd, VIDIOC_QUERYCAP, caps, "query cap");
592 }
593 
v4l2_overlay_stream_on(int fd)594 int v4l2_overlay_stream_on(int fd)
595 {
596     LOG_FUNCTION_NAME
597 
598     int ret;
599     uint32_t type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
600 
601     ret = v4l2_overlay_set_local_alpha(fd, 1);
602     if (ret)
603         return ret;
604 
605     ret = v4l2_overlay_ioctl(fd, VIDIOC_STREAMON, &type, "stream on");
606 
607     return ret;
608 }
609 
v4l2_overlay_stream_off(int fd)610 int v4l2_overlay_stream_off(int fd)
611 {
612     LOG_FUNCTION_NAME
613 
614     int ret;
615     uint32_t type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
616 
617     ret = v4l2_overlay_set_local_alpha(fd, 0);
618     if (ret)
619         return ret;
620 
621     ret = v4l2_overlay_ioctl(fd, VIDIOC_STREAMOFF, &type, "stream off");
622 
623     return ret;
624 }
625 
v4l2_overlay_q_buf(int fd,int index)626 int v4l2_overlay_q_buf(int fd, int index)
627 {
628     struct v4l2_buffer buf;
629     int ret;
630 
631     /*
632     ret = v4l2_overlay_query_buffer(fd, buffer_cookie, index, &buf);
633     if (ret)
634         return ret;
635     if (is_queued(buf)) {
636         LOGE("Trying to queue buffer to kernel that is already queued!\n");
637         return -EINVAL
638     }
639     */
640     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
641     buf.index = index;
642     buf.memory = V4L2_MEMORY_MMAP;
643     buf.field = V4L2_FIELD_NONE;
644     buf.timestamp.tv_sec = 0;
645     buf.timestamp.tv_usec = 0;
646     buf.flags = 0;
647 
648     return v4l2_overlay_ioctl(fd, VIDIOC_QBUF, &buf, "qbuf");
649 }
650 
v4l2_overlay_dq_buf(int fd,int * index)651 int v4l2_overlay_dq_buf(int fd, int *index)
652 {
653     struct v4l2_buffer buf;
654     int ret;
655 
656     /*
657     ret = v4l2_overlay_query_buffer(fd, buffer_cookie, index, &buf);
658     if (ret)
659         return ret;
660 
661     if (is_dequeued(buf)) {
662         LOGE("Trying to dequeue buffer that is not in kernel!\n");
663         return -EINVAL
664     }
665     */
666     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
667     buf.memory = V4L2_MEMORY_MMAP;
668 
669     ret = v4l2_overlay_ioctl(fd, VIDIOC_DQBUF, &buf, "dqbuf");
670     if (ret)
671       return ret;
672     *index = buf.index;
673     return 0;
674 }
675