• 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_RGB_565:
197             pix->pixelformat = V4L2_PIX_FMT_RGB565;
198             break;
199         case OVERLAY_FORMAT_YCbYCr_422_I:
200             pix->pixelformat = V4L2_PIX_FMT_YUYV;
201             break;
202         case OVERLAY_FORMAT_CbYCrY_422_I:
203             pix->pixelformat = V4L2_PIX_FMT_UYVY;
204             break;
205         default:
206             return -1;
207     }
208     pix->width = w;
209     pix->height = h;
210     return 0;
211 }
212 
configure_window(struct v4l2_window * win,int32_t w,int32_t h,int32_t x,int32_t y)213 static void configure_window(struct v4l2_window *win, int32_t w,
214                              int32_t h, int32_t x, int32_t y)
215 {
216     LOG_FUNCTION_NAME
217 
218     win->w.left = x;
219     win->w.top = y;
220     win->w.width = w;
221     win->w.height = h;
222 }
223 
get_window(struct v4l2_format * format,int32_t * x,int32_t * y,int32_t * w,int32_t * h)224 void get_window(struct v4l2_format *format, int32_t *x,
225                 int32_t *y, int32_t *w, int32_t *h)
226 {
227     LOG_FUNCTION_NAME
228 
229     *x = format->fmt.win.w.left;
230     *y = format->fmt.win.w.top;
231     *w = format->fmt.win.w.width;
232     *h = format->fmt.win.w.height;
233 }
234 
v4l2_overlay_init(int fd,uint32_t w,uint32_t h,uint32_t fmt)235 int v4l2_overlay_init(int fd, uint32_t w, uint32_t h, uint32_t fmt)
236 {
237     LOG_FUNCTION_NAME
238 
239     struct v4l2_format format;
240     int ret;
241 
242     /* configure the v4l2_overlay framebuffer */
243     /*
244     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf, "get fbuf");
245     if (ret)
246         return ret;
247     if (fbuf.fmt.pixelformat != dst_format) {
248         fbuf.fmt.pixelformat = dst_format;
249         ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "set fbuf");
250         if (ret)
251             return ret;
252     }
253     */
254 
255     format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
256     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get format");
257     if (ret)
258         return ret;
259     LOGI("v4l2_overlay_init:: w=%d h=%d\n", format.fmt.pix.width, format.fmt.pix.height);
260 
261     format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
262     configure_pixfmt(&format.fmt.pix, fmt, w, h);
263     LOGI("v4l2_overlay_init:: w=%d h=%d\n", format.fmt.pix.width, format.fmt.pix.height);
264     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &format, "set output format");
265 
266     format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
267     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get output format");
268     LOGI("v4l2_overlay_init:: w=%d h=%d\n", format.fmt.pix.width, format.fmt.pix.height);
269     return ret;
270 }
271 
v4l2_overlay_get_input_size_and_format(int fd,uint32_t * w,uint32_t * h,uint32_t * fmt)272 int v4l2_overlay_get_input_size_and_format(int fd, uint32_t *w, uint32_t *h, uint32_t *fmt)
273 {
274     LOG_FUNCTION_NAME
275 
276     struct v4l2_format format;
277     int ret;
278 
279     format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
280     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get format");
281     *w = format.fmt.pix.width;
282     *h = format.fmt.pix.height;
283     //if (format.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY)
284     if (format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
285         *fmt = OVERLAY_FORMAT_CbYCrY_422_I;
286     else return -EINVAL;
287     return ret;
288 }
289 
v4l2_overlay_set_position(int fd,int32_t x,int32_t y,int32_t w,int32_t h)290 int v4l2_overlay_set_position(int fd, int32_t x, int32_t y, int32_t w, int32_t h)
291 {
292     LOG_FUNCTION_NAME
293 
294     struct v4l2_format format;
295     int ret;
296 
297      /* configure the src format pix */
298     /* configure the dst v4l2_overlay window */
299     format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
300     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format,
301                              "get v4l2_overlay format");
302     if (ret)
303        return ret;
304     LOGI("v4l2_overlay_set_position:: w=%d h=%d", format.fmt.win.w.width, format.fmt.win.w.height);
305 
306     configure_window(&format.fmt.win, w, h, x, y);
307 
308     format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
309     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &format,
310                              "set v4l2_overlay format");
311     LOGI("v4l2_overlay_set_position:: w=%d h=%d", format.fmt.win.w.width, format.fmt.win.w.height);
312 
313     if (ret)
314        return ret;
315     v4l2_overlay_dump_state(fd);
316 
317     return 0;
318 }
319 
v4l2_overlay_get_position(int fd,int32_t * x,int32_t * y,int32_t * w,int32_t * h)320 int v4l2_overlay_get_position(int fd, int32_t *x, int32_t *y, int32_t *w, int32_t *h)
321 {
322     struct v4l2_format format;
323     int ret;
324 
325     format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
326     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get v4l2_overlay format");
327     if (ret)
328        return ret;
329     get_window(&format, x, y, w, h);
330     return 0;
331 }
332 
v4l2_overlay_set_crop(int fd,uint32_t x,uint32_t y,uint32_t w,uint32_t h)333 int v4l2_overlay_set_crop(int fd, uint32_t x, uint32_t y, uint32_t w, uint32_t h)
334 {
335     LOG_FUNCTION_NAME
336 
337     struct v4l2_crop crop;
338     int ret;
339 
340     crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
341     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_CROP, &crop, "get crop");
342     crop.c.left = x;
343     crop.c.top = y;
344     crop.c.width = w;
345     crop.c.height = h;
346     crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
347 
348     return v4l2_overlay_ioctl(fd, VIDIOC_S_CROP, &crop, "set crop");
349 }
350 
v4l2_overlay_get_crop(int fd,uint32_t * x,uint32_t * y,uint32_t * w,uint32_t * h)351 int v4l2_overlay_get_crop(int fd, uint32_t *x, uint32_t *y, uint32_t *w, uint32_t *h)
352 {
353     LOG_FUNCTION_NAME
354 
355     struct v4l2_crop crop;
356     int ret;
357 
358     crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
359     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_CROP, &crop, "get crop");
360     *x = crop.c.left;
361     *y = crop.c.top;
362     *w = crop.c.width;
363     *h = crop.c.height;
364     return ret;
365 }
366 
v4l2_overlay_set_rotation(int fd,int degree,int step)367 int v4l2_overlay_set_rotation(int fd, int degree, int step)
368 {
369     LOG_FUNCTION_NAME
370 
371     int ret;
372     struct v4l2_control ctrl;
373 
374     ctrl.id = V4L2_CID_ROTATE;
375     ctrl.value = degree;
376     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_CTRL, &ctrl, "set rotation");
377 
378     return ret;
379 }
380 
v4l2_overlay_set_colorkey(int fd,int enable,int colorkey)381 int v4l2_overlay_set_colorkey(int fd, int enable, int colorkey)
382 {
383     LOG_FUNCTION_NAME
384 
385     int ret;
386     struct v4l2_framebuffer fbuf;
387     struct v4l2_format fmt;
388 
389     memset(&fbuf, 0, sizeof(fbuf));
390     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf, "get transparency enables");
391 
392     if (ret)
393         return ret;
394 
395     if (enable)
396         fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY;
397     else
398         fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY;
399 
400     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "enable colorkey");
401 
402     if (ret)
403         return ret;
404 
405     if (enable)
406 
407     {
408         memset(&fmt, 0, sizeof(fmt));
409         fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
410         ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &fmt, "get colorkey");
411 
412         if (ret)
413             return ret;
414 
415         fmt.fmt.win.chromakey = colorkey & 0xFFFFFF;
416 
417         ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &fmt, "set colorkey");
418     }
419 
420     return ret;
421 }
422 
v4l2_overlay_set_global_alpha(int fd,int enable,int alpha)423 int v4l2_overlay_set_global_alpha(int fd, int enable, int alpha)
424 {
425     LOG_FUNCTION_NAME
426 
427     int ret;
428     struct v4l2_framebuffer fbuf;
429     struct v4l2_format fmt;
430 
431     memset(&fbuf, 0, sizeof(fbuf));
432     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf, "get transparency enables");
433 
434     if (ret)
435         return ret;
436 
437     if (enable)
438         fbuf.flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
439     else
440         fbuf.flags &= ~V4L2_FBUF_FLAG_GLOBAL_ALPHA;
441 
442     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "enable global alpha");
443 
444     if (ret)
445         return ret;
446 
447     if (enable)
448     {
449         memset(&fmt, 0, sizeof(fmt));
450         fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
451         ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &fmt, "get global alpha");
452 
453         if (ret)
454             return ret;
455 
456         fmt.fmt.win.global_alpha = alpha & 0xFF;
457 
458         ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &fmt, "set global alpha");
459     }
460 
461     return ret;
462 }
463 
v4l2_overlay_set_local_alpha(int fd,int enable)464 int v4l2_overlay_set_local_alpha(int fd, int enable)
465 {
466     int ret;
467     struct v4l2_framebuffer fbuf;
468 
469     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf,
470                              "get transparency enables");
471 
472     if (ret)
473         return ret;
474 
475     if (enable)
476         fbuf.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
477     else
478         fbuf.flags &= ~V4L2_FBUF_FLAG_LOCAL_ALPHA;
479 
480     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "enable global alpha");
481 
482     return ret;
483 }
484 
v4l2_overlay_req_buf(int fd,uint32_t * num_bufs,int cacheable_buffers)485 int v4l2_overlay_req_buf(int fd, uint32_t *num_bufs, int cacheable_buffers)
486 {
487     LOG_FUNCTION_NAME
488 
489     struct v4l2_requestbuffers reqbuf;
490     int ret, i;
491     reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
492     reqbuf.memory = V4L2_MEMORY_MMAP;
493     reqbuf.count = *num_bufs;
494     //reqbuf.reserved[0] = cacheable_buffers;
495     ret = ioctl(fd, VIDIOC_REQBUFS, &reqbuf);
496     if (ret < 0) {
497         error(fd, "reqbuf ioctl");
498         return ret;
499     }
500     LOGI("%d buffers allocated %d requested\n", reqbuf.count, 4);
501     if (reqbuf.count > *num_bufs) {
502         error(fd, "Not enough buffer structs passed to get_buffers");
503         return -ENOMEM;
504     }
505     *num_bufs = reqbuf.count;
506     LOGI("buffer cookie is %d\n", reqbuf.type);
507     return 0;
508 }
509 
is_mmaped(struct v4l2_buffer * buf)510 static int is_mmaped(struct v4l2_buffer *buf)
511 {
512     return buf->flags == V4L2_BUF_FLAG_MAPPED;
513 }
514 
is_queued(struct v4l2_buffer * buf)515 static int is_queued(struct v4l2_buffer *buf)
516 {
517     /* is either on the input or output queue in the kernel */
518     return (buf->flags & V4L2_BUF_FLAG_QUEUED) ||
519            (buf->flags & V4L2_BUF_FLAG_DONE);
520 }
521 
is_dequeued(struct v4l2_buffer * buf)522 static int is_dequeued(struct v4l2_buffer *buf)
523 {
524     /* is on neither input or output queue in kernel */
525     return (!(buf->flags & V4L2_BUF_FLAG_QUEUED) &&
526             !(buf->flags & V4L2_BUF_FLAG_DONE));
527 }
528 
v4l2_overlay_query_buffer(int fd,int index,struct v4l2_buffer * buf)529 int v4l2_overlay_query_buffer(int fd, int index, struct v4l2_buffer *buf)
530 {
531     LOG_FUNCTION_NAME
532 
533     memset(buf, 0, sizeof(struct v4l2_buffer));
534 
535     buf->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
536     buf->memory = V4L2_MEMORY_MMAP;
537     buf->index = index;
538     LOGI("query buffer, mem=%u type=%u index=%u\n", buf->memory, buf->type,
539          buf->index);
540     return v4l2_overlay_ioctl(fd, VIDIOC_QUERYBUF, buf, "querybuf ioctl");
541 }
542 
v4l2_overlay_map_buf(int fd,int index,void ** start,size_t * len)543 int v4l2_overlay_map_buf(int fd, int index, void **start, size_t *len)
544 {
545     LOG_FUNCTION_NAME
546 
547     struct v4l2_buffer buf;
548     int ret;
549 
550     ret = v4l2_overlay_query_buffer(fd, index, &buf);
551     if (ret)
552         return ret;
553 
554     if (is_mmaped(&buf)) {
555         LOGE("Trying to mmap buffers that are already mapped!\n");
556         return -EINVAL;
557     }
558 
559     *len = buf.length;
560     *start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED,
561                   fd, buf.m.offset);
562     if (*start == MAP_FAILED) {
563         LOGE("map failed, length=%u offset=%u\n", buf.length, buf.m.offset);
564         return -EINVAL;
565     }
566     return 0;
567 }
568 
v4l2_overlay_unmap_buf(void * start,size_t len)569 int v4l2_overlay_unmap_buf(void *start, size_t len)
570 {
571     LOG_FUNCTION_NAME
572 
573   return munmap(start, len);
574 }
575 
576 
v4l2_overlay_get_caps(int fd,struct v4l2_capability * caps)577 int v4l2_overlay_get_caps(int fd, struct v4l2_capability *caps)
578 {
579     return v4l2_overlay_ioctl(fd, VIDIOC_QUERYCAP, caps, "query cap");
580 }
581 
v4l2_overlay_stream_on(int fd)582 int v4l2_overlay_stream_on(int fd)
583 {
584     LOG_FUNCTION_NAME
585 
586     int ret;
587     uint32_t type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
588 
589     ret = v4l2_overlay_set_local_alpha(fd, 1);
590     if (ret)
591         return ret;
592 
593     ret = v4l2_overlay_ioctl(fd, VIDIOC_STREAMON, &type, "stream on");
594 
595     return ret;
596 }
597 
v4l2_overlay_stream_off(int fd)598 int v4l2_overlay_stream_off(int fd)
599 {
600     LOG_FUNCTION_NAME
601 
602     int ret;
603     uint32_t type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
604 
605     ret = v4l2_overlay_set_local_alpha(fd, 0);
606     if (ret)
607         return ret;
608 
609     ret = v4l2_overlay_ioctl(fd, VIDIOC_STREAMOFF, &type, "stream off");
610 
611     return ret;
612 }
613 
v4l2_overlay_q_buf(int fd,int index)614 int v4l2_overlay_q_buf(int fd, int index)
615 {
616     struct v4l2_buffer buf;
617     int ret;
618 
619     /*
620     ret = v4l2_overlay_query_buffer(fd, buffer_cookie, index, &buf);
621     if (ret)
622         return ret;
623     if (is_queued(buf)) {
624         LOGE("Trying to queue buffer to kernel that is already queued!\n");
625         return -EINVAL
626     }
627     */
628     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
629     buf.index = index;
630     buf.memory = V4L2_MEMORY_MMAP;
631     buf.field = V4L2_FIELD_NONE;
632     buf.timestamp.tv_sec = 0;
633     buf.timestamp.tv_usec = 0;
634     buf.flags = 0;
635 
636     return v4l2_overlay_ioctl(fd, VIDIOC_QBUF, &buf, "qbuf");
637 }
638 
v4l2_overlay_dq_buf(int fd,int * index)639 int v4l2_overlay_dq_buf(int fd, int *index)
640 {
641     struct v4l2_buffer buf;
642     int ret;
643 
644     /*
645     ret = v4l2_overlay_query_buffer(fd, buffer_cookie, index, &buf);
646     if (ret)
647         return ret;
648 
649     if (is_dequeued(buf)) {
650         LOGE("Trying to dequeue buffer that is not in kernel!\n");
651         return -EINVAL
652     }
653     */
654     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
655     buf.memory = V4L2_MEMORY_MMAP;
656 
657     ret = v4l2_overlay_ioctl(fd, VIDIOC_DQBUF, &buf, "dqbuf");
658     if (ret)
659       return ret;
660     *index = buf.index;
661     return 0;
662 }
663