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