Home | History | Annotate | Download | only in liboverlay
      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 "v4l2_utils"
     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 
     30 #define LOG_FUNCTION_NAME    LOGV("%s: %s",  __FILE__, __func__);
     31 
     32 #define V4L2_CID_PRIV_OFFSET         0x0
     33 #define V4L2_CID_PRIV_ROTATION       (V4L2_CID_PRIVATE_BASE \
     34         + V4L2_CID_PRIV_OFFSET + 0)
     35 #define V4L2_CID_PRIV_COLORKEY       (V4L2_CID_PRIVATE_BASE \
     36         + V4L2_CID_PRIV_OFFSET + 1)
     37 #define V4L2_CID_PRIV_COLORKEY_EN    (V4L2_CID_PRIVATE_BASE \
     38         + V4L2_CID_PRIV_OFFSET + 2)
     39 
     40 extern unsigned int g_lcd_width;
     41 extern unsigned int g_lcd_height;
     42 extern unsigned int g_lcd_bpp;
     43 
     44 int v4l2_overlay_get(int name)
     45 {
     46     int result = -1;
     47     switch (name) {
     48     case OVERLAY_MINIFICATION_LIMIT:
     49         result = 4; /* 0 = no limit */
     50         break;
     51     case OVERLAY_MAGNIFICATION_LIMIT:
     52         result = 2; /* 0 = no limit */
     53         break;
     54     case OVERLAY_SCALING_FRAC_BITS:
     55         result = 0; /* 0 = infinite */
     56         break;
     57     case OVERLAY_ROTATION_STEP_DEG:
     58         result = 90; /* 90 rotation steps (for instance) */
     59         break;
     60     case OVERLAY_HORIZONTAL_ALIGNMENT:
     61         result = 1; /* 1-pixel alignment */
     62         break;
     63     case OVERLAY_VERTICAL_ALIGNMENT:
     64         result = 1; /* 1-pixel alignment */
     65         break;
     66     case OVERLAY_WIDTH_ALIGNMENT:
     67         result = 1; /* 1-pixel alignment */
     68         break;
     69     case OVERLAY_HEIGHT_ALIGNMENT:
     70         result = 1; /* 1-pixel alignment */
     71         break;
     72     }
     73     return result;
     74 }
     75 
     76 int v4l2_overlay_open(int id)
     77 {
     78     LOG_FUNCTION_NAME
     79     return open("/dev/video1", O_RDWR);
     80 }
     81 
     82 int v4l2_overlay_init_fimc(int fd, s5p_fimc_t *s5p_fimc)
     83 {
     84     int ret;
     85     struct v4l2_control    vc;
     86 
     87     if (fd < 0)
     88         return -1;
     89 
     90     vc.id = V4L2_CID_FIMC_VERSION;
     91     vc.value = 0;
     92 
     93     s5p_fimc->dev_fd = fd;
     94 
     95     ret = ioctl(s5p_fimc->dev_fd, VIDIOC_G_CTRL, &vc);
     96     if (ret < 0) {
     97         LOGE("Error in video VIDIOC_G_CTRL - V4L2_CID_FIMC_VERSION (%d)", ret);
     98         LOGE("FIMC version is set with default");
     99         vc.value = 0x43;
    100     }
    101     s5p_fimc->hw_ver = vc.value;
    102     return 0;
    103 }
    104 
    105 void dump_pixfmt(struct v4l2_pix_format *pix)
    106 {
    107     LOGV("w: %d\n", pix->width);
    108     LOGV("h: %d\n", pix->height);
    109     LOGV("color: %x\n", pix->colorspace);
    110 
    111     switch (pix->pixelformat) {
    112     case V4L2_PIX_FMT_YUYV:
    113         LOGV("YUYV\n");
    114         break;
    115     case V4L2_PIX_FMT_UYVY:
    116         LOGV("UYVY\n");
    117         break;
    118     case V4L2_PIX_FMT_RGB565:
    119         LOGV("RGB565\n");
    120         break;
    121     case V4L2_PIX_FMT_RGB565X:
    122         LOGV("RGB565X\n");
    123         break;
    124     default:
    125         LOGV("not supported\n");
    126     }
    127 }
    128 
    129 void dump_crop(struct v4l2_crop *crop)
    130 {
    131     LOGV("crop l: %d ", crop->c.left);
    132     LOGV("crop t: %d ", crop->c.top);
    133     LOGV("crop w: %d ", crop->c.width);
    134     LOGV("crop h: %d\n", crop->c.height);
    135 }
    136 
    137 void dump_window(struct v4l2_window *win)
    138 {
    139     LOGV("window l: %d ", win->w.left);
    140     LOGV("window t: %d ", win->w.top);
    141     LOGV("window w: %d ", win->w.width);
    142     LOGV("window h: %d\n", win->w.height);
    143 }
    144 
    145 void v4l2_overlay_dump_state(int fd)
    146 {
    147     struct v4l2_format format;
    148     struct v4l2_crop crop;
    149     int ret;
    150 
    151     LOGV("dumping driver state:");
    152     format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    153     ret = ioctl(fd, VIDIOC_G_FMT, &format);
    154     if (ret < 0)
    155         return;
    156     LOGV("output pixfmt:\n");
    157     dump_pixfmt(&format.fmt.pix);
    158 
    159     format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
    160     ret = ioctl(fd, VIDIOC_G_FMT, &format);
    161     if (ret < 0)
    162         return;
    163     LOGV("v4l2_overlay window:\n");
    164     dump_window(&format.fmt.win);
    165 
    166     crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    167     ret = ioctl(fd, VIDIOC_G_CROP, &crop);
    168     if (ret < 0)
    169         return;
    170     LOGV("output crop:\n");
    171     dump_crop(&crop);
    172 }
    173 
    174 static void error(int fd, const char *msg)
    175 {
    176     LOGE("Error = %s from %s", strerror(errno), msg);
    177 #ifdef OVERLAY_DEBUG
    178     v4l2_overlay_dump_state(fd);
    179 #endif
    180 }
    181 
    182 static int v4l2_overlay_ioctl(int fd, int req, void *arg, const char* msg)
    183 {
    184     int ret;
    185     ret = ioctl(fd, req, arg);
    186     if (ret < 0) {
    187         error(fd, msg);
    188         return -1;
    189     }
    190     return 0;
    191 }
    192 
    193 #define v4l2_fourcc(a, b, c, d)  ((__u32)(a) | ((__u32)(b) << 8) | \
    194                                  ((__u32)(c) << 16) | ((__u32)(d) << 24))
    195 /* 12  Y/CbCr 4:2:0 64x32 macroblocks */
    196 #define V4L2_PIX_FMT_NV12T       v4l2_fourcc('T', 'V', '1', '2')
    197 
    198 int configure_pixfmt(struct v4l2_pix_format *pix, int32_t fmt,
    199         uint32_t w, uint32_t h)
    200 {
    201     LOG_FUNCTION_NAME
    202     int fd;
    203 
    204     switch (fmt) {
    205     case OVERLAY_FORMAT_RGBA_8888:
    206         return -1;
    207     case OVERLAY_FORMAT_RGB_565:
    208         pix->pixelformat = V4L2_PIX_FMT_RGB565;
    209         break;
    210     case OVERLAY_FORMAT_BGRA_8888:
    211         return -1;
    212     case OVERLAY_FORMAT_YCbYCr_422_I:
    213     case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I:
    214         pix->pixelformat = V4L2_PIX_FMT_YUYV;
    215         break;
    216     case OVERLAY_FORMAT_CbYCrY_422_I:
    217     case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I:
    218         pix->pixelformat = V4L2_PIX_FMT_UYVY;
    219         break;
    220     case HAL_PIXEL_FORMAT_YCbCr_420_P:
    221         pix->pixelformat = V4L2_PIX_FMT_YUV420;
    222         break;
    223     case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP:
    224         pix->pixelformat = V4L2_PIX_FMT_NV12T;
    225         break;
    226     case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP:
    227         pix->pixelformat = V4L2_PIX_FMT_NV21;
    228         break;
    229     default:
    230         return -1;
    231     }
    232     pix->width = w;
    233     pix->height = h;
    234     return 0;
    235 }
    236 
    237 static void configure_window(struct v4l2_window *win, int32_t w,
    238         int32_t h, int32_t x, int32_t y)
    239 {
    240     LOG_FUNCTION_NAME
    241 
    242     win->w.left = x;
    243     win->w.top = y;
    244     win->w.width = w;
    245     win->w.height = h;
    246 }
    247 
    248 void get_window(struct v4l2_format *format, int32_t *x,
    249         int32_t *y, int32_t *w, int32_t *h)
    250 {
    251     LOG_FUNCTION_NAME
    252 
    253     *x = format->fmt.win.w.left;
    254     *y = format->fmt.win.w.top;
    255     *w = format->fmt.win.w.width;
    256     *h = format->fmt.win.w.height;
    257 }
    258 
    259 int v4l2_overlay_init(int fd, uint32_t w, uint32_t h, uint32_t fmt,
    260                       uint32_t addr)
    261 {
    262     LOG_FUNCTION_NAME
    263 
    264     struct v4l2_format format;
    265     struct v4l2_framebuffer fbuf;
    266     int ret;
    267 
    268     format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    269     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get format");
    270     if (ret)
    271         return ret;
    272     LOGV("v4l2_overlay_init:: w=%d h=%d\n", format.fmt.pix.width,
    273          format.fmt.pix.height);
    274 
    275     format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    276     configure_pixfmt(&format.fmt.pix, fmt, w, h);
    277     LOGV("v4l2_overlay_init:: w=%d h=%d\n", format.fmt.pix.width,
    278          format.fmt.pix.height);
    279     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &format, "set output format");
    280     if (ret)
    281         return ret;
    282 
    283     ret = v4l2_overlay_s_fbuf(fd, 0);
    284     if (ret)
    285         return ret;
    286 
    287     return ret;
    288 }
    289 
    290 int v4l2_overlay_s_fbuf(int fd, int rotation)
    291 {
    292     struct v4l2_framebuffer fbuf;
    293     int ret;
    294 
    295     /* configure the v4l2_overlay framebuffer */
    296     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf, "get fbuf");
    297     if (ret)
    298         return ret;
    299 
    300     /* if fbuf.base value is set by 0, using local DMA. */
    301     fbuf.base             = (void *)0;
    302     if (rotation == 0 || rotation == 180) {
    303         fbuf.fmt.width         = g_lcd_width;
    304         fbuf.fmt.height     = g_lcd_height;
    305     } else {
    306         fbuf.fmt.width         = g_lcd_height;
    307         fbuf.fmt.height     = g_lcd_width;
    308     }
    309 
    310     if (g_lcd_bpp == 32)
    311         fbuf.fmt.pixelformat     = V4L2_PIX_FMT_RGB32;
    312     else
    313         fbuf.fmt.pixelformat     = V4L2_PIX_FMT_RGB565;
    314 
    315     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "set fbuf");
    316     if (ret)
    317         return ret;
    318 
    319     return ret;
    320 }
    321 
    322 int v4l2_overlay_get_input_size_and_format(int fd, uint32_t *w, uint32_t *h
    323                                                  , uint32_t *fmt)
    324 {
    325     LOG_FUNCTION_NAME
    326 
    327     struct v4l2_format format;
    328     int ret;
    329 
    330     format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    331     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format, "get format");
    332     *w = format.fmt.pix.width;
    333     *h = format.fmt.pix.height;
    334     if (format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
    335         *fmt = OVERLAY_FORMAT_CbYCrY_422_I;
    336     else
    337         return -EINVAL;
    338     return ret;
    339 }
    340 
    341 int v4l2_overlay_set_position(int fd, int32_t x, int32_t y
    342                                     , int32_t w, int32_t h, int rotation)
    343 {
    344     LOG_FUNCTION_NAME
    345 
    346     struct v4l2_format format;
    347     int ret;
    348     int rot_x = 0, rot_y = 0 , rot_w = 0, rot_h = 0;
    349 
    350     /* configure the src format pix */
    351     /* configure the dst v4l2_overlay window */
    352     format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
    353     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format,
    354             "get v4l2_overlay format");
    355     if (ret)
    356         return ret;
    357     LOGV("v4l2_overlay_set_position:: w=%d h=%d", format.fmt.win.w.width
    358                                                 , format.fmt.win.w.height);
    359 
    360     if (rotation == 0) {
    361         rot_x = x;
    362         rot_y = y;
    363         rot_w = w;
    364         rot_h = h;
    365     } else if (rotation == 90) {
    366         rot_x = y;
    367         rot_y = g_lcd_width - (x + w);
    368         rot_w = h;
    369         rot_h = w;
    370     } else if (rotation == 180) {
    371         rot_x = g_lcd_width - (x + w);
    372         rot_y = g_lcd_height - (y + h);
    373         rot_w = w;
    374         rot_h = h;
    375     } else if (rotation == 270) {
    376         rot_x = g_lcd_height - (y + h);
    377         rot_y = x;
    378         rot_w = h;
    379         rot_h = w;
    380     }
    381 
    382     configure_window(&format.fmt.win, rot_w, rot_h, rot_x, rot_y);
    383 
    384     format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
    385     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &format,
    386             "set v4l2_overlay format");
    387 
    388     LOGV("v4l2_overlay_set_position:: w=%d h=%d rotation=%d"
    389                  , format.fmt.win.w.width, format.fmt.win.w.height, rotation);
    390 
    391     if (ret)
    392         return ret;
    393     v4l2_overlay_dump_state(fd);
    394 
    395     return 0;
    396 }
    397 
    398 int v4l2_overlay_get_position(int fd, int32_t *x, int32_t *y, int32_t *w,
    399                               int32_t *h)
    400 {
    401     struct v4l2_format format;
    402     int ret;
    403 
    404     format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
    405     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &format,
    406                                  "get v4l2_overlay format");
    407 
    408     if (ret)
    409         return ret;
    410 
    411     get_window(&format, x, y, w, h);
    412 
    413     return 0;
    414 }
    415 
    416 int v4l2_overlay_set_crop(int fd, uint32_t x, uint32_t y, uint32_t w,
    417                           uint32_t h)
    418 {
    419     LOG_FUNCTION_NAME
    420 
    421     struct v4l2_crop crop;
    422     int ret;
    423 
    424     crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    425     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_CROP, &crop, "get crop");
    426     crop.c.left = x;
    427     crop.c.top = y;
    428     crop.c.width = w;
    429     crop.c.height = h;
    430     crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    431 
    432     LOGV("%s:crop.c.left = %d\n", __func__, crop.c.left);
    433     LOGV("%s:crop.c.top = %d\n", __func__, crop.c.top);
    434     LOGV("%s:crop.c.width = %d\n", __func__, crop.c.width);
    435     LOGV("%s:crop.c.height = %d\n", __func__, crop.c.height);
    436     LOGV("%s:crop.type = 0x%x\n", __func__, crop.type);
    437 
    438     return v4l2_overlay_ioctl(fd, VIDIOC_S_CROP, &crop, "set crop");
    439 }
    440 
    441 int v4l2_overlay_get_crop(int fd, uint32_t *x, uint32_t *y, uint32_t *w,
    442                           uint32_t *h)
    443 {
    444     LOG_FUNCTION_NAME
    445 
    446     struct v4l2_crop crop;
    447     int ret;
    448 
    449     crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    450     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_CROP, &crop, "get crop");
    451     *x = crop.c.left;
    452     *y = crop.c.top;
    453     *w = crop.c.width;
    454     *h = crop.c.height;
    455     return ret;
    456 }
    457 
    458 int v4l2_overlay_set_flip(int fd, int flip)
    459 {
    460     LOG_FUNCTION_NAME
    461 
    462     int ret;
    463     struct v4l2_control ctrl_v;
    464     struct v4l2_control ctrl_h;
    465 
    466     switch (flip) {
    467     case 0:
    468         ctrl_v.value = 0;
    469         ctrl_h.value = 0;
    470         break;
    471     case V4L2_CID_HFLIP:
    472         ctrl_v.value = 0;
    473         ctrl_h.value = 1;
    474         break;
    475     case V4L2_CID_VFLIP:
    476         ctrl_v.value = 1;
    477         ctrl_h.value = 0;
    478         break;
    479     default:
    480         return -1;
    481     }
    482 
    483     ctrl_v.id = V4L2_CID_VFLIP;
    484     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_CTRL, &ctrl_v, "set vflip");
    485     if (ret) return ret;
    486 
    487     ctrl_h.id = V4L2_CID_HFLIP;
    488     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_CTRL, &ctrl_h, "set hflip");
    489     return ret;
    490 }
    491 
    492 int v4l2_overlay_set_rotation(int fd, int degree, int step)
    493 {
    494     LOG_FUNCTION_NAME
    495 
    496     int ret;
    497     struct v4l2_control ctrl;
    498 
    499     ctrl.id = V4L2_CID_PRIV_ROTATION;
    500     ctrl.value = degree;
    501     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_CTRL, &ctrl, "set rotation");
    502 
    503     return ret;
    504 }
    505 
    506 int v4l2_overlay_set_colorkey(int fd, int enable, int colorkey)
    507 {
    508     LOG_FUNCTION_NAME
    509 
    510     int ret;
    511     struct v4l2_framebuffer fbuf;
    512     struct v4l2_format fmt;
    513 
    514     memset(&fbuf, 0, sizeof(fbuf));
    515     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf,
    516                              "get transparency enables");
    517 
    518     if (ret)
    519         return ret;
    520 
    521     if (enable)
    522         fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY;
    523     else
    524         fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY;
    525 
    526     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "enable colorkey");
    527 
    528     if (ret)
    529         return ret;
    530 
    531     if (enable) {
    532         memset(&fmt, 0, sizeof(fmt));
    533         fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
    534         ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &fmt, "get colorkey");
    535 
    536         if (ret)
    537             return ret;
    538 
    539         fmt.fmt.win.chromakey = colorkey & 0xFFFFFF;
    540 
    541         ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &fmt, "set colorkey");
    542     }
    543 
    544     return ret;
    545 }
    546 
    547 int v4l2_overlay_set_global_alpha(int fd, int enable, int alpha)
    548 {
    549     LOG_FUNCTION_NAME
    550 
    551     int ret;
    552     struct v4l2_framebuffer fbuf;
    553     struct v4l2_format fmt;
    554 
    555     memset(&fbuf, 0, sizeof(fbuf));
    556     ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FBUF, &fbuf,
    557                              "get transparency enables");
    558 
    559     if (ret)
    560         return ret;
    561 
    562     if (enable)
    563         fbuf.flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
    564     else
    565         fbuf.flags &= ~V4L2_FBUF_FLAG_GLOBAL_ALPHA;
    566 
    567     ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FBUF, &fbuf, "enable global alpha");
    568 
    569     if (ret)
    570         return ret;
    571 
    572     if (enable) {
    573         memset(&fmt, 0, sizeof(fmt));
    574         fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
    575         ret = v4l2_overlay_ioctl(fd, VIDIOC_G_FMT, &fmt, "get global alpha");
    576 
    577         if (ret)
    578             return ret;
    579 
    580         fmt.fmt.win.global_alpha = alpha & 0xFF;
    581 
    582         ret = v4l2_overlay_ioctl(fd, VIDIOC_S_FMT, &fmt, "set global alpha");
    583     }
    584 
    585     return ret;
    586 }
    587 
    588 int v4l2_overlay_set_local_alpha(int fd, int enable)
    589 {
    590     int ret;
    591     struct v4l2_framebuffer fbuf;
    592 
    593     ret = 0;
    594 
    595     return ret;
    596 }
    597 
    598 int v4l2_overlay_req_buf(int fd, uint32_t *num_bufs, int cacheable_buffers, int zerocopy)
    599 {
    600     struct v4l2_requestbuffers reqbuf;
    601     int ret, i;
    602 
    603     reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    604 
    605     if (zerocopy)
    606         reqbuf.memory = V4L2_MEMORY_USERPTR;
    607     else
    608         reqbuf.memory = V4L2_MEMORY_MMAP;
    609     reqbuf.count = *num_bufs;
    610 
    611     ret = ioctl(fd, VIDIOC_REQBUFS, &reqbuf);
    612     if (ret < 0) {
    613         error(fd, "reqbuf ioctl");
    614         return ret;
    615     }
    616 
    617     if (reqbuf.count > *num_bufs) {
    618         error(fd, "Not enough buffer structs passed to get_buffers");
    619         return -ENOMEM;
    620     }
    621     *num_bufs = reqbuf.count;
    622 
    623     return 0;
    624 }
    625 
    626 static int is_mmaped(struct v4l2_buffer *buf)
    627 {
    628     return buf->flags == V4L2_BUF_FLAG_MAPPED;
    629 }
    630 
    631 static int is_queued(struct v4l2_buffer *buf)
    632 {
    633     /* is either on the input or output queue in the kernel */
    634     return (buf->flags & V4L2_BUF_FLAG_QUEUED) ||
    635         (buf->flags & V4L2_BUF_FLAG_DONE);
    636 }
    637 
    638 static int is_dequeued(struct v4l2_buffer *buf)
    639 {
    640     /* is on neither input or output queue in kernel */
    641     return !(buf->flags & V4L2_BUF_FLAG_QUEUED) &&
    642             !(buf->flags & V4L2_BUF_FLAG_DONE);
    643 }
    644 
    645 int v4l2_overlay_query_buffer(int fd, int index, struct v4l2_buffer *buf)
    646 {
    647     LOG_FUNCTION_NAME
    648 
    649     memset(buf, 0, sizeof(struct v4l2_buffer));
    650 
    651     buf->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    652     buf->memory = V4L2_MEMORY_MMAP;
    653     buf->index = index;
    654     LOGV("query buffer, mem=%u type=%u index=%u\n",
    655          buf->memory, buf->type, buf->index);
    656     return v4l2_overlay_ioctl(fd, VIDIOC_QUERYBUF, buf, "querybuf ioctl");
    657 }
    658 
    659 int v4l2_overlay_map_buf(int fd, int index, void **start, size_t *len)
    660 {
    661     LOG_FUNCTION_NAME
    662 
    663     struct v4l2_buffer buf;
    664     int ret;
    665 
    666     ret = v4l2_overlay_query_buffer(fd, index, &buf);
    667     if (ret)
    668         return ret;
    669 
    670     if (is_mmaped(&buf)) {
    671         LOGE("Trying to mmap buffers that are already mapped!\n");
    672         return -EINVAL;
    673     }
    674 
    675     *len = buf.length;
    676     *start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED,
    677             fd, buf.m.offset);
    678     if (*start == MAP_FAILED) {
    679         LOGE("map failed, length=%u offset=%u\n", buf.length, buf.m.offset);
    680         return -EINVAL;
    681     }
    682     return 0;
    683 }
    684 
    685 int v4l2_overlay_unmap_buf(void *start, size_t len)
    686 {
    687     LOG_FUNCTION_NAME
    688     return munmap(start, len);
    689 }
    690 
    691 
    692 int v4l2_overlay_get_caps(int fd, struct v4l2_capability *caps)
    693 {
    694     return v4l2_overlay_ioctl(fd, VIDIOC_QUERYCAP, caps, "query cap");
    695 }
    696 
    697 int v4l2_overlay_stream_on(int fd)
    698 {
    699     int ret;
    700     uint32_t type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    701 
    702     ret = v4l2_overlay_set_local_alpha(fd, 1);
    703     if (ret)
    704         return ret;
    705 
    706     ret = v4l2_overlay_ioctl(fd, VIDIOC_STREAMON, &type, "stream on");
    707 
    708     return ret;
    709 }
    710 
    711 int v4l2_overlay_stream_off(int fd)
    712 {
    713     int ret;
    714     uint32_t type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    715 
    716     ret = v4l2_overlay_set_local_alpha(fd, 0);
    717     if (ret)
    718         return ret;
    719 
    720     ret = v4l2_overlay_ioctl(fd, VIDIOC_STREAMOFF, &type, "stream off");
    721 
    722     return ret;
    723 }
    724 
    725 int v4l2_overlay_q_buf(int fd, int buffer, int zerocopy)
    726 {
    727     struct v4l2_buffer buf;
    728     int ret;
    729 
    730     if (zerocopy) {
    731         uint8_t *pPhyYAddr;
    732         uint8_t *pPhyCAddr;
    733         struct fimc_buf fimc_src_buf;
    734         uint8_t index;
    735 
    736         memcpy(&pPhyYAddr, (void *) buffer, sizeof(pPhyYAddr));
    737         memcpy(&pPhyCAddr, (void *) (buffer + sizeof(pPhyYAddr)),
    738                sizeof(pPhyCAddr));
    739         memcpy(&index,
    740                (void *) (buffer + sizeof(pPhyYAddr) + sizeof(pPhyCAddr)),
    741                sizeof(index));
    742 
    743         fimc_src_buf.base[0] = (dma_addr_t) pPhyYAddr;
    744         fimc_src_buf.base[1] = (dma_addr_t) pPhyCAddr;
    745         fimc_src_buf.base[2] =
    746                (dma_addr_t) (pPhyCAddr + (pPhyCAddr - pPhyYAddr)/4);
    747 
    748         buf.index = index;
    749         buf.memory      = V4L2_MEMORY_USERPTR;
    750         buf.m.userptr   = (unsigned long)&fimc_src_buf;
    751         buf.length      = 0;
    752     } else {
    753         buf.index = buffer;
    754         buf.memory      = V4L2_MEMORY_MMAP;
    755     }
    756 
    757     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    758     buf.field = V4L2_FIELD_NONE;
    759     buf.timestamp.tv_sec = 0;
    760     buf.timestamp.tv_usec = 0;
    761     buf.flags = 0;
    762 
    763     return v4l2_overlay_ioctl(fd, VIDIOC_QBUF, &buf, "qbuf");
    764 }
    765 
    766 int v4l2_overlay_dq_buf(int fd, int *index, int zerocopy)
    767 {
    768     struct v4l2_buffer buf;
    769     int ret;
    770 
    771     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    772 
    773     if (zerocopy)
    774         buf.memory = V4L2_MEMORY_USERPTR;
    775     else
    776         buf.memory = V4L2_MEMORY_MMAP;
    777 
    778     ret = v4l2_overlay_ioctl(fd, VIDIOC_DQBUF, &buf, "dqbuf");
    779     if (ret)
    780         return ret;
    781     *index = buf.index;
    782     return 0;
    783 }
    784